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:
Fri Jul 22 09:44:55 2016 +0000
Revision:
1:35fdc7056f66
Parent:
0:6262fc7582a9
Child:
2:5318159b5eab
Added small comments.

Who changed what in which revision?

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