You are on page 1of 11

Lets equip Arduino with a serial-interface JPEG Camera with

IR and try two applications: the first one saves shots (on a SD-
card) at regular intervals while the second uses a PIR sensor
to detect intrusions and photograph what happens.
Recently, miniaturized cameras with serial communication interface have been launched on the
market. Compared to traditional cameras, they offer easier integration with Arduino or other
microcontroller-based boards.
It is quite easy to understand that using a composite or USB interface camera requires a
considerable effort, on both hardware and software sides. If you decide to bet on a serial
interface camera, everything gets easier, because all the prototyping boards (Arduino in
particular) and all microcontrollers (Microchip, Atmel etc.) have at least one serial port as a
standard feature.
The basic concept of these cameras is that you can send all the setup commands, take
screenshots and viewing images through appropriate bytes sequences via their serial port.
In our case, we will use a LinkSprite camera connected to Arduino Uno. Special feature of this
camera is the ability to capture images even at night; in fact, it has a brightness sensor and
infrared LEDs activated automatically when the detected light falls below a certain threshold
(refer to the pictures in these pages to get an idea of how infrared LEDs work).
The camera is capable of capturing high-resolution images, sending them as JPEG through the
serial port. It has a four-pin connector where two pins are for the power supply (+ 5V and GND)
and two for the serial port (RX and TX).
This article will show how to use this camera in two different Arduino projects: the first creates a
timing system to take pictures on specific intervals, storing them on the SD-card, while the
second is an automatic surveillance system activated only if the special PIR sensor (Passive
Infrared Radar) detects a warm object moving in the camera view field. In practice, this second
application is a time-lapse video surveillance device that records what happens in a room,
activated by the detection of moving people or vehicles. Of course, the PIR detection area must
match the same camera angle so that the captured images effectively show the triggering foe.
Images will be saved on a Sd-card in JPEG format file and therefore we need a dedicated Sd-
card shield (available on Futura Elettronica).
Finally, we will use software libraries (JPEGCamera) developed by us specifically for these
camera usage examples.
SYSTEM HARDWARE
About the first application, the hardware consists of an Arduino Uno Rev 3 and a SD-card shield
used to save images, all connected to the serial camera. The SD shield has four jumpers
allowing us to choose which Arduino pin works as chip select (you can choose between D4, D8,
D9 and D10); for chip select we mean the command line that enables the shield.
In our examples, we use D4 therefore we have to insert the corresponding jumper.
The camera has a four-pin connector used for both power and serial interface, and is supplied
with a four wires cable (colors: red, brown, purple and gray) ending with female jumpers. Please
note that for the serial communication between Arduino and the camera we decided not to use
the hardware serial port, but we use the software one (mapped on Arduino D2 and D3 pins); in
this way, the software library keeps the hardware port free for debugging.
To connect Arduino to the camera you need to connect the red wire (RXD) to Arduino D3 pin; the
brown (TXD) to D2; the gray to the + 5V signal and finally the violet to ground (GND).
For the second application, we must add the PIR sensor to the hardware just described. What we
used for our prototype is a device with a certain intelligence on-board, which implements two
different trigger modes, providing a programmable delay time (between the motion detection and
the signal trigger ) ranging from 0.3 to 180 seconds, has a 120 detection angle and 7 meters
maximum range. The sensor has three pins (TTL 0V 3.3V output and positive-negative power
supply). To connect Arduino you must create a three-wire cable where the power supply positive
and negative pins must be connected to Arduino +5V and GND while the TTL output to Arduino
D5 pin. Through the output, the device sends the trigger signal caused by PIR sensor movement
detection.

