mirror of https://github.com/arendst/Tasmota.git
Merge branch 'arendst:development' into bp1658cj
This commit is contained in:
commit
a600403d65
|
@ -12,6 +12,7 @@ All notable changes to this project will be documented in this file.
|
||||||
- ESP32 Support for DMX ArtNet Led matrix animations (#16984)
|
- ESP32 Support for DMX ArtNet Led matrix animations (#16984)
|
||||||
- Command ``SetOption47 1..255`` to delay power on relay state in seconds reducing power surge. ``SO47 1`` delays until network connected. ``SO47 2`` delays until mqtt connected
|
- Command ``SetOption47 1..255`` to delay power on relay state in seconds reducing power surge. ``SO47 1`` delays until network connected. ``SO47 2`` delays until mqtt connected
|
||||||
- ESP32 DMX ArtNet optimization to avoid any object allocation and avoid garbage collector pauses
|
- ESP32 DMX ArtNet optimization to avoid any object allocation and avoid garbage collector pauses
|
||||||
|
- Berry add ``dyn`` class
|
||||||
|
|
||||||
### Breaking Changed
|
### Breaking Changed
|
||||||
|
|
||||||
|
@ -23,6 +24,7 @@ All notable changes to this project will be documented in this file.
|
||||||
### Fixed
|
### Fixed
|
||||||
- Deduplicate code and fix %timer n% rule regression from v12.2.0 (#16914)
|
- Deduplicate code and fix %timer n% rule regression from v12.2.0 (#16914)
|
||||||
- Serial initialization for baudrate and config (#16970)
|
- Serial initialization for baudrate and config (#16970)
|
||||||
|
- ModbusBridge buffer overflow (#16979)
|
||||||
|
|
||||||
### Removed
|
### Removed
|
||||||
- Define ``USE_PN532_DATA_RAW`` from NFC reader (#16939)
|
- Define ``USE_PN532_DATA_RAW`` from NFC reader (#16939)
|
||||||
|
|
|
@ -178,6 +178,7 @@ BERRY_LOCAL const bntvmodule* const be_module_table[] = {
|
||||||
NULL /* do not remove */
|
NULL /* do not remove */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
be_extern_native_class(dyn);
|
||||||
be_extern_native_class(tasmota);
|
be_extern_native_class(tasmota);
|
||||||
be_extern_native_class(Trigger);
|
be_extern_native_class(Trigger);
|
||||||
be_extern_native_class(Driver);
|
be_extern_native_class(Driver);
|
||||||
|
@ -228,6 +229,7 @@ be_extern_native_class(int64);
|
||||||
BERRY_LOCAL bclass_array be_class_table = {
|
BERRY_LOCAL bclass_array be_class_table = {
|
||||||
#ifdef TASMOTA
|
#ifdef TASMOTA
|
||||||
/* first list are direct classes */
|
/* first list are direct classes */
|
||||||
|
&be_native_class(dyn),
|
||||||
&be_native_class(tasmota),
|
&be_native_class(tasmota),
|
||||||
&be_native_class(Trigger),
|
&be_native_class(Trigger),
|
||||||
&be_native_class(Driver),
|
&be_native_class(Driver),
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
/********************************************************************
|
||||||
|
* Tasmota dyn class
|
||||||
|
*******************************************************************/
|
||||||
|
#include "solidify/solidified_dyn.h"
|
|
@ -0,0 +1,27 @@
|
||||||
|
#################################################################################
|
||||||
|
# dyn class
|
||||||
|
#
|
||||||
|
# Allows to use a map with members
|
||||||
|
# see https://github.com/berry-lang/berry/wiki/Chapter-8
|
||||||
|
#################################################################################
|
||||||
|
#@ solidify:dyn
|
||||||
|
class dyn
|
||||||
|
var _attr
|
||||||
|
def init()
|
||||||
|
self._attr = {}
|
||||||
|
end
|
||||||
|
def setmember(name, value)
|
||||||
|
self._attr[name] = value
|
||||||
|
end
|
||||||
|
def member(name)
|
||||||
|
if self._attr.contains(name)
|
||||||
|
return self._attr[name]
|
||||||
|
else
|
||||||
|
import undefined
|
||||||
|
return undefined
|
||||||
|
end
|
||||||
|
end
|
||||||
|
def tostring()
|
||||||
|
return self._attr.tostring()
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,157 @@
|
||||||
|
/* Solidification of dyn.h */
|
||||||
|
/********************************************************************\
|
||||||
|
* Generated code, don't edit *
|
||||||
|
\********************************************************************/
|
||||||
|
#include "be_constobj.h"
|
||||||
|
|
||||||
|
/********************************************************************
|
||||||
|
** Solidified function: tostring
|
||||||
|
********************************************************************/
|
||||||
|
be_local_closure(dyn_tostring, /* name */
|
||||||
|
be_nested_proto(
|
||||||
|
3, /* nstack */
|
||||||
|
1, /* argc */
|
||||||
|
2, /* varg */
|
||||||
|
0, /* has upvals */
|
||||||
|
NULL, /* no upvals */
|
||||||
|
0, /* has sup protos */
|
||||||
|
NULL, /* no sub protos */
|
||||||
|
1, /* has constants */
|
||||||
|
( &(const bvalue[ 2]) { /* constants */
|
||||||
|
/* K0 */ be_nested_str(_attr),
|
||||||
|
/* K1 */ be_nested_str(tostring),
|
||||||
|
}),
|
||||||
|
&be_const_str_tostring,
|
||||||
|
&be_const_str_solidified,
|
||||||
|
( &(const binstruction[ 4]) { /* code */
|
||||||
|
0x88040100, // 0000 GETMBR R1 R0 K0
|
||||||
|
0x8C040301, // 0001 GETMET R1 R1 K1
|
||||||
|
0x7C040200, // 0002 CALL R1 1
|
||||||
|
0x80040200, // 0003 RET 1 R1
|
||||||
|
})
|
||||||
|
)
|
||||||
|
);
|
||||||
|
/*******************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/********************************************************************
|
||||||
|
** Solidified function: member
|
||||||
|
********************************************************************/
|
||||||
|
be_local_closure(dyn_member, /* name */
|
||||||
|
be_nested_proto(
|
||||||
|
5, /* nstack */
|
||||||
|
2, /* argc */
|
||||||
|
2, /* varg */
|
||||||
|
0, /* has upvals */
|
||||||
|
NULL, /* no upvals */
|
||||||
|
0, /* has sup protos */
|
||||||
|
NULL, /* no sub protos */
|
||||||
|
1, /* has constants */
|
||||||
|
( &(const bvalue[ 3]) { /* constants */
|
||||||
|
/* K0 */ be_nested_str(_attr),
|
||||||
|
/* K1 */ be_nested_str(contains),
|
||||||
|
/* K2 */ be_nested_str(undefined),
|
||||||
|
}),
|
||||||
|
&be_const_str_member,
|
||||||
|
&be_const_str_solidified,
|
||||||
|
( &(const binstruction[12]) { /* code */
|
||||||
|
0x88080100, // 0000 GETMBR R2 R0 K0
|
||||||
|
0x8C080501, // 0001 GETMET R2 R2 K1
|
||||||
|
0x5C100200, // 0002 MOVE R4 R1
|
||||||
|
0x7C080400, // 0003 CALL R2 2
|
||||||
|
0x780A0003, // 0004 JMPF R2 #0009
|
||||||
|
0x88080100, // 0005 GETMBR R2 R0 K0
|
||||||
|
0x94080401, // 0006 GETIDX R2 R2 R1
|
||||||
|
0x80040400, // 0007 RET 1 R2
|
||||||
|
0x70020001, // 0008 JMP #000B
|
||||||
|
0xA40A0400, // 0009 IMPORT R2 K2
|
||||||
|
0x80040400, // 000A RET 1 R2
|
||||||
|
0x80000000, // 000B RET 0
|
||||||
|
})
|
||||||
|
)
|
||||||
|
);
|
||||||
|
/*******************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/********************************************************************
|
||||||
|
** Solidified function: setmember
|
||||||
|
********************************************************************/
|
||||||
|
be_local_closure(dyn_setmember, /* name */
|
||||||
|
be_nested_proto(
|
||||||
|
4, /* nstack */
|
||||||
|
3, /* argc */
|
||||||
|
2, /* varg */
|
||||||
|
0, /* has upvals */
|
||||||
|
NULL, /* no upvals */
|
||||||
|
0, /* has sup protos */
|
||||||
|
NULL, /* no sub protos */
|
||||||
|
1, /* has constants */
|
||||||
|
( &(const bvalue[ 1]) { /* constants */
|
||||||
|
/* K0 */ be_nested_str(_attr),
|
||||||
|
}),
|
||||||
|
&be_const_str_setmember,
|
||||||
|
&be_const_str_solidified,
|
||||||
|
( &(const binstruction[ 3]) { /* code */
|
||||||
|
0x880C0100, // 0000 GETMBR R3 R0 K0
|
||||||
|
0x980C0202, // 0001 SETIDX R3 R1 R2
|
||||||
|
0x80000000, // 0002 RET 0
|
||||||
|
})
|
||||||
|
)
|
||||||
|
);
|
||||||
|
/*******************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/********************************************************************
|
||||||
|
** Solidified function: init
|
||||||
|
********************************************************************/
|
||||||
|
be_local_closure(dyn_init, /* name */
|
||||||
|
be_nested_proto(
|
||||||
|
2, /* nstack */
|
||||||
|
1, /* argc */
|
||||||
|
2, /* varg */
|
||||||
|
0, /* has upvals */
|
||||||
|
NULL, /* no upvals */
|
||||||
|
0, /* has sup protos */
|
||||||
|
NULL, /* no sub protos */
|
||||||
|
1, /* has constants */
|
||||||
|
( &(const bvalue[ 1]) { /* constants */
|
||||||
|
/* K0 */ be_nested_str(_attr),
|
||||||
|
}),
|
||||||
|
&be_const_str_init,
|
||||||
|
&be_const_str_solidified,
|
||||||
|
( &(const binstruction[ 4]) { /* code */
|
||||||
|
0x60040013, // 0000 GETGBL R1 G19
|
||||||
|
0x7C040000, // 0001 CALL R1 0
|
||||||
|
0x90020001, // 0002 SETMBR R0 K0 R1
|
||||||
|
0x80000000, // 0003 RET 0
|
||||||
|
})
|
||||||
|
)
|
||||||
|
);
|
||||||
|
/*******************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/********************************************************************
|
||||||
|
** Solidified class: dyn
|
||||||
|
********************************************************************/
|
||||||
|
be_local_class(dyn,
|
||||||
|
1,
|
||||||
|
NULL,
|
||||||
|
be_nested_map(5,
|
||||||
|
( (struct bmapnode*) &(const bmapnode[]) {
|
||||||
|
{ be_const_key(tostring, 2), be_const_closure(dyn_tostring_closure) },
|
||||||
|
{ be_const_key(member, 3), be_const_closure(dyn_member_closure) },
|
||||||
|
{ be_const_key(init, 4), be_const_closure(dyn_init_closure) },
|
||||||
|
{ be_const_key(setmember, -1), be_const_closure(dyn_setmember_closure) },
|
||||||
|
{ be_const_key(_attr, -1), be_const_var(0) },
|
||||||
|
})),
|
||||||
|
(bstring*) &be_const_str_dyn
|
||||||
|
);
|
||||||
|
/*******************************************************************/
|
||||||
|
|
||||||
|
void be_load_dyn_class(bvm *vm) {
|
||||||
|
be_pushntvclass(vm, &be_class_dyn);
|
||||||
|
be_setglobal(vm, "dyn");
|
||||||
|
be_pop(vm, 1);
|
||||||
|
}
|
||||||
|
/********************************************************************/
|
||||||
|
/* End of solidification */
|
|
@ -0,0 +1,190 @@
|
||||||
|
#-
|
||||||
|
Simplified Tasmota TM1637 driver written in Berry
|
||||||
|
Might be helpful in the case of using multiple displays
|
||||||
|
Supports only the 4 digit basic display
|
||||||
|
|
||||||
|
DIO_PIN and CLK_PIN are your esp32 pin numbers
|
||||||
|
How to use
|
||||||
|
|
||||||
|
> load('tm1637')
|
||||||
|
> tm = Tm1637(DIO_PIN, CLK_PIN)
|
||||||
|
> tm.set_on(4)
|
||||||
|
> tm.print('0123')
|
||||||
|
> tm.print(456)
|
||||||
|
|
||||||
|
Add custom commands to the native Tasmota console:
|
||||||
|
> tm_add_custom_commands(DIO_PIN, CLK_PIN)
|
||||||
|
|
||||||
|
And then:
|
||||||
|
TmBrightness 2
|
||||||
|
TmPrint 0123
|
||||||
|
TmPrint -5.67
|
||||||
|
|
||||||
|
Note: adding these commands to autoexec.be should be performed via creating an additional .be file with the content:
|
||||||
|
tm_add_custom_commands(DIO_PIN, CLK_PIN)
|
||||||
|
|
||||||
|
and then loading it in autoexec.be via load('tm1637') and load('script_name')
|
||||||
|
The direct addition may not work
|
||||||
|
-#
|
||||||
|
|
||||||
|
class Tm1637
|
||||||
|
static var CMD_CTRL = 0x80
|
||||||
|
static var CMD_DISP_ON = 0x08
|
||||||
|
static var CMD_DATA = 0x40
|
||||||
|
static var CMD_ADDR = 0xC0
|
||||||
|
|
||||||
|
static var SYMB_DOT = 0x80
|
||||||
|
|
||||||
|
static var DIGIT_MAP = {
|
||||||
|
'0': 0x3F,
|
||||||
|
'1': 0x06,
|
||||||
|
'2': 0x5B,
|
||||||
|
'3': 0x4F,
|
||||||
|
'4': 0x66,
|
||||||
|
'5': 0x6D,
|
||||||
|
'6': 0x7D,
|
||||||
|
'7': 0x07,
|
||||||
|
'8': 0x7F,
|
||||||
|
'9': 0x6F,
|
||||||
|
'-': 0x40,
|
||||||
|
' ': 0x00
|
||||||
|
}
|
||||||
|
|
||||||
|
var PIN_DIO
|
||||||
|
var PIN_CLK
|
||||||
|
|
||||||
|
def init(dio, clk)
|
||||||
|
self.PIN_DIO = dio
|
||||||
|
self.PIN_CLK = clk
|
||||||
|
gpio.pin_mode(self.PIN_DIO, gpio.OUTPUT)
|
||||||
|
gpio.pin_mode(self.PIN_CLK, gpio.OUTPUT)
|
||||||
|
gpio.digital_write(self.PIN_DIO, 1)
|
||||||
|
gpio.digital_write(self.PIN_CLK, 1)
|
||||||
|
end
|
||||||
|
|
||||||
|
def start()
|
||||||
|
gpio.digital_write(self.PIN_DIO, 1)
|
||||||
|
gpio.digital_write(self.PIN_CLK, 1)
|
||||||
|
gpio.digital_write(self.PIN_DIO, 0)
|
||||||
|
end
|
||||||
|
|
||||||
|
def stop()
|
||||||
|
gpio.digital_write(self.PIN_CLK, 0)
|
||||||
|
gpio.digital_write(self.PIN_DIO, 0)
|
||||||
|
gpio.digital_write(self.PIN_CLK, 1)
|
||||||
|
gpio.digital_write(self.PIN_DIO, 1)
|
||||||
|
end
|
||||||
|
|
||||||
|
def ack()
|
||||||
|
gpio.digital_write(self.PIN_CLK, 0)
|
||||||
|
gpio.pin_mode(self.PIN_DIO, gpio.INPUT_PULLUP)
|
||||||
|
var ack_state = gpio.digital_read(self.PIN_DIO) == 0
|
||||||
|
gpio.digital_write(self.PIN_CLK, 1)
|
||||||
|
gpio.digital_write(self.PIN_CLK, 0)
|
||||||
|
gpio.pin_mode(self.PIN_DIO, gpio.OUTPUT)
|
||||||
|
return ack_state
|
||||||
|
end
|
||||||
|
|
||||||
|
def write_bit(bitval)
|
||||||
|
gpio.digital_write(self.PIN_CLK, 0)
|
||||||
|
gpio.digital_write(self.PIN_DIO, bitval)
|
||||||
|
gpio.digital_write(self.PIN_CLK, 1)
|
||||||
|
end
|
||||||
|
|
||||||
|
def write_byte(byteval)
|
||||||
|
for pos: 0..7
|
||||||
|
self.write_bit((byteval >> pos) & 0x01)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def send_command(command)
|
||||||
|
self.start()
|
||||||
|
self.write_byte(command)
|
||||||
|
var ack_state = self.ack()
|
||||||
|
self.stop()
|
||||||
|
return ack_state
|
||||||
|
end
|
||||||
|
|
||||||
|
def send_data(data)
|
||||||
|
var ack_state = true
|
||||||
|
self.start()
|
||||||
|
for i : 0..size(data)-1
|
||||||
|
self.write_byte(data[i])
|
||||||
|
ack_state = self.ack() && ack_state
|
||||||
|
end
|
||||||
|
self.stop()
|
||||||
|
return ack_state
|
||||||
|
end
|
||||||
|
|
||||||
|
# 0-8 range, 0 to 'OFF'
|
||||||
|
def set_on(brightness)
|
||||||
|
if brightness == nil || brightness > 8
|
||||||
|
brightness = 8
|
||||||
|
elif brightness < 0
|
||||||
|
brightness = 0
|
||||||
|
end
|
||||||
|
var cmd = self.CMD_CTRL
|
||||||
|
if brightness
|
||||||
|
cmd |= self.CMD_DISP_ON
|
||||||
|
brightness -= 1
|
||||||
|
end
|
||||||
|
return self.send_command(cmd | brightness)
|
||||||
|
end
|
||||||
|
|
||||||
|
def print(num)
|
||||||
|
import string
|
||||||
|
|
||||||
|
num = str(num)
|
||||||
|
var max_str_len = 4
|
||||||
|
|
||||||
|
do
|
||||||
|
var dot_pos = string.find(num, '.')
|
||||||
|
if dot_pos >= 0 && dot_pos < 5
|
||||||
|
max_str_len = 5
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if size(num) > max_str_len
|
||||||
|
num = string.split(num, max_str_len)[0]
|
||||||
|
end
|
||||||
|
num = string.format('%4s', num)
|
||||||
|
var payload = bytes(-5)
|
||||||
|
payload[0] = self.CMD_ADDR
|
||||||
|
var int_offset = 1
|
||||||
|
for i : 0..size(num)-1
|
||||||
|
if num[i] == '.'
|
||||||
|
payload[i] |= self.SYMB_DOT
|
||||||
|
int_offset = 0
|
||||||
|
else
|
||||||
|
payload[i + int_offset] = self.DIGIT_MAP[num[i]]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
var ack_state = self.send_command(self.CMD_DATA) && self.send_data(payload)
|
||||||
|
if !ack_state
|
||||||
|
log('TM1637 - no ACK, please check connections')
|
||||||
|
end
|
||||||
|
return ack_state
|
||||||
|
end
|
||||||
|
|
||||||
|
def clear()
|
||||||
|
self.print(' ')
|
||||||
|
end
|
||||||
|
|
||||||
|
# Won't be called on the system restart
|
||||||
|
def deinit()
|
||||||
|
self.set_on(0)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def tm_add_custom_commands(dio, clk)
|
||||||
|
var tm = Tm1637(dio, clk)
|
||||||
|
tm.clear()
|
||||||
|
tm.set_on(4)
|
||||||
|
tasmota.add_cmd('tmprint', def(cmd, idx, payload)
|
||||||
|
tm.print(payload) ? tasmota.resp_cmnd_done() : tasmota.resp_cmnd_failed()
|
||||||
|
end)
|
||||||
|
# 0-8 range, 0 to 'OFF'
|
||||||
|
tasmota.add_cmd('tmbrightness', def(cmd, idx, payload)
|
||||||
|
tm.set_on(int(payload)) ? tasmota.resp_cmnd_done() : tasmota.resp_cmnd_failed()
|
||||||
|
end)
|
||||||
|
log("Tasmota custom commands registered: TmPrint, TmBrightness")
|
||||||
|
end
|
|
@ -35,10 +35,10 @@
|
||||||
*
|
*
|
||||||
* -- Write multiple coils --
|
* -- Write multiple coils --
|
||||||
* ModbusSend {"deviceaddress": 1, "functioncode": 15, "startaddress": 1, "type":"bit", "count":4, "values":[1,0,1,1]}
|
* ModbusSend {"deviceaddress": 1, "functioncode": 15, "startaddress": 1, "type":"bit", "count":4, "values":[1,0,1,1]}
|
||||||
*
|
*
|
||||||
* Info for modbusBridgeTCPServer:
|
* Info for modbusBridgeTCPServer:
|
||||||
* https://ipc2u.com/articles/knowledge-base/detailed-description-of-the-modbus-tcp-protocol-with-command-examples/
|
* https://ipc2u.com/articles/knowledge-base/detailed-description-of-the-modbus-tcp-protocol-with-command-examples/
|
||||||
*
|
*
|
||||||
* Info for modbus serial communications:
|
* Info for modbus serial communications:
|
||||||
* https://ozeki.hu/p_5879-mobdbus-function-code-4-read-input-registers.html
|
* https://ozeki.hu/p_5879-mobdbus-function-code-4-read-input-registers.html
|
||||||
* https://www.modbustools.com/modbus.html
|
* https://www.modbustools.com/modbus.html
|
||||||
|
@ -102,7 +102,7 @@ ModbusBridgeTCP modbusBridgeTCP;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <TasmotaModbus.h>
|
#include <TasmotaModbus.h>
|
||||||
TasmotaModbus *tasmotaModbus = nullptr;
|
TasmotaModbus *modbusBridgeModbus = nullptr;
|
||||||
|
|
||||||
enum class ModbusBridgeError
|
enum class ModbusBridgeError
|
||||||
{
|
{
|
||||||
|
@ -172,22 +172,18 @@ ModbusBridge modbusBridge;
|
||||||
|
|
||||||
/********************************************************************************************/
|
/********************************************************************************************/
|
||||||
//
|
//
|
||||||
// Helper functions for data conversion between little and big endian
|
// Helper functions
|
||||||
//
|
//
|
||||||
uint16_t swap_endian16(uint16_t num)
|
uint16_t ModbusBridgeSwapEndian16(uint16_t num)
|
||||||
{
|
{
|
||||||
return (num>>8) | (num<<8);
|
return (num>>8) | (num<<8);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t swap_endian32(uint32_t num)
|
void ModbusBridgeAllocError(const char* s)
|
||||||
{
|
{
|
||||||
return ((num>>24)&0xff) | // move byte 3 to byte 0
|
AddLog(LOG_LEVEL_ERROR, PSTR("MBS: could not allocate %s buffer"), s);
|
||||||
((num<<8)&0xff0000) | // move byte 1 to byte 2
|
|
||||||
((num>>8)&0xff00) | // move byte 2 to byte 1
|
|
||||||
((num<<24)&0xff000000); // byte 0 to byte 3
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/********************************************************************************************/
|
/********************************************************************************************/
|
||||||
//
|
//
|
||||||
// Applies serial configuration to modbus serial port
|
// Applies serial configuration to modbus serial port
|
||||||
|
@ -199,7 +195,7 @@ bool ModbusBridgeBegin(void)
|
||||||
if (Settings->modbus_sconfig > TS_SERIAL_8O2)
|
if (Settings->modbus_sconfig > TS_SERIAL_8O2)
|
||||||
Settings->modbus_sconfig = TS_SERIAL_8N1;
|
Settings->modbus_sconfig = TS_SERIAL_8N1;
|
||||||
|
|
||||||
int result = tasmotaModbus->Begin(Settings->modbus_sbaudrate * 300, ConvertSerialConfig(Settings->modbus_sconfig)); // Reinitialize modbus port with new baud rate
|
int result = modbusBridgeModbus->Begin(Settings->modbus_sbaudrate * 300, ConvertSerialConfig(Settings->modbus_sconfig)); // Reinitialize modbus port with new baud rate
|
||||||
if (result)
|
if (result)
|
||||||
{
|
{
|
||||||
if (2 == result)
|
if (2 == result)
|
||||||
|
@ -211,7 +207,7 @@ bool ModbusBridgeBegin(void)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetModbusBridgeConfig(uint32_t serial_config)
|
void ModbusBridgeSetConfig(uint32_t serial_config)
|
||||||
{
|
{
|
||||||
if (serial_config > TS_SERIAL_8O2)
|
if (serial_config > TS_SERIAL_8O2)
|
||||||
{
|
{
|
||||||
|
@ -224,7 +220,7 @@ void SetModbusBridgeConfig(uint32_t serial_config)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetModbusBridgeBaudrate(uint32_t baudrate)
|
void ModbusBridgeSetBaudrate(uint32_t baudrate)
|
||||||
{
|
{
|
||||||
if ((baudrate >= 300) && (baudrate <= 115200))
|
if ((baudrate >= 300) && (baudrate <= 115200))
|
||||||
{
|
{
|
||||||
|
@ -242,14 +238,19 @@ void SetModbusBridgeBaudrate(uint32_t baudrate)
|
||||||
//
|
//
|
||||||
void ModbusBridgeHandle(void)
|
void ModbusBridgeHandle(void)
|
||||||
{
|
{
|
||||||
bool data_ready = tasmotaModbus->ReceiveReady();
|
bool data_ready = modbusBridgeModbus->ReceiveReady();
|
||||||
if (data_ready)
|
if (data_ready)
|
||||||
{
|
{
|
||||||
uint8_t *buffer;
|
uint8_t *buffer;
|
||||||
if (modbusBridge.byteCount == 0) modbusBridge.byteCount = modbusBridge.dataCount * 2;
|
if (modbusBridge.byteCount == 0) modbusBridge.byteCount = modbusBridge.dataCount * 2;
|
||||||
buffer = (uint8_t *)malloc(9 + modbusBridge.byteCount); // Addres(1), Function(1), Length(1), Data(1..n), CRC(2)
|
buffer = (uint8_t *)malloc(9 + modbusBridge.byteCount); // Addres(1), Function(1), Length(1), Data(1..n), CRC(2)
|
||||||
|
if (nullptr == buffer)
|
||||||
|
{
|
||||||
|
ModbusBridgeAllocError(PSTR("read"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
memset(buffer, 0, 9 + modbusBridge.byteCount);
|
memset(buffer, 0, 9 + modbusBridge.byteCount);
|
||||||
uint32_t error = tasmotaModbus->ReceiveBuffer(buffer, 0, modbusBridge.byteCount);
|
uint32_t error = modbusBridgeModbus->ReceiveBuffer(buffer, 0, modbusBridge.byteCount);
|
||||||
|
|
||||||
#ifdef USE_MODBUS_BRIDGE_TCP
|
#ifdef USE_MODBUS_BRIDGE_TCP
|
||||||
for (uint32_t i = 0; i < nitems(modbusBridgeTCP.client_tcp); i++)
|
for (uint32_t i = 0; i < nitems(modbusBridgeTCP.client_tcp); i++)
|
||||||
|
@ -257,7 +258,7 @@ void ModbusBridgeHandle(void)
|
||||||
WiFiClient &client = modbusBridgeTCP.client_tcp[i];
|
WiFiClient &client = modbusBridgeTCP.client_tcp[i];
|
||||||
if (client)
|
if (client)
|
||||||
{
|
{
|
||||||
uint8_t header[8];
|
uint8_t header[9];
|
||||||
uint8_t nrOfBytes = 8;
|
uint8_t nrOfBytes = 8;
|
||||||
header[0] = modbusBridgeTCP.tcp_transaction_id >> 8;
|
header[0] = modbusBridgeTCP.tcp_transaction_id >> 8;
|
||||||
header[1] = modbusBridgeTCP.tcp_transaction_id;
|
header[1] = modbusBridgeTCP.tcp_transaction_id;
|
||||||
|
@ -274,7 +275,7 @@ void ModbusBridgeHandle(void)
|
||||||
nrOfBytes += 1;
|
nrOfBytes += 1;
|
||||||
client.write(header, 9);
|
client.write(header, 9);
|
||||||
}
|
}
|
||||||
else if (buffer[1] <= 2)
|
else if (buffer[1] <= 2)
|
||||||
{
|
{
|
||||||
header[4] = modbusBridge.byteCount >> 8;
|
header[4] = modbusBridge.byteCount >> 8;
|
||||||
header[5] = modbusBridge.byteCount + 3;
|
header[5] = modbusBridge.byteCount + 3;
|
||||||
|
@ -284,7 +285,7 @@ void ModbusBridgeHandle(void)
|
||||||
client.write(buffer + 3, modbusBridge.byteCount); // Don't send CRC
|
client.write(buffer + 3, modbusBridge.byteCount); // Don't send CRC
|
||||||
nrOfBytes += modbusBridge.byteCount;
|
nrOfBytes += modbusBridge.byteCount;
|
||||||
}
|
}
|
||||||
else if (buffer[1] <= 4)
|
else if (buffer[1] <= 4)
|
||||||
{
|
{
|
||||||
header[4] = modbusBridge.byteCount >> 8;
|
header[4] = modbusBridge.byteCount >> 8;
|
||||||
header[5] = modbusBridge.byteCount + 3;
|
header[5] = modbusBridge.byteCount + 3;
|
||||||
|
@ -358,10 +359,10 @@ void ModbusBridgeHandle(void)
|
||||||
if (modbusBridge.type == ModbusBridgeType::mb_raw)
|
if (modbusBridge.type == ModbusBridgeType::mb_raw)
|
||||||
{
|
{
|
||||||
Response_P(PSTR("{\"" D_JSON_MODBUS_RECEIVED "\":{\"RAW\":["));
|
Response_P(PSTR("{\"" D_JSON_MODBUS_RECEIVED "\":{\"RAW\":["));
|
||||||
for (uint8_t i = 0; i < tasmotaModbus->ReceiveCount(); i++)
|
for (uint8_t i = 0; i < modbusBridgeModbus->ReceiveCount(); i++)
|
||||||
{
|
{
|
||||||
ResponseAppend_P(PSTR("%d"), buffer[i]);
|
ResponseAppend_P(PSTR("%d"), buffer[i]);
|
||||||
if (i < tasmotaModbus->ReceiveCount() - 1)
|
if (i < modbusBridgeModbus->ReceiveCount() - 1)
|
||||||
ResponseAppend_P(PSTR(","));
|
ResponseAppend_P(PSTR(","));
|
||||||
}
|
}
|
||||||
ResponseAppend_P(PSTR("]}"));
|
ResponseAppend_P(PSTR("]}"));
|
||||||
|
@ -371,10 +372,10 @@ void ModbusBridgeHandle(void)
|
||||||
else if (modbusBridge.type == ModbusBridgeType::mb_hex)
|
else if (modbusBridge.type == ModbusBridgeType::mb_hex)
|
||||||
{
|
{
|
||||||
Response_P(PSTR("{\"" D_JSON_MODBUS_RECEIVED "\":{\"HEX\":["));
|
Response_P(PSTR("{\"" D_JSON_MODBUS_RECEIVED "\":{\"HEX\":["));
|
||||||
for (uint8_t i = 0; i < tasmotaModbus->ReceiveCount(); i++)
|
for (uint8_t i = 0; i < modbusBridgeModbus->ReceiveCount(); i++)
|
||||||
{
|
{
|
||||||
ResponseAppend_P(PSTR("0x%02X"), buffer[i]);
|
ResponseAppend_P(PSTR("0x%02X"), buffer[i]);
|
||||||
if (i < tasmotaModbus->ReceiveCount() - 1)
|
if (i < modbusBridgeModbus->ReceiveCount() - 1)
|
||||||
ResponseAppend_P(PSTR(","));
|
ResponseAppend_P(PSTR(","));
|
||||||
}
|
}
|
||||||
ResponseAppend_P(PSTR("]}"));
|
ResponseAppend_P(PSTR("]}"));
|
||||||
|
@ -396,7 +397,7 @@ void ModbusBridgeHandle(void)
|
||||||
ResponseAppend_P(PSTR("\"" D_JSON_MODBUS_START_ADDRESS "\":%d,"), (buffer[2] << 8) + buffer[3]);
|
ResponseAppend_P(PSTR("\"" D_JSON_MODBUS_START_ADDRESS "\":%d,"), (buffer[2] << 8) + buffer[3]);
|
||||||
dataOffset = 4;
|
dataOffset = 4;
|
||||||
}
|
}
|
||||||
ResponseAppend_P(PSTR("\"" D_JSON_MODBUS_LENGTH "\":%d,"), tasmotaModbus->ReceiveCount());
|
ResponseAppend_P(PSTR("\"" D_JSON_MODBUS_LENGTH "\":%d,"), modbusBridgeModbus->ReceiveCount());
|
||||||
ResponseAppend_P(PSTR("\"" D_JSON_MODBUS_COUNT "\":%d,"), modbusBridge.count);
|
ResponseAppend_P(PSTR("\"" D_JSON_MODBUS_COUNT "\":%d,"), modbusBridge.count);
|
||||||
ResponseAppend_P(PSTR("\"" D_JSON_MODBUS_VALUES "\":["));
|
ResponseAppend_P(PSTR("\"" D_JSON_MODBUS_VALUES "\":["));
|
||||||
|
|
||||||
|
@ -530,7 +531,7 @@ void ModbusBridgeHandle(void)
|
||||||
ResponseAppend_P(PSTR("\"" D_JSON_MODBUS_DEVICE_ADDRESS "\":%d,"), buffer[0]);
|
ResponseAppend_P(PSTR("\"" D_JSON_MODBUS_DEVICE_ADDRESS "\":%d,"), buffer[0]);
|
||||||
ResponseAppend_P(PSTR("\"" D_JSON_MODBUS_FUNCTION_CODE "\":%d,"), buffer[1]);
|
ResponseAppend_P(PSTR("\"" D_JSON_MODBUS_FUNCTION_CODE "\":%d,"), buffer[1]);
|
||||||
ResponseAppend_P(PSTR("\"" D_JSON_MODBUS_START_ADDRESS "\":%d,"), (buffer[2] << 8) + buffer[3]);
|
ResponseAppend_P(PSTR("\"" D_JSON_MODBUS_START_ADDRESS "\":%d,"), (buffer[2] << 8) + buffer[3]);
|
||||||
ResponseAppend_P(PSTR("\"" D_JSON_MODBUS_LENGTH "\":%d,"), tasmotaModbus->ReceiveCount());
|
ResponseAppend_P(PSTR("\"" D_JSON_MODBUS_LENGTH "\":%d,"), modbusBridgeModbus->ReceiveCount());
|
||||||
ResponseAppend_P(PSTR("\"" D_JSON_MODBUS_COUNT "\":%d"), (buffer[4] << 8) + buffer[5]);
|
ResponseAppend_P(PSTR("\"" D_JSON_MODBUS_COUNT "\":%d"), (buffer[4] << 8) + buffer[5]);
|
||||||
ResponseAppend_P(PSTR("}"));
|
ResponseAppend_P(PSTR("}"));
|
||||||
ResponseJsonEnd();
|
ResponseJsonEnd();
|
||||||
|
@ -557,14 +558,14 @@ void ModbusBridgeInit(void)
|
||||||
{
|
{
|
||||||
if (PinUsed(GPIO_MBR_RX) && PinUsed(GPIO_MBR_TX))
|
if (PinUsed(GPIO_MBR_RX) && PinUsed(GPIO_MBR_TX))
|
||||||
{
|
{
|
||||||
tasmotaModbus = new TasmotaModbus(Pin(GPIO_MBR_RX), Pin(GPIO_MBR_TX));
|
modbusBridgeModbus = new TasmotaModbus(Pin(GPIO_MBR_RX), Pin(GPIO_MBR_TX));
|
||||||
ModbusBridgeBegin();
|
ModbusBridgeBegin();
|
||||||
#ifdef USE_MODBUS_BRIDGE_TCP
|
#ifdef USE_MODBUS_BRIDGE_TCP
|
||||||
// If TCP bridge is enabled allocate a TCP receive buffer
|
// If TCP bridge is enabled allocate a TCP receive buffer
|
||||||
modbusBridgeTCP.tcp_buf = (uint8_t *)malloc(MODBUS_BRIDGE_TCP_BUF_SIZE);
|
modbusBridgeTCP.tcp_buf = (uint8_t *)malloc(MODBUS_BRIDGE_TCP_BUF_SIZE);
|
||||||
if (!modbusBridgeTCP.tcp_buf)
|
if (nullptr == modbusBridgeTCP.tcp_buf)
|
||||||
{
|
{
|
||||||
AddLog(LOG_LEVEL_ERROR, PSTR("MBS: MBRTCP could not allocate buffer"));
|
ModbusBridgeAllocError(PSTR("TCP"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -582,7 +583,7 @@ void ModbusTCPHandle(void)
|
||||||
bool busy; // did we transfer some data?
|
bool busy; // did we transfer some data?
|
||||||
int32_t buf_len;
|
int32_t buf_len;
|
||||||
|
|
||||||
if (!tasmotaModbus)
|
if (!modbusBridgeModbus)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// check for a new client connection
|
// check for a new client connection
|
||||||
|
@ -656,8 +657,8 @@ void ModbusTCPHandle(void)
|
||||||
if (mbfunctioncode <= 2)
|
if (mbfunctioncode <= 2)
|
||||||
{
|
{
|
||||||
count = (uint16_t)((((uint16_t)modbusBridgeTCP.tcp_buf[10]) << 8) | ((uint16_t)modbusBridgeTCP.tcp_buf[11]));
|
count = (uint16_t)((((uint16_t)modbusBridgeTCP.tcp_buf[10]) << 8) | ((uint16_t)modbusBridgeTCP.tcp_buf[11]));
|
||||||
modbusBridge.byteCount = ((count - 1) >> 3) + 1;
|
modbusBridge.byteCount = ((count - 1) >> 3) + 1;
|
||||||
modbusBridge.dataCount = ((count - 1) >> 4) + 1;
|
modbusBridge.dataCount = ((count - 1) >> 4) + 1;
|
||||||
}
|
}
|
||||||
else if (mbfunctioncode <= 4)
|
else if (mbfunctioncode <= 4)
|
||||||
{
|
{
|
||||||
|
@ -667,17 +668,22 @@ void ModbusTCPHandle(void)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// For functioncode 15 & 16 ignore bytecount, tasmotaModbus does calculate this
|
// For functioncode 15 & 16 ignore bytecount, modbusBridgeModbus does calculate this
|
||||||
uint8_t dataStartByte = mbfunctioncode <= 6 ? 10 : 13;
|
uint8_t dataStartByte = mbfunctioncode <= 6 ? 10 : 13;
|
||||||
uint16_t byteCount = (buf_len - dataStartByte);
|
uint16_t byteCount = (buf_len - dataStartByte);
|
||||||
modbusBridge.byteCount = 2;
|
modbusBridge.byteCount = 2;
|
||||||
modbusBridge.dataCount = 1;
|
modbusBridge.dataCount = 1;
|
||||||
|
|
||||||
writeData = (uint16_t *)malloc((byteCount / 2)+1);
|
writeData = (uint16_t *)malloc((byteCount / 2)+1);
|
||||||
|
if (nullptr == writeData)
|
||||||
|
{
|
||||||
|
ModbusBridgeAllocError(PSTR("write"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if ((mbfunctioncode == 15) || (mbfunctioncode == 16)) count = (uint16_t)((((uint16_t)modbusBridgeTCP.tcp_buf[10]) << 8) | ((uint16_t)modbusBridgeTCP.tcp_buf[11]));
|
if ((mbfunctioncode == 15) || (mbfunctioncode == 16)) count = (uint16_t)((((uint16_t)modbusBridgeTCP.tcp_buf[10]) << 8) | ((uint16_t)modbusBridgeTCP.tcp_buf[11]));
|
||||||
else count = 1;
|
else count = 1;
|
||||||
|
|
||||||
for (uint16_t dataPointer = 0; dataPointer < byteCount; dataPointer++)
|
for (uint16_t dataPointer = 0; dataPointer < byteCount; dataPointer++)
|
||||||
{
|
{
|
||||||
if (dataPointer % 2 == 0)
|
if (dataPointer % 2 == 0)
|
||||||
|
@ -685,7 +691,7 @@ void ModbusTCPHandle(void)
|
||||||
writeData[dataPointer / 2] = (uint16_t)(((uint16_t)modbusBridgeTCP.tcp_buf[dataStartByte + dataPointer]) << 8);
|
writeData[dataPointer / 2] = (uint16_t)(((uint16_t)modbusBridgeTCP.tcp_buf[dataStartByte + dataPointer]) << 8);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
writeData[dataPointer / 2] |= ((uint16_t)modbusBridgeTCP.tcp_buf[dataStartByte + dataPointer]);
|
writeData[dataPointer / 2] |= ((uint16_t)modbusBridgeTCP.tcp_buf[dataStartByte + dataPointer]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -694,7 +700,7 @@ void ModbusTCPHandle(void)
|
||||||
AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("MBS: MBRTCP to Modbus TransactionId:%d, deviceAddress:%d, functionCode:%d, startAddress:%d, count:%d, recvCount:%d, recvBytes:%d"),
|
AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("MBS: MBRTCP to Modbus TransactionId:%d, deviceAddress:%d, functionCode:%d, startAddress:%d, count:%d, recvCount:%d, recvBytes:%d"),
|
||||||
modbusBridgeTCP.tcp_transaction_id, mbdeviceaddress, mbfunctioncode, mbstartaddress, count, modbusBridge.dataCount, modbusBridge.byteCount);
|
modbusBridgeTCP.tcp_transaction_id, mbdeviceaddress, mbfunctioncode, mbstartaddress, count, modbusBridge.dataCount, modbusBridge.byteCount);
|
||||||
|
|
||||||
tasmotaModbus->Send(mbdeviceaddress, mbfunctioncode, mbstartaddress, count, writeData);
|
modbusBridgeModbus->Send(mbdeviceaddress, mbfunctioncode, mbstartaddress, count, writeData);
|
||||||
|
|
||||||
free(writeData);
|
free(writeData);
|
||||||
}
|
}
|
||||||
|
@ -860,6 +866,11 @@ void CmndModbusBridgeSend(void)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
writeData = (uint16_t *)malloc(modbusBridge.dataCount);
|
writeData = (uint16_t *)malloc(modbusBridge.dataCount);
|
||||||
|
if (nullptr == writeData)
|
||||||
|
{
|
||||||
|
ModbusBridgeAllocError(PSTR("write"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
for (uint8_t jsonDataArrayPointer = 0; jsonDataArrayPointer < writeDataSize; jsonDataArrayPointer++)
|
for (uint8_t jsonDataArrayPointer = 0; jsonDataArrayPointer < writeDataSize; jsonDataArrayPointer++)
|
||||||
{
|
{
|
||||||
|
@ -889,7 +900,7 @@ void CmndModbusBridgeSend(void)
|
||||||
writeData[jsonDataArrayPointer / 2] = (int8_t)jsonDataArray[jsonDataArrayPointer / 2].getInt(0) << 8;
|
writeData[jsonDataArrayPointer / 2] = (int8_t)jsonDataArray[jsonDataArrayPointer / 2].getInt(0) << 8;
|
||||||
if (modbusBridge.dataCount != writeDataSize / 2) errorcode = ModbusBridgeError::wrongcount;
|
if (modbusBridge.dataCount != writeDataSize / 2) errorcode = ModbusBridgeError::wrongcount;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ModbusBridgeType::mb_hex:
|
case ModbusBridgeType::mb_hex:
|
||||||
case ModbusBridgeType::mb_raw:
|
case ModbusBridgeType::mb_raw:
|
||||||
case ModbusBridgeType::mb_uint8:
|
case ModbusBridgeType::mb_uint8:
|
||||||
|
@ -899,31 +910,31 @@ void CmndModbusBridgeSend(void)
|
||||||
writeData[jsonDataArrayPointer / 2] = (uint8_t)jsonDataArray[jsonDataArrayPointer].getUInt(0) << 8;
|
writeData[jsonDataArrayPointer / 2] = (uint8_t)jsonDataArray[jsonDataArrayPointer].getUInt(0) << 8;
|
||||||
if (modbusBridge.dataCount != writeDataSize / 2) errorcode = ModbusBridgeError::wrongcount;
|
if (modbusBridge.dataCount != writeDataSize / 2) errorcode = ModbusBridgeError::wrongcount;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ModbusBridgeType::mb_int16:
|
case ModbusBridgeType::mb_int16:
|
||||||
writeData[jsonDataArrayPointer] = bitMode ? swap_endian16(jsonDataArray[jsonDataArrayPointer].getInt(0))
|
writeData[jsonDataArrayPointer] = bitMode ? ModbusBridgeSwapEndian16(jsonDataArray[jsonDataArrayPointer].getInt(0))
|
||||||
: (int16_t)jsonDataArray[jsonDataArrayPointer].getInt(0);
|
: (int16_t)jsonDataArray[jsonDataArrayPointer].getInt(0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ModbusBridgeType::mb_uint16:
|
case ModbusBridgeType::mb_uint16:
|
||||||
writeData[jsonDataArrayPointer] = bitMode ? swap_endian16(jsonDataArray[jsonDataArrayPointer].getUInt(0))
|
writeData[jsonDataArrayPointer] = bitMode ? ModbusBridgeSwapEndian16(jsonDataArray[jsonDataArrayPointer].getUInt(0))
|
||||||
: (int16_t)jsonDataArray[jsonDataArrayPointer].getUInt(0);
|
: (int16_t)jsonDataArray[jsonDataArrayPointer].getUInt(0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ModbusBridgeType::mb_int32:
|
case ModbusBridgeType::mb_int32:
|
||||||
writeData[(jsonDataArrayPointer * 2)] = bitMode ? swap_endian16(jsonDataArray[jsonDataArrayPointer].getInt(0))
|
writeData[(jsonDataArrayPointer * 2)] = bitMode ? ModbusBridgeSwapEndian16(jsonDataArray[jsonDataArrayPointer].getInt(0))
|
||||||
: (int16_t)(jsonDataArray[jsonDataArrayPointer].getInt(0) >> 16);
|
: (int16_t)(jsonDataArray[jsonDataArrayPointer].getInt(0) >> 16);
|
||||||
writeData[(jsonDataArrayPointer * 2) + 1] = bitMode ? swap_endian16(jsonDataArray[jsonDataArrayPointer].getInt(0) >> 16)
|
writeData[(jsonDataArrayPointer * 2) + 1] = bitMode ? ModbusBridgeSwapEndian16(jsonDataArray[jsonDataArrayPointer].getInt(0) >> 16)
|
||||||
: (uint16_t)(jsonDataArray[jsonDataArrayPointer].getInt(0));
|
: (uint16_t)(jsonDataArray[jsonDataArrayPointer].getInt(0));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ModbusBridgeType::mb_uint32:
|
case ModbusBridgeType::mb_uint32:
|
||||||
writeData[(jsonDataArrayPointer * 2)] = bitMode ? swap_endian16(jsonDataArray[jsonDataArrayPointer].getUInt(0))
|
writeData[(jsonDataArrayPointer * 2)] = bitMode ? ModbusBridgeSwapEndian16(jsonDataArray[jsonDataArrayPointer].getUInt(0))
|
||||||
: (uint16_t)(jsonDataArray[jsonDataArrayPointer].getUInt(0) >> 16);
|
: (uint16_t)(jsonDataArray[jsonDataArrayPointer].getUInt(0) >> 16);
|
||||||
writeData[(jsonDataArrayPointer * 2) + 1] = bitMode ? swap_endian16(jsonDataArray[jsonDataArrayPointer].getUInt(0) >> 16)
|
writeData[(jsonDataArrayPointer * 2) + 1] = bitMode ? ModbusBridgeSwapEndian16(jsonDataArray[jsonDataArrayPointer].getUInt(0) >> 16)
|
||||||
: (uint16_t)(jsonDataArray[jsonDataArrayPointer].getUInt(0));
|
: (uint16_t)(jsonDataArray[jsonDataArrayPointer].getUInt(0));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ModbusBridgeType::mb_float:
|
case ModbusBridgeType::mb_float:
|
||||||
// TODO
|
// TODO
|
||||||
default:
|
default:
|
||||||
|
@ -952,20 +963,20 @@ void CmndModbusBridgeSend(void)
|
||||||
if ((modbusBridge.functionCode == ModbusBridgeFunctionCode::mb_writeSingleCoil) || (modbusBridge.functionCode == ModbusBridgeFunctionCode::mb_writeSingleRegister))
|
if ((modbusBridge.functionCode == ModbusBridgeFunctionCode::mb_writeSingleCoil) || (modbusBridge.functionCode == ModbusBridgeFunctionCode::mb_writeSingleRegister))
|
||||||
modbusBridge.dataCount = 1;
|
modbusBridge.dataCount = 1;
|
||||||
|
|
||||||
uint8_t error = tasmotaModbus->Send(modbusBridge.deviceAddress, (uint8_t)modbusBridge.functionCode, modbusBridge.startAddress, modbusBridge.dataCount, writeData);
|
uint8_t error = modbusBridgeModbus->Send(modbusBridge.deviceAddress, (uint8_t)modbusBridge.functionCode, modbusBridge.startAddress, modbusBridge.dataCount, writeData);
|
||||||
free(writeData);
|
free(writeData);
|
||||||
|
|
||||||
if (error)
|
if (error)
|
||||||
{
|
{
|
||||||
AddLog(LOG_LEVEL_DEBUG, PSTR("MBS: MBR Driver send error %u"), error);
|
AddLog(LOG_LEVEL_DEBUG, PSTR("MBS: MBR Driver send error %u"), error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ResponseCmndDone();
|
ResponseCmndDone();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CmndModbusBridgeSetBaudrate(void)
|
void CmndModbusBridgeSetBaudrate(void)
|
||||||
{
|
{
|
||||||
SetModbusBridgeBaudrate(XdrvMailbox.payload);
|
ModbusBridgeSetBaudrate(XdrvMailbox.payload);
|
||||||
ResponseCmndNumber(Settings->modbus_sbaudrate * 300);
|
ResponseCmndNumber(Settings->modbus_sbaudrate * 300);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -981,7 +992,7 @@ void CmndModbusBridgeSetConfig(void)
|
||||||
{ // Use 0..23 as serial config option
|
{ // Use 0..23 as serial config option
|
||||||
if ((XdrvMailbox.payload >= TS_SERIAL_5N1) && (XdrvMailbox.payload <= TS_SERIAL_8O2))
|
if ((XdrvMailbox.payload >= TS_SERIAL_5N1) && (XdrvMailbox.payload <= TS_SERIAL_8O2))
|
||||||
{
|
{
|
||||||
SetModbusBridgeConfig(XdrvMailbox.payload);
|
ModbusBridgeSetConfig(XdrvMailbox.payload);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ((XdrvMailbox.payload >= 5) && (XdrvMailbox.payload <= 8))
|
else if ((XdrvMailbox.payload >= 5) && (XdrvMailbox.payload <= 8))
|
||||||
|
@ -989,7 +1000,7 @@ void CmndModbusBridgeSetConfig(void)
|
||||||
int8_t serial_config = ParseSerialConfig(XdrvMailbox.data);
|
int8_t serial_config = ParseSerialConfig(XdrvMailbox.data);
|
||||||
if (serial_config >= 0)
|
if (serial_config >= 0)
|
||||||
{
|
{
|
||||||
SetModbusBridgeConfig(serial_config);
|
ModbusBridgeSetConfig(serial_config);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1004,7 +1015,7 @@ void CmndModbusBridgeSetConfig(void)
|
||||||
void CmndModbusTCPStart(void)
|
void CmndModbusTCPStart(void)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (!tasmotaModbus)
|
if (!modbusBridgeModbus)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1057,7 +1068,7 @@ void CmndModbusTCPConnect(void)
|
||||||
{
|
{
|
||||||
int32_t tcp_port = XdrvMailbox.payload;
|
int32_t tcp_port = XdrvMailbox.payload;
|
||||||
|
|
||||||
if (!tasmotaModbus)
|
if (!modbusBridgeModbus)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1116,7 +1127,7 @@ bool Xdrv63(uint8_t function)
|
||||||
{
|
{
|
||||||
ModbusBridgeInit();
|
ModbusBridgeInit();
|
||||||
}
|
}
|
||||||
else if (tasmotaModbus)
|
else if (modbusBridgeModbus)
|
||||||
{
|
{
|
||||||
switch (function)
|
switch (function)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue