TRB245 Modbus RTU registers

Hello,

Im reading modbus registers from Lumel 92RE (as slave) by TRB245(master) via modbus RTU.
The read register no. 4005 is 16bit integer number.
I would like to send an sms alarm triggered by change in 7th bit of this register (0 or 1).

Please help me.

Hello,

Currently, it is not possible to trigger alarms on specific bits within a single register.

However, you should be able to achieve this via some additional scripting. This would involve writing a script that periodically requests data from your Modbus slave using crontab. It would then extract the 7th bit from the received data and compare its value. Depending on the outcome of this comparison, the script can then send an SMS message.

Here’s an example:

#!/bin/sh

# Read modbus register and get 7th bit

modbus_output=$(ubus call modbus_master tcp.test '{"ip":"127.0.0.1","port":502,"id":1,"timeout":1,"function":3,"first_reg":8,"reg_count":"1","data_type":"16bit_int_hi_first","no_brackets":1}' | jq -r .result)

bit_val=$(echo "$modbus_output 64" | awk '{ printf ("%d", and($1,$2)) }')

# If 7th bit is 1

if [ $bit_val -eq 64 ]; then

# Send SMS if 7th bit is 1

logger $bit_val

logger "sending SMS!"

gsmctl -S -s "0037000000 Modbus triggered!"

fi

Note: jq is used in this script. To install jq, exucute:

  • opkg update
  • opkg install jq

Then, you can add this script to crontab to execute periodically. If you are unfamiliar with crontab, you can take a look at an example here.

EDIT:

Did not notice that you are using Modbus RTU. You may want to use the ‘serial.test’ ubus command instead of ‘tcp.test’. Just fill in the required values.:

"serial.test":{"id":"Integer","timeout":"Integer","function":"Integer","first_reg":"Integer","reg_count":"String","data_type":"String","no_brackets":"Integer","serial_type":"String","baudrate":"Integer","databits":"Integer","stopbits":"Integer","parity":"String","flowctrl":"String"}

Kind Regards,

Hello,

Thanks for Your replay :wink:

I have some additional questions:

  1. For monitoring 8th bit should i type “128” instead of 64 in “bit_val” ?

  2. im not sure what to write here: “serial_type”:“RE92_TEST”, i wrote same name in modbus master (screen atached).

  3. Should i type herethe phone number?: “gsmctl -S -s “0037000000 Modbus triggered!””
    like this: gsmctl -S -s “48606606606 Modbus triggered!” where 48 is counrty code.

I already aplied all to crontab, but how can i test it if this work?

Hello,

1)

Yes. It should be enough to change “$modbus_output 64” and ‘-eq 64’ to 128.

You can try executing the script to see if it works:

  • sh /etc/modbusscript.sh
    Make sure you grant executiong rights:

  • chmod +x /etc/modbusscript.sh

2)

This depends on your serial. You can use the following command to see your serial devices:

  • ls /dev

So the type, for example, can be:

  • “serial_type”:“/dev/rs485”

3)

‘00’ replaces ‘+’, and 370 is the country code in my case. In your case, the number should start ‘0048’.

The ‘Modbus triggered!’ right after the phone number is the actual text message that will be sent.

To test crontab, simply set the period to be short and wait for SMS message. Assuming the bit value satisfies the condition and SMS must be sent.

You can also use ‘logger’ commands to log messages. For example, add the following into your script:

  • logger "modbus script is triggered!’

Then, if you run logread (or logread -f to view logs in real time) you should see ‘modbus script triggered!’ if the crontab executed the script.

Kind Regards,

Hello,

Thanks for Your help :wink:

Skript is now working using TCP protocol. Its sending me sms by command: sh /etc/modbus.sh. This is working fine. But not really working for Modbus RTU.

Here is my script code:

!/bin/sh

# Read modbus register and get 7th bit

# modbus_output=$(ubus call modbus_master serial.test '{"id":5,"timeout":5,"function":3,"first_reg":4006,"reg_count":"1","data_type":"16bit_int_hi_first","no_brackets":1,"serial_type":"/dev/rs485","baudrate":9600,"databits":8,"stopbits":1,"parity":"None","flowctrl":"None"}' | jq -r .result):

modbus_output=$(ubus call modbus_master tcp.test '{"ip":"192.168.1.150","port":502,"id":1,"timeout":5,"function":3,"first_reg":4006,"reg_count":"1","data_type":"16bit_int_hi_first","no_brackets":1}' | jq -r .result)

echo $modbus_output

bit_val=$(echo "$modbus_output 128" | awk '{ printf ("%d", and($1,$2)) }')

echo $bit_val

# If 7th bit is 1

if [ $bit_val -eq 128 ]; then

# Send SMS if 7th bit is 1

logger $bit_val

logger "sending SMS!"

gsmctl -S -s "0048xxxxxxxxx RE_92 ALARM WYJ. 1"

fi

The serial modbus is now commented, because its not working. When im using it, its returns me in terminal this: “Failed to create mb context”.

The Crontab is not working for now. I have added line to crontab:

          • sh /etc/modbus.sh

In logread returns me:
Tue Jul 25 16:42:00 2023 cron.err crond[6508]: USER root pid 31102 cmd sh /etc/modbus.sh

What could be wrong?

Btw i have somehow missing 1st line in crontab. I may have deleted it.

Edit:

Sending SMS message is already working via crontab. SMS is sending by Crontab every minute.
Is that possible to somehow make it to send SMS only for first trigger? Any clue?

Ok now is working like i want to, but only Modbus TCP.

modbus_output=$(ubus call modbus_master serial.test '{"id":5,"timeout":5,"function":3,"first_reg":4006,"reg_count":"1","data_type":"16bit_int_hi_first","no_brackets":1,"serial_type":"/dev/rs485",
"baudrate":9600,"databits":8,"stopbits":1,"parity":"None","flowctrl":"None"}' | jq -r .result)

Serial RTU still not working for me. I dont know why. Its give me back “Failed to create mb context”.

Where i can find the library of modbus_master serial.test , so i can check the function.