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