Project showcase
Email 3G/GPRS Camera

Email 3G/GPRS Camera © GPL3+

Photographing an object (VC0706 camera), saving a photo from a camera on a micro SD card, sending a photo using 3G/GPRS shield to an email.

  • 3,702 views
  • 1 comment
  • 9 respects

Components and supplies

Necessary tools and machines

09507 01
Soldering iron (generic)
Wires, etc.

Apps and online services

About this project

I would like to tell you how to connect the UART JPEG Camera VC0706 to Arduino Uno, take a photo, record it on a micro SD card and send this photo to an Email using 3G/GPRS shield. The basis of this article was another article which describes a similar procedure but with a different platform (Arduino M0). So we need:

  • Arduino UNO
  • MicroSD card
  • Chip resistor (1206) 2, 2kOhm and 3, 3kOhm
  • Wires, soldering iron etc.

Block Diagram

Camera (hardware) setup

At the first stage, it is necessary to connect the UART JPEG camera VC0706 and micro SD card to Arduino Uno in order to check the operability of the camera and the recording on the micro SD card.

Micro SD card adapter is connected as shown in the Figure 2.

Pay special attention to your camera. There are at least two options.The first version of the camera (www.adafruit.com/product/397), which can be connected to the Arduino UNO without modification.

Another camera variant is with the RS-232 driver MAX3232.

It is necessary to unsolder the MAX3232 chip (RS-232 driver) and solder the jumper between the contact pads of the corresponding 7 and 10 pins of the chip — the pins are responsible for the TX output of the camera. You can solder the same jumper between pads 8 and 9 - the camera will work (Figure 8).

Still, it would be more correct to reduce the amplitude of the RX signal (camera input) to a value of no more than 3.3 V using two resistors (voltage divider), as shown in the Figure 10.

So, we need to connect the camera as shown in Figure 2. The result should be something like this (Figure 14). Micro SD card must be formatted in FAT32. Do not forget to connect the USB cable.

The time has come to check the functioning of the camera and recording on micro SD. Before the first inclusion it is necessary to install additional libraries.

Software setup

Programming is done through the Arduino IDE. Additional libraries (for the whole project):

First start

Run Arduino IDE, create a sketch CameraTest.ino:

#include "SoftwareSerial.h"
#include <VC0706_UART.h>
#include <SD.h>
#include <SPI.h>
#define SS_SD  4
//use software serial
SoftwareSerial cameraconnection(2,3);//Rx, Tx
VC0706 cam = VC0706(&cameraconnection);
//use hardware serial
//VC0706 cam = VC0706(&Serial);
void setup() 
{
   Serial.begin(115200);
   Serial.println("VC0706 Camera Snapshot Test ...");
   if (!SD.begin(SS_SD)) {
       Serial.println("SD Card init failed...");
       return;
   }  
   if(true == cameraInit()){
       snapShot();
   }else{
       Serial.println("camera init error...");
   }
}
void loop() 
{
   //nothing to do
}
bool cameraInit()
{
   cam.begin(BaudRate_38400);
   char *reply = cam.getVersion();
   if (reply == 0) {
       Serial.println("Failed to get version");
       return false;
   } else {
       Serial.println("version:");
       Serial.println("-----------------");
       Serial.println(reply);
       Serial.println("-----------------");
       return true;
   }
}
void snapShot()
{
   Serial.println("Snap in 3 secs...");
   delay(3000);
   if (! cam.takePicture()){ 
       Serial.println("Failed to snap!");
   }else { 
       Serial.println("Picture taken!");
   }
   // Create an image with the name IMAGExx.JPG
   char filename[13];
   strcpy(filename, "IMAGE00.JPG");
   for (int i = 0; i < 100; i++) {
       filename[5] = '0' + i/10;
       filename[6] = '0' + i%10;
       // create if does not exist, do not open existing, write, sync after write
       if (! SD.exists(filename)) {
           break;
       }
   }
   // Open the file for writing
   File imgFile = SD.open(filename, FILE_WRITE);
   Serial.print("create ");
   Serial.println(filename);
   uint16_t jpglen = cam.getFrameLength();
   Serial.print("wait to fetch ");
   Serial.print(jpglen, DEC);
   Serial.println(" byte image ...");
   int32_t time = millis();
   cam.getPicture(jpglen);
   uint8_t *buffer;
   while(jpglen != 0){
        uint8_t bytesToRead = min(32, jpglen);
        buffer = cam.readPicture(bytesToRead);     
        imgFile.write(buffer, bytesToRead);
        //Serial.print("Read ");  Serial.print(bytesToRead, DEC); Serial.println(" bytes");
        jpglen -= bytesToRead;   
   } 
   imgFile.close();
   time = millis() - time;
   Serial.println("Done!");
   Serial.print("Took "); Serial.print(time); Serial.println(" ms");
   cam.resumeVideo();    
}

