firmata / ConfigurableFirmata

A plugin-based version of Firmata
GNU Lesser General Public License v2.1
153 stars 72 forks source link

Esp8266 connects to firmata via SERIAL/USB, but Capability response is empty and it does not respond to commands #138

Closed ale-novo closed 1 year ago

ale-novo commented 1 year ago

Hi, im using ConfigurableFirmata v2.10.1 im using perl-firmata as a client

i recently got a esp8266 board and was able to flash configurable firmata. while trying to connect via USB it does connect however the capability response is empty and the board does not respond. baudrate is 115200 For RP2040 the same script works fine and the board responds correctly. any idea what can be causing this? cheers.

alejandro@laptop:~/xparduino/perl-firmata/examples$ perl test.pl 
>f0,79,f7
>f9,00,00
<00
>f0,79,f7
>f9,00,00
>f0,79,f7
>f9,00,00
>f0,79,f7
>f9,00,00
>f0,79,f7
>f9,00,00
>f0,79,f7
>f9,00,00
>f0,79,f7
>f9,00,00
>f0,79,f7
>f9,00,00
>f0,79,f7
>f9,00,00
>f0,79,f7
>f9,00,00
>f0,79,f7
>f9,00,00
>f0,79,f7
>f9,00,00
>f0,79,f7
Firmware: 
Version: 
>ff
>f0,79,f7
>f9,00,00
>f0,79,f7
>f9,00,00
>f0,79,f7
>f9,00,00
>f0,79,f7
>f9,00,00
>f0,79,f7
>f9,00,00
>f0,79,f7
>f9,00,00
>f0,79,f7
>f9,00,00
>f0,79,f7
>f9,00,00
>f0,79,f7
>f9,00,00
>f0,79,f7
>f9,00,00
>f0,79,f7
>f9,00,00
>f0,79,f7
>f9,00,00

For a RP2040 the same script works fine:

alejandro@laptop:~/xparduino/perl-firmata/examples$ perl test.pl 
>f0,79,f7
>f9,00,00
<f0,79,02,0a,53,00,65,00,72,00,69,00,61,00,6c,00,2d,00,44,00,69,00,6e,00,2d,00,44,00,6f,00,75,00,74,00,2d,00,41,00,69,00,6e,00,2d,00,41,00,6f,00,75,00,74,00,2d,00,53,00,65,00,72,00,76,00,6f,00,2d,00,53,00,74,00,65,00,70,00,70,00,65,00,72,00,2d,00,41,00,63,00,63,00,65,00,6c,00,53,00,74,00,65,00,70,00,70,00,65,00,72,00,2d,00,45,00,6e,00,63,00,6f,00,64,00,65,00,72,00,2e,00,69,00,6e,00,6f,00,f7,f9,02,06
    < START_SYSEX
    < DATA_SYSEX
    < END_SYSEX
    < REPORT_VERSION
>f0,6b,f7
<f0,6c,00,01,0b,01,01,01,03,08,04,0e,08,15,08,15,7f,00,01,0b,01,01,01,03,08,04,0e,08,15,08,15,7f,00,01,0b,01,01,01,03,08,04,0e,08,15,08,15,7f,00,01,0b,01,01,01,03,08,04,0e,08,15,08,15,7f,00,01,0b,01,01,01,03,08,04,0e,08,15,08,15,7f,00,01,0b,01,01,01,03,08,04,0e,08,15,08,15,7f,00,01,0b,01,01,01,03,08,04,0e,08,15,08,15,7f,00,01,0b,01,01,01,03,08,04,0e,08,15,08,15,7f,00,01,0b,01,01,01,03,08,04,0e,08,15,08,15,7f,00,01,0b,01,01,01,03,08,04,0e,08,15,08,15,7f,00,01,0b,01,01,01,03,08,04,0e,08,15,08,15,7f,00,01,0b,01,01,01,03,08,04,0e,08,15,08,15,7f,00,01,0b,01,01,01,03,08,04,0e,08,15,08,15,7f,00,01,0b,01,01,01,03,08,04,0e,08,15,08,15,7f,00,01,0b,01,01,01,03,08,04,0e,08,15,08,15,7f,00,01,0b,01,01,01,03,08,04,0e,08,15,08,15,7f,00,01,0b,01,01,01,03,08,04,0e,08,15,08,15,7f,00,01,0b,01,01,01,03,08,04,0e,08,15,08,15,7f,00,01,0b,01,01,01,03,08,04,0e,08,15,08,15,7f,00,01,0b,01,01,01,03,08,04,0e,08,15,08,15,7f,00,01,0b,01,01,01,03,08,04,0e,08,15,08,15,7f,00,01,0b,01,01,01,03,08,04,0e,08,15,08,15,7f,00,01,0b,01,01,01,03,08,04,0e,08,15,08,15,7f,7f,7f,00,01,0b,01,01,01,03,08,08,15,08,15,7f,02,0a,7f,02,0a,7f,02,0a,7f,02,0a,7f,f7
    < START_SYSEX
    < DATA_SYSEX
    < END_SYSEX
