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",
"version": "1.1.1",
"version": "1.2.0",
"keywords": [
"serial", "io", "TasmotaModbus"
],

View File

@ -1,5 +1,5 @@
name=TasmotaModbus
version=1.1.1
version=1.2.0
author=Theo Arends
maintainer=Theo Arends <theo@arends.com>
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[1] = function_code;
frame[2] = (uint8_t)(start_address >> 8);
frame[3] = (uint8_t)(start_address);
frame[4] = (uint8_t)(register_count >> 8);
frame[5] = (uint8_t)(register_count);
frame[2] = (uint8_t)(start_address >> 8); // MSB
frame[3] = (uint8_t)(start_address); // LSB
frame[4] = (uint8_t)(register_count >> 8); // MSB
frame[5] = (uint8_t)(register_count); // LSB
uint16_t crc = CalculateCRC(frame, 6);
frame[6] = (uint8_t)(crc);
frame[7] = (uint8_t)(crc >> 8);
@ -80,33 +80,46 @@ bool TasmotaModbus::ReceiveReady()
uint8_t TasmotaModbus::ReceiveBuffer(uint8_t *buffer, uint8_t register_count)
{
uint8_t len = 0;
mb_len = 0;
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();
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) {
buffer[len++] = data;
buffer[mb_len++] = data;
}
} else {
buffer[len++] = data;
if (3 == len) {
buffer[mb_len++] = data;
if (3 == mb_len) {
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();
}
if (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 < 7) { return 7; } // 7 = Not enough data
uint16_t crc = (buffer[len -1] << 8) | buffer[len -2];
if (CalculateCRC(buffer, len -2) != crc) { return 9; } // 9 = crc error
/*
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
}
return 0; // 0 = No error
}

View File

@ -37,21 +37,28 @@ class TasmotaModbus : public TasmotaSerial {
bool ReceiveReady();
/* Return codes:
* 0 - No error
* 1 - Illegal function
* 2 - Illegal address
* 3 - Illegal data
* 4 - Slave error
* 7 - Not enough minimal data received
* 8 - Not enough data receieved
* 9 - Crc error
* 0 = No error
* 1 = Illegal Function,
* 2 = Illegal Data Address,
* 3 = Illegal Data Value,
* 4 = Slave Error
* 5 = Acknowledge but not finished (no error)
* 6 = Slave Busy
* 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 Receive16BitRegister(uint16_t *value);
uint8_t Receive32BitRegister(float *value);
uint8_t ReceiveCount(void) { return mb_len; }
private:
uint8_t mb_address;
uint8_t mb_len;
};
#endif // TasmotaModbus_h