Check that the "Arduino/Genuino UNO" board is selected.

Click the "Upload" button, open the Serial Monitor window. Within a minute, the following message should appear (Figure 15):

Remove the micro SD card and read its contents. If the IMAGE00.JPG file is recorded on the micro SD card (and it is readable), it means that the camera and the micro SD are connected correctly.

3G/GPRS shield (hardware) setup

Next, you need to connect the 3G/GPRS shield to the Arduino UNO as shown in Figure 17. But first you need to connect all the wires connected to the Arduino UNO to the same places on the 3G/GPRS shield.

On the SIM card, you must disable the pincode request. Install the SIM card into the "SIM" connector on the bottom side of the 3G/GPRS shield board.

Set the jumpers on the board to the position "RX-1", "TX-0". And then connect together 3G/GPRS shield and Arduino UNO. Connect the USB cable.

In the 3G/GPRS shield, a default baud rate on the serial port can be set, which may not correspond to the required one. Therefore, it is necessary to pre-set the specified exchange rate. For this you need:

  • apply power to the Arduino Uno board with the help of the USB cable, check the LED "P" on the 3G/GPRS shield board (Figure 18),
  • turn on the 3G/GPRS shield by pressing and holding the "Power" button on the 3G/GPRS shield board for 1 second (Figure 18), wait until the LEDs "S" and "N" are illuminated (Figure 19),
  • connect using a micro USB cable to a 3G/GPRS shield (Figure 19),
  • wait for the automatic installation of drivers, determine the number of the serial port in the System window (Figure 20),
  • connect using a terminal (for example PuTTY) to the port (Figure 21),
  • check the connection with the "ATI" command, set the exchange rate of the commands "AT+IRP=115200" and "AT+IRP=115200" (Figure 22).

Now you can disconnect the micro USB cable from the 3G shield and close the terminal window.

Programming

It is necessary to create a new sketch in which to register your data (instead of the characters "*****"):

