LIBRERA MODBUS
****************************************************************************/
*Modbus master
* INPUTS
* slave: modbus slave id number
* start_addr: address of the slave's first register (+1)
* reg_count: number of consecutive registers to preset
* data: array of words (ints) with the data to write into the slave
* RETURNS: the number of bytes received as response on success, or
*
*/
int preset_multiple_registers(int slave, int start_addr,
int reg_count, int *data);
/*
* read_holding_registers: Modbus function 3. Read the holding registers
* in a slave and put the data into an array
* INPUTS
* slave: modbus slave id number
* start_addr: address of the slave's first register (+1)
* count: number of consecutive registers to read
* dest: array of words (ints) on which the read data is to be stored
* dest_size: size of the array, which should be at least 'count'
* RETURNS: the number of bytes received as response on success, or
*
*/
void setup()
{
const int baudrate = 9600;
if (baudrate <= 19200)
interframe_delay = (unsigned long)(3.5 * 11 / baudrate); /*
Modbus t3.5 */
Serial.begin(baudrate);
Modbus spec. */
/* example data */
int retval;
int data[10];
void loop()
{
/* example, this will write some data in the first 10 registers of slave 1
*/
retval = preset_multiple_registers(1,1,10, data);
data[0] = retval;
data[1]++;
data[8]=0xdead;
data[9] = 0xbeaf;
delay(500);
}
/****************************************************************************
* BEGIN MODBUS RTU MASTER FUNCTIONS
****************************************************************************/
/* 1 second */
/*
CRC
INPUTS:
buf -> Array containing message to be sent to controller.
start -> Start of loop in crc counter, usually 0.
cnt -> Amount of bytes in message being sent to controller/
OUTPUTS:
temp -> Returns crc byte for message.
COMMENTS:
This routine calculates the crc high and low byte of a message.
Note that this crc is only used for Modbus, not Modbus+ etc.
****************************************************************************/
temp = 0xFFFF;
return (temp);
}
/***********************************************************************
*
*
*
***********************************************************************/
#define REQUEST_QUERY_SIZE 6
*/
#define CHECKSUM_SIZE 2
plus */
*/
/*************************************************************************
*
* modbus_query( packet, length)
*
* Function to add a checksum to the end of a packet.
* Please note that the packet array must be at least 2 fields longer than
* string_length.
**************************************************************************/
/***********************************************************************
*
* send_query(query_string, query_length )
*
* Function to send a query out to a modbus slave.
************************************************************************/
int i;
modbus_query(query, string_length);
string_length += 2;
return i;
though */
/***********************************************************************
*
receive_response( array_for_data )
*
* Function to monitor for the reply from the modbus slave.
* This function blocks for timeout seconds if there is no reply.
*
* Returns:
***********************************************************************/
int bytes_received = 0;
int i = 0;
/* wait for a response; this will block! */
while(Serial.available() == 0) {
delay(1);
if (i++ > TIMEOUT)
return bytes_received;
}
return (bytes_received);
}
/*********************************************************************
*
*
*
* Function to the correct response is returned and that the checksum
* is correct.
*
* Returns:
string_length if OK
0 if failed
*
*
*
**********************************************************************/
do {
if (response_length) {
if (crc_calc != crc_received) {
response_length = 0;
}
/************************************************************************
*
*
read_reg_response
*
*
reads the response data from a slave and puts the data into an
array.
*
************************************************************************/
if (raw_response_length > 0) {
/* FIXME: data[2] * 2 ???!!! data[2] isn't already the byte count
(number of registers * 2)?! */
for (i = 0;
i < (data[2] * 2) && i < (raw_response_length / 2);
i++) {
*/
dest[i] = temp;
}
}
return (raw_response_length);
}
/***********************************************************************
*
*
preset_response
*
*
*
***********************************************************************/
return (raw_response_length);
}
/************************************************************************
*
*
read_holding_registers
*
*
Read the holding registers in a slave and put the data into
an array.
*************************************************************************/
int ret;
ret = -1;
}
return (ret);
}
/************************************************************************
*
*
*
preset_multiple_registers
slave.
*
*************************************************************************/
packet_size++;
if (send_query(packet, packet_size) > -1) {
ret = preset_response(packet);
}
else {
ret = -1;
}
return (ret);
}