-
Notifications
You must be signed in to change notification settings - Fork 513
[WiFi] added support for ESP32 architecture and XIAO ESP32C3 board #512
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 5 commits
7d6ada1
7a6dd82
9651a7c
dde9fd9
ad79f15
4567db4
08325d1
af2e9aa
90ac082
44a8788
b3a78d5
d072c0a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -22,7 +22,7 @@ | |
|
||
See file LICENSE.txt for further informations on licensing terms. | ||
|
||
Last updated August 17th, 2017 | ||
Last updated December 17th, 2023 | ||
*/ | ||
|
||
/* | ||
|
@@ -74,7 +74,11 @@ | |
- Arduino Mega: (D5, D7, D10, D50, D52, D53) | ||
*/ | ||
|
||
#include <Servo.h> | ||
#ifdef ARDUINO_ARCH_ESP32 | ||
#include <ESP32Servo.h> | ||
#else | ||
#include <Servo.h> | ||
#endif | ||
#include <Wire.h> | ||
#include <Firmata.h> | ||
|
||
|
@@ -235,8 +239,10 @@ void detachServo(byte pin) | |
} else if (servoCount > 0) { | ||
// keep track of detached servos because we want to reuse their indexes | ||
// before incrementing the count of attached servos | ||
detachedServoCount++; | ||
detachedServos[detachedServoCount - 1] = servoPinMap[pin]; | ||
if (detachedServoCount < MAX_SERVOS) { | ||
detachedServos[detachedServoCount] = servoPinMap[pin]; | ||
detachedServoCount++; | ||
} | ||
} | ||
|
||
servoPinMap[pin] = 255; | ||
|
@@ -370,7 +376,7 @@ void setPinModeCallback(byte pin, int mode) | |
reportAnalogCallback(PIN_TO_ANALOG(pin), mode == PIN_MODE_ANALOG ? 1 : 0); // turn on/off reporting | ||
} | ||
if (IS_PIN_DIGITAL(pin)) { | ||
if (mode == INPUT || mode == PIN_MODE_PULLUP) { | ||
if (mode == PIN_MODE_INPUT || mode == PIN_MODE_PULLUP) { | ||
portConfigInputs[pin / 8] |= (1 << (pin & 7)); | ||
} else { | ||
portConfigInputs[pin / 8] &= ~(1 << (pin & 7)); | ||
|
@@ -390,14 +396,14 @@ void setPinModeCallback(byte pin, int mode) | |
Firmata.setPinMode(pin, PIN_MODE_ANALOG); | ||
} | ||
break; | ||
case INPUT: | ||
case PIN_MODE_INPUT: | ||
if (IS_PIN_DIGITAL(pin)) { | ||
pinMode(PIN_TO_DIGITAL(pin), INPUT); // disable output driver | ||
#if ARDUINO <= 100 | ||
// deprecated since Arduino 1.0.1 - TODO: drop support in Firmata 2.6 | ||
digitalWrite(PIN_TO_DIGITAL(pin), LOW); // disable internal pull-ups | ||
#endif | ||
Firmata.setPinMode(pin, INPUT); | ||
Firmata.setPinMode(pin, PIN_MODE_INPUT); | ||
} | ||
break; | ||
case PIN_MODE_PULLUP: | ||
|
@@ -407,14 +413,14 @@ void setPinModeCallback(byte pin, int mode) | |
Firmata.setPinState(pin, 1); | ||
} | ||
break; | ||
case OUTPUT: | ||
case PIN_MODE_OUTPUT: | ||
if (IS_PIN_DIGITAL(pin)) { | ||
if (Firmata.getPinMode(pin) == PIN_MODE_PWM) { | ||
// Disable PWM if pin mode was previously set to PWM. | ||
digitalWrite(PIN_TO_DIGITAL(pin), LOW); | ||
} | ||
pinMode(PIN_TO_DIGITAL(pin), OUTPUT); | ||
Firmata.setPinMode(pin, OUTPUT); | ||
Firmata.setPinMode(pin, PIN_MODE_OUTPUT); | ||
} | ||
break; | ||
case PIN_MODE_PWM: | ||
|
@@ -461,7 +467,7 @@ void setPinModeCallback(byte pin, int mode) | |
void setPinValueCallback(byte pin, int value) | ||
{ | ||
if (pin < TOTAL_PINS && IS_PIN_DIGITAL(pin)) { | ||
if (Firmata.getPinMode(pin) == OUTPUT) { | ||
if (Firmata.getPinMode(pin) == PIN_MODE_OUTPUT) { | ||
Firmata.setPinState(pin, value); | ||
digitalWrite(PIN_TO_DIGITAL(pin), value); | ||
} | ||
|
@@ -498,11 +504,11 @@ void digitalWriteCallback(byte port, int value) | |
// do not disturb non-digital pins (eg, Rx & Tx) | ||
if (IS_PIN_DIGITAL(pin)) { | ||
// do not touch pins in PWM, ANALOG, SERVO or other modes | ||
if (Firmata.getPinMode(pin) == OUTPUT || Firmata.getPinMode(pin) == INPUT) { | ||
if (Firmata.getPinMode(pin) == PIN_MODE_OUTPUT || Firmata.getPinMode(pin) == PIN_MODE_INPUT) { | ||
pinValue = ((byte)value & mask) ? 1 : 0; | ||
if (Firmata.getPinMode(pin) == OUTPUT) { | ||
if (Firmata.getPinMode(pin) == PIN_MODE_OUTPUT) { | ||
pinWriteMask |= mask; | ||
} else if (Firmata.getPinMode(pin) == INPUT && pinValue == 1 && Firmata.getPinState(pin) != 1) { | ||
} else if (Firmata.getPinMode(pin) == PIN_MODE_INPUT && pinValue == 1 && Firmata.getPinState(pin) != 1) { | ||
// only handle INPUT here for backwards compatibility | ||
#if ARDUINO > 100 | ||
pinMode(pin, INPUT_PULLUP); | ||
|
@@ -725,22 +731,26 @@ void sysexCallback(byte command, byte argc, byte *argv) | |
Firmata.write(CAPABILITY_RESPONSE); | ||
for (byte pin = 0; pin < TOTAL_PINS; pin++) { | ||
if (IS_PIN_DIGITAL(pin)) { | ||
Firmata.write((byte)INPUT); | ||
Firmata.write((byte)PIN_MODE_INPUT); | ||
Firmata.write(1); | ||
Firmata.write((byte)PIN_MODE_PULLUP); | ||
Firmata.write(1); | ||
Firmata.write((byte)OUTPUT); | ||
Firmata.write((byte)PIN_MODE_OUTPUT); | ||
Firmata.write(1); | ||
} | ||
if (IS_PIN_ANALOG(pin)) { | ||
Firmata.write(PIN_MODE_ANALOG); | ||
#ifdef DEFAULT_ADC_RESOLUTION | ||
Firmata.write(DEFAULT_ADC_RESOLUTION); | ||
#else | ||
Firmata.write(10); // 10 = 10-bit resolution | ||
#endif | ||
} | ||
if (IS_PIN_PWM(pin)) { | ||
Firmata.write(PIN_MODE_PWM); | ||
Firmata.write(DEFAULT_PWM_RESOLUTION); | ||
} | ||
if (IS_PIN_DIGITAL(pin)) { | ||
if (IS_PIN_SERVO(pin)) { | ||
Firmata.write(PIN_MODE_SERVO); | ||
Firmata.write(14); | ||
} | ||
|
@@ -820,7 +830,7 @@ void systemResetCallback() | |
setPinModeCallback(i, PIN_MODE_ANALOG); | ||
} else if (IS_PIN_DIGITAL(i)) { | ||
// sets the output to 0, configures portConfigInputs | ||
setPinModeCallback(i, OUTPUT); | ||
setPinModeCallback(i, PIN_MODE_OUTPUT); | ||
} | ||
|
||
servoPinMap[i] = 255; | ||
|
@@ -871,6 +881,7 @@ void printWifiStatus() { | |
DEBUG_PRINT( "WiFi connection failed. Status value: " ); | ||
DEBUG_PRINTLN( WiFi.status() ); | ||
} | ||
#ifdef SERIAL_DEBUG | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What is this doing for us? How does There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. SERIAL_DEBUG can be found in StandardFirmataWifi.ino:90. If not enabled with ESP32 SDK (default) the compiler will raise a warning or an error (depending on the compiler settings) because of the unused local variables like "rssi" in line 898, caused by defining DEBUG_PRINT to nothing (see utility/firmataDebug.h). |
||
else | ||
{ | ||
// print the SSID of the network you're attached to: | ||
|
@@ -888,6 +899,7 @@ void printWifiStatus() { | |
DEBUG_PRINT( rssi ); | ||
DEBUG_PRINTLN( " dBm" ); | ||
} | ||
#endif | ||
} | ||
|
||
/* | ||
|
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -6,7 +6,7 @@ | |||||||||||||||||||||||
are compatible with the Arduino WiFi library. | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
Copyright (C) 2015-2016 Jesse Frush. All rights reserved. | ||||||||||||||||||||||||
Copyright (C) 2016 Jens B. All rights reserved. | ||||||||||||||||||||||||
Copyright (C) 2016 Jens B. All rights reserved. | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
This library is free software; you can redistribute it and/or | ||||||||||||||||||||||||
modify it under the terms of the GNU Lesser General Public | ||||||||||||||||||||||||
|
@@ -15,7 +15,7 @@ | |||||||||||||||||||||||
|
||||||||||||||||||||||||
See file LICENSE.txt for further informations on licensing terms. | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
Last updated April 23rd, 2016 | ||||||||||||||||||||||||
Last updated December 17th, 2023 | ||||||||||||||||||||||||
*/ | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
#ifndef WIFI_STREAM_H | ||||||||||||||||||||||||
|
@@ -69,7 +69,7 @@ class WiFiStream : public Stream | |||||||||||||||||||||||
* network configuration | ||||||||||||||||||||||||
******************************************************************************/ | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
#ifndef ESP8266 | ||||||||||||||||||||||||
#if !ESP8266 && !ESP32 | ||||||||||||||||||||||||
/** | ||||||||||||||||||||||||
* configure a static local IP address without defining the local network | ||||||||||||||||||||||||
* DHCP will be used as long as local IP address is not defined | ||||||||||||||||||||||||
|
@@ -90,7 +90,7 @@ class WiFiStream : public Stream | |||||||||||||||||||||||
_local_ip = local_ip; | ||||||||||||||||||||||||
_subnet = subnet; | ||||||||||||||||||||||||
_gateway = gateway; | ||||||||||||||||||||||||
#ifndef ESP8266 | ||||||||||||||||||||||||
#if !ESP8266 && !ESP32 | ||||||||||||||||||||||||
WiFi.config( local_ip, IPAddress(0, 0, 0, 0), gateway, subnet ); | ||||||||||||||||||||||||
#else | ||||||||||||||||||||||||
WiFi.config( local_ip, gateway, subnet ); | ||||||||||||||||||||||||
|
@@ -115,7 +115,11 @@ class WiFiStream : public Stream | |||||||||||||||||||||||
*/ | ||||||||||||||||||||||||
virtual bool maintain() = 0; | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
#ifdef ESP8266 | ||||||||||||||||||||||||
#if ESP8266 || ESP32 | ||||||||||||||||||||||||
enum ConnectionStatus { STATUS_CLOSED = 0, | ||||||||||||||||||||||||
STATUS_ESTABLISHED = 4 | ||||||||||||||||||||||||
}; | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
Comment on lines
+118
to
+122
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Forgive me, I'm not familiar with the ESP8266 and ESP32 Wi-Fi libraries. Can you please explain the enum a little bit better? Using this enum and the logic below, it looks like you are translating a boolean into values from the ESP8266 enum. If that's correct, then I don't understand why you would want to redefine these values for ESP8266. Shouldn't the enum only be defined under
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The ESP8266 SDK defines all the constants listed in the method description, but they do not exists with the same definition in the ESP32 SDK, if at all (they are related to the low level TCP socket implementation). So similar how the Firmata library handles the PIN_MODE_XXX definitions I defined the enum to have the same definitions available, regardless which SDK is used. It would be possible to add all the constants known in the ESSP8266 SDK, but most of the other are typically of no practical value, so I added only the one that are available in both SDKs. I hope that I got your initial idea right by implementing the status() method instead of the new connected() method to avoid having a platform specific solution. If not, just let me know. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, I generally like your latest implementation. 👍 However, I'm concerned that you are "redefining" the symbols There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. STATUS_CLOSED and STATUS_ESTABLISHED are enum values and are part of the WiFiStream class namespace of Firmata. On the other hand CLOSED, LISTEN, etc. are defined as enum values in lwip/tcp.h of the ESP8266 SDK in the global namespace. So the two sets of constants have unique names and in the case oft ESP8266 SDK the same values. To make the code more robust to changes in the ESP8266 SKD one could use a switch: inline uint8_t status()
{
#ifdef ESP8266
uint8 cs = _client.status();
switch (cs)
{
case CLOSED: cs = STATUS_CLOSED; break;
case ESTABLISHED: cs = STATUS_ESTABLISHED; break;
default: break;
}
return cs;
#elif ESP32
return _client.connected()? STATUS_ESTABLISHED : STATUS_CLOSED;
#endif
} |
||||||||||||||||||||||||
/** | ||||||||||||||||||||||||
* get status of TCP connection | ||||||||||||||||||||||||
* @return status of TCP connection | ||||||||||||||||||||||||
|
@@ -133,7 +137,11 @@ class WiFiStream : public Stream | |||||||||||||||||||||||
*/ | ||||||||||||||||||||||||
inline uint8_t status() | ||||||||||||||||||||||||
{ | ||||||||||||||||||||||||
#ifdef ESP8266 | ||||||||||||||||||||||||
return _client.status(); | ||||||||||||||||||||||||
#elif ESP32 | ||||||||||||||||||||||||
return _client.connected()? STATUS_ESTABLISHED : STATUS_CLOSED; | ||||||||||||||||||||||||
#endif | ||||||||||||||||||||||||
} | ||||||||||||||||||||||||
#endif | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
|
@@ -157,10 +165,10 @@ class WiFiStream : public Stream | |||||||||||||||||||||||
|
||||||||||||||||||||||||
WiFi.begin(ssid); | ||||||||||||||||||||||||
int result = WiFi.status(); | ||||||||||||||||||||||||
return WiFi.status(); | ||||||||||||||||||||||||
return result; | ||||||||||||||||||||||||
} | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
#ifndef ESP8266 | ||||||||||||||||||||||||
#if !ESP8266 && !ESP32 | ||||||||||||||||||||||||
/** | ||||||||||||||||||||||||
* initialize WiFi with WEP security and initiate client connection | ||||||||||||||||||||||||
* if WiFi connection is already established | ||||||||||||||||||||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you explain why this is necessary again?
Maybe we can figure out a creative solution to work around your need. My fear is that you are going to break backward compatibility with this change.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had to do a similar change in ConfigurableFirmata, as the problem is that there's a conflicting definition of ANALOG (as well as INPUT and OUTPUT) in the ESP32 headers. IIRC, the values don't even match, so setting the pin mode could strangely fail, depending on which of the definitions is in scope at the calling place. But I think the right solution is to call this PIN_MODE_ANALOG, to avoid further ambiguities.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does
PIN_MODE_ANALOG
come fromArduino.h
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, I see it. It's in
FirmataDefines.h
. It seems like the right move is to move away fromANALOG
and deprecate it altogether, as we did forINPUT
andOUTPUT
.