Go Down

Topic: Don't get data from Arduino via serial USB after a day (Read 3925 times) previous topic - next topic

oduino

I connected a Raspberry Pi and an Arduino via USB. Arduino is getting data from the world via sensors (EC and temperature sensor) and writing this data to serial. The Raspberry is writing this data into a database.

The Arduino sketch:

Code: [Select]


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


code on Raspberry Pi:

Code: [Select]


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()

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

try:
        while True:
                try:
                        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})".format(temp=temp, ec=ec))
                                conn.commit()
                        print response
                except Exception as e:
                        print e
                        pass
except KeyboardInterrupt:
        s.close()
        conn.close()



Data is written for about 24 hours on Raspberry side, then I get no serial output from Arduino any more. Same problem when I restart the python script again. When I restart the python script and serial communication is started again, the Arduino resets. I did not change this default behaviour. The fact that I still do not get data via serial shows me that it is no memory problem on the Arduino side. One more hint, that it must be a problem with the Raspberry, do I get from the fact that rebooting Raspberry solves the problem and the data is logged for another 24 hours.

So this is an Arduino forum and no Raspberry. Anyway, is anybody curious enough to give me any hint, how to establish an solid communication?

Robin2

An obvious question seems to be whether a Python exception is associated with the ending of reading.
.
I have found it useful NOT to use try/except when trying to find problems because it can hide messages that would otherwise be useful.

In you code you don't seem to be making any use of the exception so I don't see the purpose of using TRY in the first place.

Does the Arduino program work continuously if it is is just feeding the Serial Monitor?

Have a look at the 3rd example in Serial Input Basics. The techniqueSerial Input Basics can be used just as well in Python code to ensure that the start and end of messages are properly detected.


...R
Two or three hours spent thinking and reading documentation solves most programming problems.

oduino

Thanks, Robin, for your input.

Right, I removed the exception catching. Since I started the python program with nohup errors will be seen in nohup.out.

Not exactly sure what you mean by 'Does the Arduino program work continuously if it is is just feeding the Serial Monitor?'. Yes, the Arduino program runs a loop and gathers and sends sensor data 3 times per minute and this is running 24 hours successfully until I don't know what happens.

Thx for linking me to the basics and yes, will have to dive deeper ...

In the meanwhile I also spent my Arduino an own power supply to ensure it's not a power issue. Before it got power via USB from the Raspberry

ieee488

USB is power managed by Windows.

Robin2

Yes, the Arduino program runs a loop and gathers and sends sensor data 3 times per minute and this is running 24 hours successfully until I don't know what happens.
Does this mean the Arduino program runs indefinitely without any problems?

If so it clearly indicates that the problem is with the PC and/or your Python code.

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

oduino

I know for sure, that it runs say 24 hours. After that, I don't know since I cannot read from serial any more. I believe so too, that the problem is on the raspberry side. Let's see tomorrow, if the dedicated power supply helped

Robin2

since I cannot read from serial any more.
Why not?

If you have a Mega you could temporarily feed the output from the Uno as input to Serial1 and have the Mega receive the data and send it to the Serial Monitor. Then you could stop and start the Mega as often as you like without having any impact on the behaviour of the Uno (I assume you are using an Uno).

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

oduino

Buying just another Computer seems not a viable solution to me. Raspberry and Arduino should be fine.

Unfortunately my python program stopped reading a couple of hours after my last post yesterday.

I inserted a timeout of 2 seconds today and now every 2 seconds the python program prints an empty line. There is no error, it does not crash, just prints nothing.

If I reboot the Raspberry, everything will work again. Just trying to fix the error at the root. Some other process on Raspberry blocking this USB port (/dev/ttyACM0)? How to find out?

By the way I have already a Mega, it's a Saint Smart. It's said to be compatible ...

Another point: My Raspberry is using an old pyserial version. It is not easy to uninstall, Raspberry is telling me it belongs to root.

Update: It is working again without rebooting the Pi. I removed the Mega from the power supply and cut its USB connection to the Pi. The Mega blinked 2 times with the L-LED when I reconnected it with power. But there was no blinking of the TX-LED (transmitting). Same when pressing the reset button. Not before I connected the Mega to the Raspberry via USB the TX-LED blinked regularly showing me that the program works and sends sensor data to the Pi. So, yesterday rebooting the Pi helped because the Arduino got power and USB input from the Pi.

