Go Down

Topic: Help with ModBus RTU Master-Slave: SimpleModbus [SOLVED] (Read 317670 times) previous topic - next topic

ardutech

Hi friend,

I 'm a Greek student and my diploma project refers to arduino Omron MX2 VFD control system.

I have an arduino mega, an MX2 Omron motor inverter, an RS485 to arduino shield and i like to control this MX2 inverter with arduino via RS485 cable and modbus rtu protocol.

I need help me with code to do it for my diploma exercise. As long as i try with different modbus arduino libraries, i didn't make it.

I need to have a simple control an VFD Omron MX2 inverter through arduino.
The protocol i will use is a Modbus RTU through RS485 serial connection.

I 've managed to control this inverter from arduino serial port through software modbus poll by giving commands from the test function inside program Modbus Poll like "01 05 00 00 FF 00" and the inverter goes to RUN mode, but i couldn't do it the same from arduino as a master.

The code i've found about MX2 VFD from another person is the above:

Code: [Select]
      /**
*  Modbus master example 1:
*  The purpose of this example is to query an array of data
*  from an external Modbus slave device.
*  The link media can be USB or RS232.
*
*  Recommended Modbus slave:
*  diagslave http://www.modbusdriver.com/diagslave.html
*
*  In a Linux box, run
*  "./diagslave /dev/ttyUSB0 -b 19200 -d 8 -s 1 -p none -m rtu -a 1"
* This is:
* serial port /dev/ttyUSB0 at 19200 baud 8N1
* RTU mode and address @1
*/

#include <ModbusRtu.h>

// data array for modbus network sharing
uint16_t au16data[16];
uint8_t u8state;

/**
*  Modbus object declaration
*  u8id : node id = 0 for master, = 1..247 for slave
*  u8serno : serial port (use 0 for Serial)
*  u8txenpin : 0 for RS-232 and USB-FTDI
*               or any pin number > 1 for RS-485
*/
Modbus master(0,0,9); // this is master and RS-232 or USB-FTDI, PIN 9 PARA INDICAR QUE TRASMITO

/**
* This is an structe which contains a query to an slave device
*/
modbus_t telegram;

unsigned long u32wait;

void setup() {
 master.begin( 9600 ); // baud-rate at 19200
 master.setTimeOut( 2000 ); // if there is no answer in 2000 ms, roll over
 u32wait = millis() + 1000;
 u8state = 0;
}

