2016-07-15 112 views
0

我通過USB連接了Raspberry Pi和Arduino。 Arduino通過傳感器(EC和溫度傳感器)從世界上獲取數據並將這些數據寫入串口。 Raspberry將這些數據寫入數據庫。通過pyserial的樹莓Arduino通信在一天後停止

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 

數據對樹莓側約24小時寫的,然後我從沒有Arduino的串行輸出了。同樣的問題,當我重新啓動python腳本。當我重新啓動python腳本並且串行通信再次啓動時,Arduino重置。我沒有改變這種默認行爲。我仍然沒有通過串口獲取數據的事實表明,在Arduino方面它沒有內存問題。還有一點提示,它必定是Raspberry的一個問題,我能從重啓Raspberry解決問題以及數據記錄24小時的事實中得到什麼。

有沒有人有足夠的好奇給我一個提示,如何建立一個堅實的溝通?

+0

只是一些建議。在樹莓上爲主循環添加一些延遲,以便CPU不被100%使用。這可能不是問題,但它可能有幫助。在Arduino上添加GetEC函數中的其他序列打印(在樹莓上你會忽略),這樣你就可以看到它是否總是停在同一行。 – ChatterOne

+0

Thx,ChatterOne供您評論。沒有收到任何電子郵件以識別您的活動。不知何故,python設法無論如何都增加了延遲。根據命令行工具頂部有很多空閒時間。是的,我在每條命令後添加了串行打印,這讓我進一步觀察,看到我的答案 –

回答

0

我的問題解決了。

當我在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天的傳感器數據。