Hi there,
can someone help me how to correctly convert the payload of a ModbusTCP return? I need the value in watts. Currently, a value of 65123 (from register 1066) or similar comes from the register. Unit is UNIT16.
Another register (2066) contains -> active power = (value in # 1066) * 10 ^ (value in # 2066) - which is a multiplication by a power of ten, right? But no idea how I do it ...
Modbus returns "0" from 2066.
What do I have to enter in a function node for the conversion?
try the Javascript function Math.pow()
let value = 65123; // replace with value from register 1066
let exponent = 0; // replace with value from register 2066
let activePower = value * Math.pow(10, exponent);
msg.payload = activePower;
return msg
Hi, thx - but this isnt it.
Return is 65123 ... as number
I have a tcl script that does the job - I can't use it in node red, can I?
package provide modbus 1.0
namespace eval ::modbus {
variable Priv
array set Priv [list \
sn 0x1234 \
-mode "TCP" \
-ip "127.168.178.8" \
-port "502" \
-com "/dev/ttyUSB0" \
-settings "9600,n,8,1" \
-timeout 2 \
]
}
proc ::modbus::configure {args} {
variable Priv
set names [lsort [array names Priv -*]]
foreach {opt val} $args {
if {[lsearch $names $opt] < 0} {
puts "bad option \"$opt\": must be $names"
exit
}
set Priv($opt) $val
}
}
proc ::modbus::asc2bin {args} {
# ex. asc2bin 0x02 0x01 0x00 0x00 0x01 0x01 0x03
set ret ""
foreach c $args {
append ret [binary format c $c]
}
return $ret
}
proc ::modbus::bin2asc {data} {
set len [string length $data]
set str ""
for {set i 0} {$i<$len} {incr i} {
binary scan [string index $data $i] c ch
if {$ch < 0} {incr ch 256}
lappend str [format %02X $ch]
}
return $str
}
proc ::modbus::debug {data} {
puts [::modbus::bin2asc $data]
}
proc ::modbus::cmd {fun args} {
variable Priv
set fun [string range 00[expr $fun] end-1 end]
foreach {reqCmd rspLen} [eval ::modbus::cmd${fun}_pack $args] break
set mode [string tolower $Priv(-mode)]
foreach {reqCmd rspLen} [::modbus::pack_$mode $reqCmd $rspLen ] break
::modbus::port_open
set rspCmd [::modbus::port_send $reqCmd $rspLen]
::modbus::port_close
set rspCmd [::modbus::unpack_$mode $reqCmd $rspCmd]
if {$rspCmd == ""} {return ""}
if {$mode == "tcp"} {set reqCmd [string range $reqCmd 6 end]}
return [::modbus::cmd${fun}_unpack $reqCmd $rspCmd]
}
proc ::modbus::cmd03_pack {sta addr len} {
# function : read holding registers
# station : 1 byte
# function : 1 byte (always 0x03)
# addr : 2 bytes
# read len : 2 bytes (how much registers)
# response
#station : 1 byte
#function : 1 byte (always 0x03)
#byte count : 1 byte
#data : N*2 bytes (reg1_low...reg1_hi...reg2_low...reg2_hi...)
# 1+1+1+2*len
# sta=>1 fun=>1 dlen=>1
# return [list [binary format ccSS $sta 0x03 $addr $len] [expr 1+1+1+2*$len]]
return [list [binary format ccSS $sta 0x03 $addr $len] [expr 1+1+1+2*$len]]
}
sorry i have no idea how tcl scripts work or how to use them in node-red
(i was under the impression that you had them in NR already)
you cant use some Modbus nodes to get the values from you device ?