简体   繁体   中英

Arduino Uno Raspberry Pi Serial Communication double readings

I use an Arduino Uno to convert Analog data to digital from a light sensor and send this data to raspberry pi by an USB cable. However when I run the code I read values like 1923 from a 10-bit sensor.

Here is the arduino code

int a = A0;
int meas = 0;
void setup() {
Serial.begin(9600);
}
void loop() {
meas = analogRead(a);
if(Serial.readString() == "1"){ //Check that Raspberry wants data or not
Serial.println(meas);     
}
}

Here is the Python code in Raspberry Pi

import serial
from datetime import datetime
now = datetime.now()

ser = serial.Serial('/dev/ttyACM0', 9600)
ser.write("1".encode())
s = ser.readline()

file = open("dataset.txt", "a")
file.write(now.strftime("%Y-%m-%d %H:%M") + " Sensor Value:" + str(s)+ "\n")
file.close()

Here is the example output after running code once in every 5 minutes

14:08 Sensor Value:6
14:10 Sensor Value:8
14:15 Sensor Value:8
14:20 Sensor Value:10
14:25 Sensor Value:6
14:30 Sensor Value:9
14:35 Sensor Value:6
14:40 Sensor Value:7
14:45 Sensor Value:5
14:50 Sensor Value:5
14:55 Sensor Value:12
15:00 Sensor Value:1
15:05 Sensor Value:1
15:10 Sensor Value:10
15:15 Sensor Value:12
15:20 Sensor Value:14
15:25 Sensor Value:1922
15:30 Sensor Value:2211
15:35 Sensor Value:11
15:39 Sensor Value:6
15:40 Sensor Value:7
15:45 Sensor Value:8
15:50 Sensor Value:10
15:55 Sensor Value:1
16:00 Sensor Value:
16:05 Sensor Value:11

I want to get rid of these 1's and 1922 like things they are certainly meaningless data.

PS: Sensor is on the top of a mountain, I am using remote connection the check the data and manipulate the code.

How can I do that? Thank you for your time.

I think Mark Setchell is right. You are getting data from past measurements.

Personally I'd implement a more robust protocol, but since your application is quite basic you can try with a simpler approach, which is what he suggested.

This is solved easily by adding a small delay in the python program, between the request and the reading. Something like this can be enough:

from time import sleep
...
ser.write("1".encode())
sleep(0.05);
s = ser.readline()

In the mean time, I don't like the way you handle the reading in the arduino. If you are always sending single-char commands, I suggest this approach:

void loop() {
    meas = analogRead(a);
    if (Serial.available())
    {
        if (Serial.read() == '1')
        {
            Serial.println(meas);
        }
    }
}

This does not block the execution of the loop (which can come in handy if you plan to expand the functionalities)

You might have a look at calibration, here's a sample piece of code,

https://www.arduino.cc/en/Tutorial/Calibration

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM