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返回 异常信息 等等
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)