MrYsLab / pymata4

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

Weirdness in _send_sysex vs. _send_command #23

Closed cujo0072 closed 3 years ago

cujo0072 commented 3 years ago

I have installed FirmataExpress 1.1.4 on my Adruino Uno. I manually set my port board = pymata4.Pymata4(com_port='/dev/ttyS0',baud_rate=115200)

and run the example digital_input.py :

python3 ./digital_input.py pymata4: Version 1.10

Copyright (c) 2020 Alan Yorinks All Rights Reserved.

Opening /dev/ttyS0...

Waiting 4 seconds(arduino_wait) for Arduino devices to reset... Traceback (most recent call last): File "./digital_input.py", line 59, in board = pymata4.Pymata4(com_port='/dev/ttyS0',baud_rate=115200) File "/home/cujo/.local/lib/python3.7/site-packages/pymata4/pymata4.py", line 242, in init self._manual_open() File "/home/cujo/.local/lib/python3.7/site-packages/pymata4/pymata4.py", line 426, in _manual_open raise RuntimeError('Invalid Arduino ID reply length') RuntimeError: Invalid Arduino ID reply length

IF I just open the serial port and issue the SYSEX commands manually I get the "14" on the write to the serial port. START_SYSEX = 0xF0 # start a MIDI Sysex message

ARE_YOU_THERE = 0x51 # poll for boards existence

sysex_command = 0x51 END_SYSEX = 0xF7 # end a MIDI Sysex message

the_command = [0xF0, 0x51, 0xF7]

import serial import io ser = serial.Serial() ser.baudrate = 115200 ser.port = '/dev/ttyS0' ser.open() test = ser.write(b'0xF0,0x51,0xF7') type(test) <class 'int'> test 14 ser.close()

So I look at _send_command and see that the definition says that it will return the number of bytes sent. def _send_command(self, command): """ This is a private utility method. The method sends a non-sysex command to Firmata. :param command: command data :returns: number of bytes sent """ but it actually returns the result. IF _send_sysex also returned the result would I not get the correct info needed? kinda like: i_am_here = self._send_sysex(PrivateConstants.ARE_YOU_THERE)

check sysex command is I_AM_HERE

            if i_am_here % 10 != PrivateConstants.I_AM_HERE:
                raise RuntimeError('Retrieving ID From Arduino Failed.')
            else:
                # got an I am here message - is it the correct ID?
                if i_am_here / 10 == self.arduino_instance_id:
                    return
                else:
                    raise RuntimeError('Invalid Arduino identifier retrieved')
MrYsLab commented 3 years ago

I apologize, but I may not be fully understanding your question. The comment for _send_command is correct. It calls serial_write which returns the number of bytes written.. That value is never used by any of the callers, but was left in for debugging purposes.

The result of a _send_command or _send_sysex may result in a report from FirmataExpress in response to the command or sysex message.

Please let me know if I am misunderstaning your question, and if so, could you please clarify what you are asking.

Thanks.

cujo0072 commented 3 years ago

Thanks for the help. I think my arduino Uno "compatible" board was the problem. I stole an Uno from another project and it seems to be working better.

MrYsLab commented 3 years ago

Thanks for letting me know. You may try extending the 4 second wait time for your board. Some boards take a long time to come up after a reboot.