COMedia C328-7640 Serial Camera Arduino "self portrait"
UPDATE: You can still find the Arduino Library here: arms22.googlecode.com/files/CameraC328R.zip
// C328R_with_I2C_flash_LCD
// by s_p_e_x, some rights reserved
//
// Based on work by Sean Voisen
// (gizmologi.st/2009/04/taking-pictures-with-arduino/)
// and Ryan Detzel
// (10kohms.com/arduino-external-eeprom-24lc256)
//
// I converted Seans code to use I2C EEPROM instead of SPI
// Flash. Also I wrote A base64 encoder in an attempt to dodge
// problems with escape codes messing up terminal programs. I'm
// still having issues. But it does work and opens the door to
// a direct interface via Ethernet and a web browser.
// Oh, and I added LCD support to have some clue about what is
// going on. Without having access to the serial interface I
// was really puzzled by why it wasn't working.
// After struggling with getting a proper 3.3V source
// (I finally switched to a "real" Arduino with a built in
// 3.3 regulator) and with iffy contacts on the camera cable
// I was totally thrown by the long delay to write the image to
// the I2C flash. Having an LCD took much of the guess work out.
//
// My I2C EEPROM is a 24LC256, and I use the highest two bytes
// to hold the picture size so when you reset it knows how much
// to read back.
// Unforunately the I2C EEPROM is SLOW, so if you can't monitor
// the progress via an LCD, be very patient waiting for the
// lights to blink and tell you setup() is over. ~5 minutes
// Here's a Function Map which helped me figure out the example:
//setup(){
// if A0 is HIGH
// camera.sync()
// camera.initial()
// camera.setPackageSize()
// camera.setLightFrequency()
// camera.snapshot()
// camera.getJPEGPicture()
// fillPageBuffer()
// writeBuffer() -- for loop
// writeEEPROM() -- write bytes to EEPROM
// getJPEGPicture_callback()
// camera.poweroff()
// if A0 is LOW
// transferPicture() -- print bytes from EEPROM
// bintoascii() -- base64 encoder not perfect but works
// readEEPROM() -- for loop read bytes from EEPROM
//}
//loop(){
// blink LED
//}
// wire A0 HIGH or LOW to take a picture or to extract a picture
// HIGH will guide the camera through init and a photograph and
// transferring to flash before exiting setup().
// LOW will read back the flash and send the data base64 encoded to
// the console. I added a header and footer to take advantage of the
// URI data scheme:
// secure.wikimedia.org/wikipedia/en/wiki/Data_URI_scheme
// On my Mac I extracted the picture with screen:
// screen /dev/tty.usbmodemfd551 38400
// This was on a Mac with an Arduino Uno. The device name may vary.
// Very quickly turn on the logging ^aH (control-A and then shift-H).
// Once the image is done dumping, exit screen completely: ^a^\
// rename the logfile to a .html file:
// mv ~/screenlog.0 image.html
// You should now be able to view your image directly with FireFox.
#include "CameraC328R.h"
#include
#include
#define LED_PIN 13
#define PAGE_SIZE 64
#define BAUD 38400
#define eeprom1 0x50 //Address of 24LC256 eeprom chip
// Buffer for EEPROM data
byte pageBuffer[PAGE_SIZE];
CameraC328R camera;
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
static uint16_t pictureSizeCount = 0;
static uint16_t pageBufferIndex = 0;
static uint16_t currentAddress = 0;
bool dirtyBuffer = false;
int capture_mode_switch = A0; //HIGH => take picture; LOW => extract picture
int CaptureMode;
byte readEEPROM(int deviceaddress, unsigned int eeaddress ) {
byte rdata = 0xFF;
Wire.beginTransmission(deviceaddress);
Wire.send((int)(eeaddress >> 8)); // MSB
Wire.send((int)(eeaddress & 0xFF)); // LSB
Wire.endTransmission();
Wire.requestFrom(deviceaddress,1);
if (Wire.available()) rdata = Wire.receive();
return rdata;
}
void writeEEPROM(int deviceaddress, unsigned int eeaddress, byte data ) {
Wire.beginTransmission(deviceaddress);
Wire.send((int)(eeaddress >> 8)); // MSB
Wire.send((int)(eeaddress & 0xFF)); // LSB
Wire.send(data);
Wire.endTransmission();
//yes you need this delay, and yes it makes flashing take 5 minutes or so
delay(5);
}
/**
* Writes the data in the buffer to the EEPROM at the page
* starting at the given address.
*/
void writeBuffer( int deviceaddress, uint16_t address, uint16_t bufferSize )
{
// Send the data
for( uint16_t i = 0; i < bufferSize; i++ )
{
writeEEPROM(deviceaddress, address+i, pageBuffer[i]);
}
//digitalWrite( SS_PIN, HIGH );
}
/**
* Fills the page buffer for the EEPROM with data.
*/
void fillPageBuffer( byte* data, uint16_t dataSize )
{
for( uint16_t i = 0; i < dataSize; i++ )
{
pageBuffer[pageBufferIndex] = data[i];
dirtyBuffer = true;
pageBufferIndex++;
if( pageBufferIndex == PAGE_SIZE && dirtyBuffer )
{
pageBufferIndex = 0;
writeBuffer(eeprom1, currentAddress, PAGE_SIZE );
currentAddress += PAGE_SIZE;
dirtyBuffer = false;
delay( 50 );
}
}
}
void bintoascii(char * outstring, byte byte0, byte byte1, byte byte2, uint16_t count)
{
//outstring points to 4char string
// byteX are the three possible input bytes
// count marks the number of input bytes, this should
// always be 0 unless it is the last one or two input bytes
byte temp1, temp2, temp0;
char base64chars[]= "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
if (count == 0){
temp0 = byte0;
temp1 = byte1;
temp2 = byte2;
}
if (count == 1){
temp0 = byte2;
temp1 = 0;
temp2 = 0;
}
if (count == 2){
temp0 = byte1;
temp1 = byte2;
temp2 = 0;
}
outstring[0]=base64chars[temp0 >> 2];
//Serial.println(base64chars[temp0 >> 2], BYTE);
outstring[1]=base64chars[((temp0 & 0x03) 4)];
outstring[2]=base64chars[((temp1 & 0x0f) 6)];
outstring[3]=base64chars[(temp2 & 0x3f)];
// add padding
if (count == 1){
outstring[2]='=';
outstring[3]='=';
}
if (count == 2){
outstring[3]='=';
}
}
/**
* Sends a picture to the computer.
*/
void transferPicture( uint16_t startAddress, uint16_t size )
{
char base64text[]="****";
byte old, older, oldest;
uint16_t endAddress = startAddress + size;
uint16_t i;
Serial.println("<img src=\"data:image/jpeg;base64,");
for( i = startAddress; i < endAddress; i++ )
{
oldest = older;
older = old;
old = readEEPROM( eeprom1, i );
// Serial.print(i, DEC); Serial.print(": "); Serial.println(old, DEC);
if ((i+1) % 3 == 0) { // every 3 bytes you print 4 characters
// Serial.print(oldest, DEC); Serial.print(" "); Serial.print(older, DEC); Serial.print(" "); Serial.print(old, DEC); Serial.print(" ");
bintoascii(base64text, oldest, older, old, 0);
Serial.print(base64text);
}
if((i+1) % 57 == 0) { // every 72 characters, you start a new line
Serial.println("");
}
}
//Serial.print( readEEPROM( eeprom1, i ), BYTE );
if ((size % 3) != 0) { //if the image is not a multple of 3 bytes, encode the stragglers
//Serial.print(oldest, DEC); Serial.print(" "); Serial.print(older, DEC); Serial.print(" "); Serial.print(old, DEC); Serial.print(" ");
bintoascii(base64text, oldest, older, old, i%3);
Serial.print(base64text);
}
Serial.println("\" />");
}
/**
* This callback is called EVERY time a JPEG data packet is received.
*/
void getJPEGPicture_callback( uint16_t pictureSize, uint16_t packageSize, uint16_t packageCount, byte* package )
{
// packageSize is the size of the picture part of the package
pictureSizeCount += packageSize;
// print progress
lcd.setCursor(0, 1);
// 0123456789012345
lcd.print(" ");
lcd.setCursor(0, 0);
// 0123456789012345
lcd.print("Camera -> EEPROM");
lcd.setCursor(0, 1);
lcd.print(pictureSizeCount, DEC);
lcd.print("/");
lcd.print(pictureSize, DEC);
// package contains everything in the package
fillPageBuffer( package, packageSize );
if( pictureSizeCount == pictureSize )
{
// Is there still stuff in the buffer?
if( dirtyBuffer )
{
writeBuffer(eeprom1, currentAddress, pageBufferIndex );
}
writeEEPROM(eeprom1, 65534, pictureSize & 0xff);
writeEEPROM(eeprom1, 65535, pictureSize >> 8 & 0xff);
camera.powerOff();
lcd.setCursor(0, 0);
// 0123456789012345
lcd.print("Camera OFF. ");
digitalWrite( LED_PIN, HIGH ); // DONE!
// Serial.flush();
// delay( 5000 ); // Give us 5 seconds to hit a key ...
//
// lcd.setCursor(0, 1);
// // 0123456789012345
// lcd.print("Send over Serial");
// transferPicture( 0, pictureSize );
}
}
//***********************************************************
//
// S E T U P
//
//***********************************************************
void setup()
{
uint16_t storedpicturesize;
Serial.begin( BAUD );
Wire.begin();
pinMode( LED_PIN, OUTPUT );
digitalWrite( LED_PIN, HIGH );
lcd.begin(16, 2);
if (analogRead(capture_mode_switch) > 511) {
CaptureMode = 1;
} else {
CaptureMode = 0;
}
if(CaptureMode == 1) {
if( !camera.sync() )
{
//Serial.println( "Sync failed." );
lcd.setCursor(0, 0);
lcd.print("Sync failed.");
return;
} else {
lcd.setCursor(0, 0);
lcd.print("Synced.");
}
digitalWrite( LED_PIN, LOW );
if( !camera.initial( CameraC328R::CT_JPEG, CameraC328R::PR_160x120, CameraC328R::JR_640x480 ) )
{
//Serial.println( "Initial failed." );
lcd.setCursor(0, 0);
lcd.print("Initial failed.");
return;
} else {
lcd.setCursor(0, 0);
lcd.print("Inited.");
}
if( !camera.setPackageSize( 64 ) )
{
//Serial.println( "Package size failed." );
lcd.setCursor(0, 0);
lcd.print("Package size failed.");
return;
} else {
lcd.setCursor(0, 0);
lcd.print("Package sized.");
}
if( !camera.setLightFrequency( CameraC328R::FT_50Hz ) )
{
//Serial.println( "Light frequency failed." );
lcd.setCursor(0, 0);
lcd.print("Light frequency failed.");
return;
} else {
lcd.setCursor(0, 0);
lcd.print("Light frequenced.");
}
// Let camera settle, per manual
delay(2000);
digitalWrite( LED_PIN, HIGH );
if( !camera.snapshot( CameraC328R::ST_COMPRESSED, 0 ) )
{
//Serial.println( "Snapshot failed." );
lcd.setCursor(0, 0);
lcd.print("Snapshot failed.");
return;
} else {
lcd.setCursor(0, 0);
lcd.print("Snapshotted.");
}
digitalWrite( LED_PIN, LOW);
if( !camera.getJPEGPicture( CameraC328R::PT_JPEG, PROCESS_DELAY, &getJPEGPicture_callback ) )
{
//Serial.println( "Get JPEG failed." );
lcd.setCursor(0, 0);
lcd.print("Get JPEG failed.");
return;
} else {
lcd.setCursor(0, 0);
lcd.print("Got JPEG.");
}
} else {
lcd.setCursor(0, 0);
// 0123456789012345
lcd.print("Send in 5 secs ");
Serial.flush();
delay( 5000 ); // Give us 5 seconds to hit a key ...
lcd.setCursor(0, 0);
// 0123456789012345
lcd.print("Send over Serial");
storedpicturesize = readEEPROM( eeprom1, 65535 );
storedpicturesize = ((storedpicturesize*256) + readEEPROM( eeprom1, 65534 ) );
//storedpicturesize = ((storedpicturesize << 8) | readEEPROM( eeprom1, 32766 ) );
//storedpicturesize = ((storedpicturesize << 8) | readEEPROM( eeprom1, 32767 ) );
lcd.setCursor(0, 1);
// 0123456789012345
lcd.print("send");
lcd.print(storedpicturesize, DEC);
lcd.print(" bytes");
transferPicture( 0, storedpicturesize );
lcd.setCursor(0, 0);
// 0123456789012345
lcd.print("send complete ");
}
}
void loop()
{
digitalWrite( LED_PIN, HIGH ); // DONE!
delay(100);
digitalWrite( LED_PIN, LOW ); // DONE!
delay(100);
}
// wow, flickr is not a good place to be sharing code
COMedia C328-7640 Serial Camera Arduino "self portrait"
UPDATE: You can still find the Arduino Library here: arms22.googlecode.com/files/CameraC328R.zip
// C328R_with_I2C_flash_LCD
// by s_p_e_x, some rights reserved
//
// Based on work by Sean Voisen
// (gizmologi.st/2009/04/taking-pictures-with-arduino/)
// and Ryan Detzel
// (10kohms.com/arduino-external-eeprom-24lc256)
//
// I converted Seans code to use I2C EEPROM instead of SPI
// Flash. Also I wrote A base64 encoder in an attempt to dodge
// problems with escape codes messing up terminal programs. I'm
// still having issues. But it does work and opens the door to
// a direct interface via Ethernet and a web browser.
// Oh, and I added LCD support to have some clue about what is
// going on. Without having access to the serial interface I
// was really puzzled by why it wasn't working.
// After struggling with getting a proper 3.3V source
// (I finally switched to a "real" Arduino with a built in
// 3.3 regulator) and with iffy contacts on the camera cable
// I was totally thrown by the long delay to write the image to
// the I2C flash. Having an LCD took much of the guess work out.
//
// My I2C EEPROM is a 24LC256, and I use the highest two bytes
// to hold the picture size so when you reset it knows how much
// to read back.
// Unforunately the I2C EEPROM is SLOW, so if you can't monitor
// the progress via an LCD, be very patient waiting for the
// lights to blink and tell you setup() is over. ~5 minutes
// Here's a Function Map which helped me figure out the example:
//setup(){
// if A0 is HIGH
// camera.sync()
// camera.initial()
// camera.setPackageSize()
// camera.setLightFrequency()
// camera.snapshot()
// camera.getJPEGPicture()
// fillPageBuffer()
// writeBuffer() -- for loop
// writeEEPROM() -- write bytes to EEPROM
// getJPEGPicture_callback()
// camera.poweroff()
// if A0 is LOW
// transferPicture() -- print bytes from EEPROM
// bintoascii() -- base64 encoder not perfect but works
// readEEPROM() -- for loop read bytes from EEPROM
//}
//loop(){
// blink LED
//}
// wire A0 HIGH or LOW to take a picture or to extract a picture
// HIGH will guide the camera through init and a photograph and
// transferring to flash before exiting setup().
// LOW will read back the flash and send the data base64 encoded to
// the console. I added a header and footer to take advantage of the
// URI data scheme:
// secure.wikimedia.org/wikipedia/en/wiki/Data_URI_scheme
// On my Mac I extracted the picture with screen:
// screen /dev/tty.usbmodemfd551 38400
// This was on a Mac with an Arduino Uno. The device name may vary.
// Very quickly turn on the logging ^aH (control-A and then shift-H).
// Once the image is done dumping, exit screen completely: ^a^\
// rename the logfile to a .html file:
// mv ~/screenlog.0 image.html
// You should now be able to view your image directly with FireFox.
#include "CameraC328R.h"
#include
#include
#define LED_PIN 13
#define PAGE_SIZE 64
#define BAUD 38400
#define eeprom1 0x50 //Address of 24LC256 eeprom chip
// Buffer for EEPROM data
byte pageBuffer[PAGE_SIZE];
CameraC328R camera;
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
static uint16_t pictureSizeCount = 0;
static uint16_t pageBufferIndex = 0;
static uint16_t currentAddress = 0;
bool dirtyBuffer = false;
int capture_mode_switch = A0; //HIGH => take picture; LOW => extract picture
int CaptureMode;
byte readEEPROM(int deviceaddress, unsigned int eeaddress ) {
byte rdata = 0xFF;
Wire.beginTransmission(deviceaddress);
Wire.send((int)(eeaddress >> 8)); // MSB
Wire.send((int)(eeaddress & 0xFF)); // LSB
Wire.endTransmission();
Wire.requestFrom(deviceaddress,1);
if (Wire.available()) rdata = Wire.receive();
return rdata;
}
void writeEEPROM(int deviceaddress, unsigned int eeaddress, byte data ) {
Wire.beginTransmission(deviceaddress);
Wire.send((int)(eeaddress >> 8)); // MSB
Wire.send((int)(eeaddress & 0xFF)); // LSB
Wire.send(data);
Wire.endTransmission();
//yes you need this delay, and yes it makes flashing take 5 minutes or so
delay(5);
}
/**
* Writes the data in the buffer to the EEPROM at the page
* starting at the given address.
*/
void writeBuffer( int deviceaddress, uint16_t address, uint16_t bufferSize )
{
// Send the data
for( uint16_t i = 0; i < bufferSize; i++ )
{
writeEEPROM(deviceaddress, address+i, pageBuffer[i]);
}
//digitalWrite( SS_PIN, HIGH );
}
/**
* Fills the page buffer for the EEPROM with data.
*/
void fillPageBuffer( byte* data, uint16_t dataSize )
{
for( uint16_t i = 0; i < dataSize; i++ )
{
pageBuffer[pageBufferIndex] = data[i];
dirtyBuffer = true;
pageBufferIndex++;
if( pageBufferIndex == PAGE_SIZE && dirtyBuffer )
{
pageBufferIndex = 0;
writeBuffer(eeprom1, currentAddress, PAGE_SIZE );
currentAddress += PAGE_SIZE;
dirtyBuffer = false;
delay( 50 );
}
}
}
void bintoascii(char * outstring, byte byte0, byte byte1, byte byte2, uint16_t count)
{
//outstring points to 4char string
// byteX are the three possible input bytes
// count marks the number of input bytes, this should
// always be 0 unless it is the last one or two input bytes
byte temp1, temp2, temp0;
char base64chars[]= "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
if (count == 0){
temp0 = byte0;
temp1 = byte1;
temp2 = byte2;
}
if (count == 1){
temp0 = byte2;
temp1 = 0;
temp2 = 0;
}
if (count == 2){
temp0 = byte1;
temp1 = byte2;
temp2 = 0;
}
outstring[0]=base64chars[temp0 >> 2];
//Serial.println(base64chars[temp0 >> 2], BYTE);
outstring[1]=base64chars[((temp0 & 0x03) 4)];
outstring[2]=base64chars[((temp1 & 0x0f) 6)];
outstring[3]=base64chars[(temp2 & 0x3f)];
// add padding
if (count == 1){
outstring[2]='=';
outstring[3]='=';
}
if (count == 2){
outstring[3]='=';
}
}
/**
* Sends a picture to the computer.
*/
void transferPicture( uint16_t startAddress, uint16_t size )
{
char base64text[]="****";
byte old, older, oldest;
uint16_t endAddress = startAddress + size;
uint16_t i;
Serial.println("<img src=\"data:image/jpeg;base64,");
for( i = startAddress; i < endAddress; i++ )
{
oldest = older;
older = old;
old = readEEPROM( eeprom1, i );
// Serial.print(i, DEC); Serial.print(": "); Serial.println(old, DEC);
if ((i+1) % 3 == 0) { // every 3 bytes you print 4 characters
// Serial.print(oldest, DEC); Serial.print(" "); Serial.print(older, DEC); Serial.print(" "); Serial.print(old, DEC); Serial.print(" ");
bintoascii(base64text, oldest, older, old, 0);
Serial.print(base64text);
}
if((i+1) % 57 == 0) { // every 72 characters, you start a new line
Serial.println("");
}
}
//Serial.print( readEEPROM( eeprom1, i ), BYTE );
if ((size % 3) != 0) { //if the image is not a multple of 3 bytes, encode the stragglers
//Serial.print(oldest, DEC); Serial.print(" "); Serial.print(older, DEC); Serial.print(" "); Serial.print(old, DEC); Serial.print(" ");
bintoascii(base64text, oldest, older, old, i%3);
Serial.print(base64text);
}
Serial.println("\" />");
}
/**
* This callback is called EVERY time a JPEG data packet is received.
*/
void getJPEGPicture_callback( uint16_t pictureSize, uint16_t packageSize, uint16_t packageCount, byte* package )
{
// packageSize is the size of the picture part of the package
pictureSizeCount += packageSize;
// print progress
lcd.setCursor(0, 1);
// 0123456789012345
lcd.print(" ");
lcd.setCursor(0, 0);
// 0123456789012345
lcd.print("Camera -> EEPROM");
lcd.setCursor(0, 1);
lcd.print(pictureSizeCount, DEC);
lcd.print("/");
lcd.print(pictureSize, DEC);
// package contains everything in the package
fillPageBuffer( package, packageSize );
if( pictureSizeCount == pictureSize )
{
// Is there still stuff in the buffer?
if( dirtyBuffer )
{
writeBuffer(eeprom1, currentAddress, pageBufferIndex );
}
writeEEPROM(eeprom1, 65534, pictureSize & 0xff);
writeEEPROM(eeprom1, 65535, pictureSize >> 8 & 0xff);
camera.powerOff();
lcd.setCursor(0, 0);
// 0123456789012345
lcd.print("Camera OFF. ");
digitalWrite( LED_PIN, HIGH ); // DONE!
// Serial.flush();
// delay( 5000 ); // Give us 5 seconds to hit a key ...
//
// lcd.setCursor(0, 1);
// // 0123456789012345
// lcd.print("Send over Serial");
// transferPicture( 0, pictureSize );
}
}
//***********************************************************
//
// S E T U P
//
//***********************************************************
void setup()
{
uint16_t storedpicturesize;
Serial.begin( BAUD );
Wire.begin();
pinMode( LED_PIN, OUTPUT );
digitalWrite( LED_PIN, HIGH );
lcd.begin(16, 2);
if (analogRead(capture_mode_switch) > 511) {
CaptureMode = 1;
} else {
CaptureMode = 0;
}
if(CaptureMode == 1) {
if( !camera.sync() )
{
//Serial.println( "Sync failed." );
lcd.setCursor(0, 0);
lcd.print("Sync failed.");
return;
} else {
lcd.setCursor(0, 0);
lcd.print("Synced.");
}
digitalWrite( LED_PIN, LOW );
if( !camera.initial( CameraC328R::CT_JPEG, CameraC328R::PR_160x120, CameraC328R::JR_640x480 ) )
{
//Serial.println( "Initial failed." );
lcd.setCursor(0, 0);
lcd.print("Initial failed.");
return;
} else {
lcd.setCursor(0, 0);
lcd.print("Inited.");
}
if( !camera.setPackageSize( 64 ) )
{
//Serial.println( "Package size failed." );
lcd.setCursor(0, 0);
lcd.print("Package size failed.");
return;
} else {
lcd.setCursor(0, 0);
lcd.print("Package sized.");
}
if( !camera.setLightFrequency( CameraC328R::FT_50Hz ) )
{
//Serial.println( "Light frequency failed." );
lcd.setCursor(0, 0);
lcd.print("Light frequency failed.");
return;
} else {
lcd.setCursor(0, 0);
lcd.print("Light frequenced.");
}
// Let camera settle, per manual
delay(2000);
digitalWrite( LED_PIN, HIGH );
if( !camera.snapshot( CameraC328R::ST_COMPRESSED, 0 ) )
{
//Serial.println( "Snapshot failed." );
lcd.setCursor(0, 0);
lcd.print("Snapshot failed.");
return;
} else {
lcd.setCursor(0, 0);
lcd.print("Snapshotted.");
}
digitalWrite( LED_PIN, LOW);
if( !camera.getJPEGPicture( CameraC328R::PT_JPEG, PROCESS_DELAY, &getJPEGPicture_callback ) )
{
//Serial.println( "Get JPEG failed." );
lcd.setCursor(0, 0);
lcd.print("Get JPEG failed.");
return;
} else {
lcd.setCursor(0, 0);
lcd.print("Got JPEG.");
}
} else {
lcd.setCursor(0, 0);
// 0123456789012345
lcd.print("Send in 5 secs ");
Serial.flush();
delay( 5000 ); // Give us 5 seconds to hit a key ...
lcd.setCursor(0, 0);
// 0123456789012345
lcd.print("Send over Serial");
storedpicturesize = readEEPROM( eeprom1, 65535 );
storedpicturesize = ((storedpicturesize*256) + readEEPROM( eeprom1, 65534 ) );
//storedpicturesize = ((storedpicturesize << 8) | readEEPROM( eeprom1, 32766 ) );
//storedpicturesize = ((storedpicturesize << 8) | readEEPROM( eeprom1, 32767 ) );
lcd.setCursor(0, 1);
// 0123456789012345
lcd.print("send");
lcd.print(storedpicturesize, DEC);
lcd.print(" bytes");
transferPicture( 0, storedpicturesize );
lcd.setCursor(0, 0);
// 0123456789012345
lcd.print("send complete ");
}
}
void loop()
{
digitalWrite( LED_PIN, HIGH ); // DONE!
delay(100);
digitalWrite( LED_PIN, LOW ); // DONE!
delay(100);
}
// wow, flickr is not a good place to be sharing code