firmata / protocol

Documentation of the Firmata protocol.
994 stars 151 forks source link

Single-Read Functionality #92

Closed Molorius closed 7 years ago

Molorius commented 7 years ago

Presently, the only way to get the value of a digital port or analog pin is by setting it to report. This is very efficient, but in several cases this constant flow of data may be more of a hindrance than a help. For example, here is a large discussion on this: firmata/firmata.js#127

I propose a new set of commands to handle a single read of a pin/port. The microcontroller could report the data in the same format that it presently does, using the 0xE0 and the 0x90 blocks. For the host, I have two potential commands in mind:

  1. Using a single byte. This would implement the 0xA0 and 0xB0 blocks to request an analog pin or digital port, respectively. For example, to request the value of analog pin 2 the host would send 0xA2, with no additional byte.
  2. Using two bytes. This would use 0xF2 for an analog read and 0xF3 for a digital read. The second byte would specify the desired port/pin. For example, to request the value of digital port 1 the host would send 0xF3 0x01

I already have working code with StandardFirmata.ino for testing. This was a quick port, so it uses the 0xA0 and 0xB0 blocks but then requires an additional byte (it can be anything). That pull request can be found here: firmata/arduino#377 This was tested using a small python script. I can upload and maintain that as well if anybody requests it.

soundanalogous commented 7 years ago

Digital port reporting is actually much more efficient than querying the port value. Port values are only updated if a pin in that port has changed since the last read. There is also less latency than you'd have with a call and response type of API, you get the value as soon as the next iteration of the loop if it has changed. That said, I'm not opposed to adding a way to query for the digital pin or port value.

Regarding a new message to query a single analog pin, this would be useful and there are already a couple of discussions around the ability to query individual analog or digital pin values. You can find proposals here and here.

I'd also shy away from using 0xA0 and 0xB0 since the aim is to keep Firmata 2.0 midi-compliant. This may change in Firmata 3.0 however.

soundanalogous commented 7 years ago

Also see this proposal which uses a single message to report a variety of pins, both individual as well as groups of pins: https://github.com/firmata/protocol/issues/59.

Molorius commented 7 years ago

I have not used midi before, so I was not aware the 0xA0 and 0xB0 blocks would cause a problem.

My proposal is a more simple version of #59, which I did not see before. It doesn't matter to me how this is implemented, but I would be more than happy to help.

How should I continue? Should I make the code I've already written better, or should I try to implement proposal #59?

soundanalogous commented 7 years ago

There needs to be a larger discussion here in order to proceed since these proposals adds core functionality which is not easy to change in a non-breaking way going forward. I need to discuss further with @zfields to plan where this feature fits into the bigger picture we are starting to work through.

Molorius commented 7 years ago

Of the desired changes for v2.6, it seems like #68 is the next logical step forward. I'll start implementing that until I hear otherwise. Since this proposal is similar to others, I'll close this unless you comment further.

zfields commented 7 years ago

@Molorius First, I must say I completely agree with your motive, and your code fits in nicely into the existing implementation. However, the problem we need to solve is more deeply rooted. The protocol was originally written to support the configuration of the Arduino UNO and all rail compatible clones. Recently, with the explosion of board designers and seemingly infinite board configurations and products, we have realized (at a minimum) the current handling of analog messages is rapidly becoming insufficient, and we need to address this problem with a more broad and sweeping solution. While your addition is a good one, it entrenches us further into a short coming of the protocol.