Hello forum,
My previous experience with Arduino and Modbus is limited to getting wind directions from a wind vane. Now I’m trying to get values from a ultra-sonic water flow meter, like battery voltage, water velocity, flow, etc.
I used the same code that I used for the wind vane, and I’m able to get values from the different registers. But the values I’m getting does not correspond to anything that one would expect - battery voltage which is over 12.0V always returns a value of zero, and the other registers all return values that are clearly not actual values, since they’re always something like 512, 1024, 2048, 1536 (which is 512 + 1024.)
I’m using the ModbusMaster library (GitHub - syvic/ModbusMaster: Arduino class library for communicating with Modbus slaves over RS232/485), and from the example named RS_485HalfDuplex and changed the code a bit to work with my hardware: UNO with MAX485 (https://www.ebay.co.uk/itm/RS485-Module-MAX485-TTL-RS-485-for-Arduino-Raspberry-Pi-AA119/283989866584?hash=item421f1d7858:g:In4AAOSw-nRfRQb0)
#include <ModbusMaster.h>
#include <SoftwareSerial.h>
SoftwareSerial MAX485(6, 7);
#define MAX485_DE 4
#define MAX485_RE_NEG 5
ModbusMaster node;
void preTransmission()
{
digitalWrite(MAX485_RE_NEG, 1);
digitalWrite(MAX485_DE, 1);
}
void postTransmission()
{
digitalWrite(MAX485_RE_NEG, 0);
digitalWrite(MAX485_DE, 0);
}
void setup()
{
pinMode(MAX485_RE_NEG, OUTPUT);
pinMode(MAX485_DE, OUTPUT);
digitalWrite(MAX485_RE_NEG, 0);
digitalWrite(MAX485_DE, 0);
Serial.begin(19200);
MAX485.begin(9600);
node.begin(1, MAX485); // Modbus slave ID
node.preTransmission(preTransmission);
node.postTransmission(postTransmission);
}
void loop()
{
uint8_t resultMain;
resultMain = node.readHoldingRegisters(0x0002, 1);
if (resultMain == node.ku8MBSuccess)
{
Serial.print("Result: ");
Serial.println(node.getResponseBuffer(0x00));
}
else
Serial.println(F(">>>>>> BAD RESULT"));
delay(500);
}
Sample output:
17:05:22.568 -> Result: 512
17:05:23.812 -> Result: 512
17:05:23.812 -> Result: 512
17:05:25.813 -> Result: 512
17:05:25.813 -> Result: 512
This code worked for my wind vane, since it gave decimal values of 0 to 15, each number corresponding to a wind direction. For the ultra-sonic sensor the decimal output is clearly not doing the trick, and I need to work out how to get the original hex values coming from the holding registers. If I can get the hex values I can work out the single precision floating value.
From the sensor manual:
7.3.2 Data format
(1) Instrument data storage format is:IEEE754 standard single-precision floating number
IEEE754 standard single-precision floating number consists of 1 sign bit+8 exponent +23 mantissa, use four hexadecimal digits. e.g. 124.75 use hexadecimal express as 42 F9 80 00. It’s calculated as: 24.75 Binary is 1111100.11
"
I don’t understand much about the internal working of this library, but I assume it reads the hex values coming from the sensor and converts it to decimal in a direct manner, without keeping the IEEE754 standard in mind. My question, how do I use this library to give me the data in the format I need so I can calculate the correct values?
Attached is the full manual.