ESP32+micropython+TB6600控制器+42步进电机【续】 wifi +udp遥控

参照合集 “ESP32+micro python+编程” 内容。继续增加功能

思路: PC机(上位机)的网络调试助手(Net Assist)发送指令,ESP接收指令,控制步进电机

 

将  ESP32+micropython+TB6600控制器+42步进电机  和 eps32+micro python+ wifi UDP方式接收和发送数据

的代码 贴到一个文件中,经过少量修改(背景色突出),即可实现 wifi控制

复制代码
import machine
import time
# TB6600 两相混合式步进电机驱动器说明书
#要点: 脉冲宽度不小于1.2us
#      方向信号先于脉冲信号不少于5us


# 方向控制
STEP_MOTOR_DIR = machine.Pin(2, machine.Pin.OUT)
# 脉冲信号,即PWM波,频率和脉冲数可设置
STEP_MOTOR_PUL = machine.Pin(1, machine.Pin.OUT)

# 步进电机 转动一个步进角
def ONE_STEP_FUN(half_period_us):
    STEP_MOTOR_PUL.value(1)
    time.sleep_us(half_period_us)
    STEP_MOTOR_PUL.value(0)
    time.sleep_us(half_period_us)    
    return

# 步进电机 变更方向
def DIR_STEP_FUN( unclockwise=1):
    time.sleep_us(10) #方向信号先于脉冲信号不少于5us
    STEP_MOTOR_DIR.value(unclockwise)
    time.sleep_us(10) #方向信号先于脉冲信号不少于5us
    return


# 按照加速-匀速-减速过程控制步进电机,参数:步数、脉冲控制
def STEP_ROTATE_FUN(freq,steps):
    half_period_us_target = 1000000/freq # 1000 000 us/1000Hz
    steps_now = 0
    half_period_us = 200 # us
    speed_up_steps =0 # 记录加速的步数
    for i in range(steps):
        ONE_STEP_FUN(half_period_us)
        
        if(half_period_us > half_period_us_target) and(i*2<=steps) and(half_period_us !=10):
            half_period_us = half_period_us-10 # 加速过程
            speed_up_steps =speed_up_steps+1   # 记录加速的步数
            if half_period_us< 10:
                half_period_us =10
        
        if(steps-i<= speed_up_steps)and(i*2>steps) :
             half_period_us = half_period_us+10 # 减速过程
            
    return


# 整体流程
# 1. 链接wifi
# 2. 启动网络功能(UDP)
# 3. 接收网络数据
# 4. 处理接收的数据


import socket
import time
import network
import machine


def do_connect():
    wlan = network.WLAN(network.STA_IF)
    wlan.active(True)
    if not wlan.isconnected():
        print('connecting to network...')
        wlan.connect('dongfeiqiu', 'wangmingdong1225')# 输入wifi热点账号和密码
        i = 1
        while not wlan.isconnected():
            print("正在链接...{}".format(i))
            i += 1
            time.sleep(1)
    print('network config:', wlan.ifconfig())


def start_udp():
    # 2. 启动网络功能(UDP)

    # 2.1. 创建udp套接字
    udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    # 2.2. 绑定本地信息
    udp_socket.bind(("0.0.0.0", 7788))

    return udp_socket


