firmata/ConfigurableFirmata

ConfigurableFirmata USB becomes not ready

Opened this issue · 12 comments

Hi,

Hoping to get some advice on setting-up ConfigurableFirmata on an Arduino Nano with an AT328PB.

Added a condition to lump the AT328PB in with nano group during board.h configuration:

... // Arduino Duemilanove, Diecimila, Uno, Nano, etc. #if defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__) || defined(__AVR_ATmega328__) || defined(__AVR_ATmega328PB__) ...

Have ConfigurableFirmata version 3.1.0 loaded in arduino-ide_2.2.1_Linux_64bit.

Set-up serial baud rate in ConfigurableFirmata.ino

... //Firmata.begin(115200); Firmata.begin(57600) ...

Module enable defines in ConfigurableFirmata.ino:

``
...
#include <DigitalInputFirmata.h>
DigitalInputFirmata digitalInput;

#include <DigitalOutputFirmata.h>
DigitalOutputFirmata digitalOutput;

#include <SerialFirmata.h>
SerialFirmata serial;
...
``
Arduino serial monitor set to 57600 baud captures the following sequence, whenever the Nano board is reset:

"(Gibber)...ConfigurableFirmata qBooting device. Stand by... qUnknown pin mode q...(repeats last message ad infinitum)."

The repeated 'Unknown pin mode' message is a worry!

I copied the Firmata.js example blink.js file, and also set the baud rate for 57600 baud:

