unsigned int modbus_update() { if(is_update == true) { long t_now=millis(); Serial.print(t_now-t_getPacket); Serial.println(" ms."); unsigned char buffer = pointer_buffer; // The minimum request packet is 8 bytes for function 3 & 16 if (buffer > 7) { unsigned char id = frame[0]; broadcastFlag = 0; if (id == 0) broadcastFlag = 1; if (id == slaveID || broadcastFlag) // if the recieved ID matches the slaveID or broadcasting id (0), continue { unsigned int crc = ((frame[buffer - 2] << 8) | frame[buffer - 1]); // combine the crc Low & High bytes if (calculateCRC(buffer - 2) == crc) // if the calculated crc matches the recieved crc continue { function = frame[1]; unsigned int startingAddress = ((frame[2] << 8) | frame[3]); // combine the starting address bytes unsigned int no_of_registers = ((frame[4] << 8) | frame[5]); // combine the number of register bytes unsigned int maxData = startingAddress + no_of_registers; unsigned char index; unsigned char address; unsigned int crc16; // broadcasting is not supported for function 3 if (!broadcastFlag && (function == 3)) { if (startingAddress < holdingRegsSize) // check exception 2 ILLEGAL DATA ADDRESS { if (maxData <= holdingRegsSize) // check exception 3 ILLEGAL DATA VALUE { unsigned char noOfBytes = no_of_registers * 2; // ID, function, noOfBytes, (dataLo + dataHi)*number of registers, // crcLo, crcHi unsigned char responseFrameSize = 5 + noOfBytes; frame[0] = slaveID; frame[1] = function; frame[2] = noOfBytes; address = 3; // PDU starts at the 4th byte unsigned int temp; for (index = startingAddress; index < maxData; index++) { temp = regs[index]; frame[address] = temp >> 8; // split the register into 2 bytes address++; frame[address] = temp & 0xFF; address++; } crc16 = calculateCRC(responseFrameSize - 2); frame[responseFrameSize - 2] = crc16 >> 8; // split crc into 2 bytes frame[responseFrameSize - 1] = crc16 & 0xFF; sendPacket(responseFrameSize); } else exceptionResponse(3); // exception 3 ILLEGAL DATA VALUE }
unsigned int modbus_update() { if ((*ModbusPort).available()) { unsigned char buffer = 0; unsigned char overflow = 0; while ((*ModbusPort).available()) { // If more bytes is received than the BUFFER_SIZE the overflow flag will be set and the // serial buffer will be red untill all the data is cleared from the receive buffer. if (overflow) (*ModbusPort).read(); else { if (buffer == BUFFER_SIZE) overflow = 1; frame[buffer] = (*ModbusPort).read(); buffer++; } delayMicroseconds(T1_5); // inter character time out } // If an overflow occurred increment the errorCount // variable and return to the main sketch without // responding to the request i.e. force a timeout if (overflow) return errorCount++; // The minimum request packet is 8 bytes for function 3 & 16 if (buffer > 7) { unsigned char id = frame[0]; broadcastFlag = 0; if (id == 0) broadcastFlag = 1; if (id == slaveID || broadcastFlag) // if the recieved ID matches the slaveID or broadcasting id (0), continue { unsigned int crc = ((frame[buffer - 2] << 8) | frame[buffer - 1]); // combine the crc Low & High bytes if (calculateCRC(buffer - 2) == crc) // if the calculated crc matches the recieved crc continue { function = frame[1]; unsigned int startingAddress = ((frame[2] << 8) | frame[3]); // combine the starting address bytes unsigned int no_of_registers = ((frame[4] << 8) | frame[5]); // combine the number of register bytes unsigned int maxData = startingAddress + no_of_registers; unsigned char index; unsigned char address; unsigned int crc16; // broadcasting is not supported for function 3 if (!broadcastFlag && (function == 3)) { if (startingAddress < holdingRegsSize) // check exception 2 ILLEGAL DATA ADDRESS { if (maxData <= holdingRegsSize) // check exception 3 ILLEGAL DATA VALUE { unsigned char noOfBytes = no_of_registers * 2; // ID, function, noOfBytes, (dataLo + dataHi)*number of registers, // crcLo, crcHi unsigned char responseFrameSize = 5 + noOfBytes; frame[0] = slaveID; frame[1] = function; frame[2] = noOfBytes; address = 3; // PDU starts at the 4th byte unsigned int temp; for (index = startingAddress; index < maxData; index++) { temp = regs[index]; frame[address] = temp >> 8; // split the register into 2 bytes address++; frame[address] = temp & 0xFF; address++; } crc16 = calculateCRC(responseFrameSize - 2); frame[responseFrameSize - 2] = crc16 >> 8; // split crc into 2 bytes frame[responseFrameSize - 1] = crc16 & 0xFF; sendPacket(responseFrameSize); } else exceptionResponse(3); // exception 3 ILLEGAL DATA VALUE }
boolean MBSLAVE:: modbus_update(unsigned char *count, unsigned char *_functionCode ) { boolean dataReceived = false; *count = 0; *_functionCode = 0; if ((*ModbusPort).available()) { unsigned char buffer = 0; unsigned char overflow = 0; while ((*ModbusPort).available()) { // If more bytes is received than the BUFFER_SIZE the overflow flag will be set and the // serial buffer will be red untill all the data is cleared from the receive buffer. if (overflow) (*ModbusPort).read(); else { if (buffer == BUFFER_SIZE) overflow = 1; frame[buffer] = (*ModbusPort).read(); buffer++; } delayMicroseconds(T1_5); // inter character time out } // If an overflow occurred increment the errorCount // variable and return to the main sketch without // responding to the request i.e. force a timeout if (overflow) return errorCount++; // The minimum request packet is 8 bytes for function 3 & 16 if (buffer > 7) { unsigned char id = frame[0]; broadcastFlag = 0; if (id == 0) broadcastFlag = 1; if (id == slaveID || broadcastFlag) // if the recieved ID matches the slaveID or broadcasting id (0), continue { unsigned int crc = ((frame[buffer - 2] << 8) | frame[buffer - 1]); // combine the crc Low & High bytes if (calculateCRC(buffer - 2) == crc) // if the calculated crc matches the recieved crc continue { function = frame[1]; unsigned int startingAddress = ((frame[2] << 8) | frame[3]); // combine the starting address bytes unsigned int no_of_registers = ((frame[4] << 8) | frame[5]); // combine the number of register bytes unsigned int maxData = startingAddress + no_of_registers; *count = no_of_registers * 2; //byte count; unsigned char index; unsigned char address; unsigned int crc16; // broadcasting is not supported for function 3 if (!broadcastFlag && (function == 3)) { if (startingAddress < holdingRegsSize) // check exception 2 ILLEGAL DATA ADDRESS { if (maxData <= holdingRegsSize) // check exception 3 ILLEGAL DATA VALUE { Serial.println( "waiting for slave response" ); *_functionCode = function; f3StartingAdd = startingAddress; dataReceived = true; return dataReceived; /*unsigned char noOfBytes = no_of_registers * 2; // ID, function, noOfBytes, (dataLo + dataHi)*number of registers, // crcLo, crcHi unsigned char responseFrameSize = 5 + noOfBytes; frame[0] = slaveID; frame[1] = function; frame[2] = noOfBytes; address = 3; // PDU starts at the 4th byte unsigned int temp; callback( frame+address, maxData, startingAddress ); for (index = startingAddress; index < maxData; index++) { temp = regs[index]; frame[address] = temp >> 8; // split the register into 2 bytes address++; frame[address] = temp & 0xFF; address++; } crc16 = calculateCRC(responseFrameSize - 2); frame[responseFrameSize - 2] = crc16 >> 8; // split crc into 2 bytes frame[responseFrameSize - 1] = crc16 & 0xFF; sendPacket(responseFrameSize); */ } else exceptionResponse(3); // exception 3 ILLEGAL DATA VALUE } else exceptionResponse(2); // exception 2 ILLEGAL DATA ADDRESS } else if (function == 6) { if (startingAddress < holdingRegsSize) // check exception 2 ILLEGAL DATA ADDRESS { regs[startingAddress] = ((frame[4] << 8) | frame[5]);// the 4th and 5th elements in frame is the 16 bit data value // only the first 6 bytes are used for CRC calculation crc16 = calculateCRC(6); frame[6] = crc16 >> 8; // split crc into 2 bytes frame[7] = crc16 & 0xFF; // a function 16 response is an echo of the first 6 bytes from // the request + 2 crc bytes if (!broadcastFlag) // don't respond if it's a broadcast message sendPacket(8); } else