GPRS Camera Project

About:

 In short, this was a project I started working on out of necessity when vandals damaged a family member's summer cabin. The crux of the project is a webcam of decent resolution (in this case 640x480) which can be located in a region with no WiFi, no internet connection, and no electricity. There are existing products on the market which satisfy these requirements, but they tend to be specialized (ie most shops don't stock them) and expensive.

And so was born this project, in which a cheap LinkSprite camera is paired with an inexpensive solar powered Arduino controller and a GPRS interface.

Parts List:

PHASE 1 

The first step in this project is to confirm that the camera and the arduino board can interface properly, and pass the image file on to a processing program running on the PC through its serial port.

Arduino Code:

Note: In this code, the LinkSprite camera is connected to pins 4 (RX) and 5 (TX), and the libraries used are available here. It is a modification of the example code given at that website. I provide the rough code here not just because it is useful, but because during this phase of development I had literally dozens of engineers and techies claim that an Arduino was too weak to ever transmit photos to a computer.

#include "JPEGCamera.h"
#include "NewSoftSerial.h"

//Create an instance of the camera
JPEGCamera camera;

const int buttonPin = 7;   
const int ledPin = 13;   

//Count is used to store the number of characters in the response string.
unsigned int count=0;
//Size will be set to the size of the jpeg image.
int size=0;
//This will keep track of the data address being read from the camera
int address=0;
//eof is a flag for the sketch to determine when the end of a file is detected
//while reading the file data from the camera.
int eof=0;

void setup(){
  camera.begin();
  Serial.begin(19200);
  pinMode(ledPin,OUTPUT);
  
  //Reset the camera
  count=camera.reset(response);
  delay(3000);
  
   //Take a picture
   count=camera.takePicture(response);
    
   //Get the size of the picture
   count = camera.getSize(response, &size);

  while(address//Read the data starting at the current address.
        count=camera.readData(response, address);
        //Store all of the data that we read to the SD card
        for(int i=0; i//Check the response for the eof indicator (0xFF, 0xD9). If we find it, set the eof flag
            if((response[i] == (char)0xD9) && (response[i-1]==(char)0xFF))eof=1;
            //Save the data to the SD card
            Serial.print(response[i]);
            digitalWrite(ledPin,HIGH);
            //If we found the eof character, get out of this loop and stop reading data
            if(eof==1)break;
        }
        //Increment the current address by the number of bytes we read
        address+=count;
        digitalWrite(ledPin,LOW);
        //Make sure we stop reading data if the eof flag is set.
        if(eof==1)break;
  }
  return;
}

void loop(){
}

Processing Code:


import processing.serial.*;  
   
 Serial myPort;  
 OutputStream output;  
   
   
 void setup() {  
   
  size(320, 240);  
   
  //println( Serial.list() );  
  myPort = new Serial( this, Serial.list()[5], 19200);  
  myPort.clear();  
   
  output = createOutput("pic.jpg");  
 }  
   
   
 void draw() {  
   
  try {   
   while ( myPort.available () > 0 ) {  
    output.write(myPort.read());  
    print("*");
   }  
  }   
  catch (IOException e) {  
   e.printStackTrace();  
  }  
 }  
   
   
 void keyPressed() {  
   
  try {   
   output.flush(); // Writes the remaining data to the file  
   output.close(); // Finishes the file  
  }   
   
  catch (IOException e) {  
   e.printStackTrace();  
  }  
 }    

PHASE 2 

The second step in this project is to confirm that the Arduino board can send e-mail messages through the GPRS cell phone network. This requires an activated SIM card, a valid cell phone service (some providers require a data plan, others will work with a basic voice & text plan), and of course a GPRS shield for the Arduino. I am using the Seedstudio version, but others that use the AT protocals should work with this code as well.

Arduino code:

Note: In the following code, the APN, username, and password are specific to each service provider. However these can usually be found with a quick online search. Also, in my own testing it appears that the sender e-mail address needs to be a valid address but no password is required for it. The sender e-mail isn't really important for this project since the code sends an e-mail to the user directly, but is included as the e-mail protocols require it.  The recipient address is the destination for the final photos and data. It should also be noted that the delays are the values that worked for me, but may need to be adjusted to give the server sufficient time to respond to each command.

#include <SoftwareSerial.h>
#include <String.h>


SoftwareSerial mySerial(7, 8);
 
void setup()
{
  mySerial.begin(19200);               // the GPRS baud rate   
  Serial.begin(19200);    // the GPRS baud rate 
  delay(500);
}
 
void loop()
{
  if (Serial.available())
    switch(Serial.read())
   {
      case 'e':
       SendEmail();
       break;  
   } 
  if (mySerial.available())
    Serial.write(mySerial.read());
}
 
///Send EMail

void SendEmail()
{

  mySerial.println("AT+CIPSHUT");
  delay(100);
  mySerial.println("AT+CSTT=\"APN\",\"username\",\"password\"\r");
  delay(2200);
  ShowSerialData();
  mySerial.println("AT+CIPSHUT");
  delay(200);
  mySerial.println("AT+CIPSTART=\"TCP\",\"gprs.provider.com\",25");
  delay(2500);
   ShowSerialData();
  mySerial.println("AT+CIPSEND");
  delay(400);
  mySerial.println("HELO gprs.provider.com");
  delay(400);
     ShowSerialData();
  mySerial.println((char)26);//the ASCII code of the ctrl+z is 26
  delay(400);
  mySerial.println("AT+CIPSEND");
  delay(400);
  mySerial.println("MAIL From: address@server.com");
  delay(400);
  mySerial.println((char)26);//the ASCII code of the ctrl+z is 26
  delay(400);
     ShowSerialData();
  mySerial.println("AT+CIPSEND");
  delay(200);
  mySerial.println("RCPT To: address@server.com");
  delay(400);
  mySerial.println((char)26);//the ASCII code of the ctrl+z is 26
  delay(400);
       ShowSerialData();
  mySerial.println("AT+CIPSEND");
  delay(300);
  mySerial.println("DATA");
  delay(400);
  mySerial.println((char)26);//the ASCII code of the ctrl+z is 26
  delay(400);
  ShowSerialData();
  mySerial.println("AT+CIPSEND");
  delay(200);
  mySerial.println("From: \"SENDER\"<address@server.com>");
  delay(200);
    mySerial.println((char)26);//the ASCII code of the ctrl+z is 26
  delay(400);
  ShowSerialData();
    mySerial.println("AT+CIPSEND");
  delay(200);
  mySerial.println("To: \"RECIPIENT\"<address@server.com>");
  delay(100);
    mySerial.println((char)26);//the ASCII code of the ctrl+z is 26
  delay(400);
  ShowSerialData();
    mySerial.println("AT+CIPSEND");
  delay(200);
  mySerial.println("Subject: EMail Test");
  delay(200);
  mySerial.println((char)26);//the ASCII code of the ctrl+z is 26
  delay(400);
  ShowSerialData();
    mySerial.println("AT+CIPSEND");
  delay(200);
  mySerial.println("This is a test of the cell phone email system");
  delay(200);
  ShowSerialData();
  mySerial.println((char)26);//the ASCII code of the ctrl+z is 26
  delay(400);
      mySerial.println("AT+CIPSEND");
  delay(200);
  mySerial.println(".");
  delay(600);
  ShowSerialData();
  mySerial.println((char)26);//the ASCII code of the ctrl+z is 26
  delay(400);
  mySerial.println("AT+CIPSHUT");
  delay(100);
}
 


void ShowSerialData()
{
  while(mySerial.available()!=0)
    Serial.write(mySerial.read());
}


Make a free website with Yola