#include <VC0706_UART.h>
#include <SPI.h>
#include <SD.h>
#include <XModem.h>
// comment out this line if using Arduino V23 or earlier
#include <SoftwareSerial.h>         
#define chipSelect 4
SoftwareSerial cameraconnection = SoftwareSerial(2, 3);
XModem xmodem(&Serial, ModeXModem);
VC0706 cam = VC0706(&cameraconnection);
const char smtp_server[ ]    = "*****";   // SMTP server
const char smtp_user_name[ ] = "*****";   // SMTP user name
const char smtp_password[ ]  = "*****";   // SMTP password
const char smtp_port[ ]      = "*****";   // SMTP server port
//Write here you SIM card data
const char apn[]             = "*****";
const char user_name[]       = "*****";
const char password[]        = "*****";
//Write here your information about sender, direcctions and names
const char sender_address[ ] = "*****";   // Sender address
const char sender_name[ ]    = "*****";   // Sender name
const char to_address[ ]     = "*****";   // Recipient address
const char to_name[ ]        = "*****";   // Recipient name
char subject[ ] = "My First Email";
const char body[ ] = "Picture:";
#define chipSelect  4 // enable uSD card
int8_t answer;
int    onModulePin = 8;
char   aux_str[64];
char   filename[14];
void  setup(void)
{
   pinMode(onModulePin, OUTPUT);
   Serial.begin(115200);
   delay(5000);
   power_on();
   while ((sendATcommand("AT+CREG?", "+CREG: 0,1", 500) || 
       sendATcommand("AT+CREG?", "+CREG: 0,5", 500)) == 0 );
   // see if the card is present and can be initialized:
   if (!SD.begin(chipSelect)) {
       // don't do anything more:
       return;
   }  
   if (true == cameraInit()) {
       snapShot();
       sendEmail();
   } else {
   }
}
void  loop(void)
{
}
bool  cameraInit(void)
{
   cam.begin(BaudRate_38400);
   char *reply = cam.getVersion();
   if (reply == 0) {
       return false;
   } else {
       return true;
   }
}
void  snapShot(void)
{
   if (!cam.takePicture()) { 
   } else { 
   }
   // Create an image with the name IMAGExx.JPG
   strcpy(filename, "IMAGE000.JPG");
   for (int i = 0; i < 1000; i++) {
       filename[5] = '0' + i/100;
       filename[6] = '0' + (i/10)%10;
       filename[7] = '0' + i%10;
       // create if does not exist, do not open existing, write, sync after write
       if (! SD.exists(filename)) {
           break;
       }
   }
   // Open the file for writing
   File imgFile = SD.open(filename, FILE_WRITE);
   uint16_t jpglen = cam.getFrameLength();
   int32_t time = millis();
   cam.getPicture(jpglen);
   uint8_t *buffer;
   while(jpglen != 0) {
        uint8_t bytesToRead = min(32, jpglen);
        buffer = cam.readPicture(bytesToRead);     
        imgFile.write(buffer, bytesToRead);
        //Serial.print("Read ");  Serial.print(bytesToRead, DEC); Serial.println(" bytes");
        jpglen -= bytesToRead;   
   } 
   imgFile.close();
   time = millis() - time;
   cam.resumeVideo();    
}
void  sendEmail(void)
{
   sprintf(aux_str, "AT+CRXFILE=\"%s\"", filename);
   if (!sendATcommand(aux_str, "OK", 2000)) {
   }
   File dataFile = SD.open(filename);
   // if the file is available, write to it:
   if (dataFile) {
       xmodem.sendFile(dataFile, filename);
   }
   // if the file isn't open, pop up an error:
   else {
       return;
   } 
   dataFile.close();
   // sets the SMTP server and port
   sprintf(aux_str, "AT+SMTPSRV=\"%s\",%s", smtp_server, smtp_port);
   if (!sendATcommand(aux_str, "OK", 2000)) {
   }
   // sets user name and password
   sprintf(aux_str, "AT+SMTPAUTH=1,\"%s\",\"%s\"", smtp_user_name, smtp_password);
   if (!sendATcommand(aux_str, "OK", 2000)) {
   }
   // sets sender adress and name
   sprintf(aux_str, "AT+SMTPFROM=\"%s\",\"%s\"", sender_address, sender_name);
   if (!sendATcommand(aux_str, "OK", 2000)) {
   }
   // sets sender adress and name
   sprintf(aux_str, "AT+SMTPRCPT=1,0,\"%s\",\"%s\"", to_address, to_name);
   if (!sendATcommand(aux_str, "OK", 2000)) {
   }
   // subjet of the email
   sprintf(aux_str, "AT+SMTPSUB=\"%s\"", filename);
   if (!sendATcommand(aux_str, "OK", 2000)) {
   }
   // body of the email
   sprintf(aux_str, "AT+SMTPBODY=\"%s %s\" ", body, filename);
   if (!sendATcommand(aux_str, "OK", 2000)) {
   }
   sprintf(aux_str, "AT+SMTPFILE=1,\"%s\"", filename);
   if (!sendATcommand(aux_str, "OK", 2000)) {
   }
   // sets APN, user name and password
   sprintf(aux_str, "AT+CGSOCKCONT=1,\"IP\",\"%s\"", apn);
   if (!sendATcommand(aux_str, "OK", 2000)) {
   }
   sprintf(aux_str, "AT+CSOCKAUTH=1,1,\"%s\",\"%s\"", user_name, password);
   if (!sendATcommand(aux_str, "OK", 2000)) {
   }
   delay(2000);
   // sends the email and waits the answer of the module
   answer = sendATcommand("AT+SMTPSEND", "+SMTP: SUCCESS", 60000);
   if (answer == 1) {
   } else {
   }
}
void  power_on(void)
{
   uint8_t answer=0;
   // checks if the module is started
   answer = sendATcommand("AT", "OK", 2000);
   if (answer == 0) {
       // power on pulse
       digitalWrite(onModulePin,HIGH);
       delay(3000);
       digitalWrite(onModulePin,LOW);
       // waits for an answer from the module
       while(answer == 0) {     // Send AT every two seconds and wait for the answer
           answer = sendATcommand("AT", "OK", 10000);    
       }
   }
}
int8_t  sendATcommand(char* ATcommand, char* expected_answer1, unsigned int timeout)
{
   uint8_t x=0,  answer=0;
   char response[100];
   unsigned long previous;
   memset(response, '\0', 100);    // Initialize the string
   delay(100);
   while( Serial.available() > 0) Serial.read();  // Clean the input buffer
   Serial.println(ATcommand);    // Send the AT command
   x = 0;
   previous = millis();
   // this loop waits for the answer
   do {
       // if there are data in the UART input buffer, reads it and checks for the answer
       if (Serial.available() != 0) {
           response[x] = Serial.read();
           x++;
           // check if the desired answer is in the response of the module
           if (strstr(response, expected_answer1) != NULL) {
               answer = 1;
           }
       }
       // Waits for the answer with time out
   }
   while((answer == 0) && ((millis() - previous) < timeout));
   return answer;
}