def main():
    # 1. 链接wifi
    do_connect()
    # 2. 创建UDP
    udp_socket = start_udp()
    # 3. 接收网络数据
    while True:
        recv_data, sender_info = udp_socket.recvfrom(1024)
        
        #  解析对方的ip地址
        dest_ip = sender_info[0]
        #  解析对方的port
        dest_port = int(sender_info[1])
            
        print("{}发送{}".format(sender_info, recv_data))
        
        try:# 错误信息处理
            recv_data_str = recv_data.decode("utf-8")
            print(recv_data_str)
        except Exception as ret:
            print("error:", ret)
            continue
        
        # 4. 处理接收的数据
        if recv_data_str   == "rotate clockwise":
            msg ="rotate clockwise"
            #  发送数据
            udp_socket.sendto(msg.encode("utf-8"), (dest_ip, dest_port))
            
            print("这里是要顺时针转动的代码...")
            print("unclockwise=0")
            DIR_STEP_FUN(0)
            STEP_ROTATE_FUN(8000,8000)
            
        elif recv_data_str == "rotate unclockwise":
            msg ="rotate unclockwise"
            #  发送数据
            udp_socket.sendto(msg.encode("utf-8"), (dest_ip, dest_port))
            
            print("这里是要逆时针转动的代码...")
            print("unclockwise=1")
            DIR_STEP_FUN(1)
            STEP_ROTATE_FUN(8000,8000)
            
        else:
            msg ="please input rotate clockwise or rotate unclockwise"
            #  发送数据
            udp_socket.sendto(msg.encode("utf-8"), (dest_ip, dest_port))


if __name__ == "__main__":
    main()

#     print("unclockwise=1")
#     DIR_STEP_FUN(1)
# #     for i in range(4000):
# #         ONE_STEP_FUN()
#     STEP_ROTATE_FUN(8000,8000)
#     time.sleep(1)
#     print("unclockwise=0")
#     DIR_STEP_FUN(0)
# #     for i in range(4000):
# #         ONE_STEP_FUN()
#     STEP_ROTATE_FUN(8000,8000)
#     time.sleep(1)
复制代码

继续改进,希望通过wifi发频率,步数等参数控制步进电机。

数据类型,选择dict字典,特别考虑到已实现UDP收发字符串。编写一小段代码,测试一下如何使用json将字典与字符串互相转换

Net Assit使用的测试字符串:{"steps": 8000, "clockwise":1, "freq": 8000, "crc": "0xFF"}  和 {"steps": 8000, "clockwise":0, "freq": 8000, "crc": "0xFF"}

 

复制代码
import json
 
# 准备数据
data = {
    "clockwise": 1,
    "freq": 8000,
    "steps": 8000,
    "crc": '0xFF'
}
# 字典编码为字符串
msg_str = json.dumps(data)
print(type(msg_str))
print("json字符串:{}".format(msg_str))
# 字符串解码为字典
data_ = json.loads(msg_str)
print(type(data_ ))
print("json字典:{}".format(data_ ))
复制代码

 

实现改进,通过wifi发方向,频率,步数等参数控制步进电机。

复制代码
import machine
import time
# TB6600 两相混合式步进电机驱动器说明书
#要点: 脉冲宽度不小于1.2us
#      方向信号先于脉冲信号不少于5us


# 方向控制
STEP_MOTOR_DIR = machine.Pin(2, machine.Pin.OUT)
# 脉冲信号,即PWM波,频率和脉冲数可设置
STEP_MOTOR_PUL = machine.Pin(1, machine.Pin.OUT)

# 步进电机 转动一个步进角
def ONE_STEP_FUN(half_period_us):
    STEP_MOTOR_PUL.value(1)
    time.sleep_us(half_period_us)
    STEP_MOTOR_PUL.value(0)
    time.sleep_us(half_period_us)    
    return

# 步进电机 变更方向
def DIR_STEP_FUN( unclockwise=1):
    time.sleep_us(10) #方向信号先于脉冲信号不少于5us
    STEP_MOTOR_DIR.value(unclockwise)
    time.sleep_us(10) #方向信号先于脉冲信号不少于5us
    return


# 按照加速-匀速-减速过程控制步进电机,参数:步数、脉冲控制
def STEP_ROTATE_FUN(freq,steps):
    half_period_us_target = 1000000/freq # 1000 000 us/1000Hz
    steps_now = 0
    half_period_us = 200 # us
    speed_up_steps =0 # 记录加速的步数
    for i in range(steps):
        ONE_STEP_FUN(half_period_us)
        
        if(half_period_us > half_period_us_target) and(i*2<=steps) and(half_period_us !=10):
            half_period_us = half_period_us-10 # 加速过程
            speed_up_steps =speed_up_steps+1   # 记录加速的步数
            if half_period_us< 10:
                half_period_us =10
        
        if(steps-i<= speed_up_steps)and(i*2>steps) :
             half_period_us = half_period_us+10 # 减速过程
            
    return


# 整体流程
# 1. 链接wifi
# 2. 启动网络功能(UDP)
# 3. 接收网络数据
# 4. 处理接收的数据


import socket
import time
import network
import machine

import json

def do_connect():
    wlan = network.WLAN(network.STA_IF)
    wlan.active(True)
    if not wlan.isconnected():
        print('connecting to network...')
        wlan.connect('dongfeiqiu', 'wangmingdong1225')# 输入wifi热点账号和密码
        i = 1
        while not wlan.isconnected():
            print("正在链接...{}".format(i))
            i += 1
            time.sleep(1)
    print('network config:', wlan.ifconfig())


def start_udp():
    # 2. 启动网络功能(UDP)

    # 2.1. 创建udp套接字
    udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    # 2.2. 绑定本地信息
    udp_socket.bind(("0.0.0.0", 7788))

    return udp_socket


def main():
    # 1. 链接wifi
    do_connect()
    # 2. 创建UDP
    udp_socket = start_udp()
    # 3. 接收网络数据
    while True:
        recv_data, sender_info = udp_socket.recvfrom(1024)
        
        #  解析对方的ip地址
        dest_ip = sender_info[0]
        #  解析对方的port
        dest_port = int(sender_info[1])
            
        print("{}发送{}".format(sender_info, recv_data))
        
        try:# 错误信息处理
            recv_data_str = recv_data.decode("utf-8")
            print(recv_data_str)
            
            cmd_dict = json.loads(recv_data_str) #json字符串 解码为字典
            #举例子{'steps': 8000, 'clockwise': 1, 'freq': 8000, 'crc': '0xFF'}
            print(cmd_dict)
        except Exception as ret:
            print("error:", ret)
            continue
        
        # 4. 处理接收的数据
        msg =json.dumps(cmd_dict)
        #  发送数据
        udp_socket.sendto(msg.encode("utf-8"), (dest_ip, dest_port))
        
        print("执行命令...")
        DIR_STEP_FUN(cmd_dict['clockwise'])
        STEP_ROTATE_FUN(cmd_dict['freq'],cmd_dict['steps'])
        print("...完成命令")

if __name__ == "__main__":
    main()
复制代码

 

 

发现在电机STEP_ROTATE_FUN()函数执行中,就不能进行wifi通信。 解决办法是 多线程。参考:本合集 的  4.ESP32+micropython + 多线程

修改为,接收命令,启动一个电机线程执行STEP_ROTATE_FUN()函数。

 

复制代码
import socket
import time
import network
import machine

import json    # json
import _thread # 多线程

STEP_ROTATE_FUN_thread_none = True # 标识 电机正在运行,防止多个线程同时控制电机

# TB6600 两相混合式步进电机驱动器说明书
#要点: 脉冲宽度不小于1.2us
#      方向信号先于脉冲信号不少于5us


# 方向控制
STEP_MOTOR_DIR = machine.Pin(2, machine.Pin.OUT)
# 脉冲信号,即PWM波,频率和脉冲数可设置
STEP_MOTOR_PUL = machine.Pin(1, machine.Pin.OUT)

# 步进电机 转动一个步进角
def ONE_STEP_FUN(half_period_us):
    STEP_MOTOR_PUL.value(1)
    time.sleep_us(half_period_us)
    STEP_MOTOR_PUL.value(0)
    time.sleep_us(half_period_us)    
    return

# 步进电机 变更方向
def DIR_STEP_FUN( unclockwise=1):
    time.sleep_us(10) #方向信号先于脉冲信号不少于5us
    STEP_MOTOR_DIR.value(unclockwise)
    time.sleep_us(10) #方向信号先于脉冲信号不少于5us
    return


