从串行记录不是实时的。如何让它不飘散?

2024-05-16 03:21:02 发布

您现在位置:Python中文网/ 问答频道 /正文

我在从Arduino到Raspberry PI的序列上得到湿度传感器的值。我的Python脚本应该记录它。是的,但是时间越来越慢了。我猜(在谷歌5个小时后)问题出在某个地方的缓冲区,我正在阅读旧数据并“赶上”。如何调整代码以从Arduino获取最新的序列信息?请记住,我是一个大傻瓜,如果你能解释尽可能简单。我整晚都在想这个问题,但我对编程知之甚少。再加上图表,你可以看到漂移,我把传感器从水里放出来,当我看到图表掉下来的时候就把它放进去了。你知道吗

enter image description here

Arduino代码:

/*
Chirp - arduino example

Connection 
Chirp pin 1 - no connection
Chirp pin 2 - Arduino VCC
Chirp pin 3 - Arduino A5
Chirp pin 4 - Arduino A4
Chirp pin 5 - Arduino pin 2
Chirp pin 6 - Arduino GND
*/

#include <Wire.h>
#define RELAY1  7

void writeI2CRegister8bit(int addr, int value) {
  Wire.beginTransmission(addr);
  Wire.write(value);
  Wire.endTransmission();
}

unsigned int readI2CRegister16bit(int addr, int reg) {
  Wire.beginTransmission(addr);
  Wire.write(reg);
  Wire.endTransmission();
  delay(1100);
  Wire.requestFrom(addr, 2);
  unsigned int t = Wire.read() << 8;
  t = t | Wire.read();
  return t;
}

void setup() {
  Wire.begin();
  Serial.begin(9600);
  pinMode(RELAY1, OUTPUT);
  digitalWrite(RELAY1,HIGH);

  pinMode(2, OUTPUT);
  digitalWrite(2, LOW); //Reset the Chirp
  delay(1); //maybe allow some time for chirp to reset
  digitalWrite(2, HIGH); //Go out from reset
  writeI2CRegister8bit(0x20, 3); //send something on the I2C bus
  delay(1000); //allow chirp to boot
}

void loop() {
  Serial.println(readI2CRegister16bit(0x20, 0)); //read capacitance register
  //writeI2CRegister8bit(0x20, 3); //request light measurement 
  //delay(9000);                   //this can take a while
  //Serial.print(", ");
  //Serial.println(readI2CRegister16bit(0x20, 4)); //read light register
  if (readI2CRegister16bit(0x20, 0) < 420){
  //Serial.println ("watering"); 
  digitalWrite(RELAY1,LOW);
  delay(2000);
  digitalWrite(RELAY1,HIGH);
  delay(2000);
}
else{
  digitalWrite(RELAY1,HIGH);
  //Serial.println ("moist");
  delay(2000);
}
}

Python代码:

import serial
import time
import csv
import os
import plotly.plotly as py
from plotly.graph_objs import Scatter, Layout, Figure

os.chdir('/home/pi/csvdata')

username = '------------'
api_key = '------------'
stream_token = '------------'
py.sign_in(username, api_key)


trace1 = Scatter(
    x=[],
    y=[],
    stream=dict(
        token=stream_token,
        maxpoints=200000000000
    )
)

layout = Layout(
    title='------------'
)

fig = Figure(data=[trace1], layout=layout)

print py.plot(fig, filename='------------')

stream = py.Stream(stream_token)
stream.open()






def mainloop():
    name=time.strftime('%b %d %Y %H:%M:%S')
    f=open(name+'.csv', 'wt')
    writer = csv.writer(f,delimiter=',')

    ser = serial.Serial('/dev/ttyUSB0',9600,timeout=1)

    for t in range(500):
        #time.sleep(5)
        kk=ser.readline()
        kk2=kk.split('\r',1)
        s=kk2[0]
        text=time.strftime('%X %x'),s
        streamtext=({'x': time.strftime('%X %x'), 'y': kk})
        writer.writerow (text)
        stream.write (streamtext)
        f.flush()
        print (text)
        time.sleep(5);
        ser.flush()
        #ser.flushInput()
        #ser.flushOutput()

    if t  == 499:
        print ("why")
        f.close()
        ser.close()
        mainloop()
    else:
        time.sleep(5);

mainloop()

Tags: importstreamtimepinserialarduinoserint
1条回答
网友
1楼 · 发布于 2024-05-16 03:21:02

您还没有发布来自Arduino和Python的代码,因此这里有一个示例演示您想要做什么。将相关部分复制到代码中。你知道吗

阿杜伊诺:

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  randomSeed(analogRead(0));
}

void loop() {
  // put your main code here, to run repeatedly:
  int moisture_value = random(300);
  // millis() is the time in milliseconds since the arduino started running
  Serial.println(String(millis()) + ":" + String(moisture_value)); // We send two pieces of data, i.e. time since arduino started and the sensor value
  delay(1000);
}

Python:

import serial
import datetime


# Converts to an integer if it is an integer, or it returns it as a string
def try_parse_int(s):
    try:
        return int(s)
    except ValueError:
        return s


ser = serial.Serial('/dev/ttyACM0', 115200)
time_start = datetime.datetime.now()  # The time that we started receiving data

while True:
    data = ser.readline().decode("utf-8").strip('\n').strip('\r')  # remove newline and carriage return characters
    [time, moisture_value] = data.split(':')
    print("Received: '{}'".format(data))
    time_received = time_start + datetime.timedelta(milliseconds=try_parse_int(time))  # Add delta time to start time
    print("Moisture value: {} at {}".format(try_parse_int(moisture_value), time_received))

这是通过发送自Arduino启动以来的时间以及传感器读数来实现的。如果我们把它添加到Python的know start time中,那么我们就知道读取的时间。即使发送因故延迟,也无所谓。你知道吗

输出示例:

Received: '0:116'
Moisture value: 116 at 2017-03-15 11:26:43.024711
Received: '1000:4'
Moisture value: 4 at 2017-03-15 11:26:44.024711
Received: '2000:128'
Moisture value: 128 at 2017-03-15 11:26:45.024711
Received: '3001:123'
Moisture value: 123 at 2017-03-15 11:26:46.025711

时间格式:

你也可以用你喜欢的方式来安排时间

time_received = time_start + datetime.timedelta(milliseconds=try_parse_int(time))  # Add delta time to start time
time_formatted = '{0:%H}:{0:%M}:{0:%S} on {0:%d}/{0:%m}/{0:%y}'.format(time_received)
print("Moisture value: {} at {}".format(try_parse_int(moisture_value), time_formatted))

输出:

Moisture value: 46 at 11:42:10 on 15/03/17
Received: '117050:174'
Moisture value: 174 at 11:42:11 on 15/03/17
Received: '118050:298'

相关问题 更多 >