Skip to content

Commit

Permalink
Serial improvements (can RX, canTX)
Browse files Browse the repository at this point in the history
PinManager bugfix for unsigned long long
  • Loading branch information
blazoncek committed Sep 17, 2024
1 parent 7f1ec48 commit ac8f919
Show file tree
Hide file tree
Showing 8 changed files with 79 additions and 66 deletions.
7 changes: 6 additions & 1 deletion wled00/data/settings_sync.htm
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ <h3>Alexa Voice Assistant</h3>
<div id="Alexa">
Emulate Alexa device: <input type="checkbox" name="AL"><br>
Alexa invocation name: <input type="text" name="AI" maxlength="32"><br>
Also emulate devices to call the first <input name="AP" type="number" class="s" min="0" max="9" required> presets<br><br>
Also emulate devices to call the first <input name="AP" type="number" class="s" min="0" max="9"> presets<br><br>
</div>
<hr class="sml">
<div class="warn">&#9888; <b>MQTT and Hue sync all connect to external hosts!<br>
Expand Down Expand Up @@ -245,6 +245,10 @@ <h3>Philips Hue</h3>
Hue status: <span class="sip"> Disabled in this build </span>
</div>
<h3>Serial</h3>
<div id="NoSerial" class="hide">
<em class="warn">This firmware build does support Serial interface.<br></em>

This comment has been minimized.

Copy link
@softhack007

softhack007 Sep 17, 2024

Collaborator

should the message be "does NOT support Serial interface" ?

This comment has been minimized.

Copy link
@blazoncek

blazoncek Sep 17, 2024

Author Collaborator

🤦