# 按照加速-匀速-减速过程控制步进电机,参数:步数、脉冲控制
def STEP_ROTATE_FUN(freq,steps):
    global STEP_ROTATE_FUN_thread_none
    
    STEP_ROTATE_FUN_thread_none = False # 标识 电机正在运行,防止多个线程同时控制电机
    
    half_period_us_target = 1000000/freq # 1000 000 us/1000Hz
    steps_now = 0
    half_period_us = 200 # us
    speed_up_steps =0 # 记录加速的步数
    for i in range(steps):
        ONE_STEP_FUN(half_period_us)
        
        if(half_period_us > half_period_us_target) and(i*2<=steps) and(half_period_us !=10):
            half_period_us = half_period_us-10 # 加速过程
            speed_up_steps =speed_up_steps+1   # 记录加速的步数
            if half_period_us< 10:
                half_period_us =10
        
        if(steps-i<= speed_up_steps)and(i*2>steps) :
             half_period_us = half_period_us+10 # 减速过程
    STEP_ROTATE_FUN_thread_none = True # 标识 电机正在运行,防止多个线程同时控制电
    return


# 整体流程
# 1. 链接wifi
# 2. 启动网络功能(UDP)
# 3. 接收网络数据
# 4. 处理接收的数据



def do_connect():
    wlan = network.WLAN(network.STA_IF)
    wlan.active(True)
    if not wlan.isconnected():
        print('connecting to network...')
        wlan.connect('dongfeiqiu', 'wangmingdong1225')# 输入wifi热点账号和密码
        i = 1
        while not wlan.isconnected():
            print("正在链接...{}".format(i))
            i += 1
            time.sleep(1)
    print('network config:', wlan.ifconfig())


def start_udp():
    # 2. 启动网络功能(UDP)

    # 2.1. 创建udp套接字
    udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    # 2.2. 绑定本地信息
    udp_socket.bind(("0.0.0.0", 7788))

    return udp_socket


def main():
    # 1. 链接wifi
    do_connect()
    # 2. 创建UDP
    udp_socket = start_udp()
    # 3. 接收网络数据
    while True:
        recv_data, sender_info = udp_socket.recvfrom(1024)
        
        #  解析对方的ip地址
        dest_ip = sender_info[0]
        #  解析对方的port
        dest_port = int(sender_info[1])
            
        print("{}发送{}".format(sender_info, recv_data))
        
        try:# 错误信息处理
            recv_data_str = recv_data.decode("utf-8")
            print(recv_data_str)
            
            cmd_dict = json.loads(recv_data_str) #json字符串 解码为字典
            #举例子{'steps': 8000, 'clockwise': 1, 'freq': 8000, 'crc': '0xFF'}
            print(cmd_dict)
        except Exception as ret:
            print("error:", ret)
            continue
        
        # 4. 处理接收的数据
        msg =json.dumps(cmd_dict)
        #  发送数据
        udp_socket.sendto(msg.encode("utf-8"), (dest_ip, dest_port))
        
        while(STEP_ROTATE_FUN_thread_none==False):
            print("等待当前电机STEP_ROTATE_FUN线程结束")
            #等待当前电机STEP_ROTATE_FUN线程结束
        
        print("启动线程,执行命令...")
        DIR_STEP_FUN(cmd_dict['clockwise'])

        #STEP_ROTATE_FUN(cmd_dict['freq'],cmd_dict['steps'])
        #_thread.start_new_thread(testParThread, ("a3421b",1))
        _thread.start_new_thread(STEP_ROTATE_FUN, (cmd_dict['freq'],cmd_dict['steps']))
        print("...完成命令")

if __name__ == "__main__":
    main()
复制代码

 

下一步还可以完善, 当电机运行时,直接wifi返回 异常信息 等等

 

posted @   辛河  阅读(88)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示