MrYsLab / pymata-aio

This is the second generation PyMata client.
https://github.com/MrYsLab/pymata-aio/wiki
GNU Affero General Public License v3.0
155 stars 51 forks source link

_encoder_data() missing 1 required positional argument: 'data' #58

Closed dtheb closed 6 years ago

dtheb commented 6 years ago

i keep getting errors like this with different method names _encoder_data() changes from run to run all from pymata core

using FirmataStandard on arduino mega

all i do is self.board.set_pin_mode(pin.number, pin.type, pin.callback) for bunch of analogs or digitals and wait.. i get callbacks data for a second then crash like that

MrYsLab commented 6 years ago

Are you doing this from a "clean" start? What I mean is that you:

  1. Kill the pymata-aio script if it is running.
  2. Remove the USB cable either from the computer or the mega.
  3. Plug the cable back in. Wait for the L13 LED to stop flashing (about 15 seconds).
  4. Start up the pymata-aio script.

Do you still see the errors?

If you get the errors by restarting the pymata-aio script and not doing a "clean" system restart, the reason is that there is no way to force the mega into a hardware reset from software. What happens is that the mega continues to stream its data (usually from an analog input pin) and since the data stream may be received by pymata-aio in the middle of the stream, it is unable to interpret the data correctly. That causes those errors.

dtheb commented 6 years ago

Yeah clean start reset by reset Pin, rest button, USB removal and even powering off the Arduino

MrYsLab commented 6 years ago

What devices are you monitoring and what pins are you connecting them to? If you could provide your python code, that would be helpful also.

If your script contains a sleep(), are you using time.sleep() or the pymata-aio sleep?

MrYsLab commented 6 years ago

Also, please provide the console output when the crash occurs. Thanks

dtheb commented 6 years ago

The error is in the development phase, before connecting anything to the pins, using Arduino Mega. using pymata sleep, and just looping over few pins here is a sample:

The set pin state code

    def watch_pin(self, pin):
        """
        Registers and watch a PIN for monitoring
        :param pin: Pin_object number 'A1', 'D34'... prefixes: A = analog, D = digital.
        """

        # create new pin instance
        pin = Pin_object(pin, self.on_data)

        key = '{0}_{1}'.format(pin.number, pin.type)
        self.pins[key] = pin
        print(pin.number)
        self.board.set_pin_mode(pin.number, pin.type, pin.callback)
        self.board.sleep(1)  #<-- just a delay trying slow down the loop same issue with or without

the loop in app init:

def init_board():
    t = firmata.BoardWatcher(msg, event, err) #<-- just a class to wrap the pymata in thread and communicate via callback
    t.daemon = True
    t.name = 'board'
    t.start()

    # for i in range(2, 54):
    #     t.watch_pin("D{0}".format(i))
    #     t.board.sleep(0.1)

    for i in range(14, 16): #<-- same issue with 1 pin or 16 pins or whatever
        t.watch_pin("A{0}".format(i))  #<-- register pins as seen above

Errors:

------------- RUN 1 -------------
Initializing Arduino - Please wait...
Arduino Firmware ID: 2.5 StandardFirmata.ino
Auto-discovery complete. Found 70 Digital Pins and 16 Analog Pins

event: Connected
14 #<----- Just my print(pin.number) in the set state above
msg: [14, 362, 2]
15 #<----- Just my print(pin.number) in the set state above
_i2c_reply() missing 1 required positional argument: 'data'
Shutting down ...

------------- RUN 2 same blabla -------------
_report_firmware() missing 1 required positional argument: 'sysex_data'
Shutting down ...

------------- RUN 3 same blabla -------------
_capability_response() missing 1 required positional argument: 'data'
Shutting down ...

------------- RUN 4 same blabla -------------
_pin_state_response() missing 1 required positional argument: 'data'
Shutting down ...
MrYsLab commented 6 years ago

The reasoning behind using pymata-aio is to avoid the use of threads and in fact mixing threads and asyncio is a very complicated endeavor. There is some discussion of threads and asyncio here: https://docs.python.org/3/library/asyncio-dev.html#concurrency-and-multithreading

Asyncio runs in a single thread and its event loop is in complete control. The asyncio coroutines can yield control back to the event loop, allowing concurrency in a "simpler" manner than threads. Threads often require complicated synchronization and locking methods, where asyncio does not. The problem is that the asyncio event loop cannot be blocked and mixing threads and asyncio can result in confusing and difficult to debug issues. The reason that one needs to use the pymata-aio sleep, is so that asyncio stays in control within its event loop.

