Python 之 Serial串口通信-实时获取最新数据(好像没有找到其他的方案?)
前言:
最近在用arduino嘛,信息流大概如下:
拿到上面的信息之后,我还需要在上位机-笔记本的python脚本中,随时获取最新的传感器数据。
这个随时和最新,就比较麻烦。因为在网上找到的demo要么是非常复杂的调用,用上了多线程或者多进程,每时每刻的获取传感器的数据。
要么就是很简单的demo,根本不考虑有其他运算的存在,一个死循环一直print串口来的数据。
但是我的主程序会执行其他脚本,只有在需要控制夹爪的时候,霍尔传感器才会有所变化,而传感器一直会发信息过来,存在缓冲区,类似队列的方式,如果用传统的read_line(),每次都会读取最新进去的数据。
我曾尝试过关闭端口,再重新打开,也不行;
尝试过flush函数,也不行。
然后我在这篇博客里面看到了对pyserial库中常见函数的一个说明,看到了readlines(),感觉可以试试,我可以把缓冲区的数据一次性读完嘛,这样下次读取的岂不是最新的数据?
debug过后发现,果然可以。
下面直接放代码吧:
arduino代码:
这段应该是改某位博客的,但是在这台机子上没搜到。先不放了~
int analogPin = A7;
int iVal = 0;
void setup()
{
Serial.begin(9600);//打开串口,设置波特率9600
pinMode(1, OUTPUT);//由于pin1是串口的Tx,所以要将其模式设置为OUTPUT
}
void loop()
{
iVal = analogRead(analogPin);
float fVal = iVal * 5000.0 / 1024 - 2500.0 - 106.0;
Serial.print(fVal, 3);
Serial.println();//输出换行符
delay(50);
}
笔记本python脚本:
先安装serial –
pip install serial
python 脚本:
import serial
import time
import numpy as np
serialPort="COM4"
baudRate=9600
ser=serial.Serial(serialPort, baudRate, timeout=0.01)
print("参数设置: 串口=%s, 波特率=%d"%(serialPort,baudRate))
ser.set_buffer_size(rx_size=1, tx_size=1)
info_count = 0
def get_hall(ser):
string = ''
while len(string)==0:
str_lines = ser.readlines()
string=ser.readline().decode('utf-8')
try:
if string == "":
string = str_lines[-1].decode('utf-8')
except:
pass
# remove /n
return string[:-2]
while 1:
# add random delay time
sleep_time = np.random.random()
time.sleep(sleep_time)
string = get_hall(ser)
print(string)
ser.close()
基本上够了,虽然看起来有点蠢,但是测试的时候,完全符合要求,凑活用吧~
加上打包成类的代码吧:
import serial
import time
import numpy as np
class Arduino:
def __init__(self,
serialPort="COM4",
baudRate=9600,
):
self.serialPort="COM4"
self.baudRate=9600
self.ser=serial.Serial(self.serialPort, self.baudRate, timeout=0.01)
print("参数设置: 串口=%s, 波特率=%d"%(self.serialPort, self.baudR
ate))
self.ser.set_buffer_size(rx_size=1, tx_size=1)
def get_hall(self):
string = ''
while len(string)==0:
str_lines = self.ser.readlines()
string=self.ser.readline().decode('utf-8')
try:
if string == "":
string = str_lines[-1].decode('utf-8')
except:
pass
return string[:-2]
def main():
ser = Arduino()
while 1:
sleep_time = np.random.random()
time.sleep(sleep_time)
string = ser.get_hall()
print(string)
ser.close()
if __name__=='__main__':
main()