Firmata with PyMata not refreshing analog_read()

Hello!

I'm having trouble reading analog inputs. If the program starts with ground connected through a resistor to A0, and I read the value, I get 0, which is right. If I change it to +5 volts and read it again, it still reads 0. Similarly, if the program starts with A0 connected to +5V and I read it, I get 1023, which is right. However, after switching the input to ground, every subsequent read is still 1023, instead of 0. Why won't this update?

A few quick caveats before the code, in case they matter.

  • Technically, this isn't an Arduino at all, but an ATMega328 slave CPU that gives my ODroid analog/PWM input/outputs. It should be equivalent to an Uno. I ran the Firmata test program and it worked flawlessly.
  • Running Standard Firmata (version: 2.4)
  • Using PyMata (version: 2.0.2)
#!/usr/bin/env python

import sys
import signal
import rospy
from PyMata.pymata import PyMata


#Set analog pin numbers
FORWARD_RANGE_PIN = 0

#Start PyMata
ATMega = PyMata("/dev/ttyACM99",'uno')

def signal_handler(sig, frame):
    print("User aborted")
    if ATMega is not None:
        ATMega.reset()
    sys.exit(0)
    
signal.signal(signal.SIGINT, signal_handler)

#Setup ROS
rospy.init_node('ATMega', anonymous=True)

#Setup pins
ATMega.set_pin_mode(FORWARD_RANGE_PIN,  ATMega.INPUT,  ATMega.ANALOG)

rate = rospy.Rate(60)

#Main loop
while not rospy.is_shutdown():
    input = raw_input("Ready...")
    if  input =="x":
        ATMega.close()
        rospy.signal_shutdown()
        sys.exit
    
    print(ATMega.analog_read(FORWARD_RANGE_PIN))
        
    rate.sleep()

The while loop just waits to read the input until enter is pressed.

PS: Why does Firmata initialize so slowly? It takes nearly a minute.

Try Firmata 2.4.1: Release Firmata 2.4.1 · firmata/arduino · GitHub. If you are still having the issue after updating, post it here: Issues · firmata/arduino · GitHub.

Also, if you believe you have an issue with PyMata, please submit an issue here:

If you are using Linux with Python 3, there is a substantial slowdown. See http://bugs.python.org/issue23324. Python 3 on Windows does not exhibit the problem, nor does PyPy on linux.

Thanks for the replies.

It seems Firmata, or Pymata at least, is designed to latch when the analog value reaches a certain threshold. Once latched, it must be reset with:

set_analog_latch(pin, condition, threshold)

Condition is for, >, <, =, etc., and threshold is the raw value (0-1023) you want to latch at. I needed continuous, live values when the pin is read, not a latch at an arbitrary value. So I tried to have it latch at >1023, or <0, without success. I also tried to reset the latch with valid threshold values, again, without success.
I'm fairly certain I have the latest Firmata, and downloaded it again just to be sure. I tried to check the version with:

refresh_report_version();
get_firmata_version();

but all I got was an empty array: []. Picking through the PyMata code, I also found a comment that said setting bluetooth to false would speed start-up. I tried this with, again, no noticeable difference.

Needless to say, I've frustratedly given up on Firmata/PyMata. I just side-stepped the whole issue and simply wrote my own firmware for the ATMega to move the data around.

I don't know if it's a bug or not. I'm too unfamiliar with the library; I could just be using it wrong.

I think you may be confusing several things about PyMata and Firmata. Here is a very simple script to read data from a potentiometer.

# analog pin
POTENTIOMETER = 2

# user provided callback routine that is called each time data is updated from the Arduino
def cb_potentiometer(data):
    print("Latest data = ",  data[DATA_VALUE])


# create a PyMata instance
board = PyMata("/dev/ttyACM0")

# enable analog data to flow from the Arduino for pin A2
board.set_pin_mode(POTENTIOMETER, board.INPUT, board.ANALOG, cb_potentiometer)

# capture data for 15 seconds
time.sleep(15)
print('Timer expired')
board.close()

If you prefer to poll for the latest data instead of using a callback function, then do not specify a callback function in the call to set_pin_mode and retrieve data by:

myData = board.analog_read(POTENTIOMETER)

For retrieving reports, try placing a small delay between the refresh_report_data call and the get_firmata_version. Different board take a different amount of time to respond to the report request.

The latching feature is not part of Firmata and is a feature unique to PyMata. The latch feature is used to capture a transient data event that meets or exceeds a user defined value. When the data meets the criteria specified by the user, the latch saves the data value detected and time stamps the event when it occurred. Its intent was to capture transient data that might otherwise be missed in a polled environment.

If a callback is specified for a latch, the callback function is called when the latch event occurs.

Latches are "one-shots" and need to be re-armed. For callbacks, they can be re-armed in the callback routine.

The bluetooth delay is added immediately after PyMata is instantiated. It is to allow a bluetooth interface to sync up. It is a one time delay and adds 5 seconds to initialization.

Again, if you have specific questions or issues about PyMata, please submit those to: