Skip to content

Commit 7d6ada1

Browse files
committed
[WiFi] added support for ESP32 architecture and XIAO ESP32C3 board
- support for ESP32 architecture with WiFi interface (WiFiStream, Firmata.h, StandardFirmataWiFi) - support for Seed Studio XIAO ESP32C3 board (Board.h) - support for Firmata applications without Servo.h (Boards.h, StandardFirmataWiFi)
1 parent 53bb550 commit 7d6ada1

File tree

7 files changed

+111
-31
lines changed

7 files changed

+111
-31
lines changed

Boards.h

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
Boards.h - Hardware Abstraction Layer for Firmata library
33
Copyright (c) 2006-2008 Hans-Christoph Steiner. All rights reserved.
44
Copyright (C) 2009-2017 Jeff Hoefs. All rights reserved.
5+
Copyright (C) 2023 Jens B. All rights reserved.
56
67
This library is free software; you can redistribute it and/or
78
modify it under the terms of the GNU Lesser General Public
@@ -10,7 +11,7 @@
1011
1112
See file LICENSE.txt for further informations on licensing terms.
1213
13-
Last updated April 15th, 2018
14+
Last updated December 17th, 2023
1415
*/
1516

1617
#ifndef Firmata_Boards_h
@@ -29,7 +30,16 @@
2930
// compile, but without support for any Servos. Hopefully that's what the
3031
// user intended by not including Servo.h
3132
#ifndef MAX_SERVOS
32-
#define MAX_SERVOS 0
33+
#define MAX_SERVOS 0
34+
class Servo
35+
{
36+
public:
37+
uint8_t attach(int pin) { return 0; };
38+
uint8_t attach(int pin, int min, int max) { return 0; };
39+
void detach() {};
40+
void write(int value) {};
41+
bool attached() { return false; };
42+
};
3343
#endif
3444

3545
/*
@@ -1021,6 +1031,29 @@ writePort(port, value, bitmask): Write an 8 bit port.
10211031
#define PIN_TO_SERVO(p) (p)
10221032
#define DEFAULT_PWM_RESOLUTION 10
10231033

1034+
// XIAO ESP32C2
1035+
// note: Firmata pin numbering schema is by ESP32 GPIO -> IS_XXX checks GPIO number
1036+
#elif defined(ARDUINO_XIAO_ESP32C3)
1037+
#define TOTAL_ANALOG_PINS (A2 + 1) // (max GPIOx + 1), there are 4 physical analog pins but only 3 are supported by ESP32 SDK 2.0.14 via ADC1
1038+
#define TOTAL_PINS NUM_DIGITAL_PINS // (max GPIOx + 1), there are 11 physical pins
1039+
#define PIN_SERIAL_RX RX
1040+
#define PIN_SERIAL_TX TX
1041+
#define IS_PIN_DIGITAL(p) (((p) >= D0 && (p) <= D10) || (p) == D6 || (p) == D7)
1042+
#define IS_PIN_ANALOG(p) ((p) >= A0 && (p) <= A2)
1043+
#define IS_PIN_PWM(p) 0
1044+
#define IS_PIN_SERVO(p) (IS_PIN_DIGITAL(p) && MAX_SERVOS > 0)
1045+
#define IS_PIN_I2C(p) ((p) == SDA || (p) == SCL)
1046+
#define IS_PIN_SPI(p) ((p) == SS || (p) == MOSI || (p) == MISO || (p) == SCK)
1047+
#define IS_PIN_INTERRUPT(p) (digitalPinToInterrupt(p) > NOT_AN_INTERRUPT)
1048+
#define IS_PIN_SERIAL(p) ((p) == PIN_SERIAL_RX || (p) == PIN_SERIAL_TX)
1049+
#define PIN_TO_DIGITAL(p) ((p) < 6? D0 + (p) : ((p) < 8? D6 + 6 - (p) : (p))) // Dx to GPIOy
1050+
#define PIN_TO_ANALOG(p) (p) // FIRMATAx to GPIOy
1051+
#define PIN_TO_PWM(p) 127 // @TODO ESP32 SDK does not support analogWrite()
1052+
#define PIN_TO_SERVO(p) 127 // @TODO ESP32 SDK does not support servos
1053+
1054+
#define DEFAULT_PWM_RESOLUTION 8 // see esp32-hal-led.c, analog_resolution
1055+
#define DEFAULT_ANALOG_RESOLUTION 12 // see esp32-hal-adc.h, analogSetWidth()
1056+
10241057
// STM32 based boards
10251058
#elif defined(ARDUINO_ARCH_STM32)
10261059
#define TOTAL_ANALOG_PINS NUM_ANALOG_INPUTS

Firmata.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
Firmata.h - Firmata library v2.5.8 - 2018-04-15
2+
Firmata.h - Firmata library v2.5.10 - 2023-12-16
33
Copyright (c) 2006-2008 Hans-Christoph Steiner. All rights reserved.
44
Copyright (C) 2009-2017 Jeff Hoefs. All rights reserved.
55
@@ -38,7 +38,9 @@
3838
//#define INPUT 0x00 // defined in Arduino.h
3939
//#define OUTPUT 0x01 // defined in Arduino.h
4040
// DEPRECATED as of Firmata v2.5
41-
#define ANALOG 0x02 // same as PIN_MODE_ANALOG
41+
#ifndef ARDUINO_ARCH_ESP32
42+
#define ANALOG 0x02 // same as PIN_MODE_ANALOG
43+
#endif
4244
#define PWM 0x03 // same as PIN_MODE_PWM
4345
#define SERVO 0x04 // same as PIN_MODE_SERVO
4446
#define SHIFT 0x05 // same as PIN_MODE_SHIFT

FirmataConstants.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ namespace firmata {
2121
*/
2222
static const int FIRMWARE_MAJOR_VERSION = 2;
2323
static const int FIRMWARE_MINOR_VERSION = 5;
24-
static const int FIRMWARE_BUGFIX_VERSION = 7;
24+
static const int FIRMWARE_BUGFIX_VERSION = 10;
2525

2626
/* Version numbers for the protocol. The protocol is still changing, so these
2727
* version numbers are important.

examples/StandardFirmataWiFi/StandardFirmataWiFi.ino

Lines changed: 29 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
2323
See file LICENSE.txt for further informations on licensing terms.
2424
25-
Last updated August 17th, 2017
25+
Last updated December 17th, 2023
2626
*/
2727

2828
/*
@@ -74,7 +74,11 @@
7474
- Arduino Mega: (D5, D7, D10, D50, D52, D53)
7575
*/
7676

77-
#include <Servo.h>
77+
#ifndef ARDUINO_ARCH_ESP32
78+
// NOTE: ESP32 SKD does not provide an implementation for class Servo
79+
// -> requires a skeleton implementation for Servo in Boards.h to be able to compile
80+
#include <Servo.h>
81+
#endif
7882
#include <Wire.h>
7983
#include <Firmata.h>
8084

@@ -235,8 +239,10 @@ void detachServo(byte pin)
235239
} else if (servoCount > 0) {
236240
// keep track of detached servos because we want to reuse their indexes
237241
// before incrementing the count of attached servos
238-
detachedServoCount++;
239-
detachedServos[detachedServoCount - 1] = servoPinMap[pin];
242+
if (detachedServoCount < MAX_SERVOS) {
243+
detachedServos[detachedServoCount] = servoPinMap[pin];
244+
detachedServoCount++;
245+
}
240246
}
241247

