I need some help with my Project on an Arduino Due
I need to specifically communicate with 1 of 4 devices as fast as possible.
This communication works perfectly, or appears to, until there is some sort of a delay brought in either by the delay function or when one of the other serial devices use a delay.
I have only included the code for the single device communication.
- The Device waits for a request before sending data.
- I need 3 sets of data of which 2 are only required at startup.
- The real time data I require as fast as possible.
- There is no start identifier, but there is and end identifier which is the same as the command you send to request.
- Each of these commands send a different length of bytes
I have 3 other devices that I communicate with of which two do not require speed
- GPS Using TinyGPS library
- Gyro Using the DFRobot_WT61PC library
- Nextion 7 Inch.
The Nextion screen I also need to communicate to as quickly as possible.
Please could you look at my approach and let me know where I am going wrong. I think it could have to do with buffer overuns as it appears to not receive the end character for quite a while ( maybe 30 seconds ) then some data comes through and so on. When the data comes through I always have the full set of data requested. It just takes random amounts of time to return it.
const static int numChars = 1794; // Set this to the size of the parameter data array received from the device which is the biggest array returned
int receivedBytes[numChars]; // to accumulate and store the received data
int recindex = 0;
const int RealtimeDataMessage = 252;
const int ParameterDataMessage = 253;
const int DeviceInfoDataMessage = 255;
bool receivedDeviceParameters = false;
bool receivedDeviceInfo = false;
bool canRequest = true;
int RequestSequence = 1;
/* Variables for Timed Events */
unsigned long TimeOutPeriod = 2000; // ms
unsigned long previousTime = 0; // ms
void setup()
{
Serial.begin(115200);
Serial1.begin(19200);
}
void loop()
{
unsigned long sp_currentTime = millis();
RequestDeviceData();
ReadDeviceSerialData();
if(sp_currentTime - previousTime >= TimeOutPeriod && !canRequest )
{
canRequest = true;
previousTime = sp_currentTime;
}
}
void RequestDeviceData()
{
if(!canRequest)
{
return;
}
canRequest = false;
if(receivedDeviceParameters && receivedDeviceInfo)
{
RequestSequence = 3;
}
if(RequestSequence == 1)
{
if(!receivedDeviceParameters) // Only need to get this once at start up
{
if (Serial1.availableForWrite())
{
Serial1.write(ParameterDataMessage);
}
}
}
if(RequestSequence == 2)
{
if(!receivedDeviceInfo) // Only need to get this once at start up
{
if (Serial1.availableForWrite())
{
Serial1.write(DeviceInfoDataMessage);
}
}
}
if(RequestSequence == 3)
{
if (Serial1.availableForWrite())
{
Serial1.write(RealtimeDataMessage); // Need this as quicky as we can possibly read
}
}
RequestSequence += 1;
if(RequestSequence > 3)
{
RequestSequence = 1;
}
//delay(1000); By implementing this delay I get mixed results.
}
void ReadDeviceSerialData()
{
if (Serial1.available() > 0)
{
// Read in request
int inByte = Serial1.read();
receivedBytes[recindex] = inByte;
recindex+=1;
switch(inByte)
{
case RealtimeDataMessage: // Check for the terminating byte
if(recindex == 14) // Length of the expected message is 14 bytes
{
processdata(recindex);
canRequest = true;
recindex = 0;
}
break;
case ParameterDataMessage:
if(recindex == 1794) // Length of the expected message is 1794 bytes
{
receivedDeviceParameters = true;
processdata(recindex);
canRequest = true;
recindex = 0;
}
break;
case DeviceInfoDataMessage:
if(recindex == 17 || recindex == 28) // Length of the expected message is 17 or 28 depending on the device type
{
receivedDeviceInfo = true;
processdata(recindex);
canRequest = true;
recindex = 0;
}
break;
}
}
}
void processdata(int bytecount)
{
for(int i = 0; i < bytecount; i++)
{
Serial.println(receivedBytes[i]);
}
Serial.println("Completed Processing. : ");
Serial.println(receivedDeviceParameters);
Serial.println(receivedDeviceInfo);
Serial.println("");
}