Skip to content

Commit 144bbb5

Browse files
committed
upgrade image_upload, able to handle write without response
1 parent d7caa64 commit 144bbb5

File tree

1 file changed

+73
-65
lines changed

1 file changed

+73
-65
lines changed

libraries/Bluefruit52Lib/examples/Peripheral/image_upload/image_upload.ino

Lines changed: 73 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,12 @@
5252
#define COLOR_BLACK 0x0000
5353
#define COLOR_YELLOW 0xFFE0
5454
#define COLOR_GREEN 0x07E0
55+
#define COLOR_RED 0xF800
5556

56-
// Uart over BLE with large buffer to hold image data
57-
BLEUart bleuart(1024*10);
57+
// Declaring Uart over BLE with large buffer to hold image data
58+
// Depending on the Image Resolution and Transfer Mode especially without response
59+
// or Interleaved with high ratio. You may need to increase this buffer size
60+
BLEUart bleuart(10*1024);
5861

5962
/* The Image Transfer module sends the image of your choice to Bluefruit LE over UART.
6063
* Each image sent begins with
@@ -71,14 +74,15 @@ uint16_t imageHeight = 0;
7174

7275
uint32_t totalPixel = 0; // received pixel
7376

74-
// color buf must be large enough to consume incoming data fast enough
75-
// otherwise bleuart fifo could be overflow and start dropping data
76-
uint16_t color_buf[2048];
77+
// pixel line buffer, should be large enough to hold an image width
78+
uint16_t pixel_buf[512];
7779

7880
// Statistics for speed testing
7981
uint32_t rxStartTime = 0;
8082
uint32_t rxLastTime = 0;
8183

84+
// for print out message to TFT once
85+
bool bleuart_overflowed = false;
8286

8387
void setup()
8488
{
@@ -104,6 +108,7 @@ void setup()
104108
// Configure and Start BLE Uart Service
105109
bleuart.begin();
106110
bleuart.setRxCallback(bleuart_rx_callback);
111+
bleuart.setRxOverflowCallback(bleuart_overflow_callback);
107112

108113
// Set up and start advertising
109114
startAdv();
@@ -142,60 +147,70 @@ void startAdv(void)
142147

143148
void loop()
144149
{
145-
if ( !Bluefruit.connected() ) return;
146-
if ( !bleuart.notifyEnabled() ) return;
147-
if ( !bleuart.available() ) return;
150+
// nothing to do
151+
}
148152

149-
// all pixel data is received
150-
if ( (totalPixel != 0) && (totalPixel == imageWidth*imageHeight) )
153+
// Invoked when receiving data from bleuart
154+
// Pull data from bleuart fifo & draw image as soon as possible,
155+
// Otherwise bleuart fifo can be overflowed
156+
void bleuart_rx_callback(uint16_t conn_hdl)
157+
{
158+
(void) conn_hdl;
159+
160+
rxLastTime = millis();
161+
162+
// Received new Image
163+
if ( (imageWidth == 0) && (imageHeight == 0) )
151164
{
152-
uint8_t crc = bleuart.read();
153-
// do checksum later
165+
// take note of time of first packet
166+
rxStartTime = millis();
154167

155-
// print speed summary
156-
print_speed(totalPixel*3 + 7, rxLastTime-rxStartTime);
168+
// Skip all data until '!I' is found
169+
while( bleuart.available() && bleuart.read() != '!' ) { }
170+
if (bleuart.read() != 'I') return;
157171

158-
// reset and waiting for new image
159-
totalPixel = imageWidth = imageHeight = 0;
160-
}
172+
if ( !bleuart.available() ) return;
161173

162-
// extract pixel data and display on TFT
163-
uint16_t pixelNum = bleuart.available() / 3;
174+
imageWidth = bleuart.read16();
175+
imageHeight = bleuart.read16();
164176

165-
// Draw multiple lines of image each time i.e pixelNum = n*imageWidth
166-
// pixelNum is capped at color_buf size (512 pixel)
167-
// the rest will be drawn in the next invocation of loop().
168-
pixelNum = min(pixelNum, sizeof(color_buf)/2);
177+
totalPixel = 0;
169178

170-
// Chop pixel number to multiple of image width
171-
pixelNum = (pixelNum / imageWidth) * imageWidth;
179+
PRINT_INT(imageWidth);
180+
PRINT_INT(imageHeight);
172181

173-
#if 0
174-
static uint32_t last_available = 0;
175-
if ( last_available != bleuart.available() )
182+
tft.fillScreen(COLOR_BLACK);
183+
tft.setCursor(0, 0);
184+
}
185+
186+
// Extract pixel data to buffer and draw image line by line
187+
while ( bleuart.available() >= 3 )
176188
{
177-
last_available = bleuart.available();
189+
uint8_t rgb[3];
190+
bleuart.read(rgb, 3);
191+
192+
pixel_buf[totalPixel % imageWidth] = ((rgb[0] & 0xF8) << 8) | ((rgb[1] & 0xFC) << 3) | (rgb[2] >> 3);
193+
194+
totalPixel++;
178195

179-
PRINT_INT(totalPixel);
180-
PRINT_INT(last_available);
181-
PRINT_INT(pixelNum);
182-
Serial.println();
196+
// enough to draw an image line
197+
if ( (totalPixel % imageWidth) == 0 )
198+
{
199+
tft.drawRGBBitmap(0, totalPixel/imageWidth, pixel_buf, imageWidth, 1);
200+
}
183201
}
184-
#endif
185202

186-
if ( pixelNum )
203+
// all pixel data is received
204+
if ( totalPixel == imageWidth*imageHeight )
187205
{
188-
for ( uint16_t i=0; i < pixelNum; i++)
189-
{
190-
uint8_t red = bleuart.read();
191-
uint8_t green = bleuart.read();
192-
uint8_t blue = bleuart.read();
206+
uint8_t crc = bleuart.read();
207+
// do checksum later
193208

194-
color_buf[i] = ((red & 0xF8) << 8) | ((green & 0xFC) << 3) | ( blue >> 3);
195-
}
209+
// print speed summary
210+
print_speed(totalPixel*3 + 7, rxLastTime-rxStartTime);
196211

197-
tft.drawRGBBitmap(0, totalPixel/imageWidth, color_buf, imageWidth, pixelNum/imageWidth);
198-
totalPixel += pixelNum;
212+
// reset and waiting for new image
213+
totalPixel = imageWidth = imageHeight = 0;
199214
}
200215
}
201216

@@ -247,36 +262,28 @@ void print_speed(uint32_t count, uint32_t ms)
247262
tft.setTextColor(COLOR_WHITE);
248263
}
249264

250-
void bleuart_rx_callback(uint16_t conn_hdl)
265+
void bleuart_overflow_callback(uint16_t conn_hdl, uint16_t leftover)
251266
{
252-
(void) conn_hdl;
253-
254-
rxLastTime = millis();
267+
Serial.println("BLEUART rx buffer OVERFLOWED!");
268+
Serial.println("Please increase buffer size for bleuart");
255269

256-
// Received new Image
257-
if ( (imageWidth == 0) && (imageHeight == 0) )
270+
// only print the first time this occur, need disconnect to reset
271+
if (!bleuart_overflowed)
258272
{
259-
rxStartTime = millis();
273+
tft.setCursor(0, imageHeight+5);
260274

261-
// Skip all data until '!I' is found
262-
while( bleuart.available() && bleuart.read() != '!' ) { }
263-
if (bleuart.read() != 'I') return;
275+
tft.setTextColor(COLOR_RED);
276+
tft.println("BLEUART rx buffer OVERFLOWED!");
264277

265-
if ( !bleuart.available() ) return;
266-
267-
imageWidth = bleuart.read16();
268-
imageHeight = bleuart.read16();
269-
270-
PRINT_INT(imageWidth);
271-
PRINT_INT(imageHeight);
272-
273-
tft.fillScreen(COLOR_BLACK);
274-
tft.setCursor(0, 0);
278+
tft.setTextColor(COLOR_WHITE);
279+
tft.print("Please increase buffer size for bleuart");
275280
}
281+
282+
bleuart_overflowed = true;
276283
}
277284

278285
/**
279-
* Callback invoked when a connection is dropped
286+
* invoked when a connection is dropped
280287
* @param conn_handle connection where this event happens
281288
* @param reason is a BLE_HCI_STATUS_CODE which can be found in ble_hci.h
282289
*/
@@ -289,6 +296,7 @@ void disconnect_callback(uint16_t conn_handle, uint8_t reason)
289296
tft.println("Advertising ...");
290297

291298
totalPixel = imageWidth = imageHeight = 0;
299+
bleuart_overflowed = false;
292300

293301
bleuart.flush();
294302
}

0 commit comments

Comments
 (0)