Reading Temperature from a Flowmeter using Modbus

Hello,

I am a beginner with Arduino and Modbus. I am currently using an Arduino Mega (Master) that connects to a Transceiver Module TTL UART Serial to RS-485 Module that is then connected to a flowmeter (Slave). The library I am using is ModbusMaster and I used the RS485_HalfDuplex example as a reference.

I am trying to read the temperature of the flowmeter in both Celsius and Fahrenheit in a single loop. I have managed to get back a response with the correct temperature values but only one at a time. However, when I request a response in two loops I can get both Celsius and Fahrenheit but I want to know how to do it in one if possible.

Some additional information: the data from the flowmeter are 2 16bits with a length of 2.

Please let me know if I need to provide any other information as I am new to the Forum, thank you.

Image of the Serial Monitor:
montr

List of Registers from the flowmeter's manual:

Here is my code:

Edit: I realize I am calling for register 0x04 for the first loop but I wanted to mention that it produces the same response of 0 even if the register is changed to 0x01 to 0x10.


```cpp

#include <ModbusMaster.h>

#define MAX485_DE 3
#define MAX485_RE_NEG 2

// instantiate ModbusMaster object
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);

  // Init in receive mode
  digitalWrite(MAX485_RE_NEG, 0);
  digitalWrite(MAX485_DE, 0);

  Serial.begin(9600);

  while (!Serial)
    ;

  Serial1.begin(9600, SERIAL_8E1);



  Serial.println(" Hello ");

  delay(1000);

  // Modbus slave ID 1
  node.begin(1, Serial1);

  // Callbacks allow us to configure the RS485 transceiver correctly

  node.preTransmission(preTransmission);

  node.postTransmission(postTransmission);
}

void loop() {


  uint8_t u8state;
  // uint64_t data[16];

  u8state = node.readHoldingRegisters(0x0040, 2);
  if (u8state == node.ku8MBSuccess) {

    Serial.print("Celsius: ");
    Serial.println(node.getResponseBuffer(0x00) / 10.0f);

    // delay(200);

    Serial.print("Fahrenheit: ");
    Serial.println(node.getResponseBuffer(0x04) / 10.0f);


    // delay(200);
  }

  delay(200);

  // New Loop to get Fahrenheit

  u8state = node.readHoldingRegisters(0x41, 16);
  if (u8state == node.ku8MBSuccess) {

    Serial.print("(2nd Loop) Fahrenheit: ");
    Serial.println(node.getResponseBuffer(0x00) / 10.0f);
  }

  delay(1000);
}

Since each of your registers you are trying to read are 32 bits, you need to read 4 16 bit values, starting with register 0x40. This will give you the 32 bits from register 0x40 and the 32 bits from register 0x41. You then need to pull the data out of your response buffer, like the examples: GitHub - 4-20ma/ModbusMaster: Enlighten your Arduino to be a Modbus master

  u8state = node.readHoldingRegisters(0x0040, 4);
  if (u8state == node.ku8MBSuccess) {

    Serial.print("Celsius: ");
    Serial.println(node.getResponseBuffer(0) / 10.0f);

    // delay(200);

    Serial.print("Fahrenheit: ");
    Serial.println(node.getResponseBuffer(2) / 10.0f);
1 Like

Thank you so much for the reply. I have attempted this before where we adjust the values to fit the required number of bits. I did try your suggestion and it resulted in the same response in the serial monitor as before.

I am currently testing to see if it is an issue with timing.

Thank you for the reply. Yes, although it would be easier to calculate Fahrenheit from the Celcius response given, I am more trying to receive multiple responses from the buffers in a single loop than I am to calculate temperature.

Do you examine all the values in the response buffer? Your original post was accessing index 4 which does not exist. If you read 4 registers, the response buffer should have values at index 0..3. Have to tried just printing those out directly?

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.