andresarmento / modbus-arduino

A library that allows your Arduino to communicate via Modbus protocol, acting as a slave (master in development). Supports serial (RS-232, RS-485) and IP via Ethernet (Modbus IP).
BSD 3-Clause "New" or "Revised" License
457 stars 270 forks source link

Help with multiple coils/inputs #7

Open marcusjelsch opened 8 years ago

marcusjelsch commented 8 years ago

Hi!

  1. All thumbs up for this great work.

Now my problem, how to modify the code for use with multiple coils.

Here my code:

`/*

I2C Adressen:

0x20 - Relais 0x21 - Eingänge (5 Taster und 3 Extern) 0x22 - LCD 4x20 Zeichen

*/

include

include

include

include

include

include

LiquidCrystal_I2C lcd(0x22, 4, 5, 6, 0, 1, 2, 3, 7, POSITIVE); // Set the LCD I2C address

ModbusIP mb; //PCF8574 Objekt PCF8574 inputs; // PCF8574 mit Adresse 0x21 PCF8574 outputs; // PCF8574 mit Adresse 0x20

void setup() { // The media access control (ethernet hardware) address for the shield byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; // The IP address for the shield byte ip[] = { 192, 168, 0, 44 }; //Config Modbus IP mb.config(mac, ip);

for (int i=100;i<8;i++) { mb.addIsts(i); }

for (int i=200;i<8;i++) { mb.addCoil(i); }

io_setup(); // Eingänge und Ausgänge initialisieren

lcd.begin(20,4);
}

void loop() { // poll messages mb.task();

lcd.home (); lcd.print ("Adr.: 192.168.0.44:502"); lcd.print (" ");

// link the Arduino pins to the Modbus array io_poll(); }

void io_setup() {
inputs.begin(0x21); for (int i=0;i<8;i++) { inputs.pinMode(i, INPUT_PULLUP); }

outputs.begin(0x20); for (int i=0;i<8;i++) { outputs.pinMode(i, OUTPUT); } }

/**

}`

I can only read the input at adress 100.

What am i doing wrong?

Thank u for help.

marcusjelsch commented 8 years ago

Found!

I made mistakes in the for-loops!

But now i have the problem, that at adress 107 and at adress 207 i can see/do no changes???!!!

Here my actual code:

`/*

I2C Adressen:

0x20 - Relais 0x21 - Eingänge (5 Taster und 3 Extern) 0x22 - LCD 4x20 Zeichen

*/

include

include

include

include

include

include

LiquidCrystal_I2C lcd(0x22, 4, 5, 6, 0, 1, 2, 3, 7, POSITIVE); // Set the LCD I2C address

ModbusIP mb; //PCF8574 Objekt PCF8574 inputs; // PCF8574 mit Adresse 0x21 PCF8574 outputs; // PCF8574 mit Adresse 0x20

void setup() { // The media access control (ethernet hardware) address for the shield byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; // The IP address for the shield byte ip[] = { 192, 168, 0, 44 }; //Config Modbus IP mb.config(mac, ip);

for (int i=100;i<108;i++) { mb.addIsts(i); }

for (int i=200;i<208;i++) { mb.addCoil(i); }

io_setup(); // Eingänge und Ausgänge initialisieren

lcd.begin(20,4);
}

void loop() { // poll messages mb.task();

lcd.home (); lcd.print ("IP-Adr:192.168.0.44");

// link the Arduino pins to the Modbus array io_poll(); }

void io_setup() {
inputs.begin(0x21); for (int i=0;i<8;i++) { inputs.pinMode(i, INPUT_PULLUP); }

outputs.begin(0x20); for (int i=0;i<8;i++) { outputs.pinMode(i, OUTPUT); } }

/**

}`

jsumm commented 8 years ago

I imagine you've already figured out a fix for this, but what I've noticed is that for coils and discrete inputs there's a problem with every 8th coil/input when you access them using the multiple read/write MODBUS commands. If you have the bandwidth you can change from using read/write multiple coils to read/write single coils and loop over all 8 coils or you can read/write 7 or less coils at a time in multiple read/write calls.

I imagine the library has a bit shift error of some sort, because it happens on every 8th coil (if you were trying to work with 16 you'd have issues with both the 8th and 16th).

DeTommer commented 7 years ago

It's actually offsetted with 8. I'm using the following code (together with the PCA9555 shield): `

define _IO_CNT 16

//ModbusIP object ModbusIP mb; void setup() { // The media access control (ethernet hardware) address for the shield byte mac[] = { 0x00, 0x06, 0x59, 0x00, 0x1B, 0xE4 };
// The IP address for the shield byte ip[] = { 172, 16, 47, 10 };
//Config Modbus IP mb.config(mac, ip);

for(byte i=0;i<_IO_CNT;i++)
{
    ioport.pinMode(i, INPUT); //Set I2C GPIOs pinMode input
    mb.addIsts(i);  //add input status register according to ammount of inputs
}

mb.addIreg(IREG0);

}

void loop() { //Call once inside loop() - all magic here mb.task();

for(byte i=0;i<_IO_CNT;i++) { io = ioport.digitalRead(i); //read IO value from PCA9555 mb.Ists((i),io); //puts IO value in Input Status ioval+=(io<<i); //Shifts IO value in 16 bit Input Register }

mb.Ireg(IREG0,ioval);   

ioval=0; } ` What I see is that when I read register 0..7, I read the correct data at 0..6 & 15... Do 7 jumped to 15, the actual 15 has jumped to 23. offset

I know this project is presumed dead, but it would still be nice to find a solution or to help others :-). If I find anything, I will post it here

DeTommer commented 7 years ago

Fixed by using this file https://github.com/seydamir/modbus-arduino/blob/9e124a2ef7e6e06f5ad360691205ef0d04df92a0/libraries/Modbus/Modbus.cpp

pawel3410 commented 6 years ago

DeTommer Could You send again this fixed file?