【问题标题】:Raspberry Arduino communication via pyserial stops after a day一天后通过 pyserial 的 Raspberry Arduino 通信停止
【发布时间】:2023-03-30 10:00:01
【问题描述】:

我通过 USB 连接了 Raspberry Pi 和 Arduino。 Arduino 通过传感器(EC 和温度传感器)从世界获取数据并将这些数据写入串行。 Raspberry 正在将此数据写入数据库。

Arduino 草图:

#include <OneWire.h>
#include <DallasTemperature.h>

int R1= 500;
int Ra=25; //Resistance of powering Pins
int ECPin= A0;
int ECGround=A1;
int ECPower =A4;

float PPMconversion=0.7; 
float TemperatureCoef = 0.019; 
float K=2.88;

#define ONE_WIRE_BUS 10          // Data wire For Temp Probe is plugged into pin 10 on the Arduino
const int TempProbePossitive =8;  //Temp Probe power connected to pin 9
const int TempProbeNegative=9;    //Temp Probe Negative connected to pin 8

OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);// Pass our oneWire reference to Dallas Temperature.


float Temperature=10;
float EC=0;
float EC25 =0;
int ppm =0;


float raw= 0;
float Vin= 5;
float Vdrop= 0;
float Rc= 0;
float buffer=0;

void setup()
{
  Serial.begin(9600);
  pinMode(TempProbeNegative , OUTPUT ); //seting ground pin as output for tmp probe
  digitalWrite(TempProbeNegative , LOW );//Seting it to ground so it can sink current
  pinMode(TempProbePossitive , OUTPUT );//ditto but for positive
  digitalWrite(TempProbePossitive , HIGH );
  pinMode(ECPin,INPUT);
  pinMode(ECPower,OUTPUT);//Setting pin for sourcing current
  pinMode(ECGround,OUTPUT);//setting pin for sinking current
  digitalWrite(ECGround,LOW);//We can leave the ground connected permanantly

  delay(100);// gives sensor time to settle
  sensors.begin();
  delay(100);
  R1=(R1+Ra);// Taking into acount Powering Pin Resitance

};

void loop()
{
  GetEC();
  PrintReadings();  // Cals Print routine [below main loop]
  delay(20000);
}

void GetEC(){
  sensors.requestTemperatures();// Send the command to get temperatures
  Temperature=sensors.getTempCByIndex(0); //Stores Value in Variable
  digitalWrite(ECPower,HIGH);
  raw= analogRead(ECPin);
  raw= analogRead(ECPin);// This is not a mistake, First reading will be low beause if charged a capacitor
  digitalWrite(ECPower,LOW);

  Vdrop= (Vin*raw)/1024.0;
  Rc=(Vdrop*R1)/(Vin-Vdrop);
  Rc=Rc-Ra; //acounting for Digital Pin Resitance
  EC = 1000/(Rc*K);

  EC25  =  EC/ (1+ TemperatureCoef*(Temperature-25.0));
  ppm=(EC25)*(PPMconversion*1000);


}

void PrintReadings(){
  Serial.print("Rc: ");
  Serial.print(Rc);
  Serial.print(" EC: ");
  Serial.print(EC25);
  Serial.print(" Simens  ");
  Serial.print(ppm);
  Serial.print(" ppm  ");
  Serial.print(Temperature);
  Serial.println(" *C ");
  Serial.print("Vdrop: ");
  Serial.println(Vdrop);
  Serial.print("Rc: ");
  Serial.println(Rc);
  Serial.print(EC);
  Serial.println("Siemens");
};

树莓派上的代码:

import serial
import time
import re
import sqlite3

for com in range(0,4):
  try:
    PORT = '/dev/ttyACM'+str(com)
    BAUD = 9600
    board = serial.Serial(PORT,BAUD)
    board.close()
    break
  except:
    pass

DEVICE = '/dev/ttyACM'+str(com)
BAUD = 9600
s = serial.Serial(DEVICE, BAUD)

conn=sqlite3.connect('mydatabase.db')
cursor=conn.cursor()

#s.open()
time.sleep(5) # der Arduino resettet nach einer Seriellen Verbindung, daher muss kurz gewartet werden

#s.write("test");

while True:
    response = s.readline()
    numbers = re.findall(r"[-+]?\d*\.\d+|\d+", response)
    if len(numbers) == 4:
            temp = numbers[3]
            ec = numbers[1]
            result = cursor.execute("INSERT INTO sensordata (temp, ec) VALUES ({temp}, {ec})".form$
            conn.commit()
    print response

数据在 Raspberry 端写入大约 24 小时,然后我不再从 Arduino 获得串行输出。当我再次重新启动 python 脚本时同样的问题。当我重新启动 python 脚本并再次启动串行通信时,Arduino 会重置。我没有改变这个默认行为。我仍然没有通过串行获取数据的事实表明,这不是 Arduino 方面的内存问题。还有一个提示,它一定是 Raspberry 的问题,我是否从重新启动 Raspberry 解决了问题并且数据会再记录 24 小时这一事实中得到。

有没有人足够好奇给我一个提示,如何建立稳固的沟通?

【问题讨论】:

  • 只是一些建议。在 Raspberry 上,向主循环添加一些延迟,这样 CPU 就不会 100% 被使用。这可能不是问题,但它可能会有所帮助。在 Arduino 上的 GetEC 函数中添加其他串行打印(您将在 Raspberry 上忽略),以便您查看它是否总是停在同一行。
  • 谢谢,ChatterOne 为您提供评论。没有收到任何电子邮件以识别您的活动。无论如何,python设法增加了延迟。根据命令行工具 top 有非常多的空闲时间。是的,我在每个命令之后添加了串行打印,这导致我进一步观察,请参阅我的答案

标签: python arduino serial-port raspberry-pi pyserial


【解决方案1】:

我的问题解决了。

当我在 Arduino 端添加大量串行打印时,我发现 Raspberry 端实际上并没有收到任何东西,而是更少,因此我的 python 程序无法解析 Arduino 草图发送的内容。另一个观察结果是:

当我用

观看串口设备时
screen /dev/ttyACM0

我得到了非常相似的效果,并且可以重现该问题。由于我在 Arduino 端添加的大量调试打印,我看到通过 pyserial 接收到的一些字符表明我的 python 脚本正在打印,但是这个屏幕命令严重损害了通信。通过屏幕观看串行设备,我看到了更多的字符,好像屏幕抢了风头。这是一团糟,我没有设法清理,我不得不重新启动覆盆子。但告诉我问题一定出在树莓派上。

解决我的问题的方法是尝试这种沟通模式:

https://github.com/gskielian/Arduino-DataLogging/blob/master/PySerial/README.md

不完全理解作者所说的“但是,请注意 Arduino 不会不断向您的程序发送数据——您可能会遇到缓冲区溢出导致的错误。”

现在要求 Arduino 提供数据并做出响应,而不是连续发送。

这对我来说仍然很神秘,但我的问题得到了解答,Raspberry 现在成功接收传感器数据 6 天。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多