This library meant to allow mbed boards (tested on F401RE) to act as modbus slave. I don't own this work, I just made some simple modifications so that it runs on mbed. My modification were labeled with "afdhal". Summary: Modified modbus Arduino library for mbed. See readme for more details. Feel free to use it as you want. Special thanks to the original authors.

Dependents:   ModbusRTU-RS232 FoodComputerARM-alpha

Committer:
AfdhalAtiffTan
Date:
Thu Jul 21 19:48:35 2016 +0000
Revision:
0:6262fc7582a9
Child:
1:35fdc7056f66
Modified Arduino library for mbed.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
AfdhalAtiffTan 0:6262fc7582a9 1 /*
AfdhalAtiffTan 0:6262fc7582a9 2 Modbus over serial line - RTU Slave Arduino Sketch
AfdhalAtiffTan 0:6262fc7582a9 3
AfdhalAtiffTan 0:6262fc7582a9 4 By Juan Pablo Zometa : jpmzometa@gmail.com
AfdhalAtiffTan 0:6262fc7582a9 5 http://sites.google.com/site/jpmzometa/
AfdhalAtiffTan 0:6262fc7582a9 6 Samuel Marco: sammarcoarmengol@gmail.com
AfdhalAtiffTan 0:6262fc7582a9 7 and Andras Tucsni.
AfdhalAtiffTan 0:6262fc7582a9 8
AfdhalAtiffTan 0:6262fc7582a9 9 These functions implement functions 3, 6, and 16 (read holding registers,
AfdhalAtiffTan 0:6262fc7582a9 10 preset single register and preset multiple registers) of the
AfdhalAtiffTan 0:6262fc7582a9 11 Modbus RTU Protocol, to be used over the Arduino serial connection.
AfdhalAtiffTan 0:6262fc7582a9 12
AfdhalAtiffTan 0:6262fc7582a9 13 This implementation DOES NOT fully comply with the Modbus specifications.
AfdhalAtiffTan 0:6262fc7582a9 14
AfdhalAtiffTan 0:6262fc7582a9 15 This Arduino adaptation is derived from the work
AfdhalAtiffTan 0:6262fc7582a9 16 By P.Costigan email: phil@pcscada.com.au http://pcscada.com.au
AfdhalAtiffTan 0:6262fc7582a9 17
AfdhalAtiffTan 0:6262fc7582a9 18 These library of functions are designed to enable a program send and
AfdhalAtiffTan 0:6262fc7582a9 19 receive data from a device that communicates using the Modbus protocol.
AfdhalAtiffTan 0:6262fc7582a9 20
AfdhalAtiffTan 0:6262fc7582a9 21 Copyright (C) 2000 Philip Costigan P.C. SCADA LINK PTY. LTD.
AfdhalAtiffTan 0:6262fc7582a9 22
AfdhalAtiffTan 0:6262fc7582a9 23 This program is free software; you can redistribute it and/or modify
AfdhalAtiffTan 0:6262fc7582a9 24 it under the terms of the GNU General Public License as published by
AfdhalAtiffTan 0:6262fc7582a9 25 the Free Software Foundation; either version 2 of the License, or
AfdhalAtiffTan 0:6262fc7582a9 26 (at your option) any later version.
AfdhalAtiffTan 0:6262fc7582a9 27
AfdhalAtiffTan 0:6262fc7582a9 28 This program is distributed in the hope that it will be useful,
AfdhalAtiffTan 0:6262fc7582a9 29 but WITHOUT ANY WARRANTY; without even the implied warranty of
AfdhalAtiffTan 0:6262fc7582a9 30 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
AfdhalAtiffTan 0:6262fc7582a9 31 GNU General Public License for more details.
AfdhalAtiffTan 0:6262fc7582a9 32
AfdhalAtiffTan 0:6262fc7582a9 33 You should have received a copy of the GNU General Public License
AfdhalAtiffTan 0:6262fc7582a9 34 along with this program; if not, write to the Free Software
AfdhalAtiffTan 0:6262fc7582a9 35 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
AfdhalAtiffTan 0:6262fc7582a9 36
AfdhalAtiffTan 0:6262fc7582a9 37 The functions included here have been derived from the
AfdhalAtiffTan 0:6262fc7582a9 38 Modicon Modbus Protocol Reference Guide
AfdhalAtiffTan 0:6262fc7582a9 39 which can be obtained from Schneider at www.schneiderautomation.com.
AfdhalAtiffTan 0:6262fc7582a9 40
AfdhalAtiffTan 0:6262fc7582a9 41 This code has its origins with
AfdhalAtiffTan 0:6262fc7582a9 42 paul@pmcrae.freeserve.co.uk (http://www.pmcrae.freeserve.co.uk)
AfdhalAtiffTan 0:6262fc7582a9 43 who wrote a small program to read 100 registers from a modbus slave.
AfdhalAtiffTan 0:6262fc7582a9 44
AfdhalAtiffTan 0:6262fc7582a9 45 I have used his code as a catalist to produce this more functional set
AfdhalAtiffTan 0:6262fc7582a9 46 of functions. Thanks paul.
AfdhalAtiffTan 0:6262fc7582a9 47 */
AfdhalAtiffTan 0:6262fc7582a9 48
AfdhalAtiffTan 0:6262fc7582a9 49
AfdhalAtiffTan 0:6262fc7582a9 50 //#include "Arduino.h" //afdhal
AfdhalAtiffTan 0:6262fc7582a9 51 #include "millis.h"
AfdhalAtiffTan 0:6262fc7582a9 52 #include "MODSERIAL.h" //afdhal
AfdhalAtiffTan 0:6262fc7582a9 53 MODSERIAL pc(USBTX, USBRX); // tx, rx //afdhal
AfdhalAtiffTan 0:6262fc7582a9 54
AfdhalAtiffTan 0:6262fc7582a9 55 #ifndef ModbusSlave232_h
AfdhalAtiffTan 0:6262fc7582a9 56 #include "ModbusSlave232.h"
AfdhalAtiffTan 0:6262fc7582a9 57 #endif
AfdhalAtiffTan 0:6262fc7582a9 58
AfdhalAtiffTan 0:6262fc7582a9 59
AfdhalAtiffTan 0:6262fc7582a9 60 /****************************************************************************
AfdhalAtiffTan 0:6262fc7582a9 61 * BEGIN MODBUS RTU SLAVE FUNCTIONS
AfdhalAtiffTan 0:6262fc7582a9 62 ****************************************************************************/
AfdhalAtiffTan 0:6262fc7582a9 63
AfdhalAtiffTan 0:6262fc7582a9 64 /* constants */
AfdhalAtiffTan 0:6262fc7582a9 65 enum {
AfdhalAtiffTan 0:6262fc7582a9 66 MAX_READ_REGS = 0x7D,
AfdhalAtiffTan 0:6262fc7582a9 67 MAX_WRITE_REGS = 0x7B,
AfdhalAtiffTan 0:6262fc7582a9 68 MAX_MESSAGE_LENGTH = 256
AfdhalAtiffTan 0:6262fc7582a9 69 };
AfdhalAtiffTan 0:6262fc7582a9 70
AfdhalAtiffTan 0:6262fc7582a9 71
AfdhalAtiffTan 0:6262fc7582a9 72 enum {
AfdhalAtiffTan 0:6262fc7582a9 73 RESPONSE_SIZE = 6,
AfdhalAtiffTan 0:6262fc7582a9 74 EXCEPTION_SIZE = 3,
AfdhalAtiffTan 0:6262fc7582a9 75 CHECKSUM_SIZE = 2
AfdhalAtiffTan 0:6262fc7582a9 76 };
AfdhalAtiffTan 0:6262fc7582a9 77
AfdhalAtiffTan 0:6262fc7582a9 78 /* exceptions code */
AfdhalAtiffTan 0:6262fc7582a9 79 enum {
AfdhalAtiffTan 0:6262fc7582a9 80 NO_REPLY = -1,
AfdhalAtiffTan 0:6262fc7582a9 81 EXC_FUNC_CODE = 1,
AfdhalAtiffTan 0:6262fc7582a9 82 EXC_ADDR_RANGE = 2,
AfdhalAtiffTan 0:6262fc7582a9 83 EXC_REGS_QUANT = 3,
AfdhalAtiffTan 0:6262fc7582a9 84 EXC_EXECUTE = 4
AfdhalAtiffTan 0:6262fc7582a9 85 };
AfdhalAtiffTan 0:6262fc7582a9 86
AfdhalAtiffTan 0:6262fc7582a9 87 /* positions inside the query/response array */
AfdhalAtiffTan 0:6262fc7582a9 88 enum {
AfdhalAtiffTan 0:6262fc7582a9 89 SLAVE = 0,
AfdhalAtiffTan 0:6262fc7582a9 90 FUNC,
AfdhalAtiffTan 0:6262fc7582a9 91 START_H,
AfdhalAtiffTan 0:6262fc7582a9 92 START_L,
AfdhalAtiffTan 0:6262fc7582a9 93 REGS_H,
AfdhalAtiffTan 0:6262fc7582a9 94 REGS_L,
AfdhalAtiffTan 0:6262fc7582a9 95 BYTE_CNT
AfdhalAtiffTan 0:6262fc7582a9 96 };
AfdhalAtiffTan 0:6262fc7582a9 97
AfdhalAtiffTan 0:6262fc7582a9 98
AfdhalAtiffTan 0:6262fc7582a9 99 /* enum of supported modbus function codes. If you implement a new one, put its function code here ! */
AfdhalAtiffTan 0:6262fc7582a9 100 enum {
AfdhalAtiffTan 0:6262fc7582a9 101 FC_READ_REGS = 0x03, //Read contiguous block of holding register
AfdhalAtiffTan 0:6262fc7582a9 102 FC_WRITE_REG = 0x06, //Write single holding register
AfdhalAtiffTan 0:6262fc7582a9 103 FC_WRITE_REGS = 0x10 //Write block of contiguous registers
AfdhalAtiffTan 0:6262fc7582a9 104 };
AfdhalAtiffTan 0:6262fc7582a9 105
AfdhalAtiffTan 0:6262fc7582a9 106 /* supported functions. If you implement a new one, put its function code into this array! */
AfdhalAtiffTan 0:6262fc7582a9 107 const unsigned char fsupported[] = { FC_READ_REGS, FC_WRITE_REG, FC_WRITE_REGS };
AfdhalAtiffTan 0:6262fc7582a9 108
AfdhalAtiffTan 0:6262fc7582a9 109
AfdhalAtiffTan 0:6262fc7582a9 110 /*
AfdhalAtiffTan 0:6262fc7582a9 111 CRC
AfdhalAtiffTan 0:6262fc7582a9 112
AfdhalAtiffTan 0:6262fc7582a9 113 INPUTS:
AfdhalAtiffTan 0:6262fc7582a9 114 buf -> Array containing message to be sent to controller.
AfdhalAtiffTan 0:6262fc7582a9 115 start -> Start of loop in crc counter, usually 0.
AfdhalAtiffTan 0:6262fc7582a9 116 cnt -> Amount of bytes in message being sent to controller/
AfdhalAtiffTan 0:6262fc7582a9 117 OUTPUTS:
AfdhalAtiffTan 0:6262fc7582a9 118 temp -> Returns crc byte for message.
AfdhalAtiffTan 0:6262fc7582a9 119 COMMENTS:
AfdhalAtiffTan 0:6262fc7582a9 120 This routine calculates the crc high and low byte of a message.
AfdhalAtiffTan 0:6262fc7582a9 121 Note that this crc is only used for Modbus, not Modbus+ etc.
AfdhalAtiffTan 0:6262fc7582a9 122 ****************************************************************************/
AfdhalAtiffTan 0:6262fc7582a9 123
AfdhalAtiffTan 0:6262fc7582a9 124 unsigned int ModbusSlave232::crc(unsigned char *buf, unsigned char start,
AfdhalAtiffTan 0:6262fc7582a9 125 unsigned char cnt)
AfdhalAtiffTan 0:6262fc7582a9 126 {
AfdhalAtiffTan 0:6262fc7582a9 127 unsigned char i, j;
AfdhalAtiffTan 0:6262fc7582a9 128 unsigned temp, temp2, flag;
AfdhalAtiffTan 0:6262fc7582a9 129
AfdhalAtiffTan 0:6262fc7582a9 130 temp = 0xFFFF;
AfdhalAtiffTan 0:6262fc7582a9 131
AfdhalAtiffTan 0:6262fc7582a9 132 for (i = start; i < cnt; i++) {
AfdhalAtiffTan 0:6262fc7582a9 133 temp = temp ^ buf[i];
AfdhalAtiffTan 0:6262fc7582a9 134
AfdhalAtiffTan 0:6262fc7582a9 135 for (j = 1; j <= 8; j++) {
AfdhalAtiffTan 0:6262fc7582a9 136 flag = temp & 0x0001;
AfdhalAtiffTan 0:6262fc7582a9 137 temp = temp >> 1;
AfdhalAtiffTan 0:6262fc7582a9 138 if (flag)
AfdhalAtiffTan 0:6262fc7582a9 139 temp = temp ^ 0xA001;
AfdhalAtiffTan 0:6262fc7582a9 140 }
AfdhalAtiffTan 0:6262fc7582a9 141 }
AfdhalAtiffTan 0:6262fc7582a9 142
AfdhalAtiffTan 0:6262fc7582a9 143 /* Reverse byte order. */
AfdhalAtiffTan 0:6262fc7582a9 144 temp2 = temp >> 8;
AfdhalAtiffTan 0:6262fc7582a9 145 temp = (temp << 8) | temp2;
AfdhalAtiffTan 0:6262fc7582a9 146 temp &= 0xFFFF;
AfdhalAtiffTan 0:6262fc7582a9 147
AfdhalAtiffTan 0:6262fc7582a9 148 return (temp);
AfdhalAtiffTan 0:6262fc7582a9 149 }
AfdhalAtiffTan 0:6262fc7582a9 150
AfdhalAtiffTan 0:6262fc7582a9 151
AfdhalAtiffTan 0:6262fc7582a9 152
AfdhalAtiffTan 0:6262fc7582a9 153
AfdhalAtiffTan 0:6262fc7582a9 154 /***********************************************************************
AfdhalAtiffTan 0:6262fc7582a9 155 *
AfdhalAtiffTan 0:6262fc7582a9 156 * The following functions construct the required query into
AfdhalAtiffTan 0:6262fc7582a9 157 * a modbus query packet.
AfdhalAtiffTan 0:6262fc7582a9 158 *
AfdhalAtiffTan 0:6262fc7582a9 159 ***********************************************************************/
AfdhalAtiffTan 0:6262fc7582a9 160
AfdhalAtiffTan 0:6262fc7582a9 161 /*
AfdhalAtiffTan 0:6262fc7582a9 162 * Start of the packet of a read_holding_register response
AfdhalAtiffTan 0:6262fc7582a9 163 */
AfdhalAtiffTan 0:6262fc7582a9 164 void ModbusSlave232::build_read_packet(unsigned char function,
AfdhalAtiffTan 0:6262fc7582a9 165 unsigned char count, unsigned char *packet)
AfdhalAtiffTan 0:6262fc7582a9 166 {
AfdhalAtiffTan 0:6262fc7582a9 167 packet[SLAVE] = slave;
AfdhalAtiffTan 0:6262fc7582a9 168 packet[FUNC] = function;
AfdhalAtiffTan 0:6262fc7582a9 169 packet[2] = count * 2;
AfdhalAtiffTan 0:6262fc7582a9 170 }
AfdhalAtiffTan 0:6262fc7582a9 171
AfdhalAtiffTan 0:6262fc7582a9 172 /*
AfdhalAtiffTan 0:6262fc7582a9 173 * Start of the packet of a preset_multiple_register response
AfdhalAtiffTan 0:6262fc7582a9 174 */
AfdhalAtiffTan 0:6262fc7582a9 175 void ModbusSlave232::build_write_packet(unsigned char function,
AfdhalAtiffTan 0:6262fc7582a9 176 unsigned int start_addr,
AfdhalAtiffTan 0:6262fc7582a9 177 unsigned char count,
AfdhalAtiffTan 0:6262fc7582a9 178 unsigned char *packet)
AfdhalAtiffTan 0:6262fc7582a9 179 {
AfdhalAtiffTan 0:6262fc7582a9 180 packet[SLAVE] = slave;
AfdhalAtiffTan 0:6262fc7582a9 181 packet[FUNC] = function;
AfdhalAtiffTan 0:6262fc7582a9 182 packet[START_H] = start_addr >> 8;
AfdhalAtiffTan 0:6262fc7582a9 183 packet[START_L] = start_addr & 0x00ff;
AfdhalAtiffTan 0:6262fc7582a9 184 packet[REGS_H] = 0x00;
AfdhalAtiffTan 0:6262fc7582a9 185 packet[REGS_L] = count;
AfdhalAtiffTan 0:6262fc7582a9 186 }
AfdhalAtiffTan 0:6262fc7582a9 187
AfdhalAtiffTan 0:6262fc7582a9 188 /*
AfdhalAtiffTan 0:6262fc7582a9 189 * Start of the packet of a write_single_register response
AfdhalAtiffTan 0:6262fc7582a9 190 */
AfdhalAtiffTan 0:6262fc7582a9 191 void ModbusSlave232::build_write_single_packet(unsigned char function,
AfdhalAtiffTan 0:6262fc7582a9 192 unsigned int write_addr, unsigned int reg_val, unsigned char* packet)
AfdhalAtiffTan 0:6262fc7582a9 193 {
AfdhalAtiffTan 0:6262fc7582a9 194 packet[SLAVE] = slave;
AfdhalAtiffTan 0:6262fc7582a9 195 packet[FUNC] = function;
AfdhalAtiffTan 0:6262fc7582a9 196 packet[START_H] = write_addr >> 8;
AfdhalAtiffTan 0:6262fc7582a9 197 packet[START_L] = write_addr & 0x00ff;
AfdhalAtiffTan 0:6262fc7582a9 198 packet[REGS_H] = reg_val >> 8;
AfdhalAtiffTan 0:6262fc7582a9 199 packet[REGS_L] = reg_val & 0x00ff;
AfdhalAtiffTan 0:6262fc7582a9 200 }
AfdhalAtiffTan 0:6262fc7582a9 201
AfdhalAtiffTan 0:6262fc7582a9 202
AfdhalAtiffTan 0:6262fc7582a9 203 /*
AfdhalAtiffTan 0:6262fc7582a9 204 * Start of the packet of an exception response
AfdhalAtiffTan 0:6262fc7582a9 205 */
AfdhalAtiffTan 0:6262fc7582a9 206 void ModbusSlave232::build_error_packet( unsigned char function,
AfdhalAtiffTan 0:6262fc7582a9 207 unsigned char exception, unsigned char *packet)
AfdhalAtiffTan 0:6262fc7582a9 208 {
AfdhalAtiffTan 0:6262fc7582a9 209 packet[SLAVE] = slave;
AfdhalAtiffTan 0:6262fc7582a9 210 packet[FUNC] = function + 0x80;
AfdhalAtiffTan 0:6262fc7582a9 211 packet[2] = exception;
AfdhalAtiffTan 0:6262fc7582a9 212 }
AfdhalAtiffTan 0:6262fc7582a9 213
AfdhalAtiffTan 0:6262fc7582a9 214
AfdhalAtiffTan 0:6262fc7582a9 215 /*************************************************************************
AfdhalAtiffTan 0:6262fc7582a9 216 *
AfdhalAtiffTan 0:6262fc7582a9 217 * modbus_query( packet, length)
AfdhalAtiffTan 0:6262fc7582a9 218 *
AfdhalAtiffTan 0:6262fc7582a9 219 * Function to add a checksum to the end of a packet.
AfdhalAtiffTan 0:6262fc7582a9 220 * Please note that the packet array must be at least 2 fields longer than
AfdhalAtiffTan 0:6262fc7582a9 221 * string_length.
AfdhalAtiffTan 0:6262fc7582a9 222 **************************************************************************/
AfdhalAtiffTan 0:6262fc7582a9 223
AfdhalAtiffTan 0:6262fc7582a9 224 void ModbusSlave232::modbus_reply(unsigned char *packet, unsigned char string_length)
AfdhalAtiffTan 0:6262fc7582a9 225 {
AfdhalAtiffTan 0:6262fc7582a9 226 int temp_crc;
AfdhalAtiffTan 0:6262fc7582a9 227
AfdhalAtiffTan 0:6262fc7582a9 228 temp_crc = crc(packet, 0, string_length);
AfdhalAtiffTan 0:6262fc7582a9 229 packet[string_length] = temp_crc >> 8;
AfdhalAtiffTan 0:6262fc7582a9 230 string_length++;
AfdhalAtiffTan 0:6262fc7582a9 231 packet[string_length] = temp_crc & 0x00FF;
AfdhalAtiffTan 0:6262fc7582a9 232 }
AfdhalAtiffTan 0:6262fc7582a9 233
AfdhalAtiffTan 0:6262fc7582a9 234
AfdhalAtiffTan 0:6262fc7582a9 235
AfdhalAtiffTan 0:6262fc7582a9 236 /***********************************************************************
AfdhalAtiffTan 0:6262fc7582a9 237 *
AfdhalAtiffTan 0:6262fc7582a9 238 * send_reply( query_string, query_length )
AfdhalAtiffTan 0:6262fc7582a9 239 *
AfdhalAtiffTan 0:6262fc7582a9 240 * Function to send a reply to a modbus master.
AfdhalAtiffTan 0:6262fc7582a9 241 * Returns: total number of characters sent
AfdhalAtiffTan 0:6262fc7582a9 242 ************************************************************************/
AfdhalAtiffTan 0:6262fc7582a9 243
AfdhalAtiffTan 0:6262fc7582a9 244 int ModbusSlave232::send_reply(unsigned char *query, unsigned char string_length)
AfdhalAtiffTan 0:6262fc7582a9 245 {
AfdhalAtiffTan 0:6262fc7582a9 246 unsigned char i;
AfdhalAtiffTan 0:6262fc7582a9 247
AfdhalAtiffTan 0:6262fc7582a9 248 /*if (txenpin > 1) { // set MAX485 to speak mode //afdhal
AfdhalAtiffTan 0:6262fc7582a9 249 UCSR0A=UCSR0A |(1 << TXC0);
AfdhalAtiffTan 0:6262fc7582a9 250 digitalWrite( txenpin, HIGH);
AfdhalAtiffTan 0:6262fc7582a9 251 delay(1);
AfdhalAtiffTan 0:6262fc7582a9 252 }*/
AfdhalAtiffTan 0:6262fc7582a9 253
AfdhalAtiffTan 0:6262fc7582a9 254 modbus_reply(query, string_length);
AfdhalAtiffTan 0:6262fc7582a9 255 string_length += 2;
AfdhalAtiffTan 0:6262fc7582a9 256
AfdhalAtiffTan 0:6262fc7582a9 257 for (i = 0; i < string_length; i++) {
AfdhalAtiffTan 0:6262fc7582a9 258 //Serial.print(char(query[i])); //afdhal
AfdhalAtiffTan 0:6262fc7582a9 259 pc.putc(char(query[i])); //afdhal
AfdhalAtiffTan 0:6262fc7582a9 260
AfdhalAtiffTan 0:6262fc7582a9 261 }
AfdhalAtiffTan 0:6262fc7582a9 262
AfdhalAtiffTan 0:6262fc7582a9 263 return i; /* it does not mean that the write was succesful, though */
AfdhalAtiffTan 0:6262fc7582a9 264 }
AfdhalAtiffTan 0:6262fc7582a9 265
AfdhalAtiffTan 0:6262fc7582a9 266 /***********************************************************************
AfdhalAtiffTan 0:6262fc7582a9 267 *
AfdhalAtiffTan 0:6262fc7582a9 268 * receive_request( array_for_data )
AfdhalAtiffTan 0:6262fc7582a9 269 *
AfdhalAtiffTan 0:6262fc7582a9 270 * Function to monitor for a request from the modbus master.
AfdhalAtiffTan 0:6262fc7582a9 271 *
AfdhalAtiffTan 0:6262fc7582a9 272 * Returns: Total number of characters received if OK
AfdhalAtiffTan 0:6262fc7582a9 273 * 0 if there is no request
AfdhalAtiffTan 0:6262fc7582a9 274 * A negative error code on failure
AfdhalAtiffTan 0:6262fc7582a9 275 ***********************************************************************/
AfdhalAtiffTan 0:6262fc7582a9 276
AfdhalAtiffTan 0:6262fc7582a9 277 int ModbusSlave232::receive_request(unsigned char *received_string)
AfdhalAtiffTan 0:6262fc7582a9 278 {
AfdhalAtiffTan 0:6262fc7582a9 279 int bytes_received = 0;
AfdhalAtiffTan 0:6262fc7582a9 280
AfdhalAtiffTan 0:6262fc7582a9 281 /* FIXME: does Serial.available wait 1.5T or 3.5T before exiting the loop? */
AfdhalAtiffTan 0:6262fc7582a9 282 //while (Serial.available()) { //afdhal
AfdhalAtiffTan 0:6262fc7582a9 283 while (pc.readable()) { //afdhal
AfdhalAtiffTan 0:6262fc7582a9 284 received_string[bytes_received] = pc.getc(); //Serial.read(); //afdhal
AfdhalAtiffTan 0:6262fc7582a9 285 //Serial.print(received_string[bytes_received], DEC);
AfdhalAtiffTan 0:6262fc7582a9 286 bytes_received++;
AfdhalAtiffTan 0:6262fc7582a9 287 if (bytes_received >= MAX_MESSAGE_LENGTH)
AfdhalAtiffTan 0:6262fc7582a9 288 return NO_REPLY; /* port error */
AfdhalAtiffTan 0:6262fc7582a9 289 }
AfdhalAtiffTan 0:6262fc7582a9 290
AfdhalAtiffTan 0:6262fc7582a9 291 return (bytes_received);
AfdhalAtiffTan 0:6262fc7582a9 292 }
AfdhalAtiffTan 0:6262fc7582a9 293
AfdhalAtiffTan 0:6262fc7582a9 294
AfdhalAtiffTan 0:6262fc7582a9 295 /*********************************************************************
AfdhalAtiffTan 0:6262fc7582a9 296 *
AfdhalAtiffTan 0:6262fc7582a9 297 * modbus_request(request_data_array)
AfdhalAtiffTan 0:6262fc7582a9 298 *
AfdhalAtiffTan 0:6262fc7582a9 299 * Function to the correct request is returned and that the checksum
AfdhalAtiffTan 0:6262fc7582a9 300 * is correct.
AfdhalAtiffTan 0:6262fc7582a9 301 *
AfdhalAtiffTan 0:6262fc7582a9 302 * Returns: string_length if OK
AfdhalAtiffTan 0:6262fc7582a9 303 * 0 if failed
AfdhalAtiffTan 0:6262fc7582a9 304 * Less than 0 for exception errors
AfdhalAtiffTan 0:6262fc7582a9 305 *
AfdhalAtiffTan 0:6262fc7582a9 306 * Note: All functions used for sending or receiving data via
AfdhalAtiffTan 0:6262fc7582a9 307 * modbus return these return values.
AfdhalAtiffTan 0:6262fc7582a9 308 *
AfdhalAtiffTan 0:6262fc7582a9 309 **********************************************************************/
AfdhalAtiffTan 0:6262fc7582a9 310
AfdhalAtiffTan 0:6262fc7582a9 311 int ModbusSlave232::modbus_request(unsigned char *data)
AfdhalAtiffTan 0:6262fc7582a9 312 {
AfdhalAtiffTan 0:6262fc7582a9 313 int response_length;
AfdhalAtiffTan 0:6262fc7582a9 314 unsigned int crc_calc = 0;
AfdhalAtiffTan 0:6262fc7582a9 315 unsigned int crc_received = 0;
AfdhalAtiffTan 0:6262fc7582a9 316 unsigned char recv_crc_hi;
AfdhalAtiffTan 0:6262fc7582a9 317 unsigned char recv_crc_lo;
AfdhalAtiffTan 0:6262fc7582a9 318
AfdhalAtiffTan 0:6262fc7582a9 319 response_length = receive_request(data);
AfdhalAtiffTan 0:6262fc7582a9 320
AfdhalAtiffTan 0:6262fc7582a9 321 if (response_length > 0) {
AfdhalAtiffTan 0:6262fc7582a9 322 crc_calc = crc(data, 0, response_length - 2);
AfdhalAtiffTan 0:6262fc7582a9 323 recv_crc_hi = (unsigned) data[response_length - 2];
AfdhalAtiffTan 0:6262fc7582a9 324 recv_crc_lo = (unsigned) data[response_length - 1];
AfdhalAtiffTan 0:6262fc7582a9 325 crc_received = data[response_length - 2];
AfdhalAtiffTan 0:6262fc7582a9 326 crc_received = (unsigned) crc_received << 8;
AfdhalAtiffTan 0:6262fc7582a9 327 crc_received =
AfdhalAtiffTan 0:6262fc7582a9 328 crc_received | (unsigned) data[response_length - 1];
AfdhalAtiffTan 0:6262fc7582a9 329
AfdhalAtiffTan 0:6262fc7582a9 330 /*********** check CRC of response ************/
AfdhalAtiffTan 0:6262fc7582a9 331 if (crc_calc != crc_received) {
AfdhalAtiffTan 0:6262fc7582a9 332 return NO_REPLY;
AfdhalAtiffTan 0:6262fc7582a9 333 }
AfdhalAtiffTan 0:6262fc7582a9 334
AfdhalAtiffTan 0:6262fc7582a9 335 /* check for slave id */
AfdhalAtiffTan 0:6262fc7582a9 336 if (slave != data[SLAVE]) {
AfdhalAtiffTan 0:6262fc7582a9 337 return NO_REPLY;
AfdhalAtiffTan 0:6262fc7582a9 338 }
AfdhalAtiffTan 0:6262fc7582a9 339 }
AfdhalAtiffTan 0:6262fc7582a9 340 return (response_length);
AfdhalAtiffTan 0:6262fc7582a9 341 }
AfdhalAtiffTan 0:6262fc7582a9 342
AfdhalAtiffTan 0:6262fc7582a9 343 /*********************************************************************
AfdhalAtiffTan 0:6262fc7582a9 344 *
AfdhalAtiffTan 0:6262fc7582a9 345 * validate_request(request_data_array, request_length, available_regs)
AfdhalAtiffTan 0:6262fc7582a9 346 *
AfdhalAtiffTan 0:6262fc7582a9 347 * Function to check that the request can be processed by the slave.
AfdhalAtiffTan 0:6262fc7582a9 348 *
AfdhalAtiffTan 0:6262fc7582a9 349 * Returns: 0 if OK
AfdhalAtiffTan 0:6262fc7582a9 350 * A negative exception code on error
AfdhalAtiffTan 0:6262fc7582a9 351 *
AfdhalAtiffTan 0:6262fc7582a9 352 **********************************************************************/
AfdhalAtiffTan 0:6262fc7582a9 353
AfdhalAtiffTan 0:6262fc7582a9 354 int ModbusSlave232::validate_request(unsigned char *data, unsigned char length,
AfdhalAtiffTan 0:6262fc7582a9 355 unsigned int regs_size)
AfdhalAtiffTan 0:6262fc7582a9 356 {
AfdhalAtiffTan 0:6262fc7582a9 357 int i, fcnt = 0;
AfdhalAtiffTan 0:6262fc7582a9 358 unsigned int regs_num = 0;
AfdhalAtiffTan 0:6262fc7582a9 359 unsigned int start_addr = 0;
AfdhalAtiffTan 0:6262fc7582a9 360 unsigned char max_regs_num;
AfdhalAtiffTan 0:6262fc7582a9 361
AfdhalAtiffTan 0:6262fc7582a9 362 /* check function code */
AfdhalAtiffTan 0:6262fc7582a9 363 for (i = 0; i < sizeof(fsupported); i++) {
AfdhalAtiffTan 0:6262fc7582a9 364 if (fsupported[i] == data[FUNC]) {
AfdhalAtiffTan 0:6262fc7582a9 365 fcnt = 1;
AfdhalAtiffTan 0:6262fc7582a9 366 break;
AfdhalAtiffTan 0:6262fc7582a9 367 }
AfdhalAtiffTan 0:6262fc7582a9 368 }
AfdhalAtiffTan 0:6262fc7582a9 369 if (0 == fcnt)
AfdhalAtiffTan 0:6262fc7582a9 370 return EXC_FUNC_CODE;
AfdhalAtiffTan 0:6262fc7582a9 371
AfdhalAtiffTan 0:6262fc7582a9 372 if (FC_WRITE_REG == data[FUNC]) {
AfdhalAtiffTan 0:6262fc7582a9 373 /* For function write single reg, this is the target reg.*/
AfdhalAtiffTan 0:6262fc7582a9 374 regs_num = ((int) data[START_H] << 8) + (int) data[START_L];
AfdhalAtiffTan 0:6262fc7582a9 375 if (regs_num >= regs_size)
AfdhalAtiffTan 0:6262fc7582a9 376 return EXC_ADDR_RANGE;
AfdhalAtiffTan 0:6262fc7582a9 377 return 0;
AfdhalAtiffTan 0:6262fc7582a9 378 }
AfdhalAtiffTan 0:6262fc7582a9 379
AfdhalAtiffTan 0:6262fc7582a9 380 /* For functions read/write regs, this is the range. */
AfdhalAtiffTan 0:6262fc7582a9 381 regs_num = ((int) data[REGS_H] << 8) + (int) data[REGS_L];
AfdhalAtiffTan 0:6262fc7582a9 382
AfdhalAtiffTan 0:6262fc7582a9 383 /* check quantity of registers */
AfdhalAtiffTan 0:6262fc7582a9 384 if (FC_READ_REGS == data[FUNC])
AfdhalAtiffTan 0:6262fc7582a9 385 max_regs_num = MAX_READ_REGS;
AfdhalAtiffTan 0:6262fc7582a9 386 else if (FC_WRITE_REGS == data[FUNC])
AfdhalAtiffTan 0:6262fc7582a9 387 max_regs_num = MAX_WRITE_REGS;
AfdhalAtiffTan 0:6262fc7582a9 388
AfdhalAtiffTan 0:6262fc7582a9 389 if ((regs_num < 1) || (regs_num > max_regs_num))
AfdhalAtiffTan 0:6262fc7582a9 390 return EXC_REGS_QUANT;
AfdhalAtiffTan 0:6262fc7582a9 391
AfdhalAtiffTan 0:6262fc7582a9 392 /* check registers range, start address is 0 */
AfdhalAtiffTan 0:6262fc7582a9 393 start_addr = ((int) data[START_H] << 8) + (int) data[START_L];
AfdhalAtiffTan 0:6262fc7582a9 394 if ((start_addr + regs_num) > regs_size)
AfdhalAtiffTan 0:6262fc7582a9 395 return EXC_ADDR_RANGE;
AfdhalAtiffTan 0:6262fc7582a9 396
AfdhalAtiffTan 0:6262fc7582a9 397 return 0; /* OK, no exception */
AfdhalAtiffTan 0:6262fc7582a9 398 }
AfdhalAtiffTan 0:6262fc7582a9 399
AfdhalAtiffTan 0:6262fc7582a9 400
AfdhalAtiffTan 0:6262fc7582a9 401
AfdhalAtiffTan 0:6262fc7582a9 402 /************************************************************************
AfdhalAtiffTan 0:6262fc7582a9 403 *
AfdhalAtiffTan 0:6262fc7582a9 404 * write_regs(first_register, data_array, registers_array)
AfdhalAtiffTan 0:6262fc7582a9 405 *
AfdhalAtiffTan 0:6262fc7582a9 406 * writes into the slave's holding registers the data in query,
AfdhalAtiffTan 0:6262fc7582a9 407 * starting at start_addr.
AfdhalAtiffTan 0:6262fc7582a9 408 *
AfdhalAtiffTan 0:6262fc7582a9 409 * Returns: the number of registers written
AfdhalAtiffTan 0:6262fc7582a9 410 ************************************************************************/
AfdhalAtiffTan 0:6262fc7582a9 411
AfdhalAtiffTan 0:6262fc7582a9 412 int ModbusSlave232::write_regs(unsigned int start_addr, unsigned char *query, int *regs)
AfdhalAtiffTan 0:6262fc7582a9 413 {
AfdhalAtiffTan 0:6262fc7582a9 414 int temp;
AfdhalAtiffTan 0:6262fc7582a9 415 unsigned int i;
AfdhalAtiffTan 0:6262fc7582a9 416
AfdhalAtiffTan 0:6262fc7582a9 417 for (i = 0; i < query[REGS_L]; i++) {
AfdhalAtiffTan 0:6262fc7582a9 418 /* shift reg hi_byte to temp */
AfdhalAtiffTan 0:6262fc7582a9 419 temp = (int) query[(BYTE_CNT + 1) + i * 2] << 8;
AfdhalAtiffTan 0:6262fc7582a9 420 /* OR with lo_byte */
AfdhalAtiffTan 0:6262fc7582a9 421 temp = temp | (int) query[(BYTE_CNT + 2) + i * 2];
AfdhalAtiffTan 0:6262fc7582a9 422
AfdhalAtiffTan 0:6262fc7582a9 423 regs[start_addr + i] = temp;
AfdhalAtiffTan 0:6262fc7582a9 424 }
AfdhalAtiffTan 0:6262fc7582a9 425 return i;
AfdhalAtiffTan 0:6262fc7582a9 426 }
AfdhalAtiffTan 0:6262fc7582a9 427
AfdhalAtiffTan 0:6262fc7582a9 428 /************************************************************************
AfdhalAtiffTan 0:6262fc7582a9 429 *
AfdhalAtiffTan 0:6262fc7582a9 430 * preset_multiple_registers(first_register, number_of_registers,
AfdhalAtiffTan 0:6262fc7582a9 431 * data_array, registers_array)
AfdhalAtiffTan 0:6262fc7582a9 432 *
AfdhalAtiffTan 0:6262fc7582a9 433 * Write the data from an array into the holding registers of the slave.
AfdhalAtiffTan 0:6262fc7582a9 434 *
AfdhalAtiffTan 0:6262fc7582a9 435 *************************************************************************/
AfdhalAtiffTan 0:6262fc7582a9 436
AfdhalAtiffTan 0:6262fc7582a9 437 int ModbusSlave232::preset_multiple_registers(unsigned int start_addr,
AfdhalAtiffTan 0:6262fc7582a9 438 unsigned char count,
AfdhalAtiffTan 0:6262fc7582a9 439 unsigned char *query,
AfdhalAtiffTan 0:6262fc7582a9 440 int *regs)
AfdhalAtiffTan 0:6262fc7582a9 441 {
AfdhalAtiffTan 0:6262fc7582a9 442 unsigned char function = FC_WRITE_REGS; /* Preset Multiple Registers */
AfdhalAtiffTan 0:6262fc7582a9 443 int status = 0;
AfdhalAtiffTan 0:6262fc7582a9 444 unsigned char packet[RESPONSE_SIZE + CHECKSUM_SIZE];
AfdhalAtiffTan 0:6262fc7582a9 445
AfdhalAtiffTan 0:6262fc7582a9 446 build_write_packet(function, start_addr, count, packet);
AfdhalAtiffTan 0:6262fc7582a9 447
AfdhalAtiffTan 0:6262fc7582a9 448 if (write_regs(start_addr, query, regs)) {
AfdhalAtiffTan 0:6262fc7582a9 449 status = send_reply(packet, RESPONSE_SIZE);
AfdhalAtiffTan 0:6262fc7582a9 450 }
AfdhalAtiffTan 0:6262fc7582a9 451
AfdhalAtiffTan 0:6262fc7582a9 452 return (status);
AfdhalAtiffTan 0:6262fc7582a9 453 }
AfdhalAtiffTan 0:6262fc7582a9 454
AfdhalAtiffTan 0:6262fc7582a9 455 /************************************************************************
AfdhalAtiffTan 0:6262fc7582a9 456 *
AfdhalAtiffTan 0:6262fc7582a9 457 * write_single_register(slave_id, write_addr, data_array, registers_array)
AfdhalAtiffTan 0:6262fc7582a9 458 *
AfdhalAtiffTan 0:6262fc7582a9 459 * Write a single int val into a single holding register of the slave.
AfdhalAtiffTan 0:6262fc7582a9 460 *
AfdhalAtiffTan 0:6262fc7582a9 461 *************************************************************************/
AfdhalAtiffTan 0:6262fc7582a9 462
AfdhalAtiffTan 0:6262fc7582a9 463 int ModbusSlave232::write_single_register(unsigned int write_addr, unsigned char *query, int *regs)
AfdhalAtiffTan 0:6262fc7582a9 464 {
AfdhalAtiffTan 0:6262fc7582a9 465 unsigned char function = FC_WRITE_REG; /* Function: Write Single Register */
AfdhalAtiffTan 0:6262fc7582a9 466 int status = 0;
AfdhalAtiffTan 0:6262fc7582a9 467 unsigned int reg_val;
AfdhalAtiffTan 0:6262fc7582a9 468 unsigned char packet[RESPONSE_SIZE + CHECKSUM_SIZE];
AfdhalAtiffTan 0:6262fc7582a9 469
AfdhalAtiffTan 0:6262fc7582a9 470 reg_val = query[REGS_H] << 8 | query[REGS_L];
AfdhalAtiffTan 0:6262fc7582a9 471 build_write_single_packet(function, write_addr, reg_val, packet);
AfdhalAtiffTan 0:6262fc7582a9 472 regs[write_addr] = (int) reg_val;
AfdhalAtiffTan 0:6262fc7582a9 473 /*
AfdhalAtiffTan 0:6262fc7582a9 474 written.start_addr=write_addr;
AfdhalAtiffTan 0:6262fc7582a9 475 written.num_regs=1;
AfdhalAtiffTan 0:6262fc7582a9 476 */
AfdhalAtiffTan 0:6262fc7582a9 477 status = send_reply(packet, RESPONSE_SIZE);
AfdhalAtiffTan 0:6262fc7582a9 478
AfdhalAtiffTan 0:6262fc7582a9 479 return (status);
AfdhalAtiffTan 0:6262fc7582a9 480 }
AfdhalAtiffTan 0:6262fc7582a9 481
AfdhalAtiffTan 0:6262fc7582a9 482 /************************************************************************
AfdhalAtiffTan 0:6262fc7582a9 483 *
AfdhalAtiffTan 0:6262fc7582a9 484 * read_holding_registers(first_register, number_of_registers,
AfdhalAtiffTan 0:6262fc7582a9 485 * registers_array)
AfdhalAtiffTan 0:6262fc7582a9 486 *
AfdhalAtiffTan 0:6262fc7582a9 487 * reads the slave's holdings registers and sends them to the Modbus master
AfdhalAtiffTan 0:6262fc7582a9 488 *
AfdhalAtiffTan 0:6262fc7582a9 489 *************************************************************************/
AfdhalAtiffTan 0:6262fc7582a9 490
AfdhalAtiffTan 0:6262fc7582a9 491 int ModbusSlave232::read_holding_registers( unsigned int start_addr,
AfdhalAtiffTan 0:6262fc7582a9 492
AfdhalAtiffTan 0:6262fc7582a9 493 unsigned char reg_count, int *regs)
AfdhalAtiffTan 0:6262fc7582a9 494 {
AfdhalAtiffTan 0:6262fc7582a9 495 unsigned char function = FC_READ_REGS; /* Read Holding Registers */
AfdhalAtiffTan 0:6262fc7582a9 496 int packet_size = 3;
AfdhalAtiffTan 0:6262fc7582a9 497 int status;
AfdhalAtiffTan 0:6262fc7582a9 498 unsigned int i;
AfdhalAtiffTan 0:6262fc7582a9 499 unsigned char packet[MAX_MESSAGE_LENGTH];
AfdhalAtiffTan 0:6262fc7582a9 500
AfdhalAtiffTan 0:6262fc7582a9 501 build_read_packet(function, reg_count, packet);
AfdhalAtiffTan 0:6262fc7582a9 502
AfdhalAtiffTan 0:6262fc7582a9 503 for (i = start_addr; i < (start_addr + (unsigned int) reg_count);
AfdhalAtiffTan 0:6262fc7582a9 504 i++) {
AfdhalAtiffTan 0:6262fc7582a9 505 packet[packet_size] = regs[i] >> 8;
AfdhalAtiffTan 0:6262fc7582a9 506 packet_size++;
AfdhalAtiffTan 0:6262fc7582a9 507 packet[packet_size] = regs[i] & 0x00FF;
AfdhalAtiffTan 0:6262fc7582a9 508 packet_size++;
AfdhalAtiffTan 0:6262fc7582a9 509 }
AfdhalAtiffTan 0:6262fc7582a9 510
AfdhalAtiffTan 0:6262fc7582a9 511 status = send_reply(packet, packet_size);
AfdhalAtiffTan 0:6262fc7582a9 512
AfdhalAtiffTan 0:6262fc7582a9 513 return (status);
AfdhalAtiffTan 0:6262fc7582a9 514 }
AfdhalAtiffTan 0:6262fc7582a9 515
AfdhalAtiffTan 0:6262fc7582a9 516 /*
AfdhalAtiffTan 0:6262fc7582a9 517 * configure(slave, baud, parity, txenpin)
AfdhalAtiffTan 0:6262fc7582a9 518 *
AfdhalAtiffTan 0:6262fc7582a9 519 * sets the communication parameters for of the serial line.
AfdhalAtiffTan 0:6262fc7582a9 520 *
AfdhalAtiffTan 0:6262fc7582a9 521 * slave: identification number of the slave in the Modbus network (1 to 127)
AfdhalAtiffTan 0:6262fc7582a9 522 * baud: baudrate in bps (typical values 9600, 19200... 115200)
AfdhalAtiffTan 0:6262fc7582a9 523 * parity: a single character sets the parity mode (character frame format):
AfdhalAtiffTan 0:6262fc7582a9 524 * 'n' no parity (8N1); 'e' even parity (8E1), 'o' for odd parity (8O1).
AfdhalAtiffTan 0:6262fc7582a9 525 * txenpin: arduino pin number that controls transmision/reception
AfdhalAtiffTan 0:6262fc7582a9 526 * of an external half-duplex device (e.g. a RS485 interface chip).
AfdhalAtiffTan 0:6262fc7582a9 527 * 0 or 1 disables this function (for a two-device network)
AfdhalAtiffTan 0:6262fc7582a9 528 * >2 for point-to-multipoint topology (e.g. several arduinos)
AfdhalAtiffTan 0:6262fc7582a9 529 */
AfdhalAtiffTan 0:6262fc7582a9 530
AfdhalAtiffTan 0:6262fc7582a9 531 void ModbusSlave232::configure(unsigned char slave, long baud, char parity)
AfdhalAtiffTan 0:6262fc7582a9 532 {
AfdhalAtiffTan 0:6262fc7582a9 533 this->slave = slave;
AfdhalAtiffTan 0:6262fc7582a9 534 //this->txenpin = 2; //afdhal
AfdhalAtiffTan 0:6262fc7582a9 535
AfdhalAtiffTan 0:6262fc7582a9 536
AfdhalAtiffTan 0:6262fc7582a9 537
AfdhalAtiffTan 0:6262fc7582a9 538 //Serial.begin(baud); //afdhal
AfdhalAtiffTan 0:6262fc7582a9 539 pc.baud(baud);
AfdhalAtiffTan 0:6262fc7582a9 540
AfdhalAtiffTan 0:6262fc7582a9 541 switch (parity) {
AfdhalAtiffTan 0:6262fc7582a9 542 case 'e': // 8E1
AfdhalAtiffTan 0:6262fc7582a9 543 //UCSR0C |= ((1<<UPM01) | (1<<UCSZ01) | (1<<UCSZ00)); //afdhal
AfdhalAtiffTan 0:6262fc7582a9 544 pc.format(8, SerialBase::Even, 1); //afdhal
AfdhalAtiffTan 0:6262fc7582a9 545 // UCSR0C &= ~((1<<UPM00) | (1<<UCSZ02) | (1<<USBS0));
AfdhalAtiffTan 0:6262fc7582a9 546 break;
AfdhalAtiffTan 0:6262fc7582a9 547 case 'o': // 8O1
AfdhalAtiffTan 0:6262fc7582a9 548 //UCSR0C |= ((1<<UPM01) | (1<<UPM00) | (1<<UCSZ01) | (1<<UCSZ00)); //afdhal
AfdhalAtiffTan 0:6262fc7582a9 549 pc.format(8, SerialBase::Odd, 1); //afdhal
AfdhalAtiffTan 0:6262fc7582a9 550 // UCSR0C &= ~((1<<UCSZ02) | (1<<USBS0));
AfdhalAtiffTan 0:6262fc7582a9 551 break;
AfdhalAtiffTan 0:6262fc7582a9 552 case 'n': // 8N1
AfdhalAtiffTan 0:6262fc7582a9 553 //UCSR0C |= ((1<<UCSZ01) | (1<<UCSZ00)); //afdhal
AfdhalAtiffTan 0:6262fc7582a9 554 pc.format(8, SerialBase::None, 1); //afdhal
AfdhalAtiffTan 0:6262fc7582a9 555 // UCSR0C &= ~((1<<UPM01) | (1<<UPM00) | (1<<UCSZ02) | (1<<USBS0));
AfdhalAtiffTan 0:6262fc7582a9 556 break;
AfdhalAtiffTan 0:6262fc7582a9 557 default:
AfdhalAtiffTan 0:6262fc7582a9 558 break;
AfdhalAtiffTan 0:6262fc7582a9 559 }
AfdhalAtiffTan 0:6262fc7582a9 560
AfdhalAtiffTan 0:6262fc7582a9 561 /*
AfdhalAtiffTan 0:6262fc7582a9 562 if (txenpin > 1) { // pin 0 & pin 1 are reserved for RX/TX
AfdhalAtiffTan 0:6262fc7582a9 563 pinMode(txenpin, OUTPUT);
AfdhalAtiffTan 0:6262fc7582a9 564 digitalWrite(txenpin, LOW);
AfdhalAtiffTan 0:6262fc7582a9 565 }*/
AfdhalAtiffTan 0:6262fc7582a9 566
AfdhalAtiffTan 0:6262fc7582a9 567 return;
AfdhalAtiffTan 0:6262fc7582a9 568 }
AfdhalAtiffTan 0:6262fc7582a9 569
AfdhalAtiffTan 0:6262fc7582a9 570
AfdhalAtiffTan 0:6262fc7582a9 571 /*
AfdhalAtiffTan 0:6262fc7582a9 572 * update(regs, regs_size)
AfdhalAtiffTan 0:6262fc7582a9 573 *
AfdhalAtiffTan 0:6262fc7582a9 574 * checks if there is any valid request from the modbus master. If there is,
AfdhalAtiffTan 0:6262fc7582a9 575 * performs the requested action
AfdhalAtiffTan 0:6262fc7582a9 576 *
AfdhalAtiffTan 0:6262fc7582a9 577 * regs: an array with the holding registers. They start at address 1 (master point of view)
AfdhalAtiffTan 0:6262fc7582a9 578 * regs_size: total number of holding registers.
AfdhalAtiffTan 0:6262fc7582a9 579 * returns: 0 if no request from master,
AfdhalAtiffTan 0:6262fc7582a9 580 * NO_REPLY (-1) if no reply is sent to the master
AfdhalAtiffTan 0:6262fc7582a9 581 * an exception code (1 to 4) in case of a modbus exceptions
AfdhalAtiffTan 0:6262fc7582a9 582 * the number of bytes sent as reply ( > 4) if OK.
AfdhalAtiffTan 0:6262fc7582a9 583 */
AfdhalAtiffTan 0:6262fc7582a9 584 unsigned long Nowdt = 0;
AfdhalAtiffTan 0:6262fc7582a9 585 unsigned int lastBytesReceived;
AfdhalAtiffTan 0:6262fc7582a9 586 const unsigned long T35 = 5;
AfdhalAtiffTan 0:6262fc7582a9 587
AfdhalAtiffTan 0:6262fc7582a9 588 int ModbusSlave232::update(int *regs,
AfdhalAtiffTan 0:6262fc7582a9 589 unsigned int regs_size)
AfdhalAtiffTan 0:6262fc7582a9 590 {
AfdhalAtiffTan 0:6262fc7582a9 591 unsigned char query[MAX_MESSAGE_LENGTH];
AfdhalAtiffTan 0:6262fc7582a9 592 unsigned char errpacket[EXCEPTION_SIZE + CHECKSUM_SIZE];
AfdhalAtiffTan 0:6262fc7582a9 593 unsigned int start_addr;
AfdhalAtiffTan 0:6262fc7582a9 594 int exception;
AfdhalAtiffTan 0:6262fc7582a9 595 int length = pc.rxBufferGetCount(); //Serial.available(); //afdhal
AfdhalAtiffTan 0:6262fc7582a9 596 unsigned long now = millis();
AfdhalAtiffTan 0:6262fc7582a9 597
AfdhalAtiffTan 0:6262fc7582a9 598
AfdhalAtiffTan 0:6262fc7582a9 599
AfdhalAtiffTan 0:6262fc7582a9 600 if (length == 0) {
AfdhalAtiffTan 0:6262fc7582a9 601 lastBytesReceived = 0;
AfdhalAtiffTan 0:6262fc7582a9 602 return 0;
AfdhalAtiffTan 0:6262fc7582a9 603 }
AfdhalAtiffTan 0:6262fc7582a9 604
AfdhalAtiffTan 0:6262fc7582a9 605 if (lastBytesReceived != length) {
AfdhalAtiffTan 0:6262fc7582a9 606 lastBytesReceived = length;
AfdhalAtiffTan 0:6262fc7582a9 607 Nowdt = now + T35;
AfdhalAtiffTan 0:6262fc7582a9 608 return 0;
AfdhalAtiffTan 0:6262fc7582a9 609 }
AfdhalAtiffTan 0:6262fc7582a9 610 if (now < Nowdt)
AfdhalAtiffTan 0:6262fc7582a9 611 return 0;
AfdhalAtiffTan 0:6262fc7582a9 612
AfdhalAtiffTan 0:6262fc7582a9 613 lastBytesReceived = 0;
AfdhalAtiffTan 0:6262fc7582a9 614
AfdhalAtiffTan 0:6262fc7582a9 615 length = modbus_request(query);
AfdhalAtiffTan 0:6262fc7582a9 616 if (length < 1)
AfdhalAtiffTan 0:6262fc7582a9 617 return length;
AfdhalAtiffTan 0:6262fc7582a9 618
AfdhalAtiffTan 0:6262fc7582a9 619 exception = validate_request(query, length, regs_size);
AfdhalAtiffTan 0:6262fc7582a9 620 if (exception) {
AfdhalAtiffTan 0:6262fc7582a9 621 build_error_packet( query[FUNC], exception,
AfdhalAtiffTan 0:6262fc7582a9 622 errpacket);
AfdhalAtiffTan 0:6262fc7582a9 623 send_reply(errpacket, EXCEPTION_SIZE);
AfdhalAtiffTan 0:6262fc7582a9 624 return (exception);
AfdhalAtiffTan 0:6262fc7582a9 625 }
AfdhalAtiffTan 0:6262fc7582a9 626
AfdhalAtiffTan 0:6262fc7582a9 627 start_addr =
AfdhalAtiffTan 0:6262fc7582a9 628 ((int) query[START_H] << 8) +
AfdhalAtiffTan 0:6262fc7582a9 629 (int) query[START_L];
AfdhalAtiffTan 0:6262fc7582a9 630
AfdhalAtiffTan 0:6262fc7582a9 631 switch (query[FUNC]) {
AfdhalAtiffTan 0:6262fc7582a9 632 case FC_READ_REGS:
AfdhalAtiffTan 0:6262fc7582a9 633 return read_holding_registers(
AfdhalAtiffTan 0:6262fc7582a9 634 start_addr,
AfdhalAtiffTan 0:6262fc7582a9 635 query[REGS_L],
AfdhalAtiffTan 0:6262fc7582a9 636 regs);
AfdhalAtiffTan 0:6262fc7582a9 637 break;
AfdhalAtiffTan 0:6262fc7582a9 638 case FC_WRITE_REGS:
AfdhalAtiffTan 0:6262fc7582a9 639 return preset_multiple_registers(
AfdhalAtiffTan 0:6262fc7582a9 640 start_addr,
AfdhalAtiffTan 0:6262fc7582a9 641 query[REGS_L],
AfdhalAtiffTan 0:6262fc7582a9 642 query,
AfdhalAtiffTan 0:6262fc7582a9 643 regs);
AfdhalAtiffTan 0:6262fc7582a9 644 break;
AfdhalAtiffTan 0:6262fc7582a9 645 case FC_WRITE_REG:
AfdhalAtiffTan 0:6262fc7582a9 646 write_single_register(
AfdhalAtiffTan 0:6262fc7582a9 647 start_addr,
AfdhalAtiffTan 0:6262fc7582a9 648 query,
AfdhalAtiffTan 0:6262fc7582a9 649 regs);
AfdhalAtiffTan 0:6262fc7582a9 650 break;
AfdhalAtiffTan 0:6262fc7582a9 651 }
AfdhalAtiffTan 0:6262fc7582a9 652
AfdhalAtiffTan 0:6262fc7582a9 653 }
AfdhalAtiffTan 0:6262fc7582a9 654
AfdhalAtiffTan 0:6262fc7582a9 655
AfdhalAtiffTan 0:6262fc7582a9 656