Go Down

Topic: Modbus tcp help please [SOLVED] (Read 1 time) previous topic - next topic

yeti195

May 17, 2014, 04:07 am Last Edit: May 18, 2014, 12:48 am by yeti195 Reason: 1
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.  :-)   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.  


Code: [Select]
// 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);
}

lemming

#1
May 17, 2014, 07:50 am Last Edit: May 17, 2014, 07:55 am by lemming Reason: 1
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.

DavidOConnor

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.

jesussancel

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.

yeti195

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

Go Up