1
1
#include " SDMMCBlockDevice.h" // Multi Media Card APIs
2
- #include " FATFileSystem.h" // Mbed API for portable and embedded systems
2
+ #include " FATFileSystem.h" // API to run operations on a FAT file system
3
3
SDMMCBlockDevice blockDevice;
4
4
mbed::FATFileSystem fileSystem (" fs" );
5
5
6
6
#include " camera.h" // Arduino Mbed Core Camera APIs
7
- #include " himax.h" // Exclusive Camera library for the Portenta Vision Shield
7
+ #include " himax.h" // API to read from the Himax camera found on the Portenta Vision Shield
8
8
HM01B0 himax;
9
9
Camera cam (himax);
10
10
11
- FrameBuffer fb ; // Buffer to save the capture
11
+ FrameBuffer frameBuffer ; // Buffer to save the camera stream
12
12
13
13
// Settings for our setup
14
- #define RES_H (unsigned int )240
15
- #define RES_W (unsigned int )320
14
+ #define IMAGE_HEIGHT (unsigned int )240
15
+ #define IMAGE_WIDTH (unsigned int )320
16
16
#define IMAGE_MODE CAMERA_GRAYSCALE
17
- #define IMAGE_BPP (unsigned int )8
17
+ #define BITS_PER_PIXEL (unsigned int )8
18
+ #define PALETTE_COLORS_AMOUNT (unsigned int )(pow(2 , BITS_PER_PIXEL))
19
+ #define PALETTE_SIZE (unsigned int )(PALETTE_COLORS_AMOUNT * 4 ) // 4 bytes = 32bit per color (3 bytes RGB and 1 byte 0x00)
20
+ #define IMAGE_PATH " /fs/image.bmp"
21
+
18
22
// Headers info
19
- #define HEADER_FILE_HEADER (unsigned int )14
20
- #define HEADER_DIB_SIZE (unsigned int )40
21
- #define HEADER_FULL_SIZE (HEADER_FILE_HEADER + HEADER_DIB_SIZE)
22
- #define PALETTE_SIZE (2 ^ IMAGE_BPP) * 4 // 4 bytes per color
23
+ #define BITMAP_FILE_HEADER_SIZE (unsigned int )14 // For storing general information about the bitmap image file
24
+ #define DIB_HEADER_SIZE (unsigned int )40 // For storing information about the image and define the pixel format
25
+ #define HEADER_SIZE (BITMAP_FILE_HEADER_SIZE + DIB_HEADER_SIZE)
23
26
24
- void setup ()
25
- {
26
- Serial.begin (115200 );
27
- while (!Serial)
28
- ;
29
27
30
- // Mount SD Card
31
- mountSD ();
28
+ void setup (){
29
+ Serial.begin (115200 );
30
+ while (!Serial && millis () < 5000 );
31
+
32
+ Serial.println (" Mounting SD Card..." );
33
+ mountSDCard ();
34
+ Serial.println (" SD Card mounted." );
32
35
33
36
// Init the cam QVGA, 30FPS, Grayscale
34
- if (!cam.begin (CAMERA_R320x240, IMAGE_MODE, 30 ))
35
- {
37
+ if (!cam.begin (CAMERA_R320x240, IMAGE_MODE, 30 )){
36
38
Serial.println (" Unable to find the camera" );
37
39
}
38
-
39
- // Save the headers and the image data into the .bmp file
40
- parseData ();
40
+ countDownBlink ();
41
+ Serial.println (" Fetching camera image..." );
42
+ unsigned char *imageData = captureImage ();
43
+ digitalWrite (LEDB, HIGH);
44
+
45
+ Serial.println (" Saving image to SD card..." );
46
+ saveImage (imageData, IMAGE_PATH);
47
+
48
+ fileSystem.unmount ();
49
+ Serial.println (" Done. You can now remove the SD card." );
41
50
}
42
51
43
- void loop ()
44
- {
45
- while (1 )
46
- ;
52
+ void loop (){
47
53
}
48
54
49
55
// Mount File system block
50
- void mountSD ()
51
- {
52
- Serial.println (" Mounting SD Card..." );
53
-
56
+ void mountSDCard (){
54
57
int error = fileSystem.mount (&blockDevice);
55
- if (error)
56
- {
57
- Serial.println (" No SD Card found" );
58
- while (1 )
59
- ;
58
+ if (error){
59
+ Serial.println (" Trying to reformat..." );
60
+ int formattingError = fileSystem.reformat (&blockDevice);
61
+ if (formattingError) {
62
+ Serial.println (" No SD Card found" );
63
+ while (1 );
64
+ }
60
65
}
61
66
}
62
67
63
- void parseData ()
64
- {
65
- unsigned char *imgData = NULL ;
66
- int fileSize = HEADER_FILE_HEADER + RES_W * RES_H;
67
-
68
- FILE *file = fopen (" /fs/image.bmp" , " w+" );
69
-
70
- // Get a Frame
71
- if (cam.grabFrame (fb, 3000 ) == 0 )
72
- {
73
- // Save the raw image data (8bpp grayscale)
74
- imgData = fb.getBuffer ();
75
- }
76
- else
77
- {
68
+ // Get the raw image data (8bpp grayscale)
69
+ unsigned char * captureImage (){
70
+ if (cam.grabFrame (frameBuffer, 3000 ) == 0 ){
71
+ return frameBuffer.getBuffer ();
72
+ } else {
78
73
Serial.println (" could not grab the frame" );
79
- while (1 )
80
- ;
74
+ while (1 );
81
75
}
82
- // Bitmap structure (Head + DIB Head + ColorMap + binary image)
83
- unsigned char bitmapFileHeader[HEADER_FILE_HEADER];
84
- unsigned char bitmapDIBHeader[HEADER_DIB_SIZE];
85
- unsigned char colorMap[PALETTE_SIZE]; // Needed for <=8bpp grayscale bitmaps
76
+ }
86
77
87
- // Set the file headers to 0
88
- memset (bitmapFileHeader, (unsigned char )(0 ), HEADER_FILE_HEADER);
89
- memset (bitmapDIBHeader, (unsigned char )(0 ), HEADER_DIB_SIZE);
90
- memset (colorMap, (unsigned char )(0 ), PALETTE_SIZE);
78
+ // Set the headers data
79
+ void setFileHeaders (unsigned char *bitmapFileHeader, unsigned char *bitmapDIBHeader, int fileSize){
80
+ // Set the headers to 0
81
+ memset (bitmapFileHeader, (unsigned char )(0 ), BITMAP_FILE_HEADER_SIZE);
82
+ memset (bitmapDIBHeader, (unsigned char )(0 ), DIB_HEADER_SIZE);
91
83
92
- // Write the headers info
93
84
// File header
94
85
bitmapFileHeader[0 ] = ' B' ;
95
86
bitmapFileHeader[1 ] = ' M' ;
96
87
bitmapFileHeader[2 ] = (unsigned char )(fileSize);
97
88
bitmapFileHeader[3 ] = (unsigned char )(fileSize >> 8 );
98
89
bitmapFileHeader[4 ] = (unsigned char )(fileSize >> 16 );
99
90
bitmapFileHeader[5 ] = (unsigned char )(fileSize >> 24 );
100
- bitmapFileHeader[10 ] = (unsigned char )HEADER_FULL_SIZE + PALETTE_SIZE;
91
+ bitmapFileHeader[10 ] = (unsigned char )HEADER_SIZE + PALETTE_SIZE;
101
92
102
93
// Info header
103
- bitmapDIBHeader[0 ] = (unsigned char )(HEADER_DIB_SIZE);
104
- bitmapDIBHeader[4 ] = (unsigned char )(RES_W);
105
- bitmapDIBHeader[5 ] = (unsigned char )(RES_W >> 8 );
106
- bitmapDIBHeader[8 ] = (unsigned char )(RES_H);
107
- bitmapDIBHeader[8 ] = (unsigned char )(RES_H >> 8 );
108
- bitmapDIBHeader[14 ] = (unsigned char )(IMAGE_BPP);
109
-
110
- // Color palette for grayscale Bitmaps (8bpp)
111
- for (int i = 0 ; i < (2 ^ IMAGE_BPP); i++)
112
- {
94
+ bitmapDIBHeader[0 ] = (unsigned char )(DIB_HEADER_SIZE);
95
+ bitmapDIBHeader[4 ] = (unsigned char )(IMAGE_WIDTH);
96
+ bitmapDIBHeader[5 ] = (unsigned char )(IMAGE_WIDTH >> 8 );
97
+ bitmapDIBHeader[8 ] = (unsigned char )(IMAGE_HEIGHT);
98
+ bitmapDIBHeader[9 ] = (unsigned char )(IMAGE_HEIGHT >> 8 );
99
+ bitmapDIBHeader[14 ] = (unsigned char )(BITS_PER_PIXEL);
100
+ }
101
+
102
+ void setColorMap (unsigned char *colorMap){
103
+ // Init the palette with zeroes
104
+ memset (colorMap, (unsigned char )(0 ), PALETTE_SIZE);
105
+
106
+ // Gray scale color palette, 4 bytes per color (R, G, B, 0x00)
107
+ for (int i = 0 ; i < PALETTE_COLORS_AMOUNT; i++) {
113
108
colorMap[i * 4 ] = i;
114
109
colorMap[i * 4 + 1 ] = i;
115
110
colorMap[i * 4 + 2 ] = i;
116
111
}
112
+ }
113
+
114
+ // Save the headers and the image data into the .bmp file
115
+ void saveImage (unsigned char *imageData, const char * imagePath){
116
+ int fileSize = BITMAP_FILE_HEADER_SIZE + DIB_HEADER_SIZE + IMAGE_WIDTH * IMAGE_HEIGHT;
117
+ FILE *file = fopen (imagePath, " w" );
117
118
118
- // Write theh bitmap file
119
- fwrite (bitmapFileHeader, 1 , HEADER_FILE_HEADER, file);
120
- fwrite (bitmapDIBHeader, 1 , HEADER_DIB_SIZE, file);
121
- fwrite (colorMap, 1 , PALETTE_SIZE, file); // Color map
122
- fwrite (imgData, 1 , RES_H * RES_W, file);
119
+ // Bitmap structure (Head + DIB Head + ColorMap + binary image)
120
+ unsigned char bitmapFileHeader[BITMAP_FILE_HEADER_SIZE];
121
+ unsigned char bitmapDIBHeader[DIB_HEADER_SIZE];
122
+ unsigned char colorMap[PALETTE_SIZE]; // Needed for <= 8bpp grayscale bitmaps
123
+
124
+ setFileHeaders (bitmapFileHeader, bitmapDIBHeader, fileSize);
125
+ setColorMap (colorMap);
126
+
127
+ // Write the bitmap file
128
+ fwrite (bitmapFileHeader, 1 , BITMAP_FILE_HEADER_SIZE, file);
129
+ fwrite (bitmapDIBHeader, 1 , DIB_HEADER_SIZE, file);
130
+ fwrite (colorMap, 1 , PALETTE_SIZE, file);
131
+ fwrite (imageData, 1 , IMAGE_HEIGHT * IMAGE_WIDTH, file);
123
132
124
- // Close the stream (bitmap file)
133
+ // Close the file stream
125
134
fclose (file);
135
+ }
136
+
137
+ void countDownBlink (){
138
+ for (int i = 0 ; i < 6 ; i++){
139
+ digitalWrite (LEDG, i % 2 );
140
+ delay (500 );
141
+ }
142
+ digitalWrite (LEDG, HIGH);
143
+ digitalWrite (LEDB, LOW);
126
144
}
0 commit comments