/* Request Cunstruct packet to send * @param: none * @return: none * @private * @comment: none */ void Modbus::constructPacket() { //Disable next transmission until get response packet or timeout _transmission_ready_flag = false; _packet->requests++; _total_request++; //calculate total packets are requested //Modbus Application Protocol v1.13b frame[0] = _packet->id; frame[1] = _packet->function; frame[2] = _packet->address >> 8; //Address Hi frame[3] = _packet->address & 0xFF; //Address Lo //If packet is single regiser, data is what it is if ( _packet->function == PRESET_SINGLE_REGISTER ){ _packet->data = _register_array[_packet->register_start_address]; } //2 bytes address frame[4] = _packet->data >> 8; //total registers Hi frame[5] = _packet->data & 0xFF; //total registers Lo //Frame size for function code 3, 4 & 6 = 8 uint8_t frameSize; if (_packet->function == PRESET_MULTIPLE_REGISTERS) frameSize = construct_F16(); else if (_packet->function == FORCE_MULTIPLE_COILS) frameSize = construct_F15(); else // else functions 1,2,3,4,5 & 6 is assumed. They all share the exact same request format. frameSize = 8; // the request is always 8 bytes in size for the above mentioned functions. //Error check CRC16 uint16_t crc16 = calculateCRC(frameSize - 2); //First 6 bytes of frame is used to calculate CRC error check frame[frameSize - 2] = crc16 >> 8; //High byte of CRC frame[frameSize - 1] = crc16 & 0xFF; //Low byte of CRC #if DEBUG_UART print("Request: "); for (uint8_t i=0;i<frameSize;i++) print(frame[i]); println(); #endif //Send packet frame to slave sendPacket(frameSize); }
void constructPacket() { packet->requests++; frame[0] = packet->id; frame[1] = packet->function; frame[2] = packet->address >> 8; // address Hi frame[3] = packet->address & 0xFF; // address Lo // For functions 1 & 2 data is the number of points // For function 5 data is either ON (0xFF00) or OFF (0x0000) // For function 6 data is exactly that, one register's data // For functions 3, 4 & 16 data is the number of registers // For function 15 data is the number of coils // The data attribute needs to be intercepted by F5 & F6 because these requests // include their data in the data register and not in the masters array if (packet->function == FORCE_SINGLE_COIL || packet->function == PRESET_SINGLE_REGISTER) packet->data = register_array[packet->local_start_address]; // get the data frame[4] = packet->data >> 8; // MSB frame[5] = packet->data & 0xFF; // LSB unsigned char frameSize; // construct the frame according to the modbus function if (packet->function == PRESET_MULTIPLE_REGISTERS) frameSize = construct_F16(); else if (packet->function == FORCE_MULTIPLE_COILS) frameSize = construct_F15(); else // else functions 1,2,3,4,5 & 6 is assumed. They all share the exact same request format. frameSize = 8; // the request is always 8 bytes in size for the above mentioned functions. unsigned int crc16 = calculateCRC(frameSize - 2); frame[frameSize - 2] = crc16 >> 8; // split crc into 2 bytes frame[frameSize - 1] = crc16 & 0xFF; sendPacket(frameSize); state = WAITING_FOR_REPLY; // state change // if broadcast is requested (id == 0) for function 5,6,15 and 16 then override // the previous state and force a success since the slave wont respond if (packet->id == 0) processSuccess(); }