242248
servoPinMap[pin] = 255;
@@ -370,7 +376,7 @@ void setPinModeCallback(byte pin, int mode)
370376
reportAnalogCallback(PIN_TO_ANALOG(pin), mode == PIN_MODE_ANALOG ? 1 : 0); // turn on/off reporting
371377
}
372378
if (IS_PIN_DIGITAL(pin)) {
373-
if (mode == INPUT || mode == PIN_MODE_PULLUP) {
379+
if (mode == PIN_MODE_INPUT || mode == PIN_MODE_PULLUP) {
374380
portConfigInputs[pin / 8] |= (1 << (pin & 7));
375381
} else {
376382
portConfigInputs[pin / 8] &= ~(1 << (pin & 7));
@@ -390,14 +396,14 @@ void setPinModeCallback(byte pin, int mode)
390396
Firmata.setPinMode(pin, PIN_MODE_ANALOG);
391397
}
392398
break;
393-
case INPUT:
399+
case PIN_MODE_INPUT:
394400
if (IS_PIN_DIGITAL(pin)) {
395401
pinMode(PIN_TO_DIGITAL(pin), INPUT); // disable output driver
396402
#if ARDUINO <= 100
397403
// deprecated since Arduino 1.0.1 - TODO: drop support in Firmata 2.6
398404
digitalWrite(PIN_TO_DIGITAL(pin), LOW); // disable internal pull-ups
399405
#endif
400-
Firmata.setPinMode(pin, INPUT);
406+
Firmata.setPinMode(pin, PIN_MODE_INPUT);
401407
}
402408
break;
403409
case PIN_MODE_PULLUP:
@@ -407,14 +413,14 @@ void setPinModeCallback(byte pin, int mode)
407413
Firmata.setPinState(pin, 1);
408414
}
409415
break;
410-
case OUTPUT:
416+
case PIN_MODE_OUTPUT:
411417
if (IS_PIN_DIGITAL(pin)) {
412418
if (Firmata.getPinMode(pin) == PIN_MODE_PWM) {
413419
// Disable PWM if pin mode was previously set to PWM.
414420
digitalWrite(PIN_TO_DIGITAL(pin), LOW);
415421
}
416422
pinMode(PIN_TO_DIGITAL(pin), OUTPUT);
417-
Firmata.setPinMode(pin, OUTPUT);
423+
Firmata.setPinMode(pin, PIN_MODE_OUTPUT);
418424
}
419425
break;
420426
case PIN_MODE_PWM:
@@ -461,7 +467,7 @@ void setPinModeCallback(byte pin, int mode)
461467
void setPinValueCallback(byte pin, int value)
462468
{
463469
if (pin < TOTAL_PINS && IS_PIN_DIGITAL(pin)) {
464-
if (Firmata.getPinMode(pin) == OUTPUT) {
470+
if (Firmata.getPinMode(pin) == PIN_MODE_OUTPUT) {
465471
Firmata.setPinState(pin, value);
466472
digitalWrite(PIN_TO_DIGITAL(pin), value);
467473
}
@@ -498,11 +504,11 @@ void digitalWriteCallback(byte port, int value)
498504
// do not disturb non-digital pins (eg, Rx & Tx)
499505
if (IS_PIN_DIGITAL(pin)) {
500506
// do not touch pins in PWM, ANALOG, SERVO or other modes
501-
if (Firmata.getPinMode(pin) == OUTPUT || Firmata.getPinMode(pin) == INPUT) {
507+
if (Firmata.getPinMode(pin) == PIN_MODE_OUTPUT || Firmata.getPinMode(pin) == PIN_MODE_INPUT) {
502508
pinValue = ((byte)value & mask) ? 1 : 0;
503-
if (Firmata.getPinMode(pin) == OUTPUT) {
509+
if (Firmata.getPinMode(pin) == PIN_MODE_OUTPUT) {
504510
pinWriteMask |= mask;
505-
} else if (Firmata.getPinMode(pin) == INPUT && pinValue == 1 && Firmata.getPinState(pin) != 1) {
511+
} else if (Firmata.getPinMode(pin) == PIN_MODE_INPUT && pinValue == 1 && Firmata.getPinState(pin) != 1) {
506512
// only handle INPUT here for backwards compatibility
507513
#if ARDUINO > 100
508514
pinMode(pin, INPUT_PULLUP);
@@ -725,22 +731,26 @@ void sysexCallback(byte command, byte argc, byte *argv)
725731
Firmata.write(CAPABILITY_RESPONSE);
726732
for (byte pin = 0; pin < TOTAL_PINS; pin++) {
727733
if (IS_PIN_DIGITAL(pin)) {
728-
Firmata.write((byte)INPUT);
734+
Firmata.write((byte)PIN_MODE_INPUT);
729735
Firmata.write(1);
730736
Firmata.write((byte)PIN_MODE_PULLUP);
731737
Firmata.write(1);
732-
Firmata.write((byte)OUTPUT);
738+
Firmata.write((byte)PIN_MODE_OUTPUT);
733739
Firmata.write(1);
734740
}
735741
if (IS_PIN_ANALOG(pin)) {
736742
Firmata.write(PIN_MODE_ANALOG);
743+
#ifdef DEFAULT_ANALOG_RESOLUTION
744+
Firmata.write(DEFAULT_ANALOG_RESOLUTION);
745+
#else
737746
Firmata.write(10); // 10 = 10-bit resolution
747+
#endif
738748
}
739749
if (IS_PIN_PWM(pin)) {
740750
Firmata.write(PIN_MODE_PWM);
741751
Firmata.write(DEFAULT_PWM_RESOLUTION);
742752
}
743-
if (IS_PIN_DIGITAL(pin)) {
753+
if (IS_PIN_SERVO(pin)) {
744754
Firmata.write(PIN_MODE_SERVO);
745755
Firmata.write(14);
746756
}
@@ -820,7 +830,7 @@ void systemResetCallback()
820830
setPinModeCallback(i, PIN_MODE_ANALOG);
821831
} else if (IS_PIN_DIGITAL(i)) {
822832
// sets the output to 0, configures portConfigInputs
823-
setPinModeCallback(i, OUTPUT);
833+
setPinModeCallback(i, PIN_MODE_OUTPUT);
824834
}
825835

826836
servoPinMap[i] = 255;
@@ -871,6 +881,7 @@ void printWifiStatus() {
871881
DEBUG_PRINT( "WiFi connection failed. Status value: " );
872882
DEBUG_PRINTLN( WiFi.status() );
873883
}
884+
#ifdef SERIAL_DEBUG
874885
else
875886
{
876887
// print the SSID of the network you're attached to:
@@ -888,6 +899,7 @@ void printWifiStatus() {
888899
DEBUG_PRINT( rssi );
889900
DEBUG_PRINTLN( " dBm" );
890901
}
902+
#endif
891903
}
892904

893905
/*

examples/StandardFirmataWiFi/wifiConfig.h

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88
*============================================================================*/
99

1010
// STEP 1 [REQUIRED]
11-
// Uncomment / comment the appropriate set of includes for your hardware (OPTION A, B or C)
12-
// Arduino MKR1000 or ESP8266 are enabled by default if compiling for either of those boards.
11+
// Uncomment / comment the appropriate set of includes for your hardware (OPTION A ... F)
12+
// Arduino MKR1000, ESP8266 and ESP32 are enabled by default if compiling for either of those boards.
1313

1414
/*
1515
* OPTION A: Configure for Arduino MKR1000 or Arduino WiFi Shield 101
@@ -137,6 +137,31 @@
137137
#endif
138138
#endif
139139

140+
/*
141+
* OPTION F: Configure for ESP32
142+
*
143+
* This will configure StandardFirmataWiFi to use the ESP8266WiFi library for boards
144+
* with an ESP32 chip.
145+
*
146+
* The appropriate libraries are included automatically when compiling for the ESP32 so
147+
* continue on to STEP 2.
148+
*/
149+
150+
#if defined(ARDUINO_ARCH_ESP32)
151+
// automatically include if compiling for ESP32
152+
#define ESP32_WIFI
153+
#endif
154+
#ifdef ESP32_WIFI
155+
#include <WiFi.h>
156+
#include "utility/WiFiClientStream.h"
157+
#include "utility/WiFiServerStream.h"
158+
#ifdef WIFI_LIB_INCLUDED
159+
#define MULTIPLE_WIFI_LIB_INCLUDES
160+
#else
161+
#define WIFI_LIB_INCLUDED
162+
#endif
163+
#endif
164+
140165
//------------------------------
141166
// TODO
142167
//------------------------------

library.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name=Firmata
2-
version=2.5.9
2+
version=2.5.10
33
author=Firmata Developers
44
maintainer=Firmata team
55
sentence=Enables the communication with computer apps using a standard serial protocol. For all Arduino/Genuino boards.

utility/WiFiStream.h

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
are compatible with the Arduino WiFi library.
77
88
Copyright (C) 2015-2016 Jesse Frush. All rights reserved.
9-
Copyright (C) 2016 Jens B. All rights reserved.
9+
Copyright (C) 2016 Jens B. All rights reserved.
1010
1111
This library is free software; you can redistribute it and/or
1212
modify it under the terms of the GNU Lesser General Public
@@ -15,7 +15,7 @@
1515
1616
See file LICENSE.txt for further informations on licensing terms.
1717
18-
Last updated April 23rd, 2016
18+
Last updated December 17th, 2023
1919
*/
2020

2121
#ifndef WIFI_STREAM_H
@@ -69,7 +69,7 @@ class WiFiStream : public Stream
6969
* network configuration
7070
******************************************************************************/
7171

72-
#ifndef ESP8266
72+
#if (!ESP8266) && (!ARDUINO_ARCH_ESP32)
7373
/**
7474
* configure a static local IP address without defining the local network
7575
* DHCP will be used as long as local IP address is not defined
@@ -90,7 +90,7 @@ class WiFiStream : public Stream
9090
_local_ip = local_ip;
9191
_subnet = subnet;
9292
_gateway = gateway;
93-
#ifndef ESP8266
93+
#if (!ESP8266) && (!ARDUINO_ARCH_ESP32)
9494
WiFi.config( local_ip, IPAddress(0, 0, 0, 0), gateway, subnet );
9595
#else
9696
WiFi.config( local_ip, gateway, subnet );
@@ -135,6 +135,14 @@ class WiFiStream : public Stream
135135
{
136136
return _client.status();
137137
}
138+
#elif ARDUINO_ARCH_ESP32
139+
/**
140+
* check if TCP connection is established
141+
*/
142+
inline uint8_t connected()
143+
{
144+
return _client.connected();
145+
}
138146
#endif
139147

140148
/**
@@ -157,10 +165,10 @@ class WiFiStream : public Stream
157165

158166
WiFi.begin(ssid);
159167
int result = WiFi.status();
160-
return WiFi.status();
168+
return result;
161169
}
162170

163-
#ifndef ESP8266
171+
#if (!ESP8266) && (!ARDUINO_ARCH_ESP32)
164172
/**
165173
* initialize WiFi with WEP security and initiate client connection
166174
* if WiFi connection is already established

0 commit comments

Comments
 (0)