2016-07-15 14 views
0

USB経由でRaspberry PiとArduinoを接続しました。 Arduinoはセンサ(ECと温度センサ)を介して世界からデータを取得し、このデータをシリアルに書き込んでいます。ラズベリーはこのデータをデータベースに書き込んでいます。ラズベリーArduinoの通信は1日後に停止します

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"); 
}; 

コード:データはラズベリー側で約24時間のために書かれ

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 

は、その後、私はこれ以上のArduinoからのシリアル出力を取得していません。 Pythonスクリプトを再起動すると同じ問題が発生します。 Pythonスクリプトを再起動してシリアル通信を再開すると、Arduinoがリセットされます。私はこのデフォルトの動作を変更しませんでした。私がまだシリアル経由でデータを取得しないという事実は、Arduino側ではメモリ上の問題ではないことを私に示しています。ラズベリーに問題があるはずですが、ラズベリーを再起動すると問題が解決され、データはさらに24時間記録されるという事実からもう一つのヒントがあります。

誰かが私にヒントを与えるほど興味がありますか、堅実なコミュニケーションを確立する方法はありますか?

+0

ちょっとした提案があります。ラズベリーでは、CPUが100%使用されないようにメインループにいくらかの遅延を加えます。それはおそらく問題ではありませんが、それは助けるかもしれません。 Arduinoでは、GetEC関数(これはラズベリーを無視する)に他のシリアルプリントを追加して、常に同じ行で停止するかどうかを確認します。 – ChatterOne

+0

Thx、あなたのコメントのためのChatterOne。あなたの活動を認識するためのメールを受け取っていませんでした。とにかくPythonは遅れを追加することができます。コマンドラインツールのトップによると、非常に多くのアイドル時間があります。はい、私は各コ​​マンドの後にシリアル印刷を追加し、それは私の答えを見て、さらに観察につながった –

答えて

0

問題が解決しました。

Arduino側で大量のシリアル印刷を追加したとき、私はラズベリーの面で実際に何も受け取っていないが、はるかに少ないので、私のpythonプログラムはArduinoスケッチが送信していたものを解析できないことがわかった。私は、私は非常によく似た効果を持って、問題を再現でき

screen /dev/ttyACM0 

とのシリアルデバイスを見たとき

:もう一つの観察は、このでした。私はArduino側に追加した大規模なデバッグ印刷のため、私はPythonスクリプトが印刷していたpyserialを介して受け取った文字を見ましたが、このscreenコマンドによって通信が深刻に傷ついていました。スクリーンを介してシリアルデバイスを見ると、スクリーンがショーを盗んだかのように多くの文字が見えました。それは私がきれいに管理していなかったと私はラズベリーを再起動しなければならなかった混乱だった。しかし、問題はラズベリー側にあるべきだと私に言った。 -

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

は、著者が何を意味するか、完全に理解していない「しかし、Arduinoのは常にあなたのプログラムにデータを送信していないことに注意してください:私の問題は、この通信パターンをしようとしていた解決は何

- バッファオーバーフィルからのエラーが発生する可能性があります。

Arduinoはデータを要求され、送信する代わりに応答します。

これはまだ私にとって不思議なことですが、私の質問には答えられ、ラズベリーは6日間センサデータを正常に受信しています。

関連する問題