>f0,69,f7
<f0,6a,7f,7f,7f,7f,7f,7f,7f,7f,7f,7f,7f,7f,7f,7f,7f,7f,7f,7f,7f,7f,7f,7f,7f,7f,7f,7f,00,01,02,03,f7
    < START_SYSEX
    < DATA_SYSEX
    < END_SYSEX
>f0,79,f7
<f0,79,02
    < START_SYSEX
    < DATA_SYSEX
<0a
    < DATA_SYSEX
<53,00
    < DATA_SYSEX
<65,00,72,00,69
    < DATA_SYSEX
<00,61,00,6c
    < DATA_SYSEX
<00,2d,00,44
    < DATA_SYSEX
<00,69,00,6e,00
    < DATA_SYSEX
<2d,00,44,00
    < DATA_SYSEX
<6f,00,75,00,74
    < DATA_SYSEX
<00,2d,00
    < DATA_SYSEX
<41,00
    < DATA_SYSEX
<69,00,6e,00
    < DATA_SYSEX
<2d,00,41,00,6f
    < DATA_SYSEX
<00,75,00,74,00,2d,00,53,00,65
    < DATA_SYSEX
<00,72,00,76,00
    < DATA_SYSEX
<6f,00,2d,00
    < DATA_SYSEX
<53,00
    < DATA_SYSEX
<74,00,65
    < DATA_SYSEX
Firmware: Serial-Din-Dout-Ain-Aout-Servo-Stepper-AccelStepper-Encoder.ino
Version: V_2_10
>ff
>f0,79,f7
>f9,00,00
<00,70,00,70,00,65,00,72,00,2d,00,41,00,63,00,63,00,65,00,6c,00,53,00,74,00,65,00,70,00,70,00,65,00,72,00,2d,00,45,00,6e,00,63,00,6f,00,64,00,65,00,72,00,2e,00,69,00,6e,00,6f,00,f7,f0,79,02,0a,53,00,65,00,72,00,69,00,61,00,6c,00,2d,00,44,00,69,00,6e,00,2d,00,44,00,6f,00,75,00,74,00,2d,00,41,00,69,00,6e,00,2d,00,41,00,6f,00,75,00,74,00,2d,00,53,00,65,00,72,00,76,00,6f,00,2d,00,53,00,74,00,65,00,70,00,70,00,65,00,72,00,2d,00,41,00,63,00,63,00,65,00,6c,00,53,00,74,00,65,00,70,00,70,00,65,00,72,00,2d,00,45,00,6e,00,63,00,6f,00,64,00,65,00,72,00,2e,00,69,00,6e,00,6f,00,f7,f9,02,06
    < DATA_SYSEX
    < END_SYSEX
    < START_SYSEX
    < DATA_SYSEX
    < END_SYSEX
    < REPORT_VERSION
>f0,6b,f7
<f0,6c,00,01,0b,01,01,01,03,08,04,0e,08,15,08,15,7f,00,01,0b,01,01,01,03,08,04,0e,08,15,08,15,7f,00,01,0b,01,01,01,03,08,04,0e,08,15,08,15,7f,00,01,0b,01,01,01,03,08,04,0e,08,15,08,15,7f,00,01,0b,01,01,01,03,08,04,0e,08,15,08,15,7f,00,01,0b,01,01,01,03,08,04,0e,08,15,08,15,7f,00,01,0b,01,01,01,03,08,04,0e,08,15,08,15,7f,00,01,0b,01,01,01,03,08,04,0e,08,15,08,15,7f,00,01,0b,01,01,01,03,08,04,0e,08,15,08,15,7f,00,01,0b,01,01,01,03,08,04,0e,08,15,08,15,7f,00,01,0b,01,01,01,03,08,04,0e,08,15,08,15,7f,00,01,0b,01,01,01,03,08,04,0e,08,15,08,15,7f,00,01,0b,01,01,01,03,08,04,0e,08,15,08,15,7f,00,01,0b,01,01,01,03,08,04,0e,08,15,08,15,7f,00,01,0b,01,01,01,03,08,04,0e,08,15,08,15,7f,00,01,0b,01,01,01,03,08,04,0e,08,15,08,15,7f,00,01,0b,01,01,01,03,08,04,0e,08,15,08,15,7f,00,01,0b,01,01,01,03,08,04,0e,08,15,08,15,7f,00,01,0b,01,01,01,03,08,04,0e,08,15,08,15,7f,00,01,0b,01,01,01,03,08,04,0e,08,15,08,15,7f,00,01,0b,01,01,01,03,08,04,0e,08,15,08,15,7f,00,01,0b,01,01,01,03,08,04,0e,08,15,08,15,7f,00,01,0b,01,01,01,03,08,04,0e,08,15,08,15,7f,7f,7f,00,01,0b,01,01,01,03,08,08,15,08,15,7f,02,0a,7f,02,0a,7f,02,0a,7f,02,0a,7f,f7
    < START_SYSEX
    < DATA_SYSEX
    < END_SYSEX
