MrYsLab / PyMata

A Python client class library for Interaction with Standard Firmata
GNU Affero General Public License v3.0
95 stars 40 forks source link

auto_discover_board fails if the board does not expose analog ports #46

Closed douardda closed 4 years ago

douardda commented 4 years ago

I'm designing a custom board (see https://whatever.sdfa3.org/opentallylight.html) to control tally lights through an ITC100 intercom (using vMix but I plan to implement support for OBS studio if needed), and I'd like to use a dedicated firmata firmware with custom features.

My current fw code -- which only declares digital I/O -- used on this arduino-compatible board does not advertise any analog device, which makes PyMata fails to initialize the connection since the code expect analog ports (in pymata_command_handler.py):

    def auto_discover_board(self, verbose):
        """
        This method will allow up to 30 seconds for discovery (communicating with) an Arduino board
        and then will determine a pin configuration table for the board.
        :return: True if board is successfully discovered or False upon timeout
        """
        # get current time
        start_time = time.time()

        # wait for up to 30 seconds for a successful capability query to occur

        while len(self.analog_mapping_query_results) == 0:
            if time.time() - start_time > 30:
                return False
                # keep sending out a capability query until there is a response
            self.send_sysex(self.ANALOG_MAPPING_QUERY)
            time.sleep(.1)

why is this done like that? I would have expected this piece of code to ask for generic stuff (firmware version etc) then for capabilities without expecting anything to be able to complete the initialization.

Is there a reason for depending on analog ports for this?

MrYsLab commented 4 years ago

Knowing the number of analog and digital pins is necessary to set up the internal response tables.

Since you are building a custom board that is non-standard, and this software was designed to work with standard Arduino's, my suggestion would be that you fork this repo and then customize it to meet your needs.

If you wish to create your own fork, and have any questions about the code, I would be happy to answer.

MrYsLab commented 4 years ago

I am going to close this issue, but if you have any comments or questions, if you post here, I will see your comments.

You may wish to look at the Firmata protocol. PyMata supports the full protocol. The number of analog and digital pins is compiled into the Arduino sketch based on board type in the boards.h file. When you create your custom sketch, if your board has a large number of digital pins, you may want to describe your board as the Mega2560. You could also just pass a "dummy" number back when PyMata queries the number of analog pins. Solving the problem on the board side may be simpler than modifying PyMata.

douardda commented 4 years ago

Thanks for your answers.

I may have not read the protocol correctly, but I had the impression the board should be able to describe its capabilities as a response to the CAPABILITY_QUERY message. So I would expect PyMata to use this by default as board's setup mechanism. It should then also be possible to disable this introspection-based board configuration by either use some other heuristics (as the current one based on analog ports declaration, which makes the assumption that the implemented firmware is StandardFirmata or very similar, or even the possibility to give a "static" board description).

Would you consider a PR going in this direction? (as well as some other refactorings I believe are necessary, like the fact there are many mutable class attributes that really should be instance attributes). Thanks

MrYsLab commented 4 years ago

Hi David, I don't think that you necessarily misread the spec, but the purpose of PyMata was to support all StandardFirmata commands and responses. So my intent was different than what your project requires. I am reluctant to accept a pull request for your suggested changes since PyMata changes very rarely, and I do not have the bandwidth to maintain such a massive undertaking. I think it would be much simpler to implement the ANALOG_MAPPING_QUERY sysex command in the sketch and return some small value of analog pseudo pins in the ANALOG_MAPPING_RESPONSE to "fake out" PyMata's autodiscovery. If you do not wish to see the header identifying the pseudo analog pins, you can always set the verbose flag to False in the init method to suppress the banner from printing to the console. If you prefer to do things on the Python side, I would prefer that you clone PyMata, and create and maintain your own Firmata client that meets your specific needs. I appreciate your offer for the PR, and I usually accept PRs for my repositories, but I apologize that I am going to have to decline this time. Again, if you have any questions, I would be happy to answer them.