Update TasmotaModbus to 1.2.0

Update TasmotaModbus to 1.2.0
This commit is contained in:
Theo Arends 2019-09-16 16:27:35 +02:00
parent 9c6b4259a4
commit d193b8cb1a
7 changed files with 49 additions and 29 deletions

View File

@ -1,6 +1,6 @@
{ {
"name": "TasmotaModbus", "name": "TasmotaModbus",
"version": "1.1.1", "version": "1.2.0",
"keywords": [ "keywords": [
"serial", "io", "TasmotaModbus" "serial", "io", "TasmotaModbus"
], ],

View File

@ -1,5 +1,5 @@
name=TasmotaModbus name=TasmotaModbus
version=1.1.1 version=1.2.0
author=Theo Arends author=Theo Arends
maintainer=Theo Arends <theo@arends.com> maintainer=Theo Arends <theo@arends.com>
sentence=Basic modbus wrapper for TasmotaSerial for ESP8266. sentence=Basic modbus wrapper for TasmotaSerial for ESP8266.

View File

@ -61,10 +61,10 @@ void TasmotaModbus::Send(uint8_t device_address, uint8_t function_code, uint16_t
frame[0] = mb_address; // 0xFE default device address or dedicated like 0x01 frame[0] = mb_address; // 0xFE default device address or dedicated like 0x01
frame[1] = function_code; frame[1] = function_code;
frame[2] = (uint8_t)(start_address >> 8); frame[2] = (uint8_t)(start_address >> 8); // MSB
frame[3] = (uint8_t)(start_address); frame[3] = (uint8_t)(start_address); // LSB
frame[4] = (uint8_t)(register_count >> 8); frame[4] = (uint8_t)(register_count >> 8); // MSB
frame[5] = (uint8_t)(register_count); frame[5] = (uint8_t)(register_count); // LSB
uint16_t crc = CalculateCRC(frame, 6); uint16_t crc = CalculateCRC(frame, 6);
frame[6] = (uint8_t)(crc); frame[6] = (uint8_t)(crc);
frame[7] = (uint8_t)(crc >> 8); frame[7] = (uint8_t)(crc >> 8);
@ -80,35 +80,48 @@ bool TasmotaModbus::ReceiveReady()
uint8_t TasmotaModbus::ReceiveBuffer(uint8_t *buffer, uint8_t register_count) uint8_t TasmotaModbus::ReceiveBuffer(uint8_t *buffer, uint8_t register_count)
{ {
uint8_t len = 0; mb_len = 0;
uint32_t last = millis(); uint32_t last = millis();
while ((available() > 0) && (len < (register_count *2) + 5) && (millis() - last < 10)) { while ((available() > 0) && (mb_len < (register_count *2) + 5) && (millis() - last < 10)) {
uint8_t data = (uint8_t)read(); uint8_t data = (uint8_t)read();
if (!len) { // Skip leading data as provided by hardware serial if (!mb_len) { // Skip leading data as provided by hardware serial
if (mb_address == data) { if (mb_address == data) {
buffer[len++] = data; buffer[mb_len++] = data;
} }
} else { } else {
buffer[len++] = data; buffer[mb_len++] = data;
if (3 == len) { if (3 == mb_len) {
if (buffer[1] & 0x80) { // 01 84 02 f2 f1 if (buffer[1] & 0x80) { // 01 84 02 f2 f1
return buffer[2]; // 1 = Illegal Function, 2 = Illegal Address, 3 = Illegal Data, 4 = Slave Error return buffer[2]; // 1 = Illegal Function,
// 2 = Illegal Data Address,
// 3 = Illegal Data Value,
// 4 = Slave Error
// 5 = Acknowledge but not finished (no error)
// 6 = Slave Busy
// 8 = Memory Parity error
// 10 = Gateway Path Unavailable
// 11 = Gateway Target device failed to respond
} }
} }
} }
last = millis(); last = millis();
} }
if (len < 7) { return 7; } // 7 = Not enough data if (mb_len < 7) { return 7; } // 7 = Not enough data
if (len != buffer[2] + 5) {
buffer[2] = len - 5; // As it's wrong anyway let's store actual number received in here (5 will be added by client) /*
return 8; // 8 = Unexpected result if (mb_len != buffer[2] + 5) {
buffer[2] = mb_len - 5; // As it's wrong anyway let's store actual number received in here (5 will be added by client)
return 3; // 3 = Unexpected result
}
*/
uint16_t crc = (buffer[mb_len -1] << 8) | buffer[mb_len -2];
if (CalculateCRC(buffer, mb_len -2) != crc) {
return 9; // 9 = crc error
} }
uint16_t crc = (buffer[len -1] << 8) | buffer[len -2]; return 0; // 0 = No error
if (CalculateCRC(buffer, len -2) != crc) { return 9; } // 9 = crc error
return 0; // 0 = No error
} }
uint8_t TasmotaModbus::Receive16BitRegister(uint16_t *value) uint8_t TasmotaModbus::Receive16BitRegister(uint16_t *value)

View File

@ -37,21 +37,28 @@ class TasmotaModbus : public TasmotaSerial {
bool ReceiveReady(); bool ReceiveReady();
/* Return codes: /* Return codes:
* 0 - No error * 0 = No error
* 1 - Illegal function * 1 = Illegal Function,
* 2 - Illegal address * 2 = Illegal Data Address,
* 3 - Illegal data * 3 = Illegal Data Value,
* 4 - Slave error * 4 = Slave Error
* 7 - Not enough minimal data received * 5 = Acknowledge but not finished (no error)
* 8 - Not enough data receieved * 6 = Slave Busy
* 9 - Crc error * 7 = Not enough minimal data received
* 8 = Memory Parity error
* 9 = Crc error
* 10 = Gateway Path Unavailable
* 11 = Gateway Target device failed to respond
*/ */
uint8_t ReceiveBuffer(uint8_t *buffer, uint8_t register_count); uint8_t ReceiveBuffer(uint8_t *buffer, uint8_t register_count);
uint8_t Receive16BitRegister(uint16_t *value); uint8_t Receive16BitRegister(uint16_t *value);
uint8_t Receive32BitRegister(float *value); uint8_t Receive32BitRegister(float *value);
uint8_t ReceiveCount(void) { return mb_len; }
private: private:
uint8_t mb_address; uint8_t mb_address;
uint8_t mb_len;
}; };
#endif // TasmotaModbus_h #endif // TasmotaModbus_h