Pymata3 acts as a proxy for the complexities of asyncio. It was created to help shield the user from having to understand how to deal with asyncio directly, but does has its limitations.

I think to do what you are trying to do would be easiest by working with pymata_core directly and adding your own coroutnes or to use PyMata and implement your design using threads.

I am sorry I don't have a simpler solution.

dtheb commented 6 years ago

I did more tests.. here is what i got now

Code:

from pymata_aio.pymata3 import PyMata3
from pymata_aio.constants import Constants

board = PyMata3(2)
board.set_sampling_interval(19)

def callback(data):
    print(data);

for i in range(14, 16):
    board.set_pin_mode(i, Constants.ANALOG, callback)

while True:
    board.sleep(1)

Errors:

--------- RUN 1 range(14, 16) ----------
Initializing Arduino - Please wait...
Arduino Firmware ID: 2.5 StandardFirmata.ino
Auto-discovery complete. Found 70 Digital Pins and 16 Analog Pins

[14, 555, 2]
[14, 335, 2]
[14, 304, 2]
[14, 288, 2]
[14, 268, 2]
[14, 259, 2]
[14, 247, 2]
[14, 241, 2]
[14, 232, 2]
_capability_response() missing 1 required positional argument: 'data'
Shutting down ...
--------- RUN 2 range(14, 16) ----------
_report_firmware() missing 1 required positional argument: 'sysex_data'
Shutting down ...
--------- RUN 3 range(14, 16) ----------
_string_data() missing 1 required positional argument: 'data'
Shutting down ... 
--------- RUN 4 range(13, 16) ----------
Initializing Arduino - Please wait...
Arduino Firmware ID: 2.5 StandardFirmata.ino
Auto-discovery complete. Found 70 Digital Pins and 16 Analog Pins

[13, 476, 2]
[14, 416, 2]
[13, 330, 2]
[14, 324, 2]
[13, 306, 2]
[14, 301, 2]
[13, 292, 2]
[14, 288, 2]
[13, 280, 2]
[14, 276, 2]
[13, 273, 2]
[14, 269, 2]
[13, 265, 2]
[14, 261, 2]
[13, 260, 2]
[14, 256, 2]
[13, 261, 2]
[14, 256, 2]
[13, 259, 2]
[14, 255, 2]
[13, 264, 2]
[14, 260, 2]
[13, 264, 2]
[14, 260, 2]
[13, 262, 2]
[14, 259, 2]
[13, 281, 2]
[14, 278, 2]
[13, 282, 2]
[14, 279, 2]
[13, 282, 2]
[14, 283, 2]
[13, 281, 2]
[14, 281, 2]
[13, 281, 2]
[14, 282, 2]
[13, 280, 2]
[14, 280, 2]
[13, 281, 2]
[14, 282, 2]
[13, 281, 2]
[14, 281, 2]
[13, 279, 2]
[14, 280, 2]
[13, 281, 2]
[14, 281, 2]
[13, 281, 2]
[14, 282, 2]
[13, 275, 2]
[14, 277, 2]
[13, 274, 2]
[14, 276, 2]
[13, 264, 2]
[14, 266, 2]
[13, 263, 2]
[14, 265, 2]
[13, 243, 2]
[14, 245, 2]
[13, 240, 2]
[14, 241, 2]
[13, 237, 2]
[14, 236, 2]
_string_data() missing 1 required positional argument: 'data'
Shutting down ... 

Check out run 4 noticed something? Pin 15 is not there, tried 2 different boards same result, it will only work after excluding the A15 port

and no the pin is not broken, works fine with simple AnalogReadSerial both boards

MrYsLab commented 6 years ago

I am looking at this and will get back to you.

MrYsLab commented 6 years ago

Ok. I can confirm that I am seeing what you are seeing. I am not sure what is "magical" about pin 15 but I will investigate. I tried loading StandardFirmata and I am seeing the same thing. That is good news because it seems that the problem is most likely within the pymata-aio code.

MrYsLab commented 6 years ago

Ok. I found the bug and it should be fixed with version 2.19 that I just published. Please let me know if this fixes the issue for you.

dtheb commented 6 years ago

Thanks, tested a bit, works fine so far 👍

MrYsLab commented 6 years ago

I am closing this issue. If necessary, you can still add comments and I will be notified.