[SOLVED] Simpel Modbus Multi Node setup HOW ?

So i found the Simpel modbus project and installed the examples. This works perfect. I can talk between two arduinos using the potion meter.

But now i want to connect up tot 10 slaves using the unos and 1 master using the mega. But how can i address the slaves ? Saying for exampel 1 ~ 10 and then using the master to communicate to them ?

For example i want internal info from slave nr 8. Then using the master en he says HELLO 8 I WANT info and then i only get response from the slave 8 and not the others ?

this version i use now: https://drive.google.com/folderview?id=0B0B286tJkafVYnBhNGo4N3poQ2c&usp=drive_web&tid=0B0B286tJkafVSENVcU1RQVBfSzg

That's part of the ModBus protocol, every slave has an address and reacts only if the master is requesting information from that address. The Google Drive files you linked to contains only files for the master part of the game. You also need the slave libraries and there you set the address, usually in the code but you can also choose the store it in the EEPROM and read it at every startup.

So i found the Simpel modbus project and installed the examples. This works perfect. I can talk between two arduinos using the potion meter.

Reading that I would expect that you already installed a master and a slave part and you're already using an address to specify the slave you want to query. From the slave library there exists a newer version, please update.

Hey i use the slave and master code. But i cant find any documentation on how to set an slave id to the slave like something as

#define SLAVEID 4

Then i found this peace of code in the slave part:

// modbus_update_comms(baud, byteFormat, id) is not needed but allows for easy update of the
// port variables and slave id dynamically in any function.
modbus_update_comms(9600, SERIAL_8N2, 1);

So y thought changing the 1 on the end to like 4 will do the trik. But how i than can tell to the master lets talk to slave 4 ?

slave code:

#include <SimpleModbusSlave.h>

#define LED 9

// Using the enum instruction allows for an easy method for adding and
// removing registers. Doing it this way saves you #defining the size
// of your slaves register array each time you want to add more registers
// and at a glimpse informs you of your slaves register layout.

//////////////// registers of your slave ///////////////////
enum
{
// just add or remove registers and your good to go...
// The first register starts at address 0
ADC_VAL,
PWM_VAL,
HOLDING_REGS_SIZE // leave this one
// total number of registers for function 3 and 16 share the same register array
// i.e. the same address space
};

unsigned int holdingRegs[HOLDING_REGS_SIZE]; // function 3 and 16 register array
////////////////////////////////////////////////////////////

void setup()
{
/* parameters(HardwareSerial* SerialPort,
long baudrate,
unsigned char byteFormat,
unsigned char ID,
unsigned char transmit enable pin,
unsigned int holding registers size,
unsigned int* holding register array)
*/

/* Valid modbus byte formats are:
SERIAL_8N2: 1 start bit, 8 data bits, 2 stop bits
SERIAL_8E1: 1 start bit, 8 data bits, 1 Even parity bit, 1 stop bit
SERIAL_8O1: 1 start bit, 8 data bits, 1 Odd parity bit, 1 stop bit

You can obviously use SERIAL_8N1 but this does not adhere to the
Modbus specifications. That said, I have tested the SERIAL_8N1 option
on various commercial masters and slaves that were suppose to adhere
to this specification and was always able to communicate... Go figure.

These byte formats are already defined in the Arduino global name space.
*/

modbus_configure(&Serial, 9600, SERIAL_8N2, 1, 2, HOLDING_REGS_SIZE, holdingRegs);

// modbus_update_comms(baud, byteFormat, id) is not needed but allows for easy update of the
// port variables and slave id dynamically in any function.
modbus_update_comms(9600, SERIAL_8N2, 1);

pinMode(LED, OUTPUT);
}

void loop()
{
// modbus_update() is the only method used in loop(). It returns the total error
// count since the slave started. You don't have to use it but it's useful
// for fault finding by the modbus master.

modbus_update();

holdingRegs[ADC_VAL] = analogRead(A0); // update data to be read by the master to adjust the PWM

analogWrite(LED, holdingRegs[PWM_VAL]>>2); // constrain adc value from the arduino master to 255

/* Note:
The use of the enum instruction is not needed. You could set a maximum allowable
size for holdinRegs[] by defining HOLDING_REGS_SIZE using a constant and then access
holdingRegs[] by "Index" addressing.
I.e.
holdingRegs[0] = analogRead(A0);
analogWrite(LED, holdingRegs[1]/4);
*/

}

