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;
*/
}