ARDUINO LIBRARY
JPEGCamera
To allow Arduino managing the JPEG camera we have developed a library (JPEGCamera) that
offers all the LinkSprite camera functions: initialization, screenshots capturing and saving
images.
The library provides an object called JPEGCamera you can call for complete hardware
management.
A Begin function initializes the entire camera management system, a Reset physically resets the
camera, a setImageSize sets the captured image size (you can choose between 160 x 120, 320
x 280 and 640 x 480 pixels). Then there is the takePicture function , who commands the camera
to capture the image currently framed (basically is the take screenshot function)
and readJpegFileSize, which reads the size (in bytes) of the image file stored. Other functions
include the readJpegFileContent, which deals with reading (a packet at a time) the image data
and finally stopTakingPictures, which stops the screenshots capture.
The readJpegFileContent function deserves a special mention: the data reading process works
with a packet (64 bytes, in our case) at a time. To do this it is necessary, each time you call the
procedure, to indicate the starting address (the first time is equal to 0, the second 64, the third
128 and so on) and the packet size to be read (in our case, always 64; please note that it is not
possible to exceed that value). The function requires as input a byte array where data will be
saved; also returns the iSend output parameter, which indicates if the reading operation has
been completed.
SKETCH EXAMPLE 1
Starting from the beginning, we analyze the first JPEG camera example code, the continuous
saving images application (Listing 1).
We include the necessary libraries (JPEGCamera.h, SoftwareSerial.h since we will use a
software serial interface and SD.h, to save images on the SD-card) and define the size (in
bytes) of a single data packet stored (chunk_size; 64 bytes).
Subsequently we define the Arduino pin (D4) we will use as SD-card chip select and some
variables that we will use in the program (in particular jpegCamera, used for camera
management). Inside the setup function we initialize the board and we call the
camerabegin command; later we initialize the SD library indicating that we want to use D4 pin as
chip select.
In the loop function, we manage the real images capture and saving; first we set to capture 320 x
280 pixels pictures and through jpegCamera.takePicture we start capturing the single
screenshot.
Afterwards we can define the save as filename (e.g. imageXX.jpg where XX ranges from 00 to
99) and through SD.open we can create and open the file in writing mode on the SD-card. Then,
through a while loop we handle the image reading and saving
process. With jpegCamera.readJpegFileContent we read one jpeg data packet at a time and we
can save it by using the File object write function.
When the while loop ends, all the picture bytes have been read and saved; then we execute
theFile object close function to close the file handler and jpegCamera.stopTakingPictures to tell
the camera to stop capturing images.
Before ending the loop, lets wait one second and increase the variable that counts the number of
pictures taken.

?
1 /*********************************************************************
* Inclusione librerie *
2 *********************************************************************/
3 #include <JPEGCamera.h>
4 #include SoftwareSerial.h
5 #include <SD.h>
// Chunk size per salvataggio immagine
6
#define CHUNK_SIZE 64
7 /*********************************************************************
8 * Definizione pin I/O Arduino *
9 *********************************************************************/
10 // Led scheda Arduino
const int pinBoardLed = 13;
11 // Pin Arduino Chip Select SD
12 const int pinSDChipSelect = 4;
13 /*********************************************************************
14 * Variabili programma *
15 *********************************************************************/
// Oggetto JPEG Camera
16 JPEGCamera jpegCamera;
17 // JPEG file
18 File jpegFile;
19 // Contatore immagine
byte i = 0;
20 /*********************************************************************
21 * Codice programma *
22 *********************************************************************/
23 // Inizializzazione Scheda
24 void setup() {
// Inizializzo I/O
25 pinMode(pinBoardLed, OUTPUT);
26 pinMode(pinSDChipSelect, OUTPUT);
27 // Accendo led Arduino
28 digitalWrite(pinBoardLed, HIGH);
// Inizializzo JPEG Camera
29 jpegCamera.begin();
30 // Init SD
31 pinMode(10, OUTPUT);
32 if (!SD.begin(pinSDChipSelect)) {
// Lampeggio led Arduino
33 for (;;) {
34 digitalWrite(pinBoardLed, HIGH);
35 delay(500);
36 digitalWrite(pinBoardLed, LOW);
37 delay(500);
}
38 }
39 // Spengo led Arduino
40 digitalWrite(pinBoardLed, LOW);
41 } // Chiusura funzione setup
// Programma Principale
42 void loop() {
43 boolean isEnd = false;
44 uint16_t address = 0x0000;
45 uint16_t chunkSize = CHUNK_SIZE;
46 byte body[CHUNK_SIZE];
// Imposto dimensione immagine
47 jpegCamera.setImageSize(jpegCamera.ImageSize320x280);
48 // Reset JPEG Camera
49 jpegCamera.reset();
50 // Scatto immagine
51 jpegCamera.takePicture();
// Identifico nome file
52 char fileName[12] = image00.jpg;
53 fileName[5] = ((i / 10) + 0x30);
54 fileName[6] = ((i % 10) + 0x30);
55 // Apro file
jpegFile = SD.open(fileName, FILE_WRITE);
56 // Leggo/salvo i dati immagine
57 isEnd = false;
58 while(isEnd == false) {
59 jpegCamera.readJpegFileContent(address, chunkSize, body, &isEnd);
60 address += chunkSize;
// Salvo i dati sul file
61 jpegFile.write(body, chunkSize);
62 }
63 // Chiudo file
64 jpegFile.close();
// Fermo immagine
65 jpegCamera.stopTakingPictures();
66 // Attesa
67 delay(1000);
68 // Prossimo file
69 i = ((i + 1) % 100);
} // Chiusura funzione loop
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85