void loop() {
 switch( u8state ) {
 case 0:
   if (millis() > u32wait) u8state++; // wait state
   break;
 case 1:
   telegram.u8id = 1; // slave address
   telegram.u8fct = 5; // function code (this one is registers read)
   telegram.u16RegAdd = 0; // start address in slave
   telegram.u16CoilsNo = 2; // number of elements (coils or registers) to read
   //telegram.au16reg = au16data; // pointer to a memory array in the Arduino
 
   // PARA EL VARIADOR OMRON MX1: MODBUS RTU 01 05 00 00 FF 00 -> START
   // 01 -> SLAVE (VFD OMRON)
   // 05 -> WRITE COIL
   //  00 00 -> ADDRESS COIL
   // FF 00 -> VALUES TO WRITE IN COIL FOR RUN
   
   telegram.au16reg[0] = 0;
   telegram.au16reg[1] = 0;
   telegram.au16reg[2] = 0;
   telegram.au16reg[3] = 0;
   telegram.au16reg[4] = 0;
   telegram.au16reg[5] = 0;
   telegram.au16reg[6] = 0;
   telegram.au16reg[7] = 0;

   telegram.au16reg[8] = 1;
   telegram.au16reg[9] = 1;
   telegram.au16reg[10] = 1;
   telegram.au16reg[11] = 1;
   telegram.au16reg[12] = 1;
   telegram.au16reg[13] = 1;
   telegram.au16reg[14] = 1;
   telegram.au16reg[15] = 1;
   
   
   master.query( telegram ); // send query (only once)
   delay(3500);
 
   telegram.u8id = 1; // slave address
   telegram.u8fct = 6; // function code (this one is registers read)
   telegram.u16RegAdd = 1; // start address in slave
   telegram.u16CoilsNo = 4; // number of elements (coils or registers) to read
   //telegram.au16reg = au16data; // pointer to a memory array in the Arduino
   //telegram.au16reg = 0000000111110100;

   // PARA EL VARIADOR OMRON MX1: MODBUS RTU 01 06 00 01 01 F4 -> CHANGE FQ
   // 01 -> SLAVE (VFD OMRON)
   // 06 -> WRITE IN REGISTE
   // 00 01 -> REGISTER ADDRESS
   // 01 F4 -> VALUE TO WRITE IN THE REGISTER TO CHANGE THE MOTOR FREQUENCY

   telegram.au16reg[0] = 0;
   telegram.au16reg[1] = 0;
   telegram.au16reg[2] = 0;
   telegram.au16reg[3] = 0;
   telegram.au16reg[4] = 0;
   telegram.au16reg[5] = 0;
   telegram.au16reg[6] = 0;
   telegram.au16reg[7] = 1;

   telegram.au16reg[8] = 1;
   telegram.au16reg[9] = 1;
   telegram.au16reg[10] = 1;
   telegram.au16reg[11] = 1;
   telegram.au16reg[12] = 0;
   telegram.au16reg[13] = 1;
   telegram.au16reg[14] = 0;
   telegram.au16reg[15] = 0;
   
   master.query( telegram ); // send query (only once)
   delay(3500);
   telegram.u8id = 1; // slave address
   telegram.u8fct = 5; // function code (this one is registers read)
   telegram.u16RegAdd = 1; // start address in slave
   telegram.u16CoilsNo = 2; // number of elements (coils or registers) to read
   //telegram.au16reg = au16data; // pointer to a memory array in the Arduino

   // PARA EL VARIADOR OMRON MX1: MODBUS RTU 01 05 00 00 00 00 -> STOP
   // 01 -> ESCLAVO (VARIADOR OMRON)
   // 05 -> ESCRIBIR EN UNA BOBINA
   // 00 00 -> DIRECCION DE LA BOBINA
   // 00 00 -> VALOR A ESCRIBIR EN LA BOBINA PARA STOP

   telegram.au16reg[0] = 0;
   telegram.au16reg[1] = 0;
   telegram.au16reg[2] = 0;
   telegram.au16reg[3] = 0;
   telegram.au16reg[4] = 0;
   telegram.au16reg[5] = 0;
   telegram.au16reg[6] = 0;
   telegram.au16reg[7] = 0;
   telegram.au16reg[8] = 0;
   telegram.au16reg[9] = 0;
   telegram.au16reg[10] = 0;
   telegram.au16reg[11] = 0;
   telegram.au16reg[12] = 0;
   telegram.au16reg[13] = 0;
   telegram.au16reg[14] = 0;
   telegram.au16reg[15] = 0;
   master.query( telegram ); // send query (only once)
   delay(3500);
   u8state++;
   break;
 case 2:
   master.poll(); // check incoming messages
   if (master.getState() == COM_IDLE) {
     u8state = 0;
     u32wait = millis() + 100;
   }
   break;
 }
}


All i want is to help me build an arduino code to give simple commands to inverter like Start, Stop, change frequency, reverse etc.

Also it would be nice if i can show somehow some values from the inverter to an LCD screen but i will do it later.

This is the manual in PDF for Omron MX2 inverter modbus protocol.

MX2 Modbus PDF
TIA

ardutech

I 've managed to send RUN command to VFD but i can't (so far) send the change frequency command "01 06 00 01 01 F4" + CRC check.
When i connect logic analyzer with modbus rtu decoder, it shows "Device ID:'1' Function Write single coil ('5') Addr: '0' value: '65280' Chksum: '14988'. So far i've managed to send only 1st telegram.
All i want is to pass both 3 commands "START", "FREQUENCY" "STOP". Can you help me? TIA

buenovito

#767
Jun 07, 2018, 11:10 pm Last Edit: Jun 07, 2018, 11:14 pm by buenovito
Hallo,

I want to read data from a compass B meter, with my Arduino and Iam using a MAX485 to transmit the data from the meter.  I'am using a simple modbus master library which basically almost everyone is using. Furthermore  it's default communication is :

