Skip to content

Commit e200f8a

Browse files
committed
Further fixes to data download:
- Detect serial overflow, stopping data download and clearing the buffer before resuming activity. - Disabled most debug messages during data download (It will fail pretty much always). - Disabled checksum handling. Arguably useless and slow down the data download, resulting in buffer overflows. Testing some use cases with data download from the FPS (GT-511C3): - 9600 and 19200 baud rates are too slow and will shutdown the FPS. - 38400 works pretty fast and stable. - 57600 also works, but you can't use debug messages and you MUST allocate all CPU time to the task. - 115200 is way too fast and will overflow the buffer immediately. Short summary, the moment you send the command packet to start downloading, you are in a race against the FPS to receive, process and send the data before your serial buffer overflow. A slower baud rate will allow you to allocate less CPU time to the task, but go too slow and the FPS will shutdown (some kind of timeout?).
1 parent 3d488cb commit e200f8a

File tree

2 files changed

+35
-65
lines changed

2 files changed

+35
-65
lines changed

src/FPS_GT511C3.cpp

Lines changed: 33 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -217,30 +217,32 @@ uint8_t Response_Packet::GetLowByte(uint16_t w)
217217
#endif //__GNUC__
218218
Data_Packet::Data_Packet(uint8_t* buffer, bool UseSerialDebug)
219219
{
220-
CheckParsing(buffer[0], DATA_START_CODE_1, DATA_START_CODE_1, "DATA_START_CODE_1", UseSerialDebug);
220+
// The checksum here is arguably useless and may make the serial buffer overflow
221+
/*CheckParsing(buffer[0], DATA_START_CODE_1, DATA_START_CODE_1, "DATA_START_CODE_1", UseSerialDebug);
221222
CheckParsing(buffer[1], DATA_START_CODE_2, DATA_START_CODE_2, "DATA_START_CODE_2", UseSerialDebug);
222223
CheckParsing(buffer[2], DATA_DEVICE_ID_1, DATA_DEVICE_ID_1, "DATA_DEVICE_ID_1", UseSerialDebug);
223224
CheckParsing(buffer[3], DATA_DEVICE_ID_2, DATA_DEVICE_ID_2, "DATA_DEVICE_ID_2", UseSerialDebug);
224225
225-
this->checksum = CalculateChecksum(buffer, 4);
226+
this->checksum = CalculateChecksum(buffer, 4);*/
226227
}
227228

228229
// Get a data packet (128 bytes), calculate checksum and send it to serial
229-
void Data_Packet::GetData(uint8_t* buffer, bool UseSerialDebug)
230+
void Data_Packet::GetData(uint8_t buffer[], uint16_t length)
230231
{
231-
SendToSerial(buffer, 128);
232-
this->checksum = CalculateChecksum(buffer, 128);
232+
for(uint16_t i = 0; i<length; i++) Serial.write(buffer[i]);
233+
//this->checksum = CalculateChecksum(buffer, 128); // Checksum slowdown
233234
}
234235

235236
// Get the last data packet (<=128 bytes), calculate checksum, validate checksum received and send it to serial
236237
void Data_Packet::GetLastData(uint8_t* buffer, uint16_t length, bool UseSerialDebug)
237238
{
238-
SendToSerial(buffer, length-2);
239-
this->checksum = CalculateChecksum(buffer, length);
239+
for(uint16_t i = 0; i<length-2, i++) Serial.write(buffer[i]);
240+
// The checksum here is arguably useless and may make the serial buffer overflow
241+
/*this->checksum = CalculateChecksum(buffer, length);
240242
uint8_t checksum_low = GetLowByte(this->checksum);
241243
uint8_t checksum_high = GetHighByte(this->checksum);
242244
CheckParsing(buffer[length-2], checksum_low, checksum_low, "Checksum_LOW", UseSerialDebug);
243-
CheckParsing(buffer[length-1], checksum_high, checksum_high, "Checksum_HIGH", UseSerialDebug);
245+
CheckParsing(buffer[length-1], checksum_high, checksum_high, "Checksum_HIGH", UseSerialDebug);*/
244246
}
245247

246248
// checks to see if the byte is the proper value, and logs it to the serial channel if not
@@ -284,26 +286,6 @@ uint8_t Data_Packet::GetLowByte(uint16_t w)
284286
return (uint8_t)w&0x00FF;
285287
}
286288

287-
// sends a byte to the serial debugger in the hex format we want EX "0F"
288-
void Data_Packet::serialPrintHex(uint8_t data)
289-
{
290-
char tmp[16];
291-
sprintf(tmp, "%.2X",data);
292-
Serial.print(tmp);
293-
}
294-
295-
// sends the byte array to the serial debugger in our hex format EX: "00 AF FF 10 00 13"
296-
void Data_Packet::SendToSerial(uint8_t data[], uint16_t length)
297-
{
298-
boolean first=true;
299-
Serial.print("\"");
300-
for(uint16_t i=0; i<length; i++)
301-
{
302-
if (first) first=false; else Serial.print(" ");
303-
serialPrintHex(data[i]);
304-
}
305-
Serial.print("\"");
306-
}
307289
#ifndef __GNUC__
308290
#pragma endregion
309291
#endif //__GNUC__
@@ -764,6 +746,10 @@ bool FPS_GT511C3::GetImage()
764746

