I'm using two Arduino Megas in a project to read data from a bunch of analog sensors and then output PWMs on digital pins according to their value. These analog signals are also being plotted on a dash app.

I'm using pyfirmata, and the program runs perfectly with either one of the two boards connected. However, when I connect both boards, The second board (second in terms of its pyfirmata.util.Iterator object being instantiated second), will always report nonetype objects when calling board2_some_analog_pin.read()

I found essentially the exact same problem here

Putting the iterators on separate processes fixed the nonetype issue for me too. However I want to know why this would fix things, because I want to be confident there isn't a threading-based solution to the nonetype problem before I start reprogramming everything to work with processes.

My instinct tells me it has to do with this code:

class Iterator(threading.Thread):

    def __init__(self, board):
        super(Iterator, self).__init__()
        self.board = board
        self.daemon = True

    def run(self):
        while 1:
                while self.board.bytes_available():
            except (AttributeError, serial.SerialException, OSError):
                # this way we can kill the thread by setting the board object
                # to None, or when the serial port is closed by board.exit()
            except Exception as e:
                # catch 'error: Bad file descriptor'
                # iterate may be called while the serial port is being closed,
                # causing an "error: (9, 'Bad file descriptor')"
                if getattr(e, "errno", None) == 9:
                    if e[0] == 9:
                except (TypeError, IndexError):
            except (KeyboardInterrupt):

found on the pyfirmata github repo here

I've been searching around for days, but still have no clue why this would cause whichever board is tied to the second instance of the iterator object to only give nonetype objects as analog reads. It's not a serial communications problem, because some_digital_pin.write(pwm) works for both boards when both plugged in.

Any help or insight into this issue would be greatly appreciated, as well as tips on how to bypass this issue to allow both boards to read without using multiprocessing.

  • 1
    Doesn't seem like it'd be this code if it's not a serial comms problem, rather something relating to how values are read or stored locally (if they are). No access to machines at the moment but I may take a look this evening. Does reading a digital pin show the same behavior? Jun 9 '21 at 11:40
  • Also, did you try via get_pin? And did you try the solution in the linked post? My current guess is that the issue is solvable with some minor tweaks to pyfirmata but I'll need to get a test env set up. Jun 9 '21 at 14:30
  • It is not a serial comms problem, I'm pretty sure. Both arduinos are detected fine. When either one is plugged in, they analog read fine. Only when both are plugged in and I run a program that has two pyfirmata.utils.iterator objects, does the arduino with the second iterator only report nonetypes. It's not an arduino issue either because I can swap the arduinos and it's always the one with the second iterator instance that gives nonetypes. Furthermore, setting PWMs on output pins work fine, suggesting no comms issue.
    – Han Zhang
    Jun 9 '21 at 17:08
  • @DaveNewton I did not try get_pin, but I did try the solution in the linked post. It worked. However, for my application, just printing values to console is insufficient, so I'll have to either rework my entire code + modules to work with multiple processes, or, which I'm really hoping might be the case, there's some threading options or functions I can use to solve whatever is causing this issue with the two arduino iterator threads.
    – Han Zhang
    Jun 9 '21 at 17:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.