我有3个Arduino传感器节点连接到运行Python的PC,XBee Series 1无线电作为无线通信的工具。波特率设置为9600,并且所有地址(ATDL,ATDH,ATMY)都设置正确,因为所有Arduino传感器节点都能够正确地将数据发送到连接到我在Python上运行的PC的XBee协调器。连接到相应Arduinos的Xbee无线电(有2个Arduino Unos和1个Arduino Nano)被配置为终端设备。
我最近发现了一个问题,即Arduino上的任何更改在到达PC时会滞后5秒,并写入CSV文件。例如,我正在读取其中一个Arduinos上的引脚状态,并在通过XBee将其传输到我的计算机后将其写入CSV文件。但是,我意识到当我在08:30:30(HH:MM:SS)实现状态更改时,更改仅在08:30:35(HH:MM:SS)的CSV文件中反映出来。
请问为什么会这样,我该如何解决?我分别为Arduino和Python提供了以下代码。
Arduino(这些代码在3个Arduino节点上大致相同):
import threading
import time
import serial
import csv
# Arduino; Arduino is now replaced by XBee modules
arduino = serial.Serial('COM18', 9600, timeout=1) # Open serial port.
def acquire_data():
while True:
try:
data_in = arduino.readline() # read serial data from Arduino
except:
pass
data_stripped = data_in.strip() # Removes spaces and \n
for data_stripped in arduino:
if data_stripped.startswith('b') and data_stripped.count(
',') == 3: # first char identifies where data is coming from; count commas to double-check incoming string
field = data_stripped.split(',') # split data to be put into 'boxes'
bed_sen = field[0] + ',' + field[1] + ',' + field[2] # We have 3 data sensor fields
bed_sen_fill = True # A flag to show that this if-statement has been completed
if data_stripped.startswith('t') and data_stripped.count(',') == 3:
field = data_stripped.split(',')
table_sen = field[0] + ',' + field[1] + ',' + field[2]
table_sen_fill = True
if data_stripped.startswith('d') and data_stripped.count(',') == 3:
field = data_stripped.split(',')
door_sen = field[0] + ',' + field[1] + ',' + field[2]
door_sen_fill = True
try:
if bed_sen_fill == True and table_sen_fill == True and door_sen_fill == True:
data_combi = bed_sen + ',' + table_sen + ',' + door_sen
break
except:
pass
if data_combi:
datasplit = data_combi.split(",")
field1 = datasplit[0]
field2 = datasplit[1]
field3 = datasplit[2]
field4 = datasplit[3]
field5 = datasplit[4]
field6 = datasplit[5]
field7 = datasplit[6]
field8 = datasplit[7]
field9 = datasplit[8]
with open('abs_testing.csv', 'ab') as csvfile: # 'ab' to remove newline char after each print
writer = csv.writer(csvfile)
sensor_fields = [field1, field2, field3, field4, field5, field6, field7, field8, field9,
time.strftime("%H%M%S")]
writer.writerow(sensor_fields)
time.sleep(1)
def counting():
while True:
sum = 3 + 2
sum2 = sum*8
print sum2
time.sleep(0.2)
def on_light():
strin = '1'
arduino.write(strin.encode())
print "Confirm ON"
def off_light():
strin = '0'
arduino.write(strin.encode())
print "Confirm OFF"
# now threading1 runs regardless of user input
threading1 = threading.Thread(target = acquire_data)
threading2 = threading.Thread(target = counting)
threading1.daemon = False # May remove later. Unsure at the moment.
threading2.daemon = False # May remove later. Unsure at the moment.
threading1.start()
threading2.start()
while True:
if raw_input() == 't':
on_light()
print "ON"
if raw_input() == 'r':
off_light()
print "OFF"
time.sleep(1)
的Python:
import my_code
多线程在这里实现了一个愚蠢的操作,找到8 * 5,因为稍后,这将扩展到实时机器学习功能,确定灯应该打开/关闭的时间。 raw_input()函数证明数据可以被中继回Arduino传感器节点。
非常感谢你的帮助! :)
答案 0 :(得分:0)
关于可能改进的一些想法:
Serial()
波特率提高到115200。sleep(1)
中的acquire_data()
。Serial()
接口未被缓冲,则可以将XBee数据包计时(请参阅ATRO
设置)并将响应作为多个数据包发送(效率较低)。尝试将ATRO
从默认值3增加到20,看看是否有帮助。您的每秒发送一次,所以平均而言,您将在I / O更改后发送0.5秒。您可以在Arduino上添加一些时序代码,以打印出组装和发送数据所需的毫秒数(这可能会导致一些延迟)。或者尝试这个替换代码:
char buffer[16];
pirValue = digitalRead(pirPin);
digitalWrite(LEDPirPIN, pinValue);
sprintf(buffer, "d%u,%u,%u,\n",
digitalRead(IR) == LOW,
pirValue == HIGH,
digitalRead(lightLED) == LOW);
xbee.print(buffer);
Serial.print(buffer);