>f0,69,f7
<f0,6a,7f,7f,7f,7f,7f,7f,7f,7f,7f,7f,7f,7f,7f,7f,7f,7f,7f,7f,7f,7f,7f,7f,7f,7f,7f,7f,00,01,02,03,f7
    < START_SYSEX
    < DATA_SYSEX
    < END_SYSEX
input: 0
input: 1
input: 2
input: 3
input: 4
input: 5
input: 6
input: 7
input: 8
input: 9
input: 10
input: 11
input: 12
input: 13
input: 14
input: 15
input: 16
input: 17
input: 18
input: 19
input: 20
input: 21
input: 22
input: 25
output: 0
output: 1
output: 2
output: 3
output: 4
output: 5
output: 6
output: 7
output: 8
output: 9
output: 10
output: 11
output: 12
output: 13
output: 14
output: 15
output: 16
output: 17
output: 18
output: 19
output: 20
output: 21
output: 22
output: 25
analog: 26
analog: 27
analog: 28
analog: 29
pwm: 0
pwm: 1
pwm: 2
pwm: 3
pwm: 4
pwm: 5
pwm: 6
pwm: 7
pwm: 8
pwm: 9
pwm: 10
pwm: 11
pwm: 12
pwm: 13
pwm: 14
pwm: 15
pwm: 16
pwm: 17
pwm: 18
pwm: 19
pwm: 20
pwm: 21
pwm: 22
pwm: 25

Sketch:

/*
 * Serial-Din-Dout.ino generated by FirmataBuilder
 * Mon Aug 22 2022 04:17:24 GMT-0400 (EDT)
 */

#include <ConfigurableFirmata.h>

#include <DigitalInputFirmata.h>
DigitalInputFirmata digitalInput;

#include <DigitalOutputFirmata.h>
DigitalOutputFirmata digitalOutput;

#include <FirmataExt.h>
FirmataExt firmataExt;

void systemResetCallback()
{
  for (byte i = 0; i < TOTAL_PINS; i++) {
    if (IS_PIN_ANALOG(i)) {
    } else if (IS_PIN_DIGITAL(i)) {
      Firmata.setPinMode(i, OUTPUT);
    }
  }
  firmataExt.reset();
}

void initTransport()
{
  // Uncomment to save a couple of seconds by disabling the startup blink sequence.
  // Firmata.disableBlinkVersion();
  Firmata.begin(115200);
}

void initFirmata()
{
  Firmata.setFirmwareVersion(FIRMATA_FIRMWARE_MAJOR_VERSION, FIRMATA_FIRMWARE_MINOR_VERSION);

  firmataExt.addFeature(digitalInput);
  firmataExt.addFeature(digitalOutput);
  Firmata.attach(SYSTEM_RESET, systemResetCallback);
}

void setup()
{
  initFirmata();

  initTransport();

  Firmata.parse(SYSTEM_RESET);
}

void loop()
{
  digitalInput.report();

  while(Firmata.available()) {
    Firmata.processInput();
  }

}
pgrawehr commented 1 year ago

I don't have an ESP8266, so I can't test that, but it should work exactly the same as for the RP2040. I have tested with ESP32, and that works fine.

Can you try whether you get an example sketch to communicate correctly using the serial port? Maybe the USB port is not the primary serial port on this device. In this case, Firmata.begin() would need to use the correct port.

ale-novo commented 1 year ago

Hi, thanks for your response my example works fine with ESP32 and RP2040. Also arduino nano, STM32 blue pill, etc. It just does not work with ESP8266 like ive described.

im not sure if the usb port is correctly configured in firmata for this board, here is the board definition https://github.com/firmata/ConfigurableFirmata/blob/master/src/utility/Boards.h#L656 i have not changed this

maybe there is an Arduino IDE setting i need to set for usb to work, but im not sure and ive looked and did not see any sensible option.

ive tried a esp8266 software serial example that reports data via the serial monitor and it works fine

pgrawehr commented 1 year ago

ive tried a esp8266 software serial example that reports data via the serial monitor and it works fine

Which example was that exactly? Because "software serial" sounds like it's not using the default port.

ale-novo commented 1 year ago

servotester from the software serial examples of esp8266 cheers

pgrawehr commented 1 year ago

I can't find that exact sample, but it looks like the ESP8266 is a bit peculiar with it's serial ports.

I can only guess, but try replacing (in initTransport())

