-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #28 from arduino-libraries/marqdevx/vision-shield/…
…bitmap-SD Portenta Vision Shield, bitmap to SD Card update sketch
- Loading branch information
Showing
2 changed files
with
99 additions
and
81 deletions.
There are no files selected for viewing
174 changes: 96 additions & 78 deletions
174
examples/Vision Shield to SD Card bmp/visionShieldBitmap/visionShieldBitmap.ino
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,126 +1,144 @@ | ||
#include "SDMMCBlockDevice.h" // Multi Media Card APIs | ||
#include "FATFileSystem.h" // Mbed API for portable and embedded systems | ||
#include "FATFileSystem.h" // API to run operations on a FAT file system | ||
SDMMCBlockDevice blockDevice; | ||
mbed::FATFileSystem fileSystem("fs"); | ||
|
||
#include "camera.h" // Arduino Mbed Core Camera APIs | ||
#include "himax.h" // Exclusive Camera library for the Portenta Vision Shield | ||
#include "himax.h" // API to read from the Himax camera found on the Portenta Vision Shield | ||
HM01B0 himax; | ||
Camera cam(himax); | ||
|
||
FrameBuffer fb; // Buffer to save the capture | ||
FrameBuffer frameBuffer; // Buffer to save the camera stream | ||
|
||
// Settings for our setup | ||
#define RES_H (unsigned int)240 | ||
#define RES_W (unsigned int)320 | ||
#define IMAGE_HEIGHT (unsigned int)240 | ||
#define IMAGE_WIDTH (unsigned int)320 | ||
#define IMAGE_MODE CAMERA_GRAYSCALE | ||
#define IMAGE_BPP (unsigned int)8 | ||
#define BITS_PER_PIXEL (unsigned int)8 | ||
#define PALETTE_COLORS_AMOUNT (unsigned int)(pow(2, BITS_PER_PIXEL)) | ||
#define PALETTE_SIZE (unsigned int)(PALETTE_COLORS_AMOUNT * 4) // 4 bytes = 32bit per color (3 bytes RGB and 1 byte 0x00) | ||
#define IMAGE_PATH "/fs/image.bmp" | ||
|
||
// Headers info | ||
#define HEADER_FILE_HEADER (unsigned int)14 | ||
#define HEADER_DIB_SIZE (unsigned int)40 | ||
#define HEADER_FULL_SIZE (HEADER_FILE_HEADER + HEADER_DIB_SIZE) | ||
#define PALETTE_SIZE (2 ^ IMAGE_BPP) * 4 // 4 bytes per color | ||
#define BITMAP_FILE_HEADER_SIZE (unsigned int)14 // For storing general information about the bitmap image file | ||
#define DIB_HEADER_SIZE (unsigned int)40 // For storing information about the image and define the pixel format | ||
#define HEADER_SIZE (BITMAP_FILE_HEADER_SIZE + DIB_HEADER_SIZE) | ||
|
||
void setup() | ||
{ | ||
Serial.begin(115200); | ||
while (!Serial) | ||
; | ||
|
||
// Mount SD Card | ||
mountSD(); | ||
void setup(){ | ||
Serial.begin(115200); | ||
while (!Serial && millis() < 5000); | ||
|
||
Serial.println("Mounting SD Card..."); | ||
mountSDCard(); | ||
Serial.println("SD Card mounted."); | ||
|
||
// Init the cam QVGA, 30FPS, Grayscale | ||
if (!cam.begin(CAMERA_R320x240, IMAGE_MODE, 30)) | ||
{ | ||
if (!cam.begin(CAMERA_R320x240, IMAGE_MODE, 30)){ | ||
Serial.println("Unable to find the camera"); | ||
} | ||
|
||
// Save the headers and the image data into the .bmp file | ||
parseData(); | ||
countDownBlink(); | ||
Serial.println("Fetching camera image..."); | ||
unsigned char *imageData = captureImage(); | ||
digitalWrite(LEDB, HIGH); | ||
|
||
Serial.println("Saving image to SD card..."); | ||
saveImage(imageData, IMAGE_PATH); | ||
|
||
fileSystem.unmount(); | ||
Serial.println("Done. You can now remove the SD card."); | ||
} | ||
|
||
void loop() | ||
{ | ||
while (1) | ||
; | ||
void loop(){ | ||
} | ||
|
||
// Mount File system block | ||
void mountSD() | ||
{ | ||
Serial.println("Mounting SD Card..."); | ||
|
||
void mountSDCard(){ | ||
int error = fileSystem.mount(&blockDevice); | ||
if (error) | ||
{ | ||
Serial.println("No SD Card found"); | ||
while (1) | ||
; | ||
if (error){ | ||
Serial.println("Trying to reformat..."); | ||
int formattingError = fileSystem.reformat(&blockDevice); | ||
if (formattingError) { | ||
Serial.println("No SD Card found"); | ||
while (1); | ||
} | ||
} | ||
} | ||
|
||
void parseData() | ||
{ | ||
unsigned char *imgData = NULL; | ||
int fileSize = HEADER_FILE_HEADER + RES_W * RES_H; | ||
|
||
FILE *file = fopen("/fs/image.bmp", "w+"); | ||
|
||
// Get a Frame | ||
if (cam.grabFrame(fb, 3000) == 0) | ||
{ | ||
// Save the raw image data (8bpp grayscale) | ||
imgData = fb.getBuffer(); | ||
} | ||
else | ||
{ | ||
// Get the raw image data (8bpp grayscale) | ||
unsigned char * captureImage(){ | ||
if (cam.grabFrame(frameBuffer, 3000) == 0){ | ||
return frameBuffer.getBuffer(); | ||
} else { | ||
Serial.println("could not grab the frame"); | ||
while (1) | ||
; | ||
while (1); | ||
} | ||
// Bitmap structure (Head + DIB Head + ColorMap + binary image) | ||
unsigned char bitmapFileHeader[HEADER_FILE_HEADER]; | ||
unsigned char bitmapDIBHeader[HEADER_DIB_SIZE]; | ||
unsigned char colorMap[PALETTE_SIZE]; // Needed for <=8bpp grayscale bitmaps | ||
} | ||
|
||
// Set the file headers to 0 | ||
memset(bitmapFileHeader, (unsigned char)(0), HEADER_FILE_HEADER); | ||
memset(bitmapDIBHeader, (unsigned char)(0), HEADER_DIB_SIZE); | ||
memset(colorMap, (unsigned char)(0), PALETTE_SIZE); | ||
// Set the headers data | ||
void setFileHeaders(unsigned char *bitmapFileHeader, unsigned char *bitmapDIBHeader, int fileSize){ | ||
// Set the headers to 0 | ||
memset(bitmapFileHeader, (unsigned char)(0), BITMAP_FILE_HEADER_SIZE); | ||
memset(bitmapDIBHeader, (unsigned char)(0), DIB_HEADER_SIZE); | ||
|
||
// Write the headers info | ||
// File header | ||
bitmapFileHeader[0] = 'B'; | ||
bitmapFileHeader[1] = 'M'; | ||
bitmapFileHeader[2] = (unsigned char)(fileSize); | ||
bitmapFileHeader[3] = (unsigned char)(fileSize >> 8); | ||
bitmapFileHeader[4] = (unsigned char)(fileSize >> 16); | ||
bitmapFileHeader[5] = (unsigned char)(fileSize >> 24); | ||
bitmapFileHeader[10] = (unsigned char)HEADER_FULL_SIZE + PALETTE_SIZE; | ||
bitmapFileHeader[10] = (unsigned char)HEADER_SIZE + PALETTE_SIZE; | ||
|
||
// Info header | ||
bitmapDIBHeader[0] = (unsigned char)(HEADER_DIB_SIZE); | ||
bitmapDIBHeader[4] = (unsigned char)(RES_W); | ||
bitmapDIBHeader[5] = (unsigned char)(RES_W >> 8); | ||
bitmapDIBHeader[8] = (unsigned char)(RES_H); | ||
bitmapDIBHeader[8] = (unsigned char)(RES_H >> 8); | ||
bitmapDIBHeader[14] = (unsigned char)(IMAGE_BPP); | ||
|
||
// Color palette for grayscale Bitmaps (8bpp) | ||
for (int i = 0; i < (2 ^ IMAGE_BPP); i++) | ||
{ | ||
bitmapDIBHeader[0] = (unsigned char)(DIB_HEADER_SIZE); | ||
bitmapDIBHeader[4] = (unsigned char)(IMAGE_WIDTH); | ||
bitmapDIBHeader[5] = (unsigned char)(IMAGE_WIDTH >> 8); | ||
bitmapDIBHeader[8] = (unsigned char)(IMAGE_HEIGHT); | ||
bitmapDIBHeader[9] = (unsigned char)(IMAGE_HEIGHT >> 8); | ||
bitmapDIBHeader[14] = (unsigned char)(BITS_PER_PIXEL); | ||
} | ||
|
||
void setColorMap(unsigned char *colorMap){ | ||
//Init the palette with zeroes | ||
memset(colorMap, (unsigned char)(0), PALETTE_SIZE); | ||
|
||
// Gray scale color palette, 4 bytes per color (R, G, B, 0x00) | ||
for (int i = 0; i < PALETTE_COLORS_AMOUNT; i++) { | ||
colorMap[i * 4] = i; | ||
colorMap[i * 4 + 1] = i; | ||
colorMap[i * 4 + 2] = i; | ||
} | ||
} | ||
|
||
// Save the headers and the image data into the .bmp file | ||
void saveImage(unsigned char *imageData, const char* imagePath){ | ||
int fileSize = BITMAP_FILE_HEADER_SIZE + DIB_HEADER_SIZE + IMAGE_WIDTH * IMAGE_HEIGHT; | ||
FILE *file = fopen(imagePath, "w"); | ||
|
||
// Write theh bitmap file | ||
fwrite(bitmapFileHeader, 1, HEADER_FILE_HEADER, file); | ||
fwrite(bitmapDIBHeader, 1, HEADER_DIB_SIZE, file); | ||
fwrite(colorMap, 1, PALETTE_SIZE, file); // Color map | ||
fwrite(imgData, 1, RES_H * RES_W, file); | ||
// Bitmap structure (Head + DIB Head + ColorMap + binary image) | ||
unsigned char bitmapFileHeader[BITMAP_FILE_HEADER_SIZE]; | ||
unsigned char bitmapDIBHeader[DIB_HEADER_SIZE]; | ||
unsigned char colorMap[PALETTE_SIZE]; // Needed for <= 8bpp grayscale bitmaps | ||
|
||
setFileHeaders(bitmapFileHeader, bitmapDIBHeader, fileSize); | ||
setColorMap(colorMap); | ||
|
||
// Write the bitmap file | ||
fwrite(bitmapFileHeader, 1, BITMAP_FILE_HEADER_SIZE, file); | ||
fwrite(bitmapDIBHeader, 1, DIB_HEADER_SIZE, file); | ||
fwrite(colorMap, 1, PALETTE_SIZE, file); | ||
fwrite(imageData, 1, IMAGE_HEIGHT * IMAGE_WIDTH, file); | ||
|
||
// Close the stream (bitmap file) | ||
// Close the file stream | ||
fclose(file); | ||
} | ||
|
||
void countDownBlink(){ | ||
for (int i = 0; i < 6; i++){ | ||
digitalWrite(LEDG, i % 2); | ||
delay(500); | ||
} | ||
digitalWrite(LEDG, HIGH); | ||
digitalWrite(LEDB, LOW); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,11 @@ | ||
name=Arduino_Pro_Tutorials | ||
version=1.0.5 | ||
version=1.0.6 | ||
author=Martino Facchin, Riccardo Ricco, Dario Pennisi, Sebastian Romero, Lenard George, Ignacio Herrera, Jose García, Pablo Marquínez | ||
maintainer=Arduino <info@arduino.cc> | ||
sentence=This library contains the complete Arduino sketches from the Pro Tutorials. | ||
paragraph=Instructions on how to use these sketches can be found on the Arduino Pro website under Documentation->Tutorials. | ||
category=Other | ||
url=https://www.arduino.cc/pro/tutorials/portenta-h7 | ||
architectures=mbed,mbed_portenta | ||
url=https://docs.arduino.cc/#pro-family | ||
architectures=mbed,mbed_portenta,mbed_nicla,mbed_edge | ||
precompiled=false | ||
depends=lvgl |