</div>
<div id="Serial">
Baud rate:
<select name=BD>
<option value=1152>115200</option>
Expand All @@ -257,6 +261,7 @@ <h3>Serial</h3>
<option value=15000>1500000</option>
</select><br>
<i>Keep at 115200 to use Improv. Some boards may not support high rates.</i>
</div>
<hr>
<button type="button" onclick="B()">Back</button><button type="submit">Save</button>
</form>
Expand Down
5 changes: 2 additions & 3 deletions wled00/ir.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -714,9 +714,8 @@ void handleIR()
if (strip.isUpdating() && timeDiff < 240) return; // be nice, but not too nice
irCheckedTime = currentTime;
if (irrecv->decode(&results)) {
if (results.value != 0) { // only print results if anything is received ( != 0 )
if (!pinManager.isPinAllocated(hardwareTX) || pinManager.getPinOwner(hardwareTX) == PinOwner::DebugOut) // Serial TX pin (GPIO 1 on ESP32 and ESP8266)
Serial.printf_P(PSTR("IR recv: 0x%lX\n"), (unsigned long)results.value);
if (results.value != 0 && serialCanTX) { // only print results if anything is received ( != 0 )
Serial.printf_P(PSTR("IR recv: 0x%lX\n"), (unsigned long)results.value);
}
decodeIR(results.value);
irrecv->resume();
Expand Down
12 changes: 12 additions & 0 deletions wled00/pin_manager.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,18 @@
#include "pin_manager.h"
#include "wled.h"

#ifdef ARDUINO_ARCH_ESP32
#ifdef bitRead
// Arduino variants assume 32 bit values
#undef bitRead
#undef bitSet
#undef bitClear
#define bitRead(var,bit) (((unsigned long long)(var)>>(bit))&0x1ULL)
#define bitSet(var,bit) ((var)|=(1ULL<<(bit)))
#define bitClear(var,bit) ((var)&=(~(1ULL<<(bit))))
#endif
#endif

#ifdef WLED_DEBUG
static void DebugPrintOwnerTag(PinOwner tag)
{
Expand Down
6 changes: 5 additions & 1 deletion wled00/pin_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,11 @@ class PinManagerClass {
PinOwner ownerTag[WLED_NUM_PINS] = { PinOwner::None };

public:
PinManagerClass() : pinAlloc(0), i2cAllocCount(0), spiAllocCount(0) {}
PinManagerClass() : pinAlloc(0ULL), i2cAllocCount(0), spiAllocCount(0) {
#ifdef ARDUINO_ARCH_ESP32
ledcAlloc = 0;
#endif
}
// De-allocates a single pin
bool deallocatePin(byte gpio, PinOwner tag);
// De-allocates multiple pins but only if all can be deallocated (PinOwner has to be specified)
Expand Down
22 changes: 12 additions & 10 deletions wled00/wled.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,17 +54,19 @@ void WLED::loop()
#endif

handleTime();
#ifndef WLED_DISABLE_INFRARED
#ifndef WLED_DISABLE_INFRARED
handleIR(); // 2nd call to function needed for ESP32 to return valid results -- should be good for ESP8266, too
#endif
#endif
handleConnection();
#ifdef WLED_ENABLE_ADALIGHT
handleSerial();
#endif
handleImprovWifiScan();
handleNotifications();
handleTransitions();
#ifdef WLED_ENABLE_DMX
#ifdef WLED_ENABLE_DMX
handleDMX();
#endif
#endif

#ifdef WLED_DEBUG
unsigned long usermodMillis = millis();
Expand Down Expand Up @@ -476,10 +478,14 @@ void WLED::setup()
WiFi.mode(WIFI_STA); // enable scanning
findWiFi(true); // start scanning for available WiFi-s

// all GPIOs are allocated at this point
serialCanRX = !pinManager.isPinAllocated(hardwareRX); // Serial RX pin (GPIO 3 on ESP32 and ESP8266)
serialCanTX = !pinManager.isPinAllocated(hardwareTX) || pinManager.getPinOwner(hardwareTX) == PinOwner::DebugOut; // Serial TX pin (GPIO 1 on ESP32 and ESP8266)

#ifdef WLED_ENABLE_ADALIGHT
//Serial RX (Adalight, Improv, Serial JSON) only possible if GPIO3 unused
//Serial TX (Debug, Improv, Serial JSON) only possible if GPIO1 unused
if (!pinManager.isPinAllocated(hardwareRX) && !pinManager.isPinAllocated(hardwareTX)) {
if (serialCanRX && serialCanTX) {
Serial.println(F("Ada"));
}
#endif
Expand All @@ -491,10 +497,6 @@ void WLED::setup()
if (mqttClientID[0] == 0) sprintf_P(mqttClientID, PSTR("WLED-%*s"), 6, escapedMac.c_str() + 6);
#endif

#ifdef WLED_ENABLE_ADALIGHT
if (Serial.available() > 0 && Serial.peek() == 'I') handleImprovPacket();
#endif

#ifndef WLED_DISABLE_OTA
if (aOtaEnabled) {
ArduinoOTA.onStart([]() {
Expand All @@ -521,7 +523,7 @@ void WLED::setup()
#endif

#ifdef WLED_ENABLE_ADALIGHT
if (Serial.available() > 0 && Serial.peek() == 'I') handleImprovPacket();
if (serialCanRX && Serial.available() > 0 && Serial.peek() == 'I') handleImprovPacket();
#endif

// HTTP server page init
Expand Down
4 changes: 3 additions & 1 deletion wled00/wled.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
*/

// version code in format yymmddb (b = daily build)
#define VERSION 2409140
#define VERSION 2409170

//uncomment this if you have a "my_config.h" file you'd like to use
//#define WLED_USE_MY_CONFIG
Expand Down Expand Up @@ -510,6 +510,8 @@ WLED_GLOBAL bool hueApplyColor _INIT(true);
#endif

WLED_GLOBAL uint16_t serialBaud _INIT(1152); // serial baud rate, multiply by 100
WLED_GLOBAL bool serialCanRX _INIT(false);
WLED_GLOBAL bool serialCanTX _INIT(false);

#ifndef WLED_DISABLE_ESPNOW
WLED_GLOBAL bool enableESPNow _INIT(false); // global on/off for ESP-NOW
Expand Down
86 changes: 36 additions & 50 deletions wled00/wled_serial.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ void updateBaudRate(uint32_t rate){
if (rate100 == currentBaud || rate100 < 96) return;
currentBaud = rate100;

if (!pinManager.isPinAllocated(hardwareTX) || pinManager.getPinOwner(hardwareTX) == PinOwner::DebugOut){
if (serialCanTX){
Serial.print(F("Baud is now ")); Serial.println(rate);
}

Expand All @@ -38,7 +38,7 @@ void updateBaudRate(uint32_t rate){

// RGB LED data return as JSON array. Slow, but easy to use on the other end.
void sendJSON(){
if (!pinManager.isPinAllocated(hardwareTX) || pinManager.getPinOwner(hardwareTX) == PinOwner::DebugOut) {
if (serialCanTX) {
unsigned used = strip.getLengthTotal();
Serial.write('[');
for (unsigned i=0; i<used; i++) {
Expand All @@ -51,7 +51,7 @@ void sendJSON(){

// RGB LED data returned as bytes in TPM2 format. Faster, and slightly less easy to use on the other end.
void sendBytes(){
if (!pinManager.isPinAllocated(hardwareTX) || pinManager.getPinOwner(hardwareTX) == PinOwner::DebugOut) {
if (serialCanTX) {
Serial.write(0xC9); Serial.write(0xDA);
unsigned used = strip.getLengthTotal();
unsigned len = used*3;
Expand All @@ -69,10 +69,8 @@ void sendBytes(){

void handleSerial()
{
if (pinManager.isPinAllocated(hardwareRX)) return;
if (!Serial) return; // arduino docs: `if (Serial)` indicates whether or not the USB CDC serial connection is open. For all non-USB CDC ports, this will always return true
if (!(serialCanRX && Serial)) return; // arduino docs: `if (Serial)` indicates whether or not the USB CDC serial connection is open. For all non-USB CDC ports, this will always return true

#ifdef WLED_ENABLE_ADALIGHT
static auto state = AdaState::Header_A;
static uint16_t count = 0;
static uint16_t pixel = 0;
Expand All @@ -86,54 +84,43 @@ void handleSerial()
byte next = Serial.peek();
switch (state) {
case AdaState::Header_A:
if (next == 'A') state = AdaState::Header_d;
else if (next == 0xC9) { //TPM2 start byte
state = AdaState::TPM2_Header_Type;
}
else if (next == 'I') {
handleImprovPacket();
return;
} else if (next == 'v') {
Serial.print("WLED"); Serial.write(' '); Serial.println(VERSION);

} else if (next == 0xB0) {updateBaudRate( 115200);
} else if (next == 0xB1) {updateBaudRate( 230400);
} else if (next == 0xB2) {updateBaudRate( 460800);
} else if (next == 0xB3) {updateBaudRate( 500000);
} else if (next == 0xB4) {updateBaudRate( 576000);
} else if (next == 0xB5) {updateBaudRate( 921600);
} else if (next == 0xB6) {updateBaudRate(1000000);
} else if (next == 0xB7) {updateBaudRate(1500000);

} else if (next == 'l') {sendJSON(); // Send LED data as JSON Array
} else if (next == 'L') {sendBytes(); // Send LED data as TPM2 Data Packet

} else if (next == 'o') {continuousSendLED = false; // Disable Continuous Serial Streaming
} else if (next == 'O') {continuousSendLED = true; // Enable Continuous Serial Streaming

} else if (next == '{') { //JSON API
if (next == 'A') { state = AdaState::Header_d; }
else if (next == 0xC9) { state = AdaState::TPM2_Header_Type; } //TPM2 start byte
else if (next == 'I') { handleImprovPacket(); return; }
else if (next == 'v') { Serial.print("WLED"); Serial.write(' '); Serial.println(VERSION); }
else if (next == 0xB0) { updateBaudRate( 115200); }
else if (next == 0xB1) { updateBaudRate( 230400); }
else if (next == 0xB2) { updateBaudRate( 460800); }
else if (next == 0xB3) { updateBaudRate( 500000); }
else if (next == 0xB4) { updateBaudRate( 576000); }
else if (next == 0xB5) { updateBaudRate( 921600); }
else if (next == 0xB6) { updateBaudRate(1000000); }
else if (next == 0xB7) { updateBaudRate(1500000); }
else if (next == 'l') { sendJSON(); } // Send LED data as JSON Array
else if (next == 'L') { sendBytes(); } // Send LED data as TPM2 Data Packet
else if (next == 'o') { continuousSendLED = false; } // Disable Continuous Serial Streaming
else if (next == 'O') { continuousSendLED = true; } // Enable Continuous Serial Streaming
else if (next == '{') { //JSON API
bool verboseResponse = false;
if (!requestJSONBufferLock(16)) {
Serial.println(F("{\"error\":3}")); // ERR_NOBUF
Serial.printf_P(PSTR("{\"error\":%d}\n"), ERR_NOBUF);
return;
}
Serial.setTimeout(100);
DeserializationError error = deserializeJson(*pDoc, Serial);
if (error) {
releaseJSONBufferLock();
return;
}
verboseResponse = deserializeState(pDoc->as<JsonObject>());
//only send response if TX pin is unused for other purposes
if (verboseResponse && (!pinManager.isPinAllocated(hardwareTX) || pinManager.getPinOwner(hardwareTX) == PinOwner::DebugOut)) {
pDoc->clear();
JsonObject state = pDoc->createNestedObject("state");
serializeState(state);
JsonObject info = pDoc->createNestedObject("info");
serializeInfo(info);

serializeJson(*pDoc, Serial);
Serial.println();
if (!error) {
verboseResponse = deserializeState(pDoc->as<JsonObject>());
//only send response if TX pin is unused for other purposes
if (verboseResponse && serialCanTX) {
pDoc->clear();
JsonObject state = pDoc->createNestedObject("state");
serializeState(state);
JsonObject info = pDoc->createNestedObject("info");
serializeInfo(info);

serializeJson(*pDoc, Serial);
Serial.println();
}
}
releaseJSONBufferLock();
}
Expand Down Expand Up @@ -199,11 +186,10 @@ void handleSerial()
// All other received bytes will disable Continuous Serial Streaming
if (continuousSendLED && next != 'O'){
continuousSendLED = false;
}
}

Serial.read(); //discard the byte
}
#endif

// If Continuous Serial Streaming is enabled, send new LED data as bytes
if (continuousSendLED && (lastUpdate != strip.getLastShow())){
Expand Down
3 changes: 3 additions & 0 deletions wled00/xml.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -571,6 +571,9 @@ void getSettingsJS(byte subPage, char* dest)
oappend(SET_F("toggle('Hue');")); // hide Hue Sync settings
#endif
sappend('v',SET_F("BD"),serialBaud);
#ifndef WLED_ENABLE_ADALIGHT
oappend(SET_F("toggle('Serial);"));
#endif
}

if (subPage == SUBPAGE_TIME)
Expand Down

0 comments on commit ac8f919

Please sign in to comment.