Quite a mystery to me ... but now the problem seems to be an the Arduino side

Robin2

Buying just another Computer seems not a viable solution to me.
I did not suggest that. And you say you already have a Mega.

Load the Mega with the second example from Serial Input Basics with the function modified to receive from Serial1 and then you will have a simple intermediary between your working Arduino and your PC or RPi.

It is straightforward to acquire "root" privileges. On an Ubuntu system you prefix a command with sudo. There is sure to be an equivalent for the RPi.

But I would be slow to meddle with the Python system until you are sure that it is broken - so that there is ZERO possibility of making it worse :)

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

oduino

Robin2, thx for pointing me to the serial basics. Unfortunately thats exactly what my sketch is based on. Concerning serial it is even much easier since nothing is received but just transmitted. The sketch is just more complex and calculates many things. I will now serial print the sensor data only every couple of minutes and print more debug messages in order to be able to recognize what goes wrong.

Sure I used sudo for uninstalling python-serial. Anyway Raspberry does not want to lose this built-in library. Sure, it is possible anyhow and right: don't do things, that are not neccessary.

Robin2

Maybe I have not made my idea clear.

When you have an Arduino connected to a PC and something goes wrong so that you need to reset or reboot the PC the Arduino will also be reset so that it is impossible to know whether the problem was caused by the Arduino or by the PC.

What I have been trying to suggest is this

  Project Arduino ------> Mega Serial1 -------Mega Serial ------> PC

Now, if the PC stops and has to be reset the Mega will be reset but it will have no impact on the project Arduino so it will be easy to see if the project Arduino continues to work. In this idea the Mega is just used temporarily while the problem is diagnosed. When you get things working properly it won't be needed.

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

oduino

Man, do we talk at cross-purposes  :)

Ok, get your idea. Still, in your scenario are 2 Arduinos involved, right? (the one where the sensor data logging sketch is running, what you call Arduino Project, and another Arduino Mega as a serial connection abstraction layer). But I have only one Arduino Mega (ok, it's a Saint Smart ;)).

Wouldn't it be far easier to prevent autoreset? Like this one

http://playground.arduino.cc/Main/DisablingAutoResetOnSerialConnection

Since, the Arduino Project has an own power supply rebooting my PC would not reset the Arduino if auto reset was disabled.

Robin2

But I have only one Arduino Mega (ok, it's a Saint Smart ;)).
Do you mean that that Mega is the project Arduino?

I had assumed from your comment in Reply #7 that you had a spare Mega that could be used to help with the diagnosis.

There is no need to disable auto-reset if the Arduino is not causing the problem. There is no advantage in disabling it if the Arduino is causing the problem.

If you have only one Arduino and you don't want to buy a second one you could try writing a short Arduino program that just Serial.println("<hello world>"); every second and a suitable RPi program to receive and display that and see if that combination will work indefinitely.

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

oduino

Do you mean that that Mega is the project Arduino?
I had assumed from your comment in Reply #7 that you had a spare Mega that could be used to help with the diagnosis.
Yes

There is no need to disable auto-reset if the Arduino is not causing the problem. There is no advantage in disabling it if the Arduino is causing the problem.

If you have only one Arduino and you don't want to buy a second one you could try writing a short Arduino program that just Serial.println("<hello world>"); every second and a suitable RPi program to receive and display that and see if that combination will work indefinitely.

...R
Nice one. IF it works I know it must be the code on Arduino side that I posted. But if it does not work ... I still don't know which side. Since tommorrow I must go on vacation (bad, bad ;)) I intuitively tried out a communication pattern I found here

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

Don't know what the author exactly mean by 'buffer overfilling'. However he warns not to sent data from Arduino constantly. The difference to the approach before is that the Arduino sends data, if he is asked for. The result is he is sending data constantly because he is asked constantly. Anyway ...

And it's working for 10 hours now. That's a good sign.

Robin2

And it's working for 10 hours now. That's a good sign.
You said previously that the problem takes 24 hours to emerge so I don't reckon 10 hours of operation tells you anything  :(

Enjoy your vacation :)

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

Go Up