Different sensor values from pyfirmata and arduino code

Hey

Reading values from a tmp36 temperature sensor I get different values wether I'm reading from the arduino IDE or using the pyfirmata2 library in python.

Python code

from pyfirmata2 import Arduino, util
from time import sleep

board = Arduino("COM5")

it = util.Iterator(board)
it.start()

pin = board.get_pin("a:0:i")

for i in range(100):
    if pin.read():
        print(pin.read())
    sleep(0.25)

Arduino code

const int sensorPin = A0;

void setup()
{
  Serial.begin(9600);

}

void loop(){
  int sensorVal = analogRead(sensorPin);

  Serial.println(sensorVal);
  delay(25);
  
}

Note that I haven't yet done the math in the code to transform the values to degrees, but needless to say different readings will give different answers.
Any idea why it's different? Physical setup is exactly the same when testing on python and on arduino IDE.

Update: I tried the same thing with a piezo, and here as well I get much lower sensor values when reading from python than arduino IDE.

Update 2: Actually it seems like the values I get in python have no root in reality. I tried disconnecting the pin from the piezo to the analog input, and still I get these low numbers when reading the pin that is unplugged.

Have you read this:
TMP36 with CircuitPython

Is your schematic including:
" Note: The simple circuit below has been found to give incorrect readings with CircuitPython because of the speed at which CircuitPython reads the analog value. To fix this problem, add a 0.01uF or 0.1uF capacitor and a 47k resistor across the output and ground pins of the TMP36. We will revise the diagram later."

You may be seeing different values also because:
"You can convert this value into a voltage (in millivolts) using a similar formula mentioned on the previous page. However there's one small change to increase the range of values from 1023 to 65535--this is necessary because CircuitPython uses a wider range of values for ADC inputs. In addition with CircuitPython you can directly access the board's analog reference voltage so one simple equation will work for both 3.3V and 5V references:"

Either of the above can contribute to what you see.

Ron

1 Like

Thanks, tried that now but exact same input. Last readings from python code.
28.0274
28.2463
0.219
0.219
0.219
0.219
0.219
0.219
0.219
0.219
0.219
0.219
0.219
28.2463
0.219
28.2463
28.2463
28.0274
28.2463
0.219
28.0274

These values should be around 140, which is what I'm getting on the Arduino.

Is there perhaps a different Python library for Arduino I could try to see if pyfirmata is the culprit?

Arduino is a 10 bit A/D on an analog input so 0 to 1024 is the range. The circuit python is a 16 bit ADC or 0 to 65535 is the range. You are not going to see the same raw data read on the Arduino and Circuit Python. Converting from the raw data to an engineering unit, as a simple example even volts the math functions for 10 bit verse 16 bit will not be the same. With a 10 bit ADC and a 16 bit ADC why would you expect to see the same number? You won't. All you are looking at is raw data, a bit count.

If you follow through and convert your Arduino or Circuit Python data to degrees C for your temp sensor you will use two different formulas. The end result should be the same.

Ron

I’m not using circuit python, but if I was then I should actually expect to see larger numbers as they would be fractions of a number about 4 times as large. But the values I receive are lower, they spike and they are generated even if I unplug the analog connection. Thanks for the reply though.

Well alrighty and yes, you are correct I would expect larger not smaller numbers. With the spiking you mention and show my guess is something in wiring which there is not much of or a faulty A/D. Beyond that I am unsure what to suggest.

Ron

Yes, but I get reasonable and «smooth» values when running the code from Arduino so I think wiring is ok. This is why I was thinking the problem may be in the Python library.

I think I found the problem. I tried to read the code with the pymata library instead, and got reasonable and smooth readings. Either I'm using the pyfirmata in a wrong way, or there's some bug in the library.

from pymata4 import pymata4
from time import sleep

board = pymata4.Pymata4(arduino_instance_id=1)

analog_pin = 0

board.set_pin_mode_analog_input(analog_pin)
sleep(1)

for i in range(100):
    print(board.analog_read(analog_pin)[0])
    sleep(0.25)

SOLVED: Pyfirmata2 gives analog output as a value between 0 and 1. Lesson learned, don't assume, read the docs.

Well congratulations to you. You nailed it and the more I thought about it the further I moved from the problem. Nice going! :slight_smile:

Ron

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.