Modbus tcp help please [SOLVED]

Hello, I’m a newbie to Arduino. I have been working on a DC voltmeter. I’m using examples found online. I have it working great and displaying the voltage on an LCD display. Really cool. :slight_smile: Now, I’m wanting to add Modbus Protocol to display the voltage on a SCADA / HMI application. I do have it working, but I can’t seem to figure out this last thing.

Measuring a 12v battery, the LCD display shows 12.57v. The same as my meter. Success. I’m using Indusoft Web Studio 7.1 as my HMI software, and I do have it reading the arduino using modbus, but it will only display 12v. Nothing on the other side of the decimal. Only whole numbers. I have tried everything I can think of, and different HMI applications all with the same results.

Could someone please look over the sketch and see what I might be doing wrong?

Thank you so much for any help.

// include the library code:
#include <LiquidCrystal.h>
#include <SPI.h>
#include <Ethernet.h>
#include <Mudbus.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(7, 8, 5, 9, 1, 0);
int backLight = 6;    // pin 6 will control the backlight
int analogInput = 0;
float vout = 0.0;
float vin = 0.0;
float R1 = 100000.0; // resistance of R1 (100K)
float R2 = 9900.0; // resistance of R2 (10K)
int value = 0;

Mudbus Mb;

void setup()
{
  uint8_t mac[]     = { 0x90, 0xA2, 0xDA, 0x00, 0x51, 0x06 };
  uint8_t ip[]      = { 192, 168, 1, 141 };
  uint8_t gateway[] = { 192, 168, 1, 1 };
  uint8_t subnet[]  = { 255, 255, 255, 0 };
  Ethernet.begin(mac, ip, gateway, subnet);
  //Avoid pins 4,10,11,12,13 when using ethernet shield
 
  delay(5000);  //Time to open the terminal
 
  pinMode(backLight, OUTPUT);
  pinMode(analogInput, INPUT);
  digitalWrite(backLight, HIGH); // turn backlight on. Replace 'HIGH' with 'LOW' to turn it off.
  lcd.begin(16, 2);
  lcd.print("     ModBus     ");
  lcd.setCursor(0, 1);
  lcd.print("  DC Voltmeter  ");
  delay(2000);
  lcd.clear();
  lcd.print("  Version: 2.0  ");
  delay(1500);
  lcd.clear();
  lcd.print("Modbus Voltmeter");
  
  Mb.R[0] = 0.00;
}


void loop() {
  
   //modbus TCP update
   Mb.Run();
   
   // read the value at analog input
   value = analogRead(analogInput);
   vout = (value * 4.81) / 1024.0; 
   vin = vout / (R2/(R1+R2)); 
   if (vin<0.09)   {
   vin=0.0; //statement to quash undesired reading !
   
} 
Mb.R[0] = (vin); 
lcd.setCursor(0, 1);
lcd.print("INPUT V = ");
lcd.print(vin);
delay(400);
}

Which library are you using? I have not heard of "Mudbus".

Where your code says "Mb.R[0] = (vin);" what is the datatype of Mb.R? If it is an integer then it will crop the float thereby losing the decimal point numbers.

Edit:
Found the library and the google code page states, "The register and coil data is held as Mb.R[0-125] signed int and....".
Confirms my suspicion. You won't get a float to display without modifying the library.

There are two ways floating point numbers are transmitted over Modbus. The first is to use two registers to hold the number. The second is to use scaling. To use scaling, multiply your voltage by a scale factor, 10 if you want one decimal place, 100 if you want two, etc. The Modbus master will have to divide by the scale factor when it reads the voltage.

Hola, buenos días, quiero saber si es posible conectar arduino por medio del protocolo modbus a otro dispositivo que maneje el mismo protocolo de comunicacion. gracias de antemano, espero su respuesta.

Thank you so much for the help. I got if figured out using the scaling method. I was over thinking it.