Protocol: MOdBUS RTU
Baud Rate: 9600
Parity: EVEN
Stop Bits: 1
Data Bits: 8

for my first step I want to read from phase Current1 which is register 1000.

so for now my modbus_construct looks like this:

modbus_construct(&packet[packet1], 1, READ_INPUT_REGISTERS, 1000, 2, regs[0];

It doesn't read the input, so I don't know if I have put the right register, therefore the attachment of the modbus register is below to see

I hope to inform you well, and hope for an answer


Kind regards,


noiasca

First step: try to read the register with any other PC based modbus test software to be shure to have the right register AND the right read mode. Your modbus-data.jpg doesn't say anything if READ_INPUT_REGISTERS is correct.

DE: Wie man Fragen postet:
1. was hat man (Sketch und Hardware)
2. was SOLL es machen
3. was macht es: IST (Fehlverhalten, Fehlermeldungen, Serial.Output ...)
4. Eine Frage stellen bzw. erklären was man erwartet

buenovito

Thanks for the reply noiasca,

 Do you have any suggestions for a modbus test software ??

 

noiasca

I'm only using

CAS Modbus Scanner

and

Simply Modbus Master 8.0.7

but at least you can test if the communication is working correctly. Much easier than starting with an unknown arduino Sketch.
DE: Wie man Fragen postet:
1. was hat man (Sketch und Hardware)
2. was SOLL es machen
3. was macht es: IST (Fehlverhalten, Fehlermeldungen, Serial.Output ...)
4. Eine Frage stellen bzw. erklären was man erwartet

buenovito

Hi noiasca,

I did the first step , which I can read the register with an modbus test software. I saw i'am using the right register, because it gives me a value.

Also, in the datasheet it says that INP_REG = READ_INPUT_REGISTERS. I don't know what is the problem , I taught maybe this is the issue:

unsigned long temp1 = (unsigned long) regs[0] << 16 | regs [1];
current = *(float*)&temp1; 

maybe I'am using it wrong ? I also add up a 120 Ohm resistor between A AND b, and still get no values in return.

noiasca

do you get unrealistic results or no result?

unrealistic:
try to change regs[0] with [1]
unsigned long temp1 = (unsigned long) regs[1] << 16 | regs
  • ;


no result:
you communication might not be ok.
now it's getting complicated.

Please ensure that you are using the right library. I'm referring to the original of Juan Bester, currently available at https://drive.google.com/folderview?id=0B0B286tJkafVSENVcU1RQVBfSzg&usp=drive_web'>

Juan has written 13 pages manual. I hope you have read it already. Did you?

next things:
You are using Serial for the modbus and Serial for debug messages.
I can hardly believe that this will work. Either use an Mega with the modbus on one of the other Serials, or a display for debug messages. I don't recommend to use softserial. But modbus AND debuging on the same serial is a mess.

to get further support in you case,
- we need a clear real picture of your wiring, how your 485 is connected to the arduino (wich one?),
- ensure to use Juan Besters library. If this is not possible, at least tell the exact source of the library which you are using.
- and a snapshot of your working test software where we can clearly see the parameters which were of success and the result of the values of the registers you requested



DE: Wie man Fragen postet:
1. was hat man (Sketch und Hardware)
2. was SOLL es machen
3. was macht es: IST (Fehlverhalten, Fehlermeldungen, Serial.Output ...)
4. Eine Frage stellen bzw. erklären was man erwartet

buenovito

Hi noiasca,

I can get result now, it works fine. I just needed to change some datatype.
Thank you so much for the help you gave me, I greatly appreciate the assistance you have provided me.

 :D

noiasca

cool, thank you for your update. Always nice to hear, if people made progress and a problem was solved!
DE: Wie man Fragen postet:
1. was hat man (Sketch und Hardware)
2. was SOLL es machen
3. was macht es: IST (Fehlverhalten, Fehlermeldungen, Serial.Output ...)
4. Eine Frage stellen bzw. erklären was man erwartet

buenovito

Hi guys,

To write values to a registers, do I only need to change the function code ?? or do I need to add something in the code as well

Sincerly,

Go Up