765747
// Gets an image that is qvga 160x120 (19200 bytes) and sends it over serial
766748
// Returns: True (device confirming download)
749+
// It only worked with baud rate at 38400-57600 in GT-511C3.
750+
// Slower speeds and the FPS will shutdown. Higher speeds and the serial buffer will overflow.
751+
// Make sure you are allocating enough CPU time for this task or you will overflow nonetheless.
752+
// Also, avoid using UseSerialDebug for this task, since it's easier to overflow.
767753
bool FPS_GT511C3::GetRawImage()
768754
{
769755
if (UseSerialDebug) Serial.println("FPS - GetRawImage");
@@ -1027,23 +1013,15 @@ void FPS_GT511C3::GetData(uint16_t length)
10271013
}
10281014
}
10291015

1030-
uint8_t* firstdata = new uint8_t[4];
1016+
uint8_t firstdata[4];
10311017
firstdata[0] = firstbyte;
10321018
firstdata[1] = secondbyte;
10331019
for (uint8_t i=2; i < 4; i++)
10341020
{
10351021
while (_serial.available() == false) delay(10);
10361022
firstdata[i]= (uint8_t) _serial.read();
10371023
}
1038-
Data_Packet* dp = new Data_Packet(firstdata, UseSerialDebug);
1039-
if(UseSerialDebug)
1040-
{
1041-
Serial.print("FPS - RECV: ");
1042-
SendToSerial(firstdata, 4);
1043-
Serial.println();
1044-
Serial.println();
1045-
}
1046-
delete firstdata;
1024+
Data_Packet dp(firstdata, UseSerialDebug);
10471025

10481026
uint16_t numberPacketsNeeded = (length-4) / 128;
10491027
bool smallLastPacket = false;
@@ -1054,42 +1032,36 @@ void FPS_GT511C3::GetData(uint16_t length)
10541032
smallLastPacket = true;
10551033
}
10561034

1057-
uint8_t* data = new uint8_t[128];
1035+
uint8_t data[128];
10581036
for (uint16_t packetCount=1; packetCount < numberPacketsNeeded; packetCount++)
10591037
{
10601038
for (uint8_t i=0; i < 128; i++)
10611039
{
1062-
while (_serial.available() == false) delay(10);
1040+
while (_serial.available() == false) delay(1);
1041+
if(_serial.overflow())
1042+
{
1043+
Serial.println("Overflow! Data download stopped");
1044+
Serial.println("Cleaning serial buffer...");
1045+
for (uint16_t j = 0; j<length; j++)
1046+
{
1047+
_serial.read();
1048+
delay(1);
1049+
}
1050+
Serial.println("Done!");
1051+
return;
1052+
}
10631053
data[i]= (uint8_t) _serial.read();
10641054
}
1065-
dp->GetData(data, UseSerialDebug);
1066-
if(UseSerialDebug)
1067-
{
1068-
Serial.print("FPS - RECV: ");
1069-
SendToSerial(data, 128);
1070-
Serial.println();
1071-
Serial.println();
1072-
}
1055+
dp.GetData(data, 128);
10731056
}
1074-
delete data;
10751057

1076-
uint8_t* lastdata = new uint8_t[lastPacketSize];
1058+
uint8_t lastdata[lastPacketSize];
10771059
for (uint8_t i=0; i < lastPacketSize; i++)
10781060
{
10791061
while (_serial.available() == false) delay(10);
10801062
lastdata[i]= (uint8_t) _serial.read();
10811063
}
1082-
dp->GetLastData(lastdata, lastPacketSize, UseSerialDebug);
1083-
if(UseSerialDebug)
1084-
{
1085-
Serial.print("FPS - RECV: ");
1086-
SendToSerial(lastdata, lastPacketSize);
1087-
Serial.println();
1088-
Serial.println();
1089-
}
1090-
delete lastdata;
1091-
1092-
return;
1064+
dp.GetLastData(lastdata, lastPacketSize, UseSerialDebug);
10931065
};
10941066

10951067
// sends the byte array to the serial debugger in our hex format EX: "00 AF FF 10 00 13"

src/FPS_GT511C3.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -157,15 +157,13 @@ class Data_Packet
157157
static const uint8_t DATA_DEVICE_ID_1 = 0x01; // Device ID Byte 1 (lesser byte) - theoretically never changes
158158
static const uint8_t DATA_DEVICE_ID_2 = 0x00; // Device ID Byte 2 (greater byte)
159159

160-
void GetData(uint8_t* buffer, bool UseSerialDebug);
161-
void GetLastData(uint8_t* buffer, uint16_t length, bool UseSerialDebug);
160+
void GetData(uint8_t buffer[], uint16_t length);
161+
void GetLastData(uint8_t buffer[], uint16_t length, bool UseSerialDebug);
162162
private:
163163
bool CheckParsing(uint8_t b, uint8_t propervalue, uint8_t alternatevalue, const char* varname, bool UseSerialDebug);
164164
uint16_t CalculateChecksum(uint8_t* buffer, uint16_t length);
165165
uint8_t GetHighByte(uint16_t w);
166166
uint8_t GetLowByte(uint16_t w);
167-
void serialPrintHex(uint8_t data);
168-
void SendToSerial(uint8_t data[], uint16_t length);
169167
};
170168
#ifndef __GNUC__
171169
#pragma endregion

0 commit comments

Comments
 (0)