MrYsLab / pymata4

A High Performance Python Client For Arduino Firmata
GNU Affero General Public License v3.0
76 stars 30 forks source link

pymata4 connects to wrong Arduino instance #18

Closed dshaw619 closed 4 years ago

dshaw619 commented 4 years ago

I have found that if I upload FirmataExpress to an Arduino Uno clone (on /dev/ttyUSB0) and it is the only Arduino connected to my Raspberry Pi, a simple test program using pymata4 connects correctly (using arduino_instance_id=2) and can read a pushbutton and light an LED on the Arduino successfully.

However, if I add another Uno clone (different manufacturer; on /dev/ttyACM0), pymata4 seems to connect to it, even if running the Arduino standard Blink sketch, rather than the device on /dev/ttyUSB0). As a result, the firmware version can't be found.

[I don't seem to have sorted out the correct way to insert code, but hopefully the following log is intelligible.]

`Python 3.7.3 (/usr/bin/python3)

%Run pymata4_test_04.py pymata4: Version 1.8

Copyright (c) 2020 Alan Yorinks All Rights Reserved.

Opening all potential serial ports... /dev/ttyUSB0 /dev/ttyACM0

Waiting 4 seconds(arduino_wait) for Arduino devices to reset...

Searching for an Arduino configured with an arduino_instance = 2 Arduino compatible device found and connected to /dev/ttyACM0

Retrieving Arduino Firmware ID... Traceback (most recent call last): File "/home/pi/Sample_Programs/pymata4_test_04.py", line 51, in Arduino02 = pymata4.Pymata4(arduino_instance_id=2) File "/usr/local/lib/python3.7/dist-packages/pymata4/pymata4.py", line 275, in init raise RuntimeError(f'Firmata Sketch Firmware Version Not Found') RuntimeError: Firmata Sketch Firmware Version Not Found

`

MrYsLab commented 4 years ago

FYI - to insert code, just surround the code with backtick marks ``` Your code ```

I tried recreating your problem, but am not able to. Here is the output I get:

python3 digital_output.py
pymata4:  Version 1.8

Copyright (c) 2020 Alan Yorinks All Rights Reserved.

Opening all potential serial ports...
    /dev/ttyUSB0
    /dev/ttyACM0

Waiting 4 seconds(arduino_wait) for Arduino devices to reset...

Searching for an Arduino configured with an arduino_instance = 2
Arduino compatible device found and connected to /dev/ttyACM0

Retrieving Arduino Firmware ID...
Arduino Firmware ID: 1.1 FirmataExpress.ino

Retrieving analog map...
Auto-discovery complete. Found 20 Digital Pins and 6 Analog Pins

ON
OFF
ON
OFF
ON
OFF
ON
OFF

I do not have an Arduino Uno that uses USB0. What you may try doing is loading FirmataExpress on the ACM0 device and the blink sketch on the USB0 device.

Also, after plugging in both boards, press the reset switches on the Arduino before starting the Python script.

BTW, I also tried running a Leonardo and an Uno and do not see the issue.

dshaw619 commented 4 years ago

I reversed the two Arduinos, putting FirmataExpress on the ACM0 device and Blink on the USB0 device. pymata4 test program found and connected to ACM0 device correctly.

I removed the USB0 device and connected another Arduino I had as /dev/ttyACM1. Loaded Blink to it. pymata4 test program found and connected to ACM0 device correctly.

Loaded FirmataExpress to ACM1 device and Blink to ACM2 device (formerly ACM0; designation changed when I disconnected and reconnected to move test circuit to ACM1 device). pymata4 test program found and connected to ACM1 device correctly.

Removed ACM1 device and reconnected the Arduino that shows up as /dev/ttyUSB0. Loaded FirmataExpress to it. Blink still loaded to ACM2 device. pymata4 test program finds Arduino instance 2 ok, but attempts to connect to ACM2 device as before. This, of course, fails since Blink is actually running on that device. I did try resetting both Arduinos before running the pymata4 test program, but it still failed.

>>> %Run pymata4_test_04.py
pymata4:  Version 1.8

Copyright (c) 2020 Alan Yorinks All Rights Reserved.

Opening all potential serial ports...
    /dev/ttyUSB0
    /dev/ttyACM2

Waiting 4 seconds(arduino_wait) for Arduino devices to reset...

Searching for an Arduino configured with an arduino_instance = 2
Arduino compatible device found and connected to /dev/ttyACM2

Retrieving Arduino Firmware ID...
Traceback (most recent call last):
  File "/home/pi/Sample_Programs/pymata4_test_04.py", line 51, in <module>
    Arduino02 = pymata4.Pymata4(arduino_instance_id=2)
  File "/usr/local/lib/python3.7/dist-packages/pymata4/pymata4.py", line 275, in __init__
    raise RuntimeError(f'Firmata Sketch Firmware Version Not Found')
RuntimeError: Firmata Sketch Firmware Version Not Found
>>> 

It seems that things work as expected if both devices are ACM, but if FirmataExpress is running on the USB0 device it is originally found, but then pymata4 attempts to connect to a different (ACM) device.

MrYsLab commented 4 years ago

Thanks for taking the time to try and debug this. I made a change in the behavior for the code that searches for an Arduino.

Could you please upgrade pymata4 to version 1.9 by typing:

sudo pip3 install pymata4 --upgrade

This should install version 1.9.

Please let me know if this solves the issue.

dshaw619 commented 4 years ago

I don't see this reply on GitHub, so replying via email.

The board is unidentified (pic below). I believe I bought it at a cut rate ($10) from inventor.io (probably a Facebook ad) about a year ago. I can't find it on their website now.

I did some additional tests. Removed the device that appears as USB0. Connected what I call Arduino01 (/dev/ttyACM0). Uploaded FirmataExpress with instance_id = 1 to it. Connected what I call Arduino03 (/dev/ttyACM2). Uploaded FirmataExpress with instance_id = 3 to it. (as you can probably guess, I'm ultimately trying to take advantage of the instance_id to get around the fact that a board might show up on a different ttyACM* and connect more than one to the RPi simultaneously).

When I run my test program and instantiate the board with Arduino02 = pymata4.Pymata4(arduino_instance_id=1) [yeah, the name is wrong] pymata4 erroneously connects to the ACM0 board with instance_id=3.

When I run the test program and instantiate the board with Arduino02 = pymata4.Pymata4(arduino_instance_id=3) pymata4 correctly connects to the ACM2 board with instance_id = 3.

I just saw on GitHub that you made a code change. I'll install v1.9 and report the results on GitHub.

Doug

On Tue, Jun 16, 2020 at 4:08 PM Alan Yorinks notifications@github.com wrote:

Thanks for taking the time to try and debug this. This is something I have not experienced before. The fact that the board comes up as USB0 tells me that its boot loader is non-standard for an Arduino. I am not sure why that would cause an issue. I have used both official Arduino Uno's and clones and none show up as USB0, and any combination of boards - Uno, Mega2560, Leonardo all work without issue.

What is the brand of this board, and would you know who sells it?

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/MrYsLab/pymata4/issues/18#issuecomment-645055943, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABQKU74YL6W2CXFTDCFQOSLRW73O3ANCNFSM4N7G55BQ .

dshaw619 commented 4 years ago

Excellent! v1.9 seems to have resolved both variations of incorrect connections.

Thanks so much for your prompt attention and resolution.

MrYsLab commented 4 years ago

Thank you for reporting the issue and your patience.