At this point, I'm guessing an error wtih an array or memcpy is the only problem, but I cannot find it. The use of memcpy seems fine, but I will investigate more and bring back a report.
Here are the uses of my arrays and memcpy in the "Radio Unit" code:
/*
FUNCTION: WiFi_UDPHandler
RETURN TYPE: void
INPUTS: none
OUTPUT: none
PURPOSE: To read the incoming UDP packet and respond
*/
void WiFi_UDPHandler(void)
{
udpPacketSize = UDP.parsePacket(); // get incoming packet size
if (udpPacketSize == rxBuffer_LEN) // only look at packets of 14 bytes
{
remoteIP = UDP.remoteIP(); // get IP address from transmitting device
Serial.print("Incoming packet from "); Serial.println(remoteIP.toString().c_str());
UDP.read(udpBufferReceive, rxBuffer_LEN); // save incoming data packet into udpBufferReceive
emergencyButtonIndex = 0; // clear first
emergencyButtonIndex = udpBufferReceive[0]; // get (deviceID)
Serial.print("emergencyButtonIndex = "); Serial.println(emergencyButtonIndex);
if (emergencyButtonIndex < numButtons) // check to make sure emergencyButtonIndex is a valid value
{
// Separate Data
memcpy(&emergencyButtonData[emergencyButtonIndex], udpBufferReceive, rxBuffer_LEN); // copy incoming data (in udpBufferReceive) to the emergencyMessage struct
}
else
{
while(1)
{
Serial.println("Error: Index out of bounds!");
}
}
Serial.print("Device ID: 0x"); Serial.println(emergencyButtonData[emergencyButtonIndex].deviceID, HEX);
Serial.print("Transmission ID: 0x"); Serial.println(emergencyButtonData[emergencyButtonIndex].transmissionID, HEX);
Serial.print("Transmission Type: 0x"); Serial.println(emergencyButtonData[emergencyButtonIndex].transmissionType, HEX);
Serial.print("Emergency Flag: 0x"); Serial.println(emergencyButtonData[emergencyButtonIndex].emergency, HEX);
Serial.print("Emergency Message ID: 0x"); Serial.println(emergencyButtonData[emergencyButtonIndex].emergencyMessageID, HEX);
Serial.print("Connectivity Check Message ID: 0x"); Serial.println(emergencyButtonData[emergencyButtonIndex].connectivityCheckMessageID, HEX);
Serial.print("Transmission Location ID: 0x"); Serial.println(emergencyButtonData[emergencyButtonIndex].transmissionLocationID, HEX);
//Serial.print("Incoming Transmission Type: "); Serial.println(emergencyButtonData[emergencyButtonIndex].transmissionType);
if (!emergencyButtonData[emergencyButtonIndex].transmissionID) // if the transmissionID indicates that the incoming message is for initialization of the corresponding E-Button
{
//Serial.println("INITIALIZATION MESSAGE");
// Save incoming information
if (emergencyButtonDeviceID[emergencyButtonIndex] != 0xFF) // if there is already an emergency button with this deviceID
{
emergencyButtonValidate[emergencyButtonIndex].deviceID_OK = 0x0; // clear to indicate ID already taken
}
else
{
//Serial.println("Device ID is OK");
emergencyButtonValidate[emergencyButtonIndex].deviceID_OK = 0xFF; // set to indicate ID OK
emergencyButtonDeviceID[emergencyButtonIndex] = emergencyButtonData[emergencyButtonIndex].deviceID; // save deviceID into memeroy
numActiveButtons++; // increment total number of active emergency buttons everytime one comes online
Serial.print("Number of Active Emergency Buttons: "); Serial.println(numActiveButtons);
}
if (emergencyButtonLocationID[emergencyButtonIndex] != 0xFF) // if there is already an emergency button with this location ID
{
emergencyButtonValidate[emergencyButtonIndex].locationID_OK = 0x0; // clear to indicate ID already taken
}
else
{
//Serial.println("Location ID is ok");
emergencyButtonValidate[emergencyButtonIndex].locationID_OK = 0xFF; // set to indicate ID OK
emergencyButtonLocationID[emergencyButtonIndex] = emergencyButtonData[emergencyButtonIndex].transmissionLocationID; // save locationID into memory
}
if (emergencyMessagesPerLocation[emergencyButtonIndex] != 0xFF) // if the emergency message is NOT unique
{
emergencyButtonValidate[emergencyButtonIndex].emergencyMessage_OK = 0x0; // clear to indicate message already being used
}
else
{
//Serial.println("Emergency message ID is ok");
emergencyButtonValidate[emergencyButtonIndex].emergencyMessage_OK = 0xFF; // set to indicate message OK
emergencyMessagesPerLocation[emergencyButtonIndex] = emergencyButtonData[emergencyButtonIndex].emergencyMessageID; // save emergency message ID into memory
}
if (connectivityCheckMessagesPerLocation[emergencyButtonIndex] != 0xFF) // check for unique connectivity message
{
emergencyButtonValidate[emergencyButtonIndex].connectivityCheckMessageID_OK = 0x00; // clear to indicate message already being used
}
else
{
//Serial.println("Connectivity Check Message ID is OK");
emergencyButtonValidate[emergencyButtonIndex].connectivityCheckMessageID_OK = 0xFF; // set to indicate message OK
connectivityCheckMessagesPerLocation[emergencyButtonIndex] = emergencyButtonData[emergencyButtonIndex].connectivityCheckMessageID; // save connectivityCheckMessageID into memory
}
}
else
{
emergencyButtonValidate[emergencyButtonIndex].deviceID_OK = 0x0; // this value isn't important if the incoming message wasn't an initialization request
emergencyButtonValidate[emergencyButtonIndex].locationID_OK = 0x0; // clear to indicate ID already taken
emergencyButtonValidate[emergencyButtonIndex].emergencyMessage_OK = 0x0; // clear to indicate message already being used
emergencyButtonValidate[emergencyButtonIndex].connectivityCheckMessageID_OK = 0x00; // clear to indicate message already being used
emergencyButtonValidate[emergencyButtonIndex].connectivityCheckMessageID = connectivityCheckMessagesPerLocation[emergencyButtonIndex]; // use the saved connectivityCheckMessageID
}
// Send emergencyButtonValidate Packet
memcpy(udpBufferSend, &emergencyButtonValidate[emergencyButtonIndex], txBuffer_LEN); // copy data from emergencyButtonValidate into udpBufferSend
UDP.beginPacket(remoteIP, UDP.remotePort()); // begin a packet transfer to the emergency button that just sent a message
UDP.write(udpBufferSend, sizeof(udpBufferSend)); // send data packet
UDP.endPacket(); // end packet transfer
}
}
And for the "emergency button"
/*
FUNCTION: WiFi_InitializeButton
RETURN TYPE: void
INPUTS: none
OUTPUT: none
PURPOSE: To connect the emergency button device to the radio unit with valid IDs
*/
void WiFi_InitializeButton(void)
{
//Serial.println("Initializing button...");
WiFi_UdpStructInitializeData(); // initialize data
//Serial.println("Sending information...");
while(!buttonIDsValid) // if any of the IDs are NOT valid
{
// Send Data to Radio Unit
memcpy(udpBufferSend, &emergencyButton, txBuffer_LEN); // copty data from struct to the transmit buffer
// Serial.println(); Serial.println(); Serial.println();
// Serial.println("EMERGENCY BUTTON STRUCT");
// Serial.print("Device ID: 0x"); Serial.println(emergencyButton.deviceID, HEX);
// Serial.print("Transmission ID: 0x"); Serial.println(emergencyButton.transmissionID, HEX);
// Serial.print("Transmission Type: 0x"); Serial.println(emergencyButton.transmissionType, HEX);
// Serial.print("Emergency Flag: 0x"); Serial.println(emergencyButton.emergency, HEX);
// Serial.print("Emergency Message ID: 0x"); Serial.println(emergencyButton.emergencyMessageID, HEX);
// Serial.print("Connectivity Check Message ID: 0x"); Serial.println(emergencyButton.connectivityCheckMessageID, HEX);
// Serial.print("Transmission Location ID: 0x"); Serial.println(emergencyButton.transmissionLocationID, HEX);
UDP.beginPacket(radioUnitIP, udpPort); // begin a packet transfer to the radio unit
UDP.write(udpBufferSend, txBuffer_LEN); // send data packet
UDP.endPacket(); // end packet transfer
emergencyButton.transmissionID++; // increment transmissionID
// Receive Data from Radio Unit
udpPacketSize = UDP.parsePacket(); // check for incoming packet
if (udpPacketSize == rxBuffer_LEN) // only look at packets of size rxBuffer_LEN
{
remoteIP = UDP.remoteIP(); // save IP address of radio unit
Serial.print("Incoming data from "); Serial.println(remoteIP.toString().c_str());
UDP.read(udpBufferReceive, sizeof(udpBufferReceive)); // save incoming data to buffer
}
memcpy(&emergencyButtonValidate, udpBufferReceive, rxBuffer_LEN); // copy udpBufferReceive into emergencyButton
if (emergencyButtonValidate.deviceID_OK == 0x00) // if the device ID is NOT valid
{
//Serial.println("deviceID already taken");
emergencyButton.deviceID++; // increment to a new ID value
buttonIDsValid = false; // button is NOT valid
}
else if (!emergencyButtonValidate.locationID_OK) // if the location ID is NOT valid
{
//Serial.println("ERROR: Invalid location ID");
buttonIDsValid = false; // button IDs are NOT valid
}
else if (!emergencyButtonValidate.emergencyMessage_OK) // if the emergency message has already been used
{
//Serial.println("Emergency Message ID already taken");
emergencyButton.emergencyMessageID++; // increment emergency message ID to a new value
buttonIDsValid = false; // button IDs are NOT valid
}
else if (!emergencyButtonValidate.connectivityCheckMessageID_OK) // if the connectivity message has already been used
{
//Serial.println("Connectivity Check Message ID already taken");
emergencyButton.connectivityCheckMessageID++; // ID to a new value
buttonIDsValid = false; // button IDs are NOT valid
}
else
{
Serial.println("Successfully connected to radio unit and initialized");
buttonIDsValid = true; // all IDs have been verified
savedEmergencyMessageID = emergencyButton.emergencyMessageID; // save emergency message ID into memory
}
}
}
/*
FUNCTION: WiFi_UDPHandler
RETURN TYPE: void
INPUTS: emergencyFlag (if there is an emergency), emergencyCallButtonNum (emergency CallButton ID)
OUTPUT: none
PURPOSE: To format and send the emergency message via UDP and listen for the response
*/
void WiFi_UDPHandler(bool emergencyFlag, uint8_t emergencyCallButtonNum)
{
emergencyButton.transmissionType = 0xFF; // do NOT try to re-initialize
if (emergencyButton.transmissionID >= 0xFFFFFFFF) // if the transmission ID has reached it max limit
{
emergencyButton.transmissionID = 0; // reset to 0
}
if (emergencyFlag) // if there is an emergency
{
emergencyButton.emergency = 0xFF; // raise flag for emergency
emergencyButton.emergencyMessageID = savedEmergencyMessageID; // pull from memory to send emergency ID message
}
else
{
emergencyButton.emergency = 0x00; // lower flag for NO emergency
emergencyButton.emergencyMessageID = 0; // clear flag for NO emergency
}
memcpy(udpBufferSend, &emergencyButton, txBuffer_LEN); // copy packet into udpBuffer
Serial.print("Device ID: 0x"); Serial.println(emergencyButton.deviceID, HEX);
Serial.print("Transmission ID: 0x"); Serial.println(emergencyButton.transmissionID, HEX);
Serial.print("Transmission Type: 0x"); Serial.println(emergencyButton.transmissionType, HEX);
Serial.print("Emergency Flag: 0x"); Serial.println(emergencyButton.emergency, HEX);
Serial.print("Emergency Message ID: 0x"); Serial.println(emergencyButton.emergencyMessageID, HEX);
Serial.print("Connectivity Check Message ID: 0x"); Serial.println(emergencyButton.connectivityCheckMessageID, HEX);
Serial.print("Transmission Location ID: 0x"); Serial.println(emergencyButton.transmissionLocationID, HEX);
UDP.beginPacket(radioUnitIP, udpPort); // load packet
UDP.write(udpBufferSend, sizeof(udpBufferSend)); // write packet
UDP.endPacket(); // end packet transmission
udpPacketSize = UDP.parsePacket(); // get incoming packet size
if (udpPacketSize) // if there is data to be read
{
IPAddress remoteIp = UDP.remoteIP(); // get IP address from transmitting device
UDP.read(udpBufferReceive, sizeof(udpBufferReceive)); // save incoming data packet into udpBufferReceive
memcpy(&emergencyButtonValidate, udpBufferReceive, sizeof(udpBufferReceive)); // copy receive buffer into emergencyButtonValidate
if (emergencyButtonValidate.connectivityCheckMessageID == emergencyButton.connectivityCheckMessageID) // if received message is the connectivity confirmation number
{
if (!connectedToReceiver) // if the status changed from not connected to receiver to connected
{
updateLEDs = true; // update LEDs only on a change in status
}
disconnectedCounter = 0; // NO disconnection
connectedToReceiver = true; // established connection to receiver
emergencyButton.transmissionID++; // increment transmissionID
heartBeat++; // increment counter to indicate connection
}
}
else
{
disconnectedCounter++; // increment counter
}
if (disconnectedCounter >= 10) // when the emergency button hasn't heard from the Radio Unit in 10 cycles
{
disconnectedCounter = 0; // reset
if (connectedToReceiver) // if the device was previously connected to the receiver
{
updateLEDs = true; // update the LEDs
}
connectedToReceiver = false; // lost connection to receiver
}
}