Please note that the serial port "Serial" is used to communicate with the 3G/GPRS shield, and not to display debug information. Therefore it is impossible to display debug information.

I registered on the mail server, installed an email application on my phone, created a new mailbox (to which I will send letters with photos), added notifications to the phone when new emails arrived.

Then I shot a video directly from the screen of my phone about how I write a message on a blank sheet, direct the lens of the Serial JPEG camera to this sheet, connect the 3G/GPRS shield to Arduino UNO, turn on the power, and after a few tens of seconds, a notification appears on the phone letter, open the mailbox and see a photo sheet with my message.

Thank you for watching.

Code

EmailCamera.inoArduino
Make photo (VC0706). Write photo to microSD card. Send photo to Email.
#include <VC0706_UART.h>
#include <SPI.h>
#include <SD.h>
#include <XModem.h>
// comment out this line if using Arduino V23 or earlier
#include <SoftwareSerial.h>         
#define chipSelect 4
SoftwareSerial cameraconnection = SoftwareSerial(2, 3);
XModem xmodem(&Serial, ModeXModem);
VC0706 cam = VC0706(&cameraconnection);
const char smtp_server[ ]    = "*****";   // SMTP server
const char smtp_user_name[ ] = "*****";   // SMTP user name
const char smtp_password[ ]  = "*****";   // SMTP password
const char smtp_port[ ]      = "*****";   // SMTP server port
//Write here you SIM card data
const char apn[]             = "*****";
const char user_name[]       = "*****";
const char password[]        = "*****";
//Write here your information about sender, direcctions and names
const char sender_address[ ] = "*****";   // Sender address
const char sender_name[ ]    = "*****";   // Sender name
const char to_address[ ]     = "*****";   // Recipient address
const char to_name[ ]        = "*****";   // Recipient name
char subject[ ] = "My First Email";
const char body[ ] = "Picture:";
#define chipSelect  4 // enable uSD card
int8_t answer;
int    onModulePin = 8;
char   aux_str[64];
char   filename[14];
void  setup(void)
{
   pinMode(onModulePin, OUTPUT);
   Serial.begin(115200);
   delay(5000);
   power_on();
   while ((sendATcommand("AT+CREG?", "+CREG: 0,1", 500) || 
       sendATcommand("AT+CREG?", "+CREG: 0,5", 500)) == 0 );
   // see if the card is present and can be initialized:
   if (!SD.begin(chipSelect)) {
       // don't do anything more:
       return;
   }  
   if (true == cameraInit()) {
       snapShot();
       sendEmail();
   } else {
   }
}
void  loop(void)
{
}
bool  cameraInit(void)
{
   cam.begin(BaudRate_38400);
   char *reply = cam.getVersion();
   if (reply == 0) {
       return false;
   } else {
       return true;
   }
}
void  snapShot(void)
{
   if (!cam.takePicture()) { 
   } else { 
   }
   // Create an image with the name IMAGExx.JPG
   strcpy(filename, "IMAGE000.JPG");
   for (int i = 0; i < 1000; i++) {
       filename[5] = '0' + i/100;
       filename[6] = '0' + (i/10)%10;
       filename[7] = '0' + i%10;
       // create if does not exist, do not open existing, write, sync after write
       if (! SD.exists(filename)) {
           break;
       }
   }
   // Open the file for writing
   File imgFile = SD.open(filename, FILE_WRITE);
   uint16_t jpglen = cam.getFrameLength();
   int32_t time = millis();
   cam.getPicture(jpglen);
   uint8_t *buffer;
   while(jpglen != 0) {
        uint8_t bytesToRead = min(32, jpglen);
        buffer = cam.readPicture(bytesToRead);     
        imgFile.write(buffer, bytesToRead);
        //Serial.print("Read ");  Serial.print(bytesToRead, DEC); Serial.println(" bytes");
        jpglen -= bytesToRead;   
   } 
   imgFile.close();
   time = millis() - time;
   cam.resumeVideo();    
}
void  sendEmail(void)
{
   sprintf(aux_str, "AT+CRXFILE=\"%s\"", filename);
   if (!sendATcommand(aux_str, "OK", 2000)) {
   }
   File dataFile = SD.open(filename);
   // if the file is available, write to it:
   if (dataFile) {
       xmodem.sendFile(dataFile, filename);
   }
   // if the file isn't open, pop up an error:
   else {
       return;
   } 
   dataFile.close();
   // sets the SMTP server and port
   sprintf(aux_str, "AT+SMTPSRV=\"%s\",%s", smtp_server, smtp_port);
   if (!sendATcommand(aux_str, "OK", 2000)) {
   }
   // sets user name and password
   sprintf(aux_str, "AT+SMTPAUTH=1,\"%s\",\"%s\"", smtp_user_name, smtp_password);
   if (!sendATcommand(aux_str, "OK", 2000)) {
   }
   // sets sender adress and name
   sprintf(aux_str, "AT+SMTPFROM=\"%s\",\"%s\"", sender_address, sender_name);
   if (!sendATcommand(aux_str, "OK", 2000)) {
   }
   // sets sender adress and name
   sprintf(aux_str, "AT+SMTPRCPT=1,0,\"%s\",\"%s\"", to_address, to_name);
   if (!sendATcommand(aux_str, "OK", 2000)) {
   }
   // subjet of the email
   sprintf(aux_str, "AT+SMTPSUB=\"%s\"", filename);
   if (!sendATcommand(aux_str, "OK", 2000)) {
   }
   // body of the email
   sprintf(aux_str, "AT+SMTPBODY=\"%s %s\" ", body, filename);
   if (!sendATcommand(aux_str, "OK", 2000)) {
   }
   sprintf(aux_str, "AT+SMTPFILE=1,\"%s\"", filename);
   if (!sendATcommand(aux_str, "OK", 2000)) {
   }
   // sets APN, user name and password
   sprintf(aux_str, "AT+CGSOCKCONT=1,\"IP\",\"%s\"", apn);
   if (!sendATcommand(aux_str, "OK", 2000)) {
   }
   sprintf(aux_str, "AT+CSOCKAUTH=1,1,\"%s\",\"%s\"", user_name, password);
   if (!sendATcommand(aux_str, "OK", 2000)) {
   }
   delay(2000);
   // sends the email and waits the answer of the module
   answer = sendATcommand("AT+SMTPSEND", "+SMTP: SUCCESS", 60000);
   if (answer == 1) {
   } else {
   }
}
void  power_on(void)
{
   uint8_t answer=0;
   // checks if the module is started
   answer = sendATcommand("AT", "OK", 2000);
   if (answer == 0) {
       // power on pulse
       digitalWrite(onModulePin,HIGH);
       delay(3000);
       digitalWrite(onModulePin,LOW);
       // waits for an answer from the module
       while(answer == 0) {     // Send AT every two seconds and wait for the answer
           answer = sendATcommand("AT", "OK", 10000);    
       }
   }
}
int8_t  sendATcommand(char* ATcommand, char* expected_answer1, unsigned int timeout)
{
   uint8_t x=0,  answer=0;
   char response[100];
   unsigned long previous;
   memset(response, '\0', 100);    // Initialize the string
   delay(100);
   while( Serial.available() > 0) Serial.read();  // Clean the input buffer
   Serial.println(ATcommand);    // Send the AT command
   x = 0;
   previous = millis();
   // this loop waits for the answer
   do {
       // if there are data in the UART input buffer, reads it and checks for the answer
       if (Serial.available() != 0) {
           response[x] = Serial.read();
           x++;
           // check if the desired answer is in the response of the module
           if (strstr(response, expected_answer1) != NULL) {
               answer = 1;
           }
       }
       // Waits for the answer with time out
   }
   while((answer == 0) && ((millis() - previous) < timeout));
   return answer;
}

Schematics

VC0706 scheme
VC0706 scheme

Comments

Similar projects you might like

RGB Camera Backlight Control With Android Mobile

Project tutorial by DIY Partners

  • 2,038 views
  • 1 comment
  • 8 respects

Camera Slider Control [Arduino Nano]

Project tutorial by Jeremy S. Cook

  • 3,003 views
  • 1 comment
  • 11 respects

Android App-Based Home Automation System Using IOT

Project tutorial by Team Autoshack

  • 25,584 views
  • 17 comments
  • 81 respects

Security System Using Arduino Bluetooth Camera

Project tutorial by amrmostaafaa

  • 7,089 views
  • 4 comments
  • 26 respects

Automated Snake Enclosure with Camera

Project showcase by hagakure

  • 6,408 views
  • 9 comments
  • 17 respects

Drone Powered 360º Circular Smartphone Camera Rig

Project showcase by kfernandesign

  • 6,259 views
  • 0 comments
  • 21 respects
Add projectSign up / Login