Master code:

#include <SimpleModbusMaster.h>

//////////////////// Port information ///////////////////
#define baud 9600
#define timeout 1000
#define polling 200 // the scan rate

// If the packets internal retry register matches
// the set retry count then communication is stopped
// on that packet. To re-enable the packet you must
// set the "connection" variable to true.
#define retry_count 10

// used to toggle the receive/transmit pin on the driver
#define TxEnablePin 2

#define LED 9

// This is the easiest way to create new packets
// Add as many as you want. TOTAL_NO_OF_PACKETS
// is automatically updated.
enum
{
PACKET1,
PACKET2,
TOTAL_NO_OF_PACKETS // leave this last entry
};

// Create an array of Packets to be configured
Packet packets[TOTAL_NO_OF_PACKETS];

// Create a packetPointer to access each packet
// individually. This is not required you can access
// the array explicitly. E.g. packets[PACKET1].id = 2;
// This does become tedious though...
packetPointer packet1 = &packets[PACKET1];
packetPointer packet2 = &packets[PACKET2];

// Data read from the arduino slave will be stored in this array
// if the array is initialized to the packet.
unsigned int readRegs[1];

// Data to be written to the arduino slave
unsigned int writeRegs[1];

void setup()
{
// The modbus packet constructor function will initialize
// the individual packet with the assigned parameters. You can always do this
// explicitly by using struct pointers. The first parameter is the address of the
// packet in question. It is effectively the "this" parameter in Java that points to
// the address of the passed object. It has the following form:
// modbus_construct(packet, id, function, address, data, register array)

// For functions 1 & 2 data is the number of points
// For functions 3, 4 & 16 data is the number of registers
// For function 15 data is the number of coils

// read 1 register starting at address 0
modbus_construct(packet1, 1, READ_HOLDING_REGISTERS, 0, 1, readRegs);

// write 1 register starting at address 1
modbus_construct(packet2, 1, PRESET_MULTIPLE_REGISTERS, 1, 1, writeRegs);

// P.S. the register array entries above can be different arrays

/* Initialize communication settings:
parameters(HardwareSerial* SerialPort,
long baud,
unsigned char byteFormat,
unsigned int timeout,
unsigned int polling,
unsigned char retry_count,
unsigned char TxEnablePin,
Packet* packets,
unsigned int total_no_of_packets);

Valid modbus byte formats are:
SERIAL_8N2: 1 start bit, 8 data bits, 2 stop bits
SERIAL_8E1: 1 start bit, 8 data bits, 1 Even parity bit, 1 stop bit
SERIAL_8O1: 1 start bit, 8 data bits, 1 Odd parity bit, 1 stop bit

You can obviously use SERIAL_8N1 but this does not adhere to the
Modbus specifications. That said, I have tested the SERIAL_8N1 option
on various commercial masters and slaves that were suppose to adhere
to this specification and was always able to communicate... Go figure.

These are already defined in the Arduino global name space.
*/
modbus_configure(&Serial, baud, SERIAL_8N2, timeout, polling, retry_count, TxEnablePin, packets, TOTAL_NO_OF_PACKETS);

pinMode(LED, OUTPUT);
}

void loop()
{
modbus_update();

writeRegs[0] = analogRead(A0); // update data to be written to arduino slave

analogWrite(LED, readRegs[0]>>2); // constrain adc value from the arduino slave to 255

/* You can check or alter the internal counters of a specific packet like this:
packet1->requests;
packet1->successful_requests;
packet1->failed_requests;
packet1->exception_errors;
packet2->requests;
packet2->successful_requests;
packet2->failed_requests;
packet2->exception_errors;
*/
}

Hmm got it half working now :slight_smile:

When i change the next code on the master between packet2 and PRESET_MULTIPLE_REGISTERS

// write 1 register starting at address 1
modbus_construct(packet2, 2, PRESET_MULTIPLE_REGISTERS, 1, 1, writeRegs);

And on the slave i change the last digit to 2

modbus_update_comms(9600, SERIAL_8N2, 2);

Then he sees indeed the command comming in 8).

But now the slave wont report back tot the master :sleeping:.

*edit

Never mind :cold_sweat: then i also have to change the read command to listen to module 2 ]:smiley: it works now! Time to test more.