/* Arduino JPEGCamera Library
* Copyright 2010 SparkFun Electronic
* Written by Ryan Owens
*/
#include <avr/pgmspace.h>
#include "JPEGCamera.h"
#include "Arduino.h"
#include "SoftwareSerial.h"
//Commands for the LinkSprite Serial JPEG Camera
const char GET_SIZE[5] = {0x56, 0x00, 0x34, 0x01, 0x00};
const char RESET_CAMERA[4] = {0x56, 0x00, 0x26, 0x00};
const char TAKE_PICTURE[5] = {0x56, 0x00, 0x36, 0x01, 0x00};
const char STOP_TAKING_PICS[5] = {0x56, 0x00, 0x36, 0x01, 0x03};
char RESIZE[9] = {0x56, 0x00, 0x31, 0x05, 0x04, 0x01, 0x00, 0x19, 0x22};
char SETBAUD[7] = {0x56, 0x00, 0x24, 0x03, 0x01, 0x2A, 0xF2};
char READ_DATA[8] = {0x56, 0x00, 0x32, 0x0C, 0x00, 0x0A, 0x00, 0x00};
char STORE[5];
//We read data from the camera in chunks, this is the chunk size
const int read_size=32;
//Make sure the camera is plugged into pins 2 and 3 for Rx/Tx
SoftwareSerial cameraPort(2,3);
JPEGCamera::JPEGCamera()
{
}
//Initialize the serial connection
void JPEGCamera::begin(void)
{
//Camera baud rate is 38400
cameraPort.begin(38400);
Serial.begin(9600);
}
void JPEGCamera::wait()
{
while(cameraPort.available() < 42);
}
int JPEGCamera::resize(char * response, int size)
{
//160x120
if(size == 1) {RESIZE[8] = 0x22;}
//320x240
if(size == 2) {RESIZE[8] = 0x11;}
//640x480
if(size == 3) {RESIZE[8] = 0x00;}
return sendCommand(RESIZE, response, 9);
}
int JPEGCamera::setBaud(char * response, int baud)
{
//38400 BAUD
if(baud == 1) {SETBAUD[5] = 0x2A;
SETBAUD[6] = 0xF2;
}
//57600 BAUD
if(baud == 2) {SETBAUD[5] = 0x1C;
SETBAUD[6] = 0x4C;
}
//115200 BAUD
if(baud == 3) {SETBAUD[5] = 0x0D;
SETBAUD[6] = 0xA6;
}
return sendCommand(SETBAUD, response, 7);
}
//Get the size of the image currently stored in the camera
//pre: response is an empty string. size is a pointer to an integer
//post: response string contains the entire camera response to the GET_SIZE command
// size is set to the size of the image
//return: number of characters in the response string
//usage: length = camera.getSize(response, &img_size);
int JPEGCamera::getSize(char * response, int * size)
{
int count=0;
//Send the GET_SIZE command string to the camera
count = sendCommand(GET_SIZE, response, 5);
//Read 4 characters from the camera and add them to the response string
for(int i=0; i<4; i++)
{
while(!cameraPort.available());
response[count+i]=cameraPort.read();
}
//Set the number of characters to return
count+=4;
//The size is in the last 2 characters of the response.
//Parse them and convert the characters to an integer
*size = response[count-2]*256;
*size += (int)response[count-1] & 0x00FF;
//Send the number of characters in the response back to the calling function
return count;
}
//Reset the camera
//pre: response is an empty string
//post: response contains the cameras response to the reset command
//returns: number of characters in the response
//Usage: camera.reset(response);
int JPEGCamera::reset(char * response)
{
return sendCommand(RESET_CAMERA, response, 4);
}
//Take a new picture
//pre: response is an empty string
//post: response contains the cameras response to the TAKE_PICTURE command
//returns: number of characters in the response
//Usage: camera.takePicture(response);
int JPEGCamera::takePicture(char * response)
{
return sendCommand(TAKE_PICTURE, response, 5);
}
//Stop taking pictures
//pre: response is an empty string
//post: response contains the cameras response to the STOP_TAKING_PICS command
//returns: number of characters in the response
//Usage: camera.stopPictures(response);
int JPEGCamera::stopPictures(char * response)
{
return sendCommand(STOP_TAKING_PICS, response, 5);
}
//Get the read_size bytes picture data from the camera
//pre: response is an empty string, address is the address of data to grab
//post: response contains the cameras response to the readData command, but the response header is parsed out.
//returns: number of characters in the response
//Usage: camera.readData(response, cur_address);
//NOTE: This function must be called repeatedly until all of the data is read
//See Sample program on how to get the entire image.
int JPEGCamera::readData(char * response, int address)
{
int count=0;
//Flush out any data currently in the serial buffer
cameraPort.flush();
//Send the command to get read_size bytes of data from the current address
for(int i=0; i<8; i++) cameraPort.print(READ_DATA[i]);
cameraPort.print(address>>8);
cameraPort.print(address);
cameraPort.print(0x00);
cameraPort.print(0x00);
cameraPort.print(read_size>>8);
cameraPort.print(read_size);
cameraPort.print(0x00);
cameraPort.print(0x0A);
//Print the data to the serial port. Used for debugging.
/*
for(int i=0; i<8; i++)Serial.print(READ_DATA[i]);
Serial.print(address>>8, BYTE);
Serial.print(address, BYTE);
Serial.print(0x00, BYTE);
Serial.print(0x00, BYTE);
Serial.print(read_size>>8, BYTE);
Serial.print(read_size, BYTE);
Serial.print(0x00, BYTE);
Serial.print(0x0A, BYTE);
Serial.println();
*/
//Read the response header.
for(int i=0; i<5; i++){
while(!cameraPort.available());
Serial.print(cameraPort.read(), HEX);
Serial.print(" ");
}
Serial.print(": ");
//Now read the actual data and add it to the response string.
count=0;
while(count < read_size)
{
while(!cameraPort.available());
*response++=cameraPort.read();
count+=1;
}
//Return the number of characters in the response.
return count;
}
//Send a command to the camera
//pre: cameraPort is a serial connection to the camera set to 3800 baud
// command is a string with the command to be sent to the camera
// response is an empty string
// length is the number of characters in the command
//post: response contains the camera response to the command
//return: the number of characters in the response string
//usage: None (private function)
int JPEGCamera::sendCommand(const char * command, char * response, int length)
{
char c=0;
int count=0;
//Clear any data currently in the serial buffer
cameraPort.flush();
//Send each character in the command string to the camera through the camera serial port
for(int i=0; i<length; i++){
cameraPort.print(*command++);
}
//Get the response from the camera and add it to the response string.
for(int i=0; i<length; i++)
{
while(!cameraPort.available());
*response++=cameraPort.read();
count+=1;
}
//return the number of characters in the response string
return count;
}