赞
踩
最近在使用并级PID控制倒立摆,使用板子上的按键调整PID参数。按钮按久了真的不舒服,想用无线串口与Python通讯实现键盘调参。以下是我研究了一晚上的成果,期间也踩了很多坑,写下来让大家少走点弯路。
软件:Python3.9.5
库: pyserial msvcrt time
注意要安装pyserial,不要安装成serial。
如果已经有serial库需要卸载掉。
打开控制台,输入以下代码
pip install pyserial
msvcrt 和 time 库是Python自带的,不需要手动安装
1.msvcrt.getch() 该函数将键盘输入的单个字符转化为字节型返回。
所以进行判断时,要将字符转化为字节 b’ ’
if(mesg == b'q'):
2.串口只能以字节的形式通讯,所以只能接受和发送字节型数据(或字节串)
data = com.read() #接收字节型数据
print(data.decode('Ascii'),end='') #以字符型解码输出
com.write(b'q') #发送字节型数据
3.msvcrt.getch() 该函数只能在控制台运行,否则该函数只会返回 b’\xff’
import serial import msvcrt import time #对键盘输入的字符进行判断,并使用串口发送出去 def send_mesg(): if(mesg == b'q'): com.write(b'q') elif(mesg == b'e'): com.write(b'e') elif(mesg == b'a'): com.write(b'a') elif(mesg == b'd'): com.write(b'd') elif(mesg == b'w'): com.write(b'w') elif(mesg == b's'): com.write(b's') elif(mesg == b' '): com.write(b' ') #接收串口收到的数据,并打印出来 def recv_data(): #com.in_waiting 如果接收缓冲区有数据返回1 if(com.in_waiting > 0): #这个判断是为了在每一次输出玩所有信息后进行一次换行 while(com.in_waiting > 0): data = com.read() #该函数只能一次接受一个字节的信息,该循环持续到读取完所有信息 print(data.decode('Ascii'),end='') #将接受到的数据解码后打印出来 print() #首先进行串口参数配置 分别是 端口 波特率 字节大小 读取超时限制 停止位 com = serial.Serial(port="COM9", baudrate=115200, bytesize=8, timeout=1, stopbits=serial.STOPBITS_ONE) #死循环,进行串口通讯 while(1): mesg = msvcrt.getch() #获取键盘输入的单个字符 send_mesg() time.sleep(0.1) #延时0.1秒,等待单片机接受信息并返回数据 recv_data()
void uart_ctrl() { if(uart_query(UART_2, &uart_buff)) { switch(uart_buff) { case 'q': state_var--; break; case 'e': state_var++; break; case 'a': state_scale--; break; case 'd': state_scale++; break; case 's': flag_j=1; break; case 'w': flag_k=1; break; case ' ': { flag_balance = !flag_balance; if(flag_balance==1) printf("open balance\n"); else printf("close balance\n"); break; } } if(state_var == 6) state_var=1; if(state_scale == 6) state_scale=1; if(state_var == 0) state_var=5; if(state_scale == 0) state_scale=5; set_debug_var(); if(uart_buff=='q'||uart_buff=='e'||uart_buff=='w'||uart_buff=='s') { switch(state_var) { case 1: printf("balance_kp: %.2f\n",balance_kp); break; case 2: printf("balance_kd: %.2f\n",balance_kd); break; case 3: printf("velocity_kp: %.2f\n",velocity_kp); break; case 4: printf("velocity_ki: %.2f\n",velocity_ki); break; case 5: printf("target_angle: %.2f\n",target_angle); break; } } if(uart_buff=='a'||uart_buff=='d') { switch(state_scale) { case 1: printf("0.01\n"); break; case 2: printf("0.1 \n"); break; case 3: printf("1 \n"); break; case 4: printf("10 \n"); break; case 5: printf("100 \n"); break; } } } } void set_debug_var() { static float Scale; switch(state_scale) { case 1: Scale = 0.01; ips200_showstr(130, 1, "0.01"); break; case 2: Scale = 0.1; ips200_showstr(130, 1, "0.1 "); break; case 3: Scale = 1; ips200_showstr(130, 1, "1 "); break; case 4: Scale = 10; ips200_showstr(130, 1, "10 "); break; case 5: Scale = 100; ips200_showstr(130, 1, "100 "); break; } switch(state_var) { case 1: change_debug_var(&balance_kp, Scale); ips200_showstr(120,0,"bal_kp"); ips200_showfloat(120,2,balance_kp,4,2); break; case 2: change_debug_var(&balance_kd, Scale); ips200_showstr(120,0,"bal_kd"); ips200_showfloat(120,3,balance_kd,3,2); break; case 3: change_debug_var(&velocity_kp, Scale); ips200_showstr(120,0,"vel_kp"); ips200_showfloat(120,4,velocity_kp,4,2); break; case 4: change_debug_var(&velocity_ki, Scale); ips200_showstr(120,0,"vel_ki"); ips200_showfloat(120,5,velocity_ki,3,2); break; case 5: change_debug_var(&target_angle, Scale); ips200_showstr(120,0,"tar_ag "); ips200_showfloat(120,6,target_angle,2,2); break; } } void change_debug_var(float *var, float scale) { if(flag_sw2 || flag_k==1) *var += scale, flag_k=0; if(flag_sw1 || flag_j==1) *var -= scale, flag_j=0; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。