... const options = { baud: 57600 // Set your desired baud rate }; const board = new Board(port.path, options); ...

Tail of output from running the blink.js file in 'output debug messages' mode of node, on a USB cable connected Linux box:

user@hostname:~$DEBUG=* node blink.js ... serialport/binding-abstract read +6ms serialport/bindings/unixRead Starting read +1ms serialport/bindings/unixRead read error [Error: EAGAIN: resource temporarily unavailable, read] { errno: -11, code: 'EAGAIN', syscall: 'read' } +1ms serialport/bindings/unixRead waiting for readable because of code: EAGAIN +0ms serialport/bindings/poller Polling for "readable" +2ms

Many reads initially occur, before the USB serial device /dev/ttyUSB0 becomes unavailable, and communication suspends.

When I run the client blink.js code in node without debug messaging, the output is as follows:

user@hostname:~$node blink.js { manufacturer: '1a86', serialNumber: undefined, pnpId: 'usb-1a86_USB2.0-Ser_-if00-port0', locationId: undefined, vendorId: '1a86', productId: '7523', path: '/dev/ttyUSB0' } board constructed

The board object is created successfully in blink.js...

... const board = new Board(port.path, options); console.log("board constructed"); ...

...yet the board.on("ready"...) function never executes.

... board.on("ready", () => { console.log("ready"); // Never fires. ...

The whole ConfigurableFirmata and Firmata.js project folder can be inspected at the following: https://file.io/OuPTk63i3foI

If anyone can follow along, and please tell me why I get the repeated 'Unknown pin mode' message after resetting the Arduino, whilst connected by Arduino serial monitor?

GBEM👽

Can you check the baud rate you're using? The number in the Firmata.begin(115200) call (115200 by default) in the .ino file must be the same than the number in the line const options = { baud: 115200}; in your .js file.

Thanks, pgrawehr. I have both set to 57600, though get the same result when they're at 115200. Curiously I get the same result when I build for an ESP32, also.

I'm mostly using ESP32 these days. For ConfigurableFirmata 3 and later, I recommend not to use FirmataBuilder, but start with the example ConfigurableFirmata.ino in the "examples\ConfigurableFirmata" folder. For building, I recommend the Arduino IDE (both 1.X and 2.X versions should work) with the latest ESP32 IDK (3.0 or above).

You can leave all the settings at default, as the ESP32 has more than enough memory to compile in all modules.

Hi pgrawehr.

Both excellent suggestions. Yes, the 'Unknown pin mode' message stream may have been caused by my having sought a minimal example, yet one that firmatabuilder made for a different version of the ConfigurableFirmata library. I started out with an at328pb as you know, but should have gone with the latest full working example on an ESP32 first.

Okay, we're close, and I can't wait to crack this.

With the ConfigurableFirmata.ino example from the installed ConfigurableFirmata 3.3.0 Arduino library, compiling on arduino-ide_2.2.1_Linux_64bit, it builds and flashes without error.

Here's what I see on the Arduino serial terminal when each time the ESP32 comes out of reset:

rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0030,len:4832
load:0x40078000,len:16460
load:0x40080400,len:4
load:0x40080404,len:3504
entry 0x400805cc
E (338) esp_cor⸮⸮fVW
}⸮⸮⸮͡⸮ Core dump data check failed:
Calculated checksum='777f37f6'
Image checksum='vf ConfigurableFirmata Booting device. Stand by...

Now I thought that looked encouraging, even with the message about data check failed.

I have a Firmata.js node script that I'm reasonable certain should toggle an output pin every half second. This is the debug message transcript, of when I run this client:

DEBUG=* node blink.js
serialport/bindings loading LinuxBinding +0ms
serialport/stream .list +0ms
{
manufacturer: 'Silicon Labs',
serialNumber: '0001',
pnpId: 'usb-Silicon_Labs_CP2102_USB_to_UART_Bridge_Controller_0001-if00-port0',
locationId: undefined,
vendorId: '10c4',
productId: 'ea60',
path: '/dev/ttyUSB0'
}
serialport/stream opening path: /dev/ttyUSB0 +156ms
serialport/binding-abstract open +0ms
board constructed
serialport/stream _read queueing _read for after open +2ms
serialport/bindings/poller Creating poller +0ms
serialport/stream opened path: /dev/ttyUSB0 +33ms
serialport/stream _read reading { start: 0, toRead: 256 } +0ms
serialport/binding-abstract read +35ms
serialport/bindings/unixRead Starting read +0ms
serialport/bindings/unixRead read error [Error: EAGAIN: resource temporarily unavailable, read] {
errno: -11,
code: 'EAGAIN',
syscall: 'read'
} +0ms
serialport/bindings/unixRead waiting for readable because of code: EAGAIN +1ms
serialport/bindings/poller Polling for "readable" +3ms
serialport/stream _write 1 bytes of data +5s
serialport/binding-abstract write 1 bytes +5s
serialport/bindings/unixWrite Starting write 1 bytes offset 0 bytesToWrite 1 +0ms
serialport/bindings/unixWrite write returned: wrote 1 bytes +1ms
serialport/bindings/unixWrite Finished writing 1 bytes +1ms
serialport/stream binding.write write finished +3ms
serialport/stream _write 3 bytes of data +0ms
serialport/binding-abstract write 3 bytes +4ms
serialport/bindings/unixWrite Starting write 3 bytes offset 0 bytesToWrite 3 +1ms
serialport/bindings/unixWrite write returned: wrote 3 bytes +0ms
serialport/bindings/unixWrite Finished writing 3 bytes +0ms
serialport/stream binding.write write finished +1ms

As soon as the client finds the attached port readable, it sends off a short sequence of small byte writes, then appears to re-enter searching for readable serial data.

Running the equivalent blink sketch written for the Johnny-Five Arduino library, yields the same apparent Firmata protocol interaction, but adds debug messages about board or interconnection failure.

I'm emitting debug messages from my Firmata.js blink test script, and from what it reports the board.on("ready"...) registered event never fires.

Not sure what the client is sending, in it's short burst. The absence of a firmata protocol response hints at a server side error, but I can't be sure. It's time to look for an alternative, known to work client library.

I skipped past a recommended python 'thing' that gave you a client UI for some basic pin control. Can't seem to find it back?

Yea, the firmware looks good, I really don't know what your script is doing there...

I'm also a maintainer of https://github.com/dotnet/iot, which also has a firmata client library and which I've been testing most of the time. Obviously that is quite a different ecosystem, but you might give the examples at https://github.com/dotnet/iot/tree/main/src/devices/Arduino/samples/ApiChecker a try. (Just check out the repository and run "build.sh" in the root directory).

Thanks for the .NET tip, Patrick. Not really set-up for that, but I'm pleased to hear there's a good, active .NET client project to fall back on. A known good APiChecker to validate a Firmata server would be just the ticket.

Okay, having zero luck blinking an output pin with Firmata.js, Johhny-Five, and now pyfirmata python library. The pyfirmata pin write appears to complete without error, yet the state of the output pin is invariant.

I wonder if there couldn't be a firmata protocol version mis-match between the current Firmata.js client and the current ConfigurableFirmata Arduino server? Maybe I should be back-dating one or other, to get them to work in unison?

It may be confabulation, but the current Firmata.js possibly could be for Firmata protocol version 2.5. Johnny-Five appears to speak version 2.5 and some 2.6. Pyfirmata was for I think 2.1 and some 2.2. But which ConfigurableFirmata do I need for firmata protocol version 2.5? That question will have to wait a bit.

Success!

arduino-ide_2.2.1_Linux_64bit
ConfigurableFirmata Arduino library version 2.10.1.
ConfigurableFirmata.ino example from version 2.10.1.
Firmata.js current version (1/11/24).
blink.js from Firmata.js examples, running in node 12.22.9.

Had to drop back to an AVR, as ESP32 not supported in ConfigurableFirmata version 2.10.1.

What a shame that there isn't a Firmata.js or Johnny-Five update for the 3.x protocol version of ConfigurableFirmata. Or, perhaps a 2.10.2 version of ConfigurableFirmata that embodies support for the ESP32 microcontroller. Controlling ESP32s via WiFi with javascript would be amazing!

I wonder what might be involved in an update to the Firmata.js' protocol, or otherwise adding ESP32 support to ConfigurableFirmata 2.10?

GBEM👽

Here are some important facts about the two versions of the ConfigurableFirmata Arduino library that you will need to know:

  • Version 2.x – No support for ESP32, but wide support under client libraries (firmata.js, Johnny-Five, pyfirmata, etc.)
  • Version 3.x – Support for ESP32, but little support under client libraries, save for the .Net library iot, and possibly some others.

Some ConfigurableFirmata client libraries, their language, and the version of the Firmata protocol they currently support:

  • firmata.js – JavaScript – Firmata protocol version 2.5.
  • Johny-Five – JavaScript – Firmata protocol version 2.5 and some 2.6.
  • pyfirmata – Python – Firmata protocol version 2.1 and some 2.2.

ConfigurableFirmata version numbers mirror the Firmata protocol version they implement. I spent a lot of time learning this the hard way, that protocol support of the chosen client library must be matched with the appropriate ConfigurableFirmata library version. Also, that the ConfigurableFirmata library must be matched to code derived from it’s version’s ConfigurableFirmata.ino example.

Here’s the list of versions and artefacts I was able to run successfully together on an AVR:

  • Arduino IDE – arduino-ide_2.2.1_Linux_64bit.
  • ConfigurableFirmata Arduino library version 2.10.1.
  • Server sketches based on the ConfigurableFirmata.ino example from version 2.10.1.
  • Node JavaScript client library – Firmata.js current version (1/11/24).
  • Client javascript implementations based on examples from the current Firmata.js, running in node 12.22.9 on client PC.

You may find the ConfigurableFirmata server sketches produced by the site at firmatabuilder.com useful, be be aware that they should only be built with the 2.10.1 version of the ConfigurableFirmata Arduino library. Get this wrong and you’ll be in a very dark place.

HTH,
GBEM👽

Thanks @Green-Bug-Eyed-Monster for this investigation. While I believe you are right, I don't really understand it. There have been no breaking changes in these firmata versions, only new features have been added. In particular, the very basic commands for blinking LEDs have certainly not changed.

I am no expert in either js or python, but I might give it a try and see whether I can debug the problem.

I've had a look at johnny-five and firmata.js. The first observation was that johnny-five uses firmata.js, so it's quite expected that if firmata.js is somehow broken, the other would also not work. Unfortunatelly, both are very poorly maintained (no relevant commits for several years) and therefore also link to very outdated libraries. I'm having a hard time just to get them to run without throwing compilation or dependency errors.

Pyfirmata has similar issues: It hasn't seen an update in a long time and seems to use a non-functioning version of the serial library. After fixing that, I get it to connect, but only if I hardcode the board layout. The reason is that the code used to parse the pin capability list is making false assumptions about the structure of the data. The way it's done there was never really correct and more or less worked by coincidence as long as the board capabilities and pin count didn't change.

It's possible to fix all that, but without a proper maintainer, I'm not sure somebody will care :-(

Awesome. Thanks, @pgrawehr.

fimata.js is the most interesting for me, and I've managed to get it to do everything that it will need to do for my current objective.

I'm only just learning javascript as it relates to server side implementations running on node. Maybe I should take a second look at the neglected firmata.js library, once I have a better grasp of the technology. Git remains a bit of a mystery also, so maybe I could do with some real-world experience.

Thanks so much for your vital assistance, @pgrawehr. Hope to get in touch again in the near future.

GBEM👽