From fbfd86992cbca5132409d0c07b80265ac5f9cd02 Mon Sep 17 00:00:00 2001 From: Sebastian Romero Date: Mon, 22 Feb 2021 12:24:39 +0100 Subject: [PATCH 1/8] Add check to Arduino sketch to wait with sending data --- .../CameraCaptureRawBytes.ino | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/libraries/Portenta_Camera/examples/CameraCaptureRawBytes/CameraCaptureRawBytes.ino b/libraries/Portenta_Camera/examples/CameraCaptureRawBytes/CameraCaptureRawBytes.ino index f69cbc5fb..ecf61ad82 100644 --- a/libraries/Portenta_Camera/examples/CameraCaptureRawBytes/CameraCaptureRawBytes.ino +++ b/libraries/Portenta_Camera/examples/CameraCaptureRawBytes/CameraCaptureRawBytes.ino @@ -4,8 +4,7 @@ CameraClass cam; uint8_t fb[320*240]; void setup() { - - Serial.begin(921600); + Serial.begin(921600); // Init the cam QVGA, 30FPS cam.begin(CAMERA_R320x240, 30); @@ -13,10 +12,14 @@ void setup() { void loop() { // put your main code here, to run repeatedly: - if (Serial) { - // Grab frame and write to serial - if (cam.grab(fb) == 0) { - Serial.write(fb, 320*240); - } + + // Wait until the receiver acknowledges + // that they are ready to receive new data + while(Serial.read() != 1){}; + + // Grab frame and write to serial + if (cam.grab(fb) == 0) { + Serial.write(fb, 320*240); } + } From 4b1746bfdd18c3596db0cc0188655bf8ccbc911a Mon Sep 17 00:00:00 2001 From: Sebastian Romero Date: Mon, 22 Feb 2021 12:26:07 +0100 Subject: [PATCH 2/8] Add check to PDE sketch to ensure all pixel data is received --- .../CameraRawBytesVisualizer.pde | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/libraries/Portenta_Camera/extras/CameraRawBytesVisualizer/CameraRawBytesVisualizer.pde b/libraries/Portenta_Camera/extras/CameraRawBytesVisualizer/CameraRawBytesVisualizer.pde index 7c8393fdc..e0826b37f 100644 --- a/libraries/Portenta_Camera/extras/CameraRawBytesVisualizer/CameraRawBytesVisualizer.pde +++ b/libraries/Portenta_Camera/extras/CameraRawBytesVisualizer/CameraRawBytesVisualizer.pde @@ -16,7 +16,8 @@ Serial myPort; final int cameraWidth = 320; final int cameraHeight = 240; final int cameraBytesPerPixel = 1; -final int bytesPerFrame = cameraWidth * cameraHeight * cameraBytesPerPixel; +final int cameraPixelCount = cameraWidth * cameraHeight; +final int bytesPerFrame = cameraPixelCount * cameraBytesPerPixel; PImage myImage; byte[] frameBuffer = new byte[bytesPerFrame]; @@ -30,13 +31,16 @@ void setup() // if you know the serial port name //myPort = new Serial(this, "COM5", 9600); // Windows - myPort = new Serial(this, "/dev/ttyACM0", 921600); // Linux - //myPort = new Serial(this, "/dev/cu.usbmodem14401", 9600); // Mac + //myPort = new Serial(this, "/dev/ttyACM0", 921600); // Linux + myPort = new Serial(this, "/dev/cu.usbmodem14401", 9600); // Mac // wait for full frame of bytes myPort.buffer(bytesPerFrame); myImage = createImage(cameraWidth, cameraHeight, ALPHA); + + // Let the Arduino sketch know we're ready to receive data + myPort.write(1); } void draw() @@ -63,7 +67,12 @@ void serialEvent(Serial myPort) { // set pixel color myImage .pixels[i++] = color(Byte.toUnsignedInt(p)); + + // Let the Arduino sketch know we received all pixels + // and are ready for the next frame + if(i == cameraPixelCount){ + myPort.write(1); + } } - myImage.updatePixels(); - + myImage.updatePixels(); } From 198d2964d31a4c9bc7ee56c2952e9a5330e204cb Mon Sep 17 00:00:00 2001 From: Sebastian Romero Date: Mon, 22 Feb 2021 12:34:56 +0100 Subject: [PATCH 3/8] Adjust baud rate --- .../CameraRawBytesVisualizer/CameraRawBytesVisualizer.pde | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libraries/Portenta_Camera/extras/CameraRawBytesVisualizer/CameraRawBytesVisualizer.pde b/libraries/Portenta_Camera/extras/CameraRawBytesVisualizer/CameraRawBytesVisualizer.pde index e0826b37f..15087260b 100644 --- a/libraries/Portenta_Camera/extras/CameraRawBytesVisualizer/CameraRawBytesVisualizer.pde +++ b/libraries/Portenta_Camera/extras/CameraRawBytesVisualizer/CameraRawBytesVisualizer.pde @@ -27,12 +27,12 @@ void setup() size(640, 480); // if you have only ONE serial port active - //myPort = new Serial(this, Serial.list()[0], 9600); // if you have only ONE serial port active + //myPort = new Serial(this, Serial.list()[0], 921600); // if you have only ONE serial port active // if you know the serial port name - //myPort = new Serial(this, "COM5", 9600); // Windows + //myPort = new Serial(this, "COM5", 921600); // Windows //myPort = new Serial(this, "/dev/ttyACM0", 921600); // Linux - myPort = new Serial(this, "/dev/cu.usbmodem14401", 9600); // Mac + myPort = new Serial(this, "/dev/cu.usbmodem14401", 921600); // Mac // wait for full frame of bytes myPort.buffer(bytesPerFrame); From ee499898a34ae0e9dec8090743b1b0e38ecdffb2 Mon Sep 17 00:00:00 2001 From: Sebastian Romero Date: Mon, 22 Feb 2021 18:32:03 +0100 Subject: [PATCH 4/8] Remove unnecessary check --- .../CameraRawBytesVisualizer.pde | 23 ++++++++----------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/libraries/Portenta_Camera/extras/CameraRawBytesVisualizer/CameraRawBytesVisualizer.pde b/libraries/Portenta_Camera/extras/CameraRawBytesVisualizer/CameraRawBytesVisualizer.pde index 15087260b..427cb3648 100644 --- a/libraries/Portenta_Camera/extras/CameraRawBytesVisualizer/CameraRawBytesVisualizer.pde +++ b/libraries/Portenta_Camera/extras/CameraRawBytesVisualizer/CameraRawBytesVisualizer.pde @@ -22,8 +22,7 @@ final int bytesPerFrame = cameraPixelCount * cameraBytesPerPixel; PImage myImage; byte[] frameBuffer = new byte[bytesPerFrame]; -void setup() -{ +void setup() { size(640, 480); // if you have only ONE serial port active @@ -43,15 +42,14 @@ void setup() myPort.write(1); } -void draw() -{ +void draw() { PImage img = myImage.copy(); img.resize(640, 480); image(img, 0, 0); } void serialEvent(Serial myPort) { - // read the saw bytes in + // read the received bytes myPort.readBytes(frameBuffer); // access raw bytes via byte buffer @@ -62,17 +60,14 @@ void serialEvent(Serial myPort) { while (bb.hasRemaining()) { // read 16-bit pixel - byte p = bb.get(); - + byte pixelValue = bb.get(); // set pixel color - myImage .pixels[i++] = color(Byte.toUnsignedInt(p)); - - // Let the Arduino sketch know we received all pixels - // and are ready for the next frame - if(i == cameraPixelCount){ - myPort.write(1); - } + myImage.pixels[i++] = color(Byte.toUnsignedInt(pixelValue)); } + myImage.updatePixels(); + // Let the Arduino sketch know we received all pixels + // and are ready for the next frame + myPort.write(1); } From b9feb3dd2d35c96089a93cb5dbe4886d2a6d26f7 Mon Sep 17 00:00:00 2001 From: Sebastian Romero Date: Tue, 23 Feb 2021 12:24:28 +0100 Subject: [PATCH 5/8] Add timeout fallback --- .../CameraRawBytesVisualizer/CameraRawBytesVisualizer.pde | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/libraries/Portenta_Camera/extras/CameraRawBytesVisualizer/CameraRawBytesVisualizer.pde b/libraries/Portenta_Camera/extras/CameraRawBytesVisualizer/CameraRawBytesVisualizer.pde index 427cb3648..2ae9a5bc0 100644 --- a/libraries/Portenta_Camera/extras/CameraRawBytesVisualizer/CameraRawBytesVisualizer.pde +++ b/libraries/Portenta_Camera/extras/CameraRawBytesVisualizer/CameraRawBytesVisualizer.pde @@ -21,6 +21,7 @@ final int bytesPerFrame = cameraPixelCount * cameraBytesPerPixel; PImage myImage; byte[] frameBuffer = new byte[bytesPerFrame]; +int lastUpdate = 0; void setup() { size(640, 480); @@ -46,9 +47,16 @@ void draw() { PImage img = myImage.copy(); img.resize(640, 480); image(img, 0, 0); + // Time out after 1.5 seconds and ask for new data + if(millis() - lastUpdate > 1500) { + println("Connection timed out."); + myPort.write(1); + } } void serialEvent(Serial myPort) { + lastUpdate = millis(); + // read the received bytes myPort.readBytes(frameBuffer); From 3512da443e2237d8077672c99173266bb119ce2d Mon Sep 17 00:00:00 2001 From: Sebastian Romero Date: Tue, 23 Feb 2021 12:24:55 +0100 Subject: [PATCH 6/8] Decrease CPU load by avoiding unnecessary redraws --- .../CameraRawBytesVisualizer.pde | 20 ++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/libraries/Portenta_Camera/extras/CameraRawBytesVisualizer/CameraRawBytesVisualizer.pde b/libraries/Portenta_Camera/extras/CameraRawBytesVisualizer/CameraRawBytesVisualizer.pde index 2ae9a5bc0..38baa14d6 100644 --- a/libraries/Portenta_Camera/extras/CameraRawBytesVisualizer/CameraRawBytesVisualizer.pde +++ b/libraries/Portenta_Camera/extras/CameraRawBytesVisualizer/CameraRawBytesVisualizer.pde @@ -22,6 +22,7 @@ final int bytesPerFrame = cameraPixelCount * cameraBytesPerPixel; PImage myImage; byte[] frameBuffer = new byte[bytesPerFrame]; int lastUpdate = 0; +boolean shouldRedraw = false; void setup() { size(640, 480); @@ -44,14 +45,18 @@ void setup() { } void draw() { - PImage img = myImage.copy(); - img.resize(640, 480); - image(img, 0, 0); // Time out after 1.5 seconds and ask for new data if(millis() - lastUpdate > 1500) { println("Connection timed out."); myPort.write(1); } + + if(shouldRedraw){ + PImage img = myImage.copy(); + img.resize(640, 480); + image(img, 0, 0); + shouldRedraw = false; + } } void serialEvent(Serial myPort) { @@ -60,14 +65,15 @@ void serialEvent(Serial myPort) { // read the received bytes myPort.readBytes(frameBuffer); - // access raw bytes via byte buffer + // Access raw bytes via byte buffer and ensure + // proper endianness of the data for > 8 bit values. ByteBuffer bb = ByteBuffer.wrap(frameBuffer); bb.order(ByteOrder.BIG_ENDIAN); int i = 0; while (bb.hasRemaining()) { - // read 16-bit pixel + // read 8-bit pixel byte pixelValue = bb.get(); // set pixel color @@ -75,6 +81,10 @@ void serialEvent(Serial myPort) { } myImage.updatePixels(); + + // Ensures that the new image data is drawn in the next draw loop + shouldRedraw = true; + // Let the Arduino sketch know we received all pixels // and are ready for the next frame myPort.write(1); From bf30ea8cc9edaac3ce64a7f625f4731885367c07 Mon Sep 17 00:00:00 2001 From: Sebastian Romero Date: Tue, 23 Feb 2021 12:37:41 +0100 Subject: [PATCH 7/8] Clear buffer on timeout --- .../extras/CameraRawBytesVisualizer/CameraRawBytesVisualizer.pde | 1 + 1 file changed, 1 insertion(+) diff --git a/libraries/Portenta_Camera/extras/CameraRawBytesVisualizer/CameraRawBytesVisualizer.pde b/libraries/Portenta_Camera/extras/CameraRawBytesVisualizer/CameraRawBytesVisualizer.pde index 38baa14d6..7a016f66f 100644 --- a/libraries/Portenta_Camera/extras/CameraRawBytesVisualizer/CameraRawBytesVisualizer.pde +++ b/libraries/Portenta_Camera/extras/CameraRawBytesVisualizer/CameraRawBytesVisualizer.pde @@ -48,6 +48,7 @@ void draw() { // Time out after 1.5 seconds and ask for new data if(millis() - lastUpdate > 1500) { println("Connection timed out."); + myPort.clear(); myPort.write(1); } From da37f87586d44cd1c8c459db312a09d6ff0dddd4 Mon Sep 17 00:00:00 2001 From: Sebastian Romero Date: Tue, 23 Feb 2021 16:18:06 +0100 Subject: [PATCH 8/8] Comment unnecessary byte ordering for 8 bit values --- .../CameraRawBytesVisualizer.pde | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/libraries/Portenta_Camera/extras/CameraRawBytesVisualizer/CameraRawBytesVisualizer.pde b/libraries/Portenta_Camera/extras/CameraRawBytesVisualizer/CameraRawBytesVisualizer.pde index 7a016f66f..1bc6746ee 100644 --- a/libraries/Portenta_Camera/extras/CameraRawBytesVisualizer/CameraRawBytesVisualizer.pde +++ b/libraries/Portenta_Camera/extras/CameraRawBytesVisualizer/CameraRawBytesVisualizer.pde @@ -66,10 +66,15 @@ void serialEvent(Serial myPort) { // read the received bytes myPort.readBytes(frameBuffer); - // Access raw bytes via byte buffer and ensure - // proper endianness of the data for > 8 bit values. + // Access raw bytes via byte buffer ByteBuffer bb = ByteBuffer.wrap(frameBuffer); - bb.order(ByteOrder.BIG_ENDIAN); + + /* + Ensure proper endianness of the data for > 8 bit values. + When using > 8bit values uncomment the following line and + adjust the translation to the pixel color. + */ + //bb.order(ByteOrder.BIG_ENDIAN); int i = 0;