SKETCH EXAMPLE 2
The second example, besides implementing the functions explained in the previous example,
manages a PIR sensor too and therefore can be used as an anti-intrusion detection system
prototype.
The algorithm works as follows: cyclically Arduino saves images (max. 5 image01.jpg, ,
image05.jpg overwriting the oldest cyclically) in a SD-card folder (DIR000, ., DIR999); when
it detects an alarm condition the cyclical saving process continues but changing the filename to
image06.jpg, ., image10.jpg and increasing the folder name number. Then, everything goes on
as before.
The first lines of this software are the same as the previous sketch (libraries inclusion, saving
process, Arduino pins definition and variables declaration).
The setup function is similar to that in Listing 1, modified to identify the first free directory (the
folder number is indicated by the dirCount variable). Even the loop cycle is quite similar to the
previous example; different parts are needed to handle the different folder and file naming during
intrusion detection.
In addition, the last function commands added, check if there is an alarm signal coming from the
PIR sensor: if yes, the file saving mechanism explained above is executed.
The sketch of the application is in Listing 2.
?
1 /******************************************************************************
* Inclusione librerie *
2 ******************************************************************************/
3 #include <JPEGCamera.h>
4 #include SoftwareSerial.h
5 #include <SD.h>
6 // Chunk size per salvataggio immagine
#define CHUNK_SIZE 64
7 /******************************************************************************
8 * Definizione pin I/O Arduino *
9 ******************************************************************************/
10 // Led scheda Arduino
const int pinBoardLed = 13;
11 // Pin Arduino Chip Select SD
12 const int pinSDChipSelect = 4;
13 // Sensore PIR scheda Arduino
14 const int pinPIRSensor = 5;
15 /******************************************************************************
* Variabili programma *
16 ******************************************************************************/
17 // Oggetto JPEG Camera
18 JPEGCamera jpegCamera;
19 // JPEG file
File jpegFile;
20
// Contatore directory
21 int dirCount = 0;
22 // Contatore immagine
23 byte fileCount = 1;
24 boolean flagSensorePIR = false;
/******************************************************************************
25 * Codice programma *
26 ******************************************************************************/
27 // Inizializzazione Scheda
28 void setup() {
// Inizializzo I/O
29 pinMode(pinBoardLed, OUTPUT);
30 pinMode(pinSDChipSelect, OUTPUT);
31 pinMode(pinPIRSensor, INPUT);
32 // Accendo led Arduino
33 digitalWrite(pinBoardLed, HIGH);
// Inizializzo JPEG Camera
34 jpegCamera.begin();
35 // Init SD
36 pinMode(10, OUTPUT);
37 if (!SD.begin(pinSDChipSelect)) {
// Lampeggio led Arduino
38 for (;;) {
39 digitalWrite(pinBoardLed, HIGH);
40 delay(500);
41 digitalWrite(pinBoardLed, LOW);
42 delay(500);
}
43 }
44 // Identifico prima directory libera
45 for (;;) {
46 char dirName[7] = DIR000;
47 dirName[3] = ((dirCount / 100) + 0x30);
dirName[4] = (((dirCount % 100) / 10) + 0x30);
48 dirName[5] = ((dirCount % 10) + 0x30);
49 // Se directory non esiste
50 if (SD.exists(dirName) == false)
51 break;
// Prossima directory
52 dirCount++;
53 }
54 // Spengo led Arduino
55 digitalWrite(pinBoardLed, LOW);
56 } // Chiusura funzione setup
// Programma Principale
57 void loop() {
58 boolean isEnd = false;
59 uint16_t address = 0x0000;
60 uint16_t chunkSize = CHUNK_SIZE;
byte body[CHUNK_SIZE];
61 // Imposto dimensione immagine
62 jpegCamera.setImageSize(jpegCamera.ImageSize320x280);
63 // Reset JPEG Camera
64 jpegCamera.reset();
65 // Scatto immagine
jpegCamera.takePicture();
66 // Identifico prima directory libera
67 char dirName[7] = DIR000;
68 dirName[3] = ((dirCount / 100) + 0x30);
69 dirName[4] = (((dirCount % 100) / 10) + 0x30);
dirName[5] = ((dirCount % 10) + 0x30);
70
// Se directory non esiste
71 if (SD.exists(dirName) == false)
72 // Creo directory
73 SD.mkdir(dirName);
74 // Identifico nome file
char pathComplete[22] = DIR000/image00.jpg;
75 pathComplete[3] = ((dirCount / 100) + 0x30);
76 pathComplete[4] = (((dirCount % 100) / 10) + 0x30);
77 pathComplete[5] = ((dirCount % 10) + 0x30);
78 pathComplete[12] = ((fileCount / 10) + 0x30);
pathComplete[13] = ((fileCount % 10) + 0x30);
79 // Apro file
80 jpegFile = SD.open(pathComplete, FILE_WRITE);
81 // Leggo/salvo i dati immagine
82 isEnd = false;
83 while(isEnd == false) {
jpegCamera.readJpegFileContent(address, chunkSize, body, &isEnd);
84 address += chunkSize;
85 // Salvo i dati sul file
86 jpegFile.write(body, chunkSize);
87 // Se sensore PIR non rilevato
if (flagSensorePIR == false) {
88 // Se sensore PIR attivo
89 if (digitalRead(pinPIRSensor) == HIGH) {
90 // Prossimo file il 6 (verr incrementato in seguito)
91 fileCount = 5;
92 flagSensorePIR = true;
}
93 }
94 }
95 // Chiudo file
96 jpegFile.close();
97 // Fermo immagine
jpegCamera.stopTakingPictures();
98 // Attesa
99 delay(100);
100 // Se sensore PIR non rilevato
101 if (flagSensorePIR == false) {
// Se sensore PIR attivo
102 if (digitalRead(pinPIRSensor) == HIGH) {
103 // Prossimo file il 6
104 fileCount = 6;
105 flagSensorePIR = true;
106 }
// Se sensore PIR non attivo
107 else {
108 // Prossimo file number
109 if (fileCount == 5)
110 fileCount = 1;
else
111 fileCount++;
112 }
113 }
114 // Se sensore PIR rilevato
115 else {
// Se salvati 5 file
116 if (fileCount == 10) {
117 // Resetto file
118 fileCount = 1;
119 // Prossima directory
dirCount++;
120
// Indico reset PIR
121 flagSensorePIR = false;
122 }
123 else
124 fileCount++;
}
125 } // Chiusura funzione loop
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153

From store

PIR motion sensor


SDcard shield for Arduino
JPEG Color Camera Serial Interface
Arduino UNO R3

You might also like