Firmata.begin(115200);

with

Serial.begin(115200);
Serial.swap(); // try with and without this
Serial.setRxBufferSize(1024);
Firmata.begin(Serial, true);

or

 SoftwareSerial* ss = new SoftwareSerial(3, 1); // Not sure which pins should be used here
Firmata.begin(*ss, true);

however I wouldn't recommend this, because it's probably significantly slower than using the hardware serial port.

ale-novo commented 1 year ago

Hi, thanks for your answer, however it did not work. the software serial example i get response from is this:

#include <SoftwareSerial.h>

SoftwareSerial swSer;

byte buf[10] =               { 0xFA, 0xAF,0x00,0x00,0x00, 0x00, 0x00, 0x00, 0x00, 0xED };
const byte cmd[10] PROGMEM = { 0xFA, 0xAF,0x00,0x00,0x00, 0x00, 0x00, 0x00, 0x00, 0xED };

void setup() {
    delay(2000);
    Serial.begin(115200);
    Serial.println(PSTR("\nAlpha 1S Servo Tester"));
    swSer.begin(115200, SWSERIAL_8N1, 12, 12, false, 256);
}

void loop() {
    for (int i = 1; i <= 32; i++) {
        GetVersion(i);
        delay(100);
    }
    SetLED(1, 0);
    GoPos(1, 0, 50);
    delay(1000);
    GoPos(1, 90, 50);
    delay(1000);
    GoPos(1, 100, 50);
    delay(1000);
    SetLED(1, 1);
    delay(2000);
}

void GetVersion(byte id) {
    memcpy_P(buf, cmd, 10);
    buf[0] = 0xFC;
    buf[1] = 0xCF;
    buf[2] = id;
    buf[3] = 0x01;
    SendCommand();
}

void GoPos(byte id, byte Pos, byte Time) {
    memcpy_P(buf, cmd, 10);
    buf[2] = id;
    buf[3] = 0x01;
    buf[4] = Pos;
    buf[5] = Time;
    buf[6] = 0x00;
    buf[7] = Time;
    SendCommand();
}

void GetPos(byte id) {
    memcpy_P(buf, cmd, 10);
    buf[2] = id;
    buf[3] = 0x02;
    SendCommand();
}

void SetLED(byte id, byte mode) {
    memcpy_P(buf, cmd, 10);
    buf[2] = id;
    buf[3] = 0x04;
    buf[4] = mode;
    SendCommand();
}

void SendCommand() {
    SendCommand(true);
}

void SendCommand(bool checkResult) {
    byte sum = 0;
    for (int i = 2; i < 8; i++) {
        sum += buf[i];
    }
    buf[8] = sum;
    ShowCommand();
    swSer.flush();
    swSer.enableTx(true);
    swSer.write(buf, 10);
    swSer.enableTx(false);
    if (checkResult) checkReturn();
}

void ShowCommand() {
    Serial.print(millis());
    Serial.print(PSTR(" OUT>>"));
    for (int i = 0; i < 10; i++) {
        Serial.print(buf[i] < 0x10 ? PSTR(" 0") : PSTR(" "));
        Serial.print(buf[i], HEX);
    }
    Serial.println();
}

void checkReturn() {
    unsigned long startMs = millis();
    while (((millis() - startMs) < 500) && (!swSer.available()));
    if (swSer.available()) {
        Serial.print(millis());
        Serial.print(PSTR(" IN>>>"));
        while (swSer.available()) {
            byte ch = (byte)swSer.read();
            Serial.print((ch < 0x10 ? PSTR(" 0") : PSTR(" ")));
            Serial.print(ch, HEX);
        }
        Serial.println();
    }
}
pgrawehr commented 1 year ago

Then try this:

SoftwareSerial swSer;

void initTransport() {
    delay(2000);
    Serial.begin(115200);
    swSer.begin(115200, SWSERIAL_8N1, 12, 12, false, 256);
    Firmata.begin(swSer, true);
}

It seems you need to experiment a bit, until you find the correct combination for the port you're using. This is hard to analyze from a distance.

ale-novo commented 1 year ago

Hi, ive found the problem

pin 1 and 3 must be ignored.

#ifdef ESP8266
  // need to ignore pins 1 and 3 when using an ESP8266 board
  Firmata.setPinMode(1, PIN_MODE_IGNORE);
  Firmata.setPinMode(3, PIN_MODE_IGNORE);
#endif

  Firmata.begin(115200);

Please for the maintainers of this repo add this to the ino serial examples

pgrawehr commented 1 year ago

@ale-novo Thanks for figuring this out. Is this now without any other change? Or still using softwareserial?

ale-novo commented 1 year ago

w/o any other change.

please refer to standard firmata serial for esp8266: https://gist.github.com/soundanalogous/87ea10c07c3f072cb46d8cad206b42d1