最近太忙,一直没时间更新,使用Python和tkinter简单写了一个通过速度模式进行寸动控制的程序,另外外接了一个20倍的减速器,虽然将就可用,但是精度只能控制为0.3°的倍数,没有达到我理想中的1°控制
简单界面如下:
Python的源码如下:(python使用的版本为3.8.3 pyinstaller版本为4.0 )
import tkinter as tk
from tkinter import ttk
from tkinter import *
from tkinter import messagebox
import threading
import os
import datetime
import serial
import time
import serial.tools.list_ports
import crcmod.predefined
# CRC16校验 入参为校验数据(16进制字符串) 返回带校验码的数据
def mk_crc_16(data):
crc16_func = crcmod.predefined.mkCrcFun('modbus')
crc8_func_value = crc16_func(bytes().fromhex(data))
CRC_16_result = hex(crc8_func_value)
# 去掉0x 并且对校验结果补位
CRC_16_result = CRC_16_result[2:]
CRC_16_result = CRC_16_result.***ill(4)
# 高低位颠倒
final_data = data + CRC_16_result[2:] + CRC_16_result[0:2]
return final_data
# 线程函数,用于开启独立线程后台执行,不影响界面刷新
def thread_another(func, *args):
# 创建
t = threading.Thread(target=func, args=args)
# 守护 随主进程消亡
t.setDaemon(True)
# 启动
t.start()
#
def send_485_cmd(cmd):
ser = serial.Serial('COM21', 38400, bytesize=8, parity='E', stopbits=1) # 选择串口,并设置波特率
if ser.is_open:
print("打开串口成功")
# 获取协议数据的CRC16校验码
agreement_add_crc = mk_crc_16(cmd)
print(agreement_add_crc)
# hex(16进制)转换为bytes(2进制)
send_data = bytes.fromhex(agreement_add_crc) # 发送数据转换为b'xffx01x00Ux00x00V'
ser.write(send_data) # 发送命令
time.sleep(0.1) # 延时,否则len_return_data将返回0,此处易忽视!!!
len_return_data = ser.inWaiting() # 获取缓冲数据(接收数据)长度
if len_return_data:
return_data = ser.read(len_return_data) # 读取缓冲数据
str_return_data = str(return_data.hex())
print(str_return_data)
print(agreement_add_crc)
# 判断设置成功与否
if str_return_data == agreement_add_crc:
print("设置成功")
# messagebox.showinfo(title='提示信息', message='设置成功')
else:
print("设置失败")
# messagebox.showinfo(title='提示信息', message='设置失败')
ser.close()
# 关闭窗口回调函数
def on_closing():
if messagebox.askokcancel("退出", " 是否确定关闭程序?"):
window.destroy()
# 电机servo ON
def motor_servo_on():
print("电机启动")
# 设置P2-10 为 1
send_485_cmd('010602140001')
# 电机servo OFF
def motor_servo_off():
print("电机停止")
# 设置P2-10 为 101
send_485_cmd('010602140101')
# 电机寸动(JOG)控制 顺时针
def motor_ccw():
print("电机顺时针转")
# 设置P4-05地址 040A 040B 十进制为4998
send_485_cmd('0106040a1386')
# 电机寸动(JOG)控制 逆时针
def motor_cw():
print("电机逆时针转")
# 设置P4-05地址 040A 040B 十进制为4999
send_485_cmd('0106040a1387')
# 电机寸动(JOG)控制 停止运转
def motor_stop():
print("电机停止运转")
# 设置P4-05地址 040A 040B 十进制为0
send_485_cmd('0106040a0000')
def motor_speed_set():
print("电机速度设置")
# 设置P4-05地址 040A 040B 十进制范围:1~5000
# 获取设置的值
speedVar = speed_entry.get()
toHexStr = hex(int(speedVar))[2:]
print(toHexStr)
# 补位 补0
if len(toHexStr) < 4:
toHexStr = toHexStr.***ill(4)
print(toHexStr)
# 组帧
speedCMD = '0106040a' + toHexStr
print(speedCMD)
send_485_cmd(speedCMD)
window = tk.Tk()
# 设置窗口大小
winWidth = 515
winHeight = 295
# 获取屏幕分辨率
screenWidth = window.winfo_screenwidth()
screenHeight = window.winfo_screenheight()
x = int((screenWidth - winWidth) / 2)
y = int((screenHeight - winHeight) / 2)
# 设置主窗口标题
window.title("台达A2-M 485控制")
# 设置窗口初始位置在屏幕居中
window.geometry("%sx%s+%s+%s" % (winWidth, winHeight, x, y))
# 设置窗口图标
# 获取当前路径下的CAN动态库路径
ico_realPath = os.path.join(os.path.dirname(os.path.realpath(__file__)), '123.ico')
window.iconbitmap(ico_realPath)
# 设置窗口宽高固定
window.resizable(0, 0)
# 电机 servo on
Button1 = Button(window, text='电机servo ON', borderwidth=2, relief="groove", width=14, height=1, font=('Microsoft YaHei', 13), fg='white', bg='Purple', command=lambda :thread_another(motor_servo_on))
Button1.grid(row=0, column=0, columnspan=2, rowspan=1, padx = 10, pady = 10)
# 电机 servo off
Button2 = Button(window, text='电机servo OFF', borderwidth=2, relief="groove", width=14, height=1, font=('Microsoft YaHei', 13), fg='white', bg='Purple', command=lambda :thread_another(motor_servo_off))
Button2.grid(row=0, column=2, columnspan=2, rowspan=1, padx = 10, pady = 10)
# 电机寸动 逆时针
Button3 = Button(window, text='寸动(顺时针)', borderwidth=2, relief="groove", width=14, height=1, font=('Microsoft YaHei', 13), fg='white', bg='Purple', command=lambda :thread_another(motor_ccw))
Button3.grid(row=1, column=0, columnspan=2, rowspan=1, padx = 10, pady = 10)
# 电机寸动 顺时针
Button4 = Button(window, text='寸动(逆时针)', borderwidth=2, relief="groove", width=14, height=1, font=('Microsoft YaHei', 13), fg='white', bg='Purple', command=lambda :thread_another(motor_cw))
Button4.grid(row=1, column=2, columnspan=2, rowspan=1, padx = 10, pady = 10)
# 电机停止运转
Button5 = Button(window, text='停止运转', borderwidth=2, relief="groove", width=14, height=1, font=('Microsoft YaHei', 13), fg='white', bg='Purple', command=lambda :thread_another(motor_stop))
Button5.grid(row=1, column=4, columnspan=2, rowspan=1, padx = 10, pady = 10)
# 寸动速度 标签
speed_label = Label(window, text='寸动速度(r/min):', width=14, height=1, font=('Microsoft YaHei', 13), fg='blue')
speed_label.grid(row=2, column=0, columnspan=2, rowspan=1, padx = 10, pady = 10)
# 寸动速度 输入框
speed_num = StringVar()
speed_entry = Entry(window, textvariable = speed_num, width=14, font=('Microsoft YaHei', 13), fg='blue')
speed_entry.grid(row=2, column=2, columnspan=2, rowspan=1, padx = 10, pady = 10)
# 寸动速度 设置按钮
Button6 = Button(window, text='速度设置', borderwidth=2, relief="groove", width=14, height=1, font=('Microsoft YaHei', 13), fg='white', bg='Purple', command=lambda :thread_another(motor_speed_set))
Button6.grid(row=2, column=4, columnspan=2, rowspan=1, padx = 10, pady = 10)
#window.protocol("WM_DELETE_WINDOW", on_closing)
window.mainloop()
最近太忙,一直没时间更新,使用Python和tkinter简单写了一个通过速度模式进行寸动控制的程序,另外外接了一个20倍的减速器,虽然将就可用,但是精度只能控制为0.3°的倍数,没有达到我理想中的1°控制
简单界面如下:
Python的源码如下:(python使用的版本为3.8.3 pyinstaller版本为4.0 )
import tkinter as tk
from tkinter import ttk
from tkinter import *
from tkinter import messagebox
import threading
import os
import datetime
import serial
import time
import serial.tools.list_ports
import crcmod.predefined
# CRC16校验 入参为校验数据(16进制字符串) 返回带校验码的数据
def mk_crc_16(data):
crc16_func = crcmod.predefined.mkCrcFun('modbus')
crc8_func_value = crc16_func(bytes().fromhex(data))
CRC_16_result = hex(crc8_func_value)
# 去掉0x 并且对校验结果补位
CRC_16_result = CRC_16_result[2:]
CRC_16_result = CRC_16_result.***ill(4)
# 高低位颠倒
final_data = data + CRC_16_result[2:] + CRC_16_result[0:2]
return final_data
# 线程函数,用于开启独立线程后台执行,不影响界面刷新
def thread_another(func, *args):
# 创建
t = threading.Thread(target=func, args=args)
# 守护 随主进程消亡
t.setDaemon(True)
# 启动
t.start()
#
def send_485_cmd(cmd):
ser = serial.Serial('COM21', 38400, bytesize=8, parity='E', stopbits=1) # 选择串口,并设置波特率
if ser.is_open:
print("打开串口成功")
# 获取协议数据的CRC16校验码
agreement_add_crc = mk_crc_16(cmd)
print(agreement_add_crc)
# hex(16进制)转换为bytes(2进制)
send_data = bytes.fromhex(agreement_add_crc) # 发送数据转换为b'xffx01x00Ux00x00V'
ser.write(send_data) # 发送命令
time.sleep(0.1) # 延时,否则len_return_data将返回0,此处易忽视!!!
len_return_data = ser.inWaiting() # 获取缓冲数据(接收数据)长度
if len_return_data:
return_data = ser.read(len_return_data) # 读取缓冲数据
str_return_data = str(return_data.hex())
print(str_return_data)
print(agreement_add_crc)
# 判断设置成功与否
if str_return_data == agreement_add_crc:
print("设置成功")
# messagebox.showinfo(title='提示信息', message='设置成功')
else:
print("设置失败")
# messagebox.showinfo(title='提示信息', message='设置失败')
ser.close()
# 关闭窗口回调函数
def on_closing():
if messagebox.askokcancel("退出", " 是否确定关闭程序?"):
window.destroy()
# 电机servo ON
def motor_servo_on():
print("电机启动")
# 设置P2-10 为 1
send_485_cmd('010602140001')
# 电机servo OFF
def motor_servo_off():
print("电机停止")
# 设置P2-10 为 101
send_485_cmd('010602140101')
# 电机寸动(JOG)控制 顺时针
def motor_ccw():
print("电机顺时针转")
# 设置P4-05地址 040A 040B 十进制为4998
send_485_cmd('0106040a1386')
# 电机寸动(JOG)控制 逆时针
def motor_cw():
print("电机逆时针转")
# 设置P4-05地址 040A 040B 十进制为4999
send_485_cmd('0106040a1387')
# 电机寸动(JOG)控制 停止运转
def motor_stop():
print("电机停止运转")
# 设置P4-05地址 040A 040B 十进制为0
send_485_cmd('0106040a0000')
def motor_speed_set():
print("电机速度设置")
# 设置P4-05地址 040A 040B 十进制范围:1~5000
# 获取设置的值
speedVar = speed_entry.get()
toHexStr = hex(int(speedVar))[2:]
print(toHexStr)
# 补位 补0
if len(toHexStr) < 4:
toHexStr = toHexStr.***ill(4)
print(toHexStr)
# 组帧
speedCMD = '0106040a' + toHexStr
print(speedCMD)
send_485_cmd(speedCMD)
window = tk.Tk()
# 设置窗口大小
winWidth = 515
winHeight = 295
# 获取屏幕分辨率
screenWidth = window.winfo_screenwidth()
screenHeight = window.winfo_screenheight()
x = int((screenWidth - winWidth) / 2)
y = int((screenHeight - winHeight) / 2)
# 设置主窗口标题
window.title("台达A2-M 485控制")
# 设置窗口初始位置在屏幕居中
window.geometry("%sx%s+%s+%s" % (winWidth, winHeight, x, y))
# 设置窗口图标
# 获取当前路径下的CAN动态库路径
ico_realPath = os.path.join(os.path.dirname(os.path.realpath(__file__)), '123.ico')
window.iconbitmap(ico_realPath)
# 设置窗口宽高固定
window.resizable(0, 0)
# 电机 servo on
Button1 = Button(window, text='电机servo ON', borderwidth=2, relief="groove", width=14, height=1, font=('Microsoft YaHei', 13), fg='white', bg='Purple', command=lambda :thread_another(motor_servo_on))
Button1.grid(row=0, column=0, columnspan=2, rowspan=1, padx = 10, pady = 10)
# 电机 servo off
Button2 = Button(window, text='电机servo OFF', borderwidth=2, relief="groove", width=14, height=1, font=('Microsoft YaHei', 13), fg='white', bg='Purple', command=lambda :thread_another(motor_servo_off))
Button2.grid(row=0, column=2, columnspan=2, rowspan=1, padx = 10, pady = 10)
# 电机寸动 逆时针
Button3 = Button(window, text='寸动(顺时针)', borderwidth=2, relief="groove", width=14, height=1, font=('Microsoft YaHei', 13), fg='white', bg='Purple', command=lambda :thread_another(motor_ccw))
Button3.grid(row=1, column=0, columnspan=2, rowspan=1, padx = 10, pady = 10)
# 电机寸动 顺时针
Button4 = Button(window, text='寸动(逆时针)', borderwidth=2, relief="groove", width=14, height=1, font=('Microsoft YaHei', 13), fg='white', bg='Purple', command=lambda :thread_another(motor_cw))
Button4.grid(row=1, column=2, columnspan=2, rowspan=1, padx = 10, pady = 10)
# 电机停止运转
Button5 = Button(window, text='停止运转', borderwidth=2, relief="groove", width=14, height=1, font=('Microsoft YaHei', 13), fg='white', bg='Purple', command=lambda :thread_another(motor_stop))
Button5.grid(row=1, column=4, columnspan=2, rowspan=1, padx = 10, pady = 10)
# 寸动速度 标签
speed_label = Label(window, text='寸动速度(r/min):', width=14, height=1, font=('Microsoft YaHei', 13), fg='blue')
speed_label.grid(row=2, column=0, columnspan=2, rowspan=1, padx = 10, pady = 10)
# 寸动速度 输入框
speed_num = StringVar()
speed_entry = Entry(window, textvariable = speed_num, width=14, font=('Microsoft YaHei', 13), fg='blue')
speed_entry.grid(row=2, column=2, columnspan=2, rowspan=1, padx = 10, pady = 10)
# 寸动速度 设置按钮
Button6 = Button(window, text='速度设置', borderwidth=2, relief="groove", width=14, height=1, font=('Microsoft YaHei', 13), fg='white', bg='Purple', command=lambda :thread_another(motor_speed_set))
Button6.grid(row=2, column=4, columnspan=2, rowspan=1, padx = 10, pady = 10)
#window.protocol("WM_DELETE_WINDOW", on_closing)
window.mainloop()
举报