From 3dcdc36e55b9bb5058fe5a62d76b07196c9f4daa Mon Sep 17 00:00:00 2001 From: Ton Huisman Date: Fri, 20 Sep 2024 23:01:46 +0200 Subject: [PATCH 1/3] [P054] Allow GPIO configuration for ESP32 units --- src/_P054_DMX512.ino | 336 +++++++++++++++++++++---------------------- 1 file changed, 165 insertions(+), 171 deletions(-) diff --git a/src/_P054_DMX512.ino b/src/_P054_DMX512.ino index 914acfea89..e38aa178c3 100644 --- a/src/_P054_DMX512.ino +++ b/src/_P054_DMX512.ino @@ -1,8 +1,14 @@ #include "_Plugin_Helper.h" #ifdef USES_P054 -//####################################################################################################### -//######################################## Plugin 054: DMX512 TX ######################################## -//####################################################################################################### + +// ####################################################################################################### +// ######################################## Plugin 054: DMX512 TX ######################################## +// ####################################################################################################### + +/** Changelog: + * 2024-09-20 tonhuisman: Reformat source, allow GPIO selection on ESP32 by _not_ resetting to GPIO 2 when not ESP8266 + * 2024-09-20 Start changelog + */ // ESPEasy Plugin to control DMX-512 Devices (DMX 512/1990; DIN 56930-2) like Dimmer-Packs, LED-Bars, Moving-Heads, Event-Lighting // written by Jochen Krapf (jk@nerd2nerd.org) @@ -27,9 +33,9 @@ // Examples: // DMX,123" Set channel 1 to value 123 -// DMX,123,22,33,44" Set channel 1 to value 123, channel 2 to 22, channel 3 to33, channel 4 to 44 +// DMX,123,22,33,44" Set channel 1 to value 123, channel 2 to 22, channel 3 to 33, channel 4 to 44 // DMX,5=123" Set channel 5 to value 123 -// DMX,5=123,22,33,44" Set channel 5 to value 123, channel 6 to 22, channel 7 to33, channel 8 to 44 +// DMX,5=123,22,33,44" Set channel 5 to value 123, channel 6 to 22, channel 7 to 33, channel 8 to 44 // DMX,5=123,8=44" Set channel 5 to value 123, channel 8 to 44 // DMX,OFF" Pitch Black @@ -49,25 +55,27 @@ // Note: The ESP serial FIFO has size of 128 uint8_t. Therefore it is rcommented to use DMX buffer sizes below 128 -//#include <*.h> //no lib needed +// #include <*.h> //no lib needed -#define PLUGIN_054 -#define PLUGIN_ID_054 54 -#define PLUGIN_NAME_054 "Communication - DMX512 TX" +# define PLUGIN_054 +# define PLUGIN_ID_054 54 +# define PLUGIN_NAME_054 "Communication - DMX512 TX" -uint8_t* Plugin_054_DMXBuffer = 0; -int16_t Plugin_054_DMXSize = 32; +uint8_t *Plugin_054_DMXBuffer = 0; +int16_t Plugin_054_DMXSize = 32; static inline void PLUGIN_054_Limit(int16_t& value, int16_t min, int16_t max) { - if (value < min) + if (value < min) { value = min; - if (value > max) + } + + if (value > max) { value = max; + } } - boolean Plugin_054(uint8_t function, struct EventStruct *event, String& string) { boolean success = false; @@ -75,198 +83,184 @@ boolean Plugin_054(uint8_t function, struct EventStruct *event, String& string) switch (function) { case PLUGIN_DEVICE_ADD: - { - Device[++deviceCount].Number = PLUGIN_ID_054; - Device[deviceCount].Type = DEVICE_TYPE_SINGLE; - Device[deviceCount].Ports = 0; - Device[deviceCount].VType = Sensor_VType::SENSOR_TYPE_NONE; - Device[deviceCount].PullUpOption = false; - Device[deviceCount].InverseLogicOption = false; - Device[deviceCount].FormulaOption = false; - Device[deviceCount].ValueCount = 0; - Device[deviceCount].SendDataOption = false; - Device[deviceCount].TimerOption = false; - Device[deviceCount].TimerOptional = false; - Device[deviceCount].GlobalSyncOption = true; - break; - } + { + Device[++deviceCount].Number = PLUGIN_ID_054; + Device[deviceCount].Type = DEVICE_TYPE_SINGLE; + Device[deviceCount].Ports = 0; + Device[deviceCount].VType = Sensor_VType::SENSOR_TYPE_NONE; + Device[deviceCount].ValueCount = 0; + break; + } case PLUGIN_GET_DEVICENAME: - { - string = F(PLUGIN_NAME_054); - break; - } + { + string = F(PLUGIN_NAME_054); + break; + } case PLUGIN_WEBFORM_LOAD: - { - CONFIG_PIN1 = 2; - PCONFIG(0) = Plugin_054_DMXSize; - addFormNote(F("Only GPIO-2 (D4) can be used as TX1!")); - addFormNumericBox(F("Channels"), F("channels"), Plugin_054_DMXSize, 1, 512); - success = true; - break; - } + { + # ifdef ESP8266 + CONFIG_PIN1 = 2; + # endif // ifdef ESP8266 + PCONFIG(0) = Plugin_054_DMXSize; + # ifdef ESP8266 + addFormNote(F("Only GPIO-2 (D4) can be used as TX1!")); + # endif // ifdef ESP8266 + addFormNumericBox(F("Channels"), F("channels"), Plugin_054_DMXSize, 1, 512); + success = true; + break; + } case PLUGIN_WEBFORM_SAVE: - { - CONFIG_PIN1 = 2; - if (Settings.Pin_status_led == 2) //Status LED assigned to TX1? - Settings.Pin_status_led = -1; - Plugin_054_DMXSize = getFormItemInt(F("channels")); - PLUGIN_054_Limit (Plugin_054_DMXSize, 1, 512); - PCONFIG(0) = Plugin_054_DMXSize; - success = true; - break; + { + # ifdef ESP8266 + CONFIG_PIN1 = 2; + # endif // ifdef ESP8266 + + if (Settings.Pin_status_led == 2) { // Status LED assigned to TX1? + Settings.Pin_status_led = -1; } + Plugin_054_DMXSize = getFormItemInt(F("channels")); + PLUGIN_054_Limit(Plugin_054_DMXSize, 1, 512); + PCONFIG(0) = Plugin_054_DMXSize; + success = true; + break; + } case PLUGIN_INIT: - { - CONFIG_PIN1 = 2; //TX1 fix to GPIO2 (D4) == onboard LED - Plugin_054_DMXSize = PCONFIG(0); - - if (Plugin_054_DMXBuffer) { - delete [] Plugin_054_DMXBuffer; - } - Plugin_054_DMXBuffer = new (std::nothrow) uint8_t[Plugin_054_DMXSize]; - if (Plugin_054_DMXBuffer != nullptr) { - memset(Plugin_054_DMXBuffer, 0, Plugin_054_DMXSize); - } + { + # ifdef ESP8266 + CONFIG_PIN1 = 2; // TX1 fix to GPIO2 (D4) == onboard LED + # endif // ifdef ESP8266 + Plugin_054_DMXSize = PCONFIG(0); + + if (Plugin_054_DMXBuffer) { + delete[] Plugin_054_DMXBuffer; + } + Plugin_054_DMXBuffer = new (std::nothrow) uint8_t[Plugin_054_DMXSize]; - success = Plugin_054_DMXBuffer != nullptr; - break; + if (Plugin_054_DMXBuffer != nullptr) { + memset(Plugin_054_DMXBuffer, 0, Plugin_054_DMXSize); } + success = Plugin_054_DMXBuffer != nullptr; + break; + } + case PLUGIN_EXIT: - { - if (Plugin_054_DMXBuffer) { - delete [] Plugin_054_DMXBuffer; - } - break; + { + if (Plugin_054_DMXBuffer) { + delete[] Plugin_054_DMXBuffer; } + break; + } case PLUGIN_WRITE: - { - String lowerString=string; - lowerString.toLowerCase(); - String command = parseString(lowerString, 1); - - if (equals(command, F("dmx"))) - { - String param; - String paramKey; - String paramVal; - uint8_t paramIdx = 2; - int16_t channel = 1; - int16_t value = 0; - //FIXME TD-er: Same code in _P057 - lowerString.replace(F(" "), " "); - lowerString.replace(F(" ="), "="); - lowerString.replace(F("= "), "="); - - param = parseString(lowerString, paramIdx++); - if (param.length()) - { - while (param.length()) - { - #ifndef BUILD_NO_DEBUG - addLog(LOG_LEVEL_DEBUG_MORE, param); - #endif - - if (equals(param, F("log"))) - { - if (loglevelActiveFor(LOG_LEVEL_INFO)) { - String log = F("DMX : "); - for (int16_t i = 0; i < Plugin_054_DMXSize; i++) - { - log += Plugin_054_DMXBuffer[i]; - log += F(", "); - } - addLogMove(LOG_LEVEL_INFO, log); + { + String command = parseString(string, 1); + + if (equals(command, F("dmx"))) { + String param; + String paramKey; + String paramVal; + uint8_t paramIdx = 2; + int16_t channel = 1; + int16_t value = 0; + + param = parseString(string, paramIdx++); + + if (param.length()) { + while (param.length()) { + # ifndef BUILD_NO_DEBUG + addLog(LOG_LEVEL_DEBUG_MORE, param); + # endif // ifndef BUILD_NO_DEBUG + + if (equals(param, F("log"))) { + if (loglevelActiveFor(LOG_LEVEL_INFO)) { + String log = F("DMX : "); + + for (int16_t i = 0; i < Plugin_054_DMXSize; ++i) { + log += concat(Plugin_054_DMXBuffer[i], F(", ")); } - success = true; - } - - else if (equals(param, F("test"))) - { - for (int16_t i = 0; i < Plugin_054_DMXSize; i++) - //Plugin_054_DMXBuffer[i] = i+1; - Plugin_054_DMXBuffer[i] = rand()&255; - success = true; + addLogMove(LOG_LEVEL_INFO, log); } + success = true; + } - else if (equals(param, F("on"))) - { - memset(Plugin_054_DMXBuffer, 255, Plugin_054_DMXSize); - success = true; + else if (equals(param, F("test"))) { + for (int16_t i = 0; i < Plugin_054_DMXSize; ++i) { + // Plugin_054_DMXBuffer[i] = i+1; + Plugin_054_DMXBuffer[i] = rand() & 255; } + success = true; + } - else if (equals(param, F("off"))) - { - memset(Plugin_054_DMXBuffer, 0, Plugin_054_DMXSize); - success = true; - } + else if (equals(param, F("on"))) { + memset(Plugin_054_DMXBuffer, 255, Plugin_054_DMXSize); + success = true; + } - else - { - int16_t index = param.indexOf('='); - if (index > 0) //syntax: "=" - { - paramKey = param.substring(0, index); - paramVal = param.substring(index+1); - channel = paramKey.toInt(); - } - else //syntax: "" - { - paramVal = param; - } + else if (equals(param, F("off"))) { + memset(Plugin_054_DMXBuffer, 0, Plugin_054_DMXSize); + success = true; + } - value = paramVal.toInt(); - PLUGIN_054_Limit (value, 0, 255); + else { + int16_t index = param.indexOf('='); - if (channel > 0 && channel <= Plugin_054_DMXSize) - Plugin_054_DMXBuffer[channel-1] = value; - channel++; + if (index > 0) { // syntax: "=" + paramKey = param.substring(0, index); + paramVal = param.substring(index + 1); + channel = paramKey.toInt(); + } + else { // syntax: "" + paramVal = param; } - param = parseString(lowerString, paramIdx++); + value = paramVal.toInt(); + PLUGIN_054_Limit(value, 0, 255); + + if ((channel > 0) && (channel <= Plugin_054_DMXSize)) { + Plugin_054_DMXBuffer[channel - 1] = value; + } + channel++; } - } - else - { - //??? no params - } - success = true; + param = parseString(string, paramIdx++); + } } - break; + success = true; } + break; + } + case PLUGIN_TEN_PER_SECOND: + { + if (Plugin_054_DMXBuffer) { - if (Plugin_054_DMXBuffer) - { - int16_t sendPin = 2; //TX1 fix to GPIO2 (D4) == onboard LED - - //empty serial from prev. transmit - Serial1.flush(); - - //send break - Serial1.end(); - pinMode(sendPin, OUTPUT); - digitalWrite(sendPin, LOW); - delayMicroseconds(120); //88µs ... inf - digitalWrite(sendPin, HIGH); - delayMicroseconds(12); //8µs ... 1s - - //send DMX data - Serial1.begin(250000, SERIAL_8N2); - Serial1.write(0); //start uint8_t - Serial1.write(Plugin_054_DMXBuffer, Plugin_054_DMXSize); - } - break; + int16_t sendPin = CONFIG_PIN1; // ESP8266: TX1 fix to GPIO2 (D4) == onboard LED + + // empty serial from prev. transmit + Serial1.flush(); + + // send break + Serial1.end(); + pinMode(sendPin, OUTPUT); + digitalWrite(sendPin, LOW); + delayMicroseconds(120); // 88µs ... inf + digitalWrite(sendPin, HIGH); + delayMicroseconds(12); // 8µs ... 1s + + // send DMX data + Serial1.begin(250000, SERIAL_8N2); + Serial1.write(0); // start uint8_t + Serial1.write(Plugin_054_DMXBuffer, Plugin_054_DMXSize); } - + break; + } } return success; } From 2d1c0911d4c011e0ccbeea53e7c7e3da55a7ce25 Mon Sep 17 00:00:00 2001 From: Ton Huisman Date: Sat, 21 Sep 2024 17:28:32 +0200 Subject: [PATCH 2/3] [P054] Use Direct-GPIO and implement ESPEasySerial --- src/_P054_DMX512.ino | 218 ++++++++++++++++++++++++++++--------------- 1 file changed, 143 insertions(+), 75 deletions(-) diff --git a/src/_P054_DMX512.ino b/src/_P054_DMX512.ino index e38aa178c3..93671097f0 100644 --- a/src/_P054_DMX512.ino +++ b/src/_P054_DMX512.ino @@ -6,6 +6,8 @@ // ####################################################################################################### /** Changelog: + * 2024-09-21 tonhuisman: Use Direct-GPIO for interacting with GPIO pins for speed & timing accuracy + * Use ESPEasySerial for more flexible serial configuration * 2024-09-20 tonhuisman: Reformat source, allow GPIO selection on ESP32 by _not_ resetting to GPIO 2 when not ESP8266 * 2024-09-20 Start changelog */ @@ -57,13 +59,16 @@ // #include <*.h> //no lib needed +# include +# include # define PLUGIN_054 # define PLUGIN_ID_054 54 # define PLUGIN_NAME_054 "Communication - DMX512 TX" -uint8_t *Plugin_054_DMXBuffer = 0; -int16_t Plugin_054_DMXSize = 32; +uint8_t *Plugin_054_DMXBuffer = 0; +int16_t Plugin_054_DMXSize = 32; +ESPeasySerial *Plugin_054_Serial = nullptr; static inline void PLUGIN_054_Limit(int16_t& value, int16_t min, int16_t max) { @@ -85,7 +90,7 @@ boolean Plugin_054(uint8_t function, struct EventStruct *event, String& string) case PLUGIN_DEVICE_ADD: { Device[++deviceCount].Number = PLUGIN_ID_054; - Device[deviceCount].Type = DEVICE_TYPE_SINGLE; + Device[deviceCount].Type = DEVICE_TYPE_SERIAL; Device[deviceCount].Ports = 0; Device[deviceCount].VType = Sensor_VType::SENSOR_TYPE_NONE; Device[deviceCount].ValueCount = 0; @@ -98,16 +103,51 @@ boolean Plugin_054(uint8_t function, struct EventStruct *event, String& string) break; } - case PLUGIN_WEBFORM_LOAD: + case PLUGIN_SET_DEFAULTS: { # ifdef ESP8266 - CONFIG_PIN1 = 2; - # endif // ifdef ESP8266 - PCONFIG(0) = Plugin_054_DMXSize; - # ifdef ESP8266 - addFormNote(F("Only GPIO-2 (D4) can be used as TX1!")); + CONFIG_PORT = static_cast(ESPEasySerialPort::serial1); // Serial1 port + CONFIG_PIN1 = -1; // RX pin + CONFIG_PIN2 = 2; // TX pin # endif // ifdef ESP8266 - addFormNumericBox(F("Channels"), F("channels"), Plugin_054_DMXSize, 1, 512); + # ifdef ESP32 + CONFIG_PORT = static_cast(ESPEasySerialPort::serial1); // Serial1 port + int rxPin = 0; + int txPin = 0; + const ESPEasySerialPort port = static_cast(CONFIG_PORT); + + ESPeasySerialType::getSerialTypePins(port, rxPin, txPin); + CONFIG_PIN1 = rxPin; + CONFIG_PIN2 = txPin; + # endif // ifdef ESP32 + + PCONFIG(0) = Plugin_054_DMXSize; // Holds default value + break; + } + + case PLUGIN_WEBFORM_PRE_SERIAL_PARAMS: + { + if ((-1 == CONFIG_PIN2) && (2 == CONFIG_PIN1)) { + CONFIG_PIN2 = CONFIG_PIN1; + CONFIG_PIN1 = -1; + } + break; + } + case PLUGIN_WEBFORM_SHOW_SERIAL_PARAMS: + { + addFormNote(F("An on-chip ESP Serial port must be selected!")); + break; + } + + case PLUGIN_GET_DEVICEGPIONAMES: + { + serialHelper_getGpioNames(event, true); + break; + } + + case PLUGIN_WEBFORM_LOAD: + { + addFormNumericBox(F("Channels"), F("channels"), PCONFIG(0), 1, 512); success = true; break; } @@ -115,10 +155,13 @@ boolean Plugin_054(uint8_t function, struct EventStruct *event, String& string) case PLUGIN_WEBFORM_SAVE: { # ifdef ESP8266 - CONFIG_PIN1 = 2; + + if (static_cast(ESPEasySerialPort::serial1) == CONFIG_PORT) { + CONFIG_PIN2 = 2; + } # endif // ifdef ESP8266 - if (Settings.Pin_status_led == 2) { // Status LED assigned to TX1? + if (Settings.Pin_status_led == CONFIG_PIN2) { // Status LED assigned to TX1? Settings.Pin_status_led = -1; } Plugin_054_DMXSize = getFormItemInt(F("channels")); @@ -130,9 +173,6 @@ boolean Plugin_054(uint8_t function, struct EventStruct *event, String& string) case PLUGIN_INIT: { - # ifdef ESP8266 - CONFIG_PIN1 = 2; // TX1 fix to GPIO2 (D4) == onboard LED - # endif // ifdef ESP8266 Plugin_054_DMXSize = PCONFIG(0); if (Plugin_054_DMXBuffer) { @@ -144,7 +184,32 @@ boolean Plugin_054(uint8_t function, struct EventStruct *event, String& string) memset(Plugin_054_DMXBuffer, 0, Plugin_054_DMXSize); } - success = Plugin_054_DMXBuffer != nullptr; + if ((-1 == CONFIG_PIN2) && (2 == CONFIG_PIN1)) { // Convert previous GPIO settings + CONFIG_PIN2 = CONFIG_PIN1; + CONFIG_PIN1 = -1; + } + int rxPin = CONFIG_PIN1; + int txPin = CONFIG_PIN2; + const ESPEasySerialPort port = static_cast(CONFIG_PORT); + + if ((rxPin < 0) && (txPin < 0)) { + ESPeasySerialType::getSerialTypePins(port, rxPin, txPin); + CONFIG_PIN1 = rxPin; + CONFIG_PIN2 = txPin; + } + delete Plugin_054_Serial; + Plugin_054_Serial = new (std::nothrow) ESPeasySerial(port, rxPin, txPin); + + if (nullptr != Plugin_054_Serial) { + # ifdef ESP8266 + Plugin_054_Serial->begin(250000, (SerialConfig)SERIAL_8N2); + # endif // ifdef ESP8266 + # ifdef ESP32 + Plugin_054_Serial->begin(250000, SERIAL_8N2); + # endif // ifdef ESP32 + } + + success = Plugin_054_DMXBuffer != nullptr && Plugin_054_Serial != nullptr && validGpio(CONFIG_PIN2); break; } @@ -153,12 +218,14 @@ boolean Plugin_054(uint8_t function, struct EventStruct *event, String& string) if (Plugin_054_DMXBuffer) { delete[] Plugin_054_DMXBuffer; } + delete Plugin_054_Serial; + Plugin_054_Serial = nullptr; break; } case PLUGIN_WRITE: { - String command = parseString(string, 1); + const String command = parseString(string, 1); if (equals(command, F("dmx"))) { String param; @@ -170,68 +237,64 @@ boolean Plugin_054(uint8_t function, struct EventStruct *event, String& string) param = parseString(string, paramIdx++); - if (param.length()) { - while (param.length()) { - # ifndef BUILD_NO_DEBUG - addLog(LOG_LEVEL_DEBUG_MORE, param); - # endif // ifndef BUILD_NO_DEBUG - - if (equals(param, F("log"))) { - if (loglevelActiveFor(LOG_LEVEL_INFO)) { - String log = F("DMX : "); + while (param.length()) { + # ifndef BUILD_NO_DEBUG + addLog(LOG_LEVEL_DEBUG_MORE, param); + # endif // ifndef BUILD_NO_DEBUG - for (int16_t i = 0; i < Plugin_054_DMXSize; ++i) { - log += concat(Plugin_054_DMXBuffer[i], F(", ")); - } - addLogMove(LOG_LEVEL_INFO, log); - } - success = true; - } + if (equals(param, F("log"))) { + if (loglevelActiveFor(LOG_LEVEL_INFO)) { + String log = F("DMX : "); - else if (equals(param, F("test"))) { for (int16_t i = 0; i < Plugin_054_DMXSize; ++i) { - // Plugin_054_DMXBuffer[i] = i+1; - Plugin_054_DMXBuffer[i] = rand() & 255; + log += concat(Plugin_054_DMXBuffer[i], F(", ")); } - success = true; - } - - else if (equals(param, F("on"))) { - memset(Plugin_054_DMXBuffer, 255, Plugin_054_DMXSize); - success = true; + addLogMove(LOG_LEVEL_INFO, log); } + success = true; + } - else if (equals(param, F("off"))) { - memset(Plugin_054_DMXBuffer, 0, Plugin_054_DMXSize); - success = true; + else if (equals(param, F("test"))) { + for (int16_t i = 0; i < Plugin_054_DMXSize; ++i) { + Plugin_054_DMXBuffer[i] = rand() & 255; } + success = true; + } - else { - int16_t index = param.indexOf('='); + else if (equals(param, F("on"))) { + memset(Plugin_054_DMXBuffer, 255, Plugin_054_DMXSize); + success = true; + } - if (index > 0) { // syntax: "=" - paramKey = param.substring(0, index); - paramVal = param.substring(index + 1); - channel = paramKey.toInt(); - } - else { // syntax: "" - paramVal = param; - } + else if (equals(param, F("off"))) { + memset(Plugin_054_DMXBuffer, 0, Plugin_054_DMXSize); + success = true; + } - value = paramVal.toInt(); - PLUGIN_054_Limit(value, 0, 255); + else { + int16_t index = param.indexOf('='); - if ((channel > 0) && (channel <= Plugin_054_DMXSize)) { - Plugin_054_DMXBuffer[channel - 1] = value; - } - channel++; + if (index > 0) { // syntax: "=" + paramKey = param.substring(0, index); + paramVal = param.substring(index + 1); + channel = paramKey.toInt(); + } + else { // syntax: "" + paramVal = param; } - param = parseString(string, paramIdx++); + value = paramVal.toInt(); + PLUGIN_054_Limit(value, 0, 255); + + if ((channel > 0) && (channel <= Plugin_054_DMXSize)) { + Plugin_054_DMXBuffer[channel - 1] = value; + } + channel++; + success = true; } - } - success = true; + param = parseString(string, paramIdx++); + } } break; @@ -239,25 +302,30 @@ boolean Plugin_054(uint8_t function, struct EventStruct *event, String& string) case PLUGIN_TEN_PER_SECOND: { - if (Plugin_054_DMXBuffer) - { - int16_t sendPin = CONFIG_PIN1; // ESP8266: TX1 fix to GPIO2 (D4) == onboard LED + if (Plugin_054_DMXBuffer && Plugin_054_Serial) { + int16_t sendPin = CONFIG_PIN2; // ESP8266: TX1 fixed to GPIO2 (D4) == onboard LED // empty serial from prev. transmit - Serial1.flush(); + Plugin_054_Serial->flush(); // send break - Serial1.end(); - pinMode(sendPin, OUTPUT); - digitalWrite(sendPin, LOW); + Plugin_054_Serial->end(); + + // DIRECT_PINMODE_OUTPUT(sendPin); // This shouldn't be needed + DIRECT_pinWrite(sendPin, LOW); delayMicroseconds(120); // 88µs ... inf - digitalWrite(sendPin, HIGH); + DIRECT_pinWrite(sendPin, HIGH); delayMicroseconds(12); // 8µs ... 1s // send DMX data - Serial1.begin(250000, SERIAL_8N2); - Serial1.write(0); // start uint8_t - Serial1.write(Plugin_054_DMXBuffer, Plugin_054_DMXSize); + # ifdef ESP8266 + Plugin_054_Serial->begin(250000, (SerialConfig)SERIAL_8N2); + # endif // ifdef ESP8266 + # ifdef ESP32 + Plugin_054_Serial->begin(250000, SERIAL_8N2); + # endif // ifdef ESP32 + Plugin_054_Serial->write((uint8_t)0); // start uint8_t + Plugin_054_Serial->write(Plugin_054_DMXBuffer, Plugin_054_DMXSize); } break; } From 0843f4dc0132f7d8fb153758b0f949878c844fdf Mon Sep 17 00:00:00 2001 From: Ton Huisman Date: Sun, 29 Sep 2024 21:05:50 +0200 Subject: [PATCH 3/3] [P054] Add documentation, small UI improvement --- docs/source/Plugin/P054.rst | 60 ++++++++++++++++-- .../Plugin/P054_DeviceConfiguration.png | Bin 0 -> 25860 bytes docs/source/Plugin/P054_SerialPortOptions.png | Bin 0 -> 43457 bytes docs/source/Plugin/P054_commands.repl | 39 ++++++++++++ .../Plugin/_plugin_substitutions_p05x.repl | 2 +- src/_P054_DMX512.ino | 11 +++- 6 files changed, 103 insertions(+), 9 deletions(-) create mode 100644 docs/source/Plugin/P054_DeviceConfiguration.png create mode 100644 docs/source/Plugin/P054_SerialPortOptions.png create mode 100644 docs/source/Plugin/P054_commands.repl diff --git a/docs/source/Plugin/P054.rst b/docs/source/Plugin/P054.rst index ad5de6617e..e1cf1f9061 100644 --- a/docs/source/Plugin/P054.rst +++ b/docs/source/Plugin/P054.rst @@ -1,4 +1,4 @@ -.. include:: ../Plugin/_plugin_substitutions_p05x.repl +.. include:: ../Plugin/_plugin_substitutions_p05x.repl .. _P054_page: |P054_typename| @@ -21,15 +21,59 @@ Maintainer: |P054_maintainer| Used libraries: |P054_usedlibraries| -Supported hardware ------------------- - |P054_usedby| -.. Commands available -.. ^^^^^^^^^^^^^^^^^^ +Description +----------- + +For controlling DMX512 equipment, this plugin can be used for sending commands to a DMX bus. As an ESP only has a 5V compatible serial interface, usually a RS485 or DMX converter is needed to connect to the DMX bus. + +This plugin can only send out commands to the DMX bus, no receiving or recording features are available. + +Configuration +------------- + +.. image:: P054_DeviceConfiguration.png + +* **Name** In the Name field a unique name should be entered. + +* **Enabled** When unchecked the plugin is not enabled. + +Actuator +^^^^^^^^ + +See: :ref:`SerialHelper_page` + +.. warning:: The selected serial port **must** use on-ESP GPIO pins, as the DMX protocol has some specific coding that is not supported by regular serial chips, and is implemented by directly interacting with the ESP TX pin. + +Example selection list (taken from an ESP32-C6 configuration): + +.. image:: P054_SerialPortOptions.png -.. .. include:: P054_commands.repl +* *HW Serial0*: First serial port, usually also in use for the serial log, so should best be avoided. + +* *HW Serial1*: Secondary serial port. Selected as the default, and required to be used on ESP8266. + +* *HW Serial2*: (Not available on an ESP32-C6, but is available on some other ESP32 models) Can be used. + +* *SW Serial*: Can be tried, and used if working as intended, but should better be avoided because of the high serial speed (250000 baud). + +* *USB HWCDC*: Can not be used. + +* *USB CDC*: Can not be used. + +* *I2C Serial*: Can not be used. + +Device Settings +^^^^^^^^^^^^^^^ + +* **Channels**: The number of DMX channels to be used. Determines the size of a memory buffer. Keep as small as possible, especially on ESP8266, where available memory can be limited. + + +Commands available +^^^^^^^^^^^^^^^^^^ + +.. include:: P054_commands.repl .. Events .. ~~~~~~ @@ -42,6 +86,8 @@ Change log .. versionchanged:: 2.0 ... + |added| 2024-09-29: Add selection for Serial port and GPIO on ESP32. + |added| Major overhaul for 2.0 release. diff --git a/docs/source/Plugin/P054_DeviceConfiguration.png b/docs/source/Plugin/P054_DeviceConfiguration.png new file mode 100644 index 0000000000000000000000000000000000000000..05154a12d5ca128045efc8be586acab0d32ac5f8 GIT binary patch literal 25860 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[,[,=]]`` + + | ``channel``: Channel number from 1 .. **Channels** set in the configuration. + + | ``value``: Numeric value between 0 and 255 (inclusive) to set for the channel. + "," + | Fills the send-buffer given value(s) for the channel and sends that to the connected devices. + + | If no channel is used with a value, it is set for the next channel. The channel is initially set to 1. + + | Multiple values, optionally with a channel prefixed, can be provided and will be processed until no more data is found. + + | Also, other subcommands (not including ``dmx``) can be used, f.e. setting up some channel data and adding a ``,log`` at the end to list the current buffer content to the log output. + " diff --git a/docs/source/Plugin/_plugin_substitutions_p05x.repl b/docs/source/Plugin/_plugin_substitutions_p05x.repl index 5baecc6bbc..22dee3255d 100644 --- a/docs/source/Plugin/_plugin_substitutions_p05x.repl +++ b/docs/source/Plugin/_plugin_substitutions_p05x.repl @@ -53,7 +53,7 @@ .. |P054_name| replace:: :cyan:`DMX512 TX` .. |P054_type| replace:: :cyan:`Communication` .. |P054_typename| replace:: :cyan:`Communication - DMX512 TX` -.. |P054_porttype| replace:: `.` +.. |P054_porttype| replace:: `Serial` .. |P054_status| replace:: :yellow:`COLLECTION` .. |P054_github| replace:: P054_DMX512.ino .. _P054_github: https://github.com/letscontrolit/ESPEasy/blob/mega/src/_P054_DMX512.ino diff --git a/src/_P054_DMX512.ino b/src/_P054_DMX512.ino index 93671097f0..09d4483c96 100644 --- a/src/_P054_DMX512.ino +++ b/src/_P054_DMX512.ino @@ -133,9 +133,17 @@ boolean Plugin_054(uint8_t function, struct EventStruct *event, String& string) } break; } + case PLUGIN_WEBFORM_SHOW_SERIAL_PARAMS: { - addFormNote(F("An on-chip ESP Serial port must be selected!")); + addFormNote(F("An on-chip ESP Serial port" + #if USES_USBCDC + " (not USB CDC)" + #endif // if USES_USBCDC + #if USES_HWCDC + " (not USB HWCDC)" + #endif // if USES_HWCDC + " must be selected!")); break; } @@ -217,6 +225,7 @@ boolean Plugin_054(uint8_t function, struct EventStruct *event, String& string) { if (Plugin_054_DMXBuffer) { delete[] Plugin_054_DMXBuffer; + Plugin_054_DMXBuffer = nullptr; } delete Plugin_054_Serial; Plugin_054_Serial = nullptr;