前言
最近在研究单片机与上位机的串口通信,刚好手头有一块ESP32-wroom-32,所以尝试通过micro-usb来与电脑进行一个通信的测试。
一、ESP32和上位机的环境
ESP32的编写是在Arduino IDE的平台上
上位机的测试编写是在python中
二、上位机部分
1.串口通信的准备
代码如下(示例):波特率的设置很重要,要与esp32的相同
import serial
serialPort = "COM5"
baudRate = 115200
ser = serial.Serial(serialPort, baudRate, timeout=0.5)
2.数据的准备与发送
我准备的数据是一组坐标,坐标带有正负号,范围在-255到255之间。
python串口发送的函数为ser.write(),网上有很多发送数据的方式,发送字符串,十六进制数等等。我这里选用的是一个字节数组将坐标数据保存,并加上头帧和尾帧进行加密,确保数据识别的精度。
偷了一张RM的图片做参考:
字节的范围为0-255,而我的坐标组有负数,所以多数据量的传输就起到了很大的作用。如果x坐标是正数,我可以将x的数据放在data1中,用十六进制0x01表示它为正数,放在data0中。如果y坐标是负数,可以用十六进制0x00放在data2中,y值的绝对值数放在data3中。
在esp32进行解析的时候,再把正负号加上去。当然,这种方式只能满足数据绝对值大小在255以内,超过255可以用其他方法进行加密。
x=100
y=100
if(x>0):
a=1
else: a=0
if(y>0):
b=1
else: b=0
key=bytearray([0xAA,a,x,b,y,0xAE])
在字节数组中,一个ASCII码就是一个字节,字节数组虽有六个元素,但每个元素都是一个字节。如果发送字符串数据,在转换十六进制的时候,变动的数据会让它的字节长度发生变换,解密的时候会变得麻烦。
print(len(key))//6个字节长度
ser.write(key)//发送的时候用HEX接收
用串口调试助手接收时,其数据为 AA 01 64 01 64 AE
三、下位机部分
1.ESP32串口通信准备
测试仅与电脑进行通信,串口设置部分比较简单
void setup() {
Serial.begin(115200);//打开串口
Serial.print("通信开始");
}
2.数据的接收
loop循环中不停地判断数据缓存区是否有数据
void loop() {
if(Serial.available())
{ delay(50);
recieve();}
}
接收数据(这里借鉴了其他博主,区别为一次接收100个字节的数据
void recieve(void)
{
byte buffnew[100];
int j=0;
int ma=0;
i=Serial.available();
if(i!=0)
{Serial.print("data recieve");
//Serial.println(Serial.available());
}
while(i--)
{ buffnew[j]=Serial.read();
//Serial.print(buffnew[j],HEX);
j++;
ma=1;
}
if(ma==1)
{ data_analyse(buffnew);
}
}
对数据进行分析(以发送的数据为六字节参考
void data_analyse(unsigned char a[100])
{ int Usart1_RecvBuffer[4];
int j=0,sta=0,ma=0;
char head,ead;
for(j=0;j<=100;j++)
{ head=a[j];
ead=a[j+5];
if(head==byte(0xAA)&&ead==byte(0xAE))
{sta=j+1;
ma=1;
break;
}
}
if(ma==1)
{
for(j=0;j<=4;j++)
{ Usart1_RecvBuffer[j]=a[sta];
sta=sta+1;
}
print_data(Usart1_RecvBuffer);
}
}
void print_data(int b[4])
{
Serial.println(b[0]);
Serial.println(b[1]);
Serial.println(b[2]);
Serial.println(b[3]);
Serial.println("data right");
delay(50);
}
当头帧和尾帧同时识别到为0xAA和0xAE时,就可以将中间的有效数据存放到另一个数组里,接着通过串口助手查看数据是否精准。下面为串口助手调试的图片:
如果发送的数据正确(包含头帧和尾帧),esp32能够准确识别并反馈。图片中间部分,我发送了一大串数据,也能够识别到数据的有效部分。
四、同时测试
python在发送数据时,我们就无法通过串口助手查看反馈的数据。所以利用ESP32自带的led灯进行反馈
void print_data(int b[4])
{
Serial.println(b[0]);
Serial.println(b[1]);
Serial.println(b[2]);
Serial.println(b[3]);
Serial.println("data right");
digitalWrite(LED_BUILTIN, HIGH);
delay(50);
}
一旦成功接收数据,ESP32的蓝灯便会发光,延迟50ms后熄灭,这里就不放动图了。
总结
以上就是今天要分享的内容,本文仅仅简单介绍了多数据的收发,但实际将ESP32运用到电子元件的实时工作时,可能还需要考虑需不需申请外部中断,串口关闭,利用指针指向最新的数据问题。
由于是新人博主,文字表达和实际能力可能较弱,有不对的地方,敬请斧正!