From b54c0e5018be08adf111cf26e27e981eca7bbd14 Mon Sep 17 00:00:00 2001 From: Emanuele Trabattoni Date: Thu, 26 Jun 2025 11:52:09 +0200 Subject: [PATCH] First version of RS485 + MODBUS Driver --- lib/RS485/WS_RS485.cpp | 369 +++++++++++++++++++---------------------- lib/RS485/WS_RS485.h | 32 ++-- src/WS_RS485.cpp | 163 ------------------ src/WS_RS485.h | 26 --- 4 files changed, 195 insertions(+), 395 deletions(-) delete mode 100644 src/WS_RS485.cpp delete mode 100644 src/WS_RS485.h diff --git a/lib/RS485/WS_RS485.cpp b/lib/RS485/WS_RS485.cpp index 59b3393..7b3ceed 100644 --- a/lib/RS485/WS_RS485.cpp +++ b/lib/RS485/WS_RS485.cpp @@ -3,7 +3,6 @@ #include #include -HardwareSerial lidarSerial(1); // Using serial port 1 uint8_t data[][8] = { // ESP32-S3-POE-ETH-8DI-8RO Control Command (RS485 receiving data) {0x06, 0x05, 0x00, 0x01, 0x55, 0x00, 0xA2, 0xED}, // ESP32-S3-POE-ETH-8DI-8RO CH1 Toggle @@ -30,151 +29,6 @@ uint8_t Send_Data[][8] = { {0x01, 0x05, 0x00, 0xFF, 0xFF, 0xFF, 0xFC, 0x4A}, // Modbus RTU Relay ALL ON {0x01, 0x05, 0x00, 0xFF, 0x00, 0x00, 0xFD, 0xFA}, // Modbus RTU Relay ALL OFF }; -uint8_t buf[20] = {0}; // Data storage area -int numRows = sizeof(data) / sizeof(data[0]); - -void SetData(uint8_t *data, size_t length) -{ - lidarSerial.write(data, length); // Send data from the RS485 -} -void ReadData(uint8_t *buf, uint8_t length) -{ - uint8_t Receive_Flag = 0; - Receive_Flag = lidarSerial.available(); - if (Receive_Flag >= length) - { - lidarSerial.readBytes(buf, length); - char printBuf[length * 3 + 1]; - sprintf(printBuf, "Received data: "); - for (int i = 0; i < length; i++) - { - sprintf(printBuf + strlen(printBuf), "%02X ", buf[i]); - } - printf(printBuf); - /************************* - Add a receiving data handler - *************************/ - Receive_Flag = 0; - memset(buf, 0, sizeof(buf)); - } -} -void RS485_Analysis(uint8_t *buf) -{ - switch (buf[1]) - { - case Extension_CH1: - SetData(Send_Data[0], sizeof(Send_Data[0])); - printf("|*** Toggle expansion channel 1 ***|\r\n"); - break; - case Extension_CH2: - SetData(Send_Data[1], sizeof(Send_Data[1])); - printf("|*** Toggle expansion channel 2 ***|\r\n"); - break; - case Extension_CH3: - SetData(Send_Data[2], sizeof(Send_Data[2])); - printf("|*** Toggle expansion channel 3 ***|\r\n"); - break; - case Extension_CH4: - SetData(Send_Data[3], sizeof(Send_Data[3])); - printf("|*** Toggle expansion channel 4 ***|\r\n"); - break; - case Extension_CH5: - SetData(Send_Data[4], sizeof(Send_Data[4])); - printf("|*** Toggle expansion channel 5 ***|\r\n"); - break; - case Extension_CH6: - SetData(Send_Data[5], sizeof(Send_Data[5])); - printf("|*** Toggle expansion channel 6 ***|\r\n"); - break; - case Extension_CH7: - SetData(Send_Data[6], sizeof(Send_Data[6])); - printf("|*** Toggle expansion channel 7 ***|\r\n"); - break; - case Extension_CH8: - SetData(Send_Data[7], sizeof(Send_Data[7])); - printf("|*** Toggle expansion channel 8 ***|\r\n"); - break; - case Extension_ALL_ON: - SetData(Send_Data[8], sizeof(Send_Data[8])); - printf("|*** Enable all extension channels ***|\r\n"); - break; - case Extension_ALL_OFF: - SetData(Send_Data[9], sizeof(Send_Data[9])); - printf("|*** Close all expansion channels ***|\r\n"); - break; - default: - printf("Note : Non-control external device instructions !\r\n"); - } -} -uint32_t Baudrate = 0; -double transmission_time = 0; -double RS485_cmd_Time = 0; -void RS485_Init() // Initializing serial port -{ - Baudrate = 9600; // Set the baud rate of the serial port - lidarSerial.begin(Baudrate, SERIAL_8N1, RXD1, TXD1); // Initializing serial port - transmission_time = 10.0 / Baudrate * 1000; - RS485_cmd_Time = transmission_time * 8; // 8:data length - xTaskCreatePinnedToCore( - RS485Task, - "RS485Task", - 4096, - NULL, - 3, - NULL, - 0); -} - -void RS485Task(void *parameter) -{ - while (1) - { - RS485_Loop(); - vTaskDelay(pdMS_TO_TICKS(50)); - } - vTaskDelete(NULL); -} - -void RS485_Loop() -{ - uint8_t Receive_Flag = 0; // Receiving mark - Receive_Flag = lidarSerial.available(); - - if (Receive_Flag > 0) - { - if (RS485_cmd_Time > 1) // Time greater than 1 millisecond - delay((uint16_t)RS485_cmd_Time); - else // Time is less than 1 millisecond - delay(1); - Receive_Flag = lidarSerial.available(); - lidarSerial.readBytes(buf, Receive_Flag); // The Receive_Flag length is read - if (Receive_Flag == 8) - { - uint8_t i = 0; - for (i = 0; i < numRows; i++) - { - bool result = std::equal(std::begin(buf), std::begin(buf) + 8, std::begin(data[i])); // Compare two arrays - if (result) - { - if (i < numRows - 1) - buf[0] = i + 1 + 48; - else if (i == numRows - 1) - buf[0] = 48; - Relay_Analysis(buf, RS485_Mode); - break; - } - } - if (i > numRows - 1) - printf("Note : Non-instruction data was received - RS485 !\r\n"); - } - else - { - printf("Note : Non-instruction data was received .Number of bytes: %d - RS485 !\r\n", Receive_Flag); - } - Receive_Flag = 0; - memset(buf, 0, sizeof(buf)); - } -} namespace drivers { @@ -230,6 +84,7 @@ namespace drivers const bool MODBUS::readCoils(const uint8_t device, const uint16_t reg, const uint16_t num, std::vector &coils) { constexpr uint8_t func = 0x01; + log_d("Read coils: dev[%02x], reg[%04x], num[%d]", device, reg, num); readBinary(func, device, reg, num, coils); } @@ -237,22 +92,75 @@ namespace drivers const bool MODBUS::readInputs(const uint8_t device, const uint16_t reg, const uint8_t num, std::vector &inputs) { constexpr uint8_t func = 0x01; + log_d("Read multi inputs: dev[%02x], reg[%04x], num[%d]", device, reg, num); readBinary(func, device, reg, num, inputs); } + // Func 0x03 + const bool MODBUS::readHoldingRegisters(const uint8_t device, const uint16_t reg, const uint8_t num, std::vector &values) + { + constexpr uint8_t func = 0x03; + log_d("Read multi holding registers: dev[%02x], reg[%04x], num[%d]", device, reg, num); + readInteger(func, device, reg, num, values); + } + + // Func 0x04 + const bool MODBUS::readInputRegisters(const uint8_t device, const uint16_t reg, const uint8_t num, std::vector &values) + { + constexpr uint8_t func = 0x04; + log_d("Read multi input registers: dev[%02x], reg[%04x], num[%d]", device, reg, num); + readInteger(func, device, reg, num, values); + } + + // Func 0x05 + const bool MODBUS::writeCoil(const uint8_t device, const uint16_t coil, const bool value) + { + constexpr uint8_t func = 0x05; + log_d("Write single coil: dev[%02x], reg[%04x], val[...]", device, reg); + return writeBinary(device, func, coil, 1, {value}); + } + + // Func 0x06 + const bool MODBUS::writeRegister(const uint8_t device, const uint16_t reg, const uint16_t value) + { + constexpr uint8_t func = 0x06; + log_d("Write single register: dev[%02x], reg[%04x], val[%04x]", device, reg, value); + return writeInteger(device, func, reg, 1, {value}); + } + + // Func 0x0F + const bool MODBUS::writeCoils(const uint8_t device, const uint16_t coils, const std::vector &values) + { + constexpr uint8_t func = 0x0F; + log_d("Write multi coils: dev[%02x], reg[%04x], val[...]", device, reg); + return writeBinary(device, func, coils, values.size(), values); + } + + // Func 0x10 + const bool MODBUS::writeRegisters(const uint8_t device, const uint16_t reg, const std::vector &values) + { + constexpr uint8_t func = 0x10; + log_d("Write multi registers: dev[%02x], reg[%04x], val[...]", device, reg); + return writeInteger(device, func, reg, values.size(), values); + } + + ///////////////////////////////////////////////////////////////// + /////////////////////// Utility Functions /////////////////////// + ///////////////////////////////////////////////////////////////// + const bool MODBUS::readBinary(const uint8_t func, const uint8_t device, const uint16_t reg, const uint16_t bits, std::vector &out) { - if (!write(buildRequest(device, func, reg, bits))) + if (!write(singleRequest(device, func, reg, bits))) { - log_e("Failed send readCoils command"); + log_e("Failed send readBinary command"); return false; } - const uint16_t nRespDataBytes = 1 + (bits % 8); // 1 bit for every coil, if not 8 mutiple padded with zeroes + const uint16_t nRespDataBytes = 1 + (uint16_t)(bits / 8); // 1 bit for every coil, if not 8 mutiple padded with zeroes const uint16_t expectedRespLen = (RESP_HEADER_SIZE + RESP_CRC_SIZE) + nRespDataBytes; // device + function + nbytes + data[] + crc(16b) std::vector response; if (!readN(expectedRespLen, response)) { - log_e("Failed receive readCoils response"); + log_e("Failed receive readBinary response"); return false; } @@ -286,21 +194,11 @@ namespace drivers } } - // Func 0x03 - const bool MODBUS::readHoldingRegisters(const uint8_t device, const uint16_t reg, const uint8_t num, std::vector &values) - { - } - - // Func 0x04 - const bool MODBUS::readInputRegisters(const uint8_t device, const uint16_t reg, const uint8_t num, std::vector &values) - { - } - const bool MODBUS::readInteger(const uint8_t func, const uint8_t device, const uint16_t reg, const uint16_t num, std::vector &out) { - if (!write(buildRequest(device, func, reg, num))) + if (!write(singleRequest(device, func, reg, num))) { - log_e("Failed send readCoils command"); + log_e("Failed send readInteger command"); return false; } const uint16_t nRespDataBytes = num * sizeof(uint16_t); @@ -308,7 +206,7 @@ namespace drivers std::vector response; if (!readN(expectedRespLen, response)) { - log_e("Failed receive readCoils response"); + log_e("Failed receive readInteger response"); return false; } @@ -330,48 +228,130 @@ namespace drivers const std::vector respData(response.begin() + RESP_HEADER_SIZE, response.end() - RESP_CRC_SIZE); for (auto i(0); i < nRespDataBytes; i++) { - reg_bytes_t val; - val.hi = respData.at(i * sizeof(uint16_t)); - val.lo = respData.at(1 + i * sizeof(uint16_t)); - out.push_back(be16toh(val.reg16)); + const uint8_t hi(respData.at(i * sizeof(uint16_t))); + const uint8_t lo(respData.at(1 + i * sizeof(uint16_t))); + const uint16_t val(0xFFFF & ((hi << 8) | lo)); + out.push_back(be16toh(val)); } } - // Func 0x05 - const bool MODBUS::writeCoil(const uint8_t device, const uint16_t coil, const bool value) + const bool MODBUS::writeBinary(const uint8_t func, const uint8_t device, const uint16_t reg, const uint16_t bits, const std::vector &in) { + std::vector bitsOut; + if (bits <= 1) // if single coil value must be 0x00FF[00] for on[off] + { + bitsOut.push_back(htobe16(in.front() ? 0x00FF : 0x0000)); + } + else // if multiple coils value is 0x01 shifted for the number of coil intended + { + const uint16_t numRegisters((uint16_t)(bits / 16) + 1); + bitsOut.resize(numRegisters, 0); + for (uint16_t i(0); i < in.size(); i++) + { + if (!in[i]) // if value is false skip + continue; + const uint16_t curReg(i / 16); + bitsOut[curReg] |= 0x01 << i % 16; + } + } + + if (!write(multiRequest(device, func, reg, bits, bitsOut))) + { + log_e("Failed send writeBinary command"); + return false; + } + + const uint16_t expectedRespLen(sizeof(resp_t)); + std::vector response; + if (!readN(expectedRespLen, response)) + { + log_e("Failed receive writeBinary response"); + return false; + } + + // compute crc of current message + if (!verifyCrc(response)) + return false; + + return true; } - // Func 0x06 - const bool MODBUS::writeRegister(const uint8_t device, const uint16_t reg, const uint16_t value) + const bool MODBUS::writeInteger(const uint8_t func, const uint8_t device, const uint16_t reg, const uint16_t num, const std::vector &in) { + if (!write(multiRequest(device, func, reg, num, in))) + { + log_e("Failed send writeInteger command"); + return false; + } + + const uint16_t expectedRespLen(sizeof(resp_t)); + std::vector response; + if (!readN(expectedRespLen, response)) + { + log_e("Failed receive writeInteger response"); + return false; + } + + // compute crc of current message + if (!verifyCrc(response)) + return false; + + return true; } - // Func 0x0F - const bool MODBUS::writeCoils(const uint8_t device, const uint16_t reg, const std::vector &coils) + const std::vector MODBUS::singleRequest(const uint8_t device, const uint8_t func, const uint16_t reg, const uint16_t data) { - } + req_t header; + header.device = device; + header.func = func; + header.reg = htobe16(reg); + header.data = htobe16(data); - // Func 0x10 - const bool MODBUS::writeRegisters(const uint8_t device, const uint16_t reg, const std::vector &values) - { - } - - const std::vector MODBUS::buildRequest(const uint8_t device, const uint8_t func, const uint16_t reg, const uint16_t qty) - { - req_t msg; - msg.device = device; - msg.func = func; - msg.reg.reg16 = htobe16(reg); - msg.qty.reg16 = htobe16(qty); + const uint8_t headerBytes(sizeof(req_t)); + const uint8_t crcBytes(sizeof(crc_t)); + // compute crc for header + data m_crc.reset(); - m_crc.add((uint8_t *)&msg, sizeof(req_t)); - msg.crc = m_crc.getCRC(); + m_crc.add((uint8_t *)&header, headerBytes); // exclude last two bytes of crc + const uint16_t crc(htole16(m_crc.getCRC())); - std::vector data(sizeof(req_t), 0); - std::memcpy(data.data(), &msg, sizeof(req_t)); - return data; + std::vector dataOut(headerBytes + crcBytes, 0); + std::memcpy(dataOut.data(), &header, headerBytes); + std::memcpy(dataOut.data() + headerBytes, &crc, crcBytes); + return dataOut; + } + + const std::vector MODBUS::multiRequest(const uint8_t device, const uint8_t func, const uint16_t reg, const uint16_t qty, const std::vector &data) + { + req_multi_t header; + header.device = device; + header.func = func; + header.reg = htobe16(reg); + header.qty = htobe16(qty); + header.bytes = (uint8_t)(data.size() * sizeof(uint16_t)); // 8 bit value + + // convert uint16_t values from host endianness to big endian + std::vector dataBe; + dataBe.reserve(data.size()); + std::for_each(data.begin(), data.end(), [&dataBe](auto v) + { dataBe.push_back(htobe16(v)); }); + + const uint8_t headerBytes(sizeof(req_multi_t)); + const uint8_t dataBytes(sizeof(uint16_t) * dataBe.size()); + const uint8_t crcBytes(sizeof(crc_t)); + + // compute crc for header + data + m_crc.reset(); + m_crc.add((uint8_t *)&header, headerBytes); // add the request excluding the CRC code + m_crc.add((uint8_t *)dataBe.data(), dataBytes); + const uint16_t crc(htole16(m_crc.getCRC())); + + std::vector dataOut; + dataOut.resize(headerBytes + dataBytes + crcBytes); // header message + data values + crc code + std::memcpy(dataOut.data(), &header, headerBytes); // copy message + std::memcpy(dataOut.data() + headerBytes, dataBe.data(), dataBytes); // copy data + std::memcpy(dataOut.data() + headerBytes + dataBytes, &crc, crcBytes); // copy crc + return dataOut; } const bool MODBUS::verifyCrc(const std::vector &data) @@ -381,13 +361,14 @@ namespace drivers m_crc.add(data.data(), data.size()); const uint16_t computedCrc(m_crc.getCRC()); // extract crc from response - const uint8_t crcHi(data.back()); - const uint8_t crcLo(data.back() - 1); + const uint16_t size(data.size()); + const uint8_t crcLo(data.at(size - 2)); + const uint8_t crcHi(data.at(size - 1)); // verify crc code if (highByte(computedCrc) != crcHi || lowByte(computedCrc) != crcLo) { - log_e("Failed verify CRC code: comp[%04x], rec[%04x]", computedCrc, 0xFFFF && ((crcHi << 8) || crcLo)); + log_e("Failed verify CRC code: comp[%04x], rec[%04x]", computedCrc, 0xFFFF & ((crcHi << 8) | crcLo)); return false; } return true; diff --git a/lib/RS485/WS_RS485.h b/lib/RS485/WS_RS485.h index 9b196e6..1c15577 100644 --- a/lib/RS485/WS_RS485.h +++ b/lib/RS485/WS_RS485.h @@ -46,23 +46,28 @@ namespace drivers { static const uint8_t RESP_HEADER_SIZE = 3; - static const uint8_t RESP_CRC_SIZE = 1; - - typedef union { - uint8_t hi; - uint8_t lo; - uint16_t reg16; - } reg_bytes_t; + static const uint8_t RESP_CRC_SIZE = 2; typedef struct { uint8_t device; uint8_t func; - reg_bytes_t reg; - reg_bytes_t qty; - uint16_t crc = 0xFF; + uint16_t reg; + uint16_t data; } req_t; + typedef struct + { + uint8_t device; + uint8_t func; + uint16_t reg; + uint16_t qty; + uint8_t bytes; + } req_multi_t; + + typedef req_t resp_t; + typedef uint16_t crc_t; + public: MODBUS(const uint32_t baud, const SerialConfig conf); @@ -85,16 +90,19 @@ namespace drivers const bool writeRegister(const uint8_t device, const uint16_t reg, const uint16_t value); // Func 0x0F - const bool writeCoils(const uint8_t device, const uint16_t reg, const std::vector &coils); + const bool writeCoils(const uint8_t device, const uint16_t coils, const std::vector &values); // Func 0x10 const bool writeRegisters(const uint8_t device, const uint16_t reg, const std::vector &values); private: CRC16 m_crc; - const std::vector buildRequest(const uint8_t device, const uint8_t func, const uint16_t reg, const uint16_t qty); + const std::vector singleRequest(const uint8_t device, const uint8_t func, const uint16_t reg, const uint16_t data); + const std::vector multiRequest(const uint8_t device, const uint8_t func, const uint16_t reg, const uint16_t qty, const std::vector &data); const bool readBinary(const uint8_t func, const uint8_t device, const uint16_t reg, const uint16_t bits, std::vector &out); const bool readInteger(const uint8_t func, const uint8_t device, const uint16_t reg, const uint16_t num, std::vector &out); + const bool writeBinary(const uint8_t func, const uint8_t device, const uint16_t reg, const uint16_t bits, const std::vector &in); + const bool writeInteger(const uint8_t func, const uint8_t device, const uint16_t reg, const uint16_t num, const std::vector &in); const bool verifyCrc(const std::vector &data); }; } diff --git a/src/WS_RS485.cpp b/src/WS_RS485.cpp deleted file mode 100644 index 4390571..0000000 --- a/src/WS_RS485.cpp +++ /dev/null @@ -1,163 +0,0 @@ -#include "WS_RS485.h" -#include - -HardwareSerial lidarSerial(1); // Using serial port 1 -uint8_t data[][8] = { // ESP32-S3-POE-ETH-8DI-8RO Control Command (RS485 receiving data) - { 0x06, 0x05, 0x00, 0x01, 0x55, 0x00, 0xA2, 0xED }, // ESP32-S3-POE-ETH-8DI-8RO CH1 Toggle - { 0x06, 0x05, 0x00, 0x02, 0x55, 0x00, 0x52, 0xED }, // ESP32-S3-POE-ETH-8DI-8RO CH2 Toggle - { 0x06, 0x05, 0x00, 0x03, 0x55, 0x00, 0x03, 0x2D }, // ESP32-S3-POE-ETH-8DI-8RO CH3 Toggle - { 0x06, 0x05, 0x00, 0x04, 0x55, 0x00, 0xB2, 0xEC }, // ESP32-S3-POE-ETH-8DI-8RO CH4 Toggle - { 0x06, 0x05, 0x00, 0x05, 0x55, 0x00, 0xE3, 0x2C }, // ESP32-S3-POE-ETH-8DI-8RO CH5 Toggle - { 0x06, 0x05, 0x00, 0x06, 0x55, 0x00, 0x13, 0x2C }, // ESP32-S3-POE-ETH-8DI-8RO CH6 Toggle - { 0x06, 0x05, 0x00, 0x07, 0x55, 0x00, 0x42, 0xEC }, // ESP32-S3-POE-ETH-8DI-8RO CH7 Toggle - { 0x06, 0x05, 0x00, 0x08, 0x55, 0x00, 0x72, 0xEF }, // ESP32-S3-POE-ETH-8DI-8RO CH8 Toggle - { 0x06, 0x05, 0x00, 0xFF, 0xFF, 0x00, 0xBD, 0xBD }, // ESP32-S3-POE-ETH-8DI-8RO ALL ON - { 0x06, 0x05, 0x00, 0xFF, 0x00, 0x00, 0xFC, 0x4D }, // ESP32-S3-POE-ETH-8DI-8RO ALL OFF -}; -uint8_t Send_Data[][8] = { // Modbus RTU Relay Control Command (RS485 send data) - { 0x01, 0x05, 0x00, 0x00, 0x55, 0x00, 0xF2, 0x9A }, // Modbus RTU Relay CH1 Toggle - { 0x01, 0x05, 0x00, 0x01, 0x55, 0x00, 0xA3, 0x5A }, // Modbus RTU Relay CH2 Toggle - { 0x01, 0x05, 0x00, 0x02, 0x55, 0x00, 0x53, 0x5A }, // Modbus RTU Relay CH3 Toggle - { 0x01, 0x05, 0x00, 0x03, 0x55, 0x00, 0x02, 0x9A }, // Modbus RTU Relay CH4 Toggle - { 0x01, 0x05, 0x00, 0x04, 0x55, 0x00, 0xB3, 0x5B }, // Modbus RTU Relay CH5 Toggle - { 0x01, 0x05, 0x00, 0x05, 0x55, 0x00, 0xE2, 0x9B }, // Modbus RTU Relay CH6 Toggle - { 0x01, 0x05, 0x00, 0x06, 0x55, 0x00, 0x12, 0x9B }, // Modbus RTU Relay CH7 Toggle - { 0x01, 0x05, 0x00, 0x07, 0x55, 0x00, 0x43, 0x5B }, // Modbus RTU Relay CH8 Toggle - { 0x01, 0x05, 0x00, 0xFF, 0xFF, 0xFF, 0xFC, 0x4A }, // Modbus RTU Relay ALL ON - { 0x01, 0x05, 0x00, 0xFF, 0x00, 0x00, 0xFD, 0xFA }, // Modbus RTU Relay ALL OFF -}; -uint8_t buf[20] = {0}; // Data storage area -int numRows = sizeof(data) / sizeof(data[0]); - -void SetData(uint8_t* data, size_t length) { - lidarSerial.write(data, length); // Send data from the RS485 -} -void ReadData(uint8_t* buf, uint8_t length) { - uint8_t Receive_Flag = 0; - Receive_Flag = lidarSerial.available(); - if (Receive_Flag >= length) { - lidarSerial.readBytes(buf, length); - char printBuf[length * 3 + 1]; - sprintf(printBuf, "Received data: "); - for (int i = 0; i < length; i++) { - sprintf(printBuf + strlen(printBuf), "%02X ", buf[i]); - } - printf(printBuf); - /************************* - Add a receiving data handler - *************************/ - Receive_Flag = 0; - memset(buf, 0, sizeof(buf)); - } -} -void RS485_Analysis(uint8_t *buf) -{ - switch(buf[1]) - { - case Extension_CH1: - SetData(Send_Data[0],sizeof(Send_Data[0])); - printf("|*** Toggle expansion channel 1 ***|\r\n"); - break; - case Extension_CH2: - SetData(Send_Data[1],sizeof(Send_Data[1])); - printf("|*** Toggle expansion channel 2 ***|\r\n"); - break; - case Extension_CH3: - SetData(Send_Data[2],sizeof(Send_Data[2])); - printf("|*** Toggle expansion channel 3 ***|\r\n"); - break; - case Extension_CH4: - SetData(Send_Data[3],sizeof(Send_Data[3])); - printf("|*** Toggle expansion channel 4 ***|\r\n"); - break; - case Extension_CH5: - SetData(Send_Data[4],sizeof(Send_Data[4])); - printf("|*** Toggle expansion channel 5 ***|\r\n"); - break; - case Extension_CH6: - SetData(Send_Data[5],sizeof(Send_Data[5])); - printf("|*** Toggle expansion channel 6 ***|\r\n"); - break; - case Extension_CH7: - SetData(Send_Data[6],sizeof(Send_Data[6])); - printf("|*** Toggle expansion channel 7 ***|\r\n"); - break; - case Extension_CH8: - SetData(Send_Data[7],sizeof(Send_Data[7])); - printf("|*** Toggle expansion channel 8 ***|\r\n"); - break; - case Extension_ALL_ON: - SetData(Send_Data[8],sizeof(Send_Data[8])); - printf("|*** Enable all extension channels ***|\r\n"); - break; - case Extension_ALL_OFF: - SetData(Send_Data[9],sizeof(Send_Data[9])); - printf("|*** Close all expansion channels ***|\r\n"); - break; - default: - printf("Note : Non-control external device instructions !\r\n"); - } -} -uint32_t Baudrate = 0; -double transmission_time = 0; -double RS485_cmd_Time = 0; -void RS485_Init() // Initializing serial port -{ - Baudrate = 9600; // Set the baud rate of the serial port - lidarSerial.begin(Baudrate, SERIAL_8N1, RXD1, TXD1); // Initializing serial port - transmission_time = 10.0 / Baudrate * 1000 ; - RS485_cmd_Time = transmission_time*8; // 8:data length - xTaskCreatePinnedToCore( - RS485Task, - "RS485Task", - 4096, - NULL, - 3, - NULL, - 0 - ); -} - -void RS485Task(void *parameter) { - while(1){ - RS485_Loop(); - vTaskDelay(pdMS_TO_TICKS(50)); - } - vTaskDelete(NULL); -} - -void RS485_Loop() -{ - uint8_t Receive_Flag = 0; // Receiving mark - Receive_Flag = lidarSerial.available(); - - if (Receive_Flag > 0) { - if(RS485_cmd_Time > 1) // Time greater than 1 millisecond - delay((uint16_t)RS485_cmd_Time); - else // Time is less than 1 millisecond - delay(1); - Receive_Flag = lidarSerial.available(); - lidarSerial.readBytes(buf, Receive_Flag); // The Receive_Flag length is read - if(Receive_Flag == 8){ - uint8_t i=0; - for(i=0;i numRows-1) - printf("Note : Non-instruction data was received - RS485 !\r\n"); - } - else{ - printf("Note : Non-instruction data was received .Number of bytes: %d - RS485 !\r\n",Receive_Flag); - } - Receive_Flag=0; - memset(buf,0, sizeof(buf)); - } -} \ No newline at end of file diff --git a/src/WS_RS485.h b/src/WS_RS485.h deleted file mode 100644 index 9eb4e98..0000000 --- a/src/WS_RS485.h +++ /dev/null @@ -1,26 +0,0 @@ -#pragma once - -#include // Reference the ESP32 built-in serial port library -#include "WS_GPIO.h" -#include "WS_Relay.h" - -#define Extension_CH1 1 // Expansion Channel 1 -#define Extension_CH2 2 // Expansion Channel 2 -#define Extension_CH3 3 // Expansion Channel 3 -#define Extension_CH4 4 // Expansion Channel 4 -#define Extension_CH5 5 // Expansion Channel 5 -#define Extension_CH6 6 // Expansion Channel 6 -#define Extension_CH7 7 // Expansion Channel 7 -#define Extension_CH8 8 // Expansion Channel 8 -#define Extension_ALL_ON 9 // Expansion ALL ON -#define Extension_ALL_OFF 10 // Expansion ALL OFF - - - -void SetData(uint8_t* data, size_t length); // Send data from the RS485 -void ReadData(uint8_t* buf, uint8_t length); // Data is received over RS485 - -void RS485_Analysis(uint8_t *buf); // External relay control -void RS485_Init(); // Example Initialize the system serial port and RS485 -void RS485_Loop(); // Read RS485 data, parse and control relays -void RS485Task(void *parameter);