Send image to a PC using ethernet shield

I'd like to send a jpg file (640x480) to a pc using ethernet shiedl. what could i use?

socket? post to a web server?

is there some exampl e?

Thanks

Where do you have that JPEG from? What does the PC has to do with the JPEG? Do you already have a web server that can store that image?

There are a lot of examples with the Arduino as a client or as a server, but which one to use depends a lot on the above questions.

I have a adafruit cam.
I take a snapshot and i must send it to a pc.
I have sucess to save it to SD.

If i use all the library (dafruitcam, SD, ethernet) i have memory problem.
I’d like not save and send it to a pc.

I can make all that i need (web server, ftp…).
I must send the file to pc in the better mode.

Thanks

Take the Ethernet example WebClientRepeating, change the method to post (http://en.wikipedia.org/wiki/POST_%28HTTP%29 and send your picture to your web server.

What kind of memory problem do you have if you use the three libraries? RAM or flash (program storage)?

i dont'know how can i do to know it? N

How do you know then, that you have a memory problem? What symptoms did you get? Who did tell you that it's a memory problem?

I post the code
(Parli italiano)?

if i use
#include <Wire.h> //Va in conflitto con ethernet
#include <RTClib.h> //va in conflitto con time

i obtain different errors (continue to start the ehernet, the program stop)

if i comment those include all works.

#include <Adafruit_VC0706.h>
#include <SoftwareSerial.h>    
#include <SPI.h>
#include <Ethernet.h>
//#include <EthernetUdp.h>
//#include <Time.h> incompatibile con RTCLIB.h

#include <SD.h>
#include <Wire.h> //Va in conflitto con ethernet
#include <RTClib.h> //va in conflitto con time
#include <Time.h>

/* ******** Ethernet Card Settings ******** */
// Set this to your Ethernet Card Mac Address
byte mac[] = { 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF }; 

/* ******** NTP Server Settings ******** */
/* us.pool.ntp.org NTP server 
   (Set to your time server of choice) */
IPAddress timeServer(96, 44, 157, 90); 

/* Set this to the offset (in seconds) to your local time*/
const long oraLegale = 3600L;   
const long timeZoneOffset = 3600L + oraLegale;   


/* Syncs to NTP server every 15 seconds for testing, 
   set to 1 hour or more to be reasonable */
unsigned int ntpSyncTime = 15;         


/* ALTER THESE VARIABLES AT YOUR OWN RISK */
// local port to listen for UDP packets
unsigned int localPort = 8888;
// NTP time stamp is in the first 48 bytes of the message
const int NTP_PACKET_SIZE= 48;      
// Buffer to hold incoming and outgoing packets
byte packetBuffer[NTP_PACKET_SIZE];  
// A UDP instance to let us send and receive packets over UDP
EthernetUDP Udp;                    
// Keeps track of how long ago we updated the NTP server
unsigned long ntpLastUpdate = 0;    
// Check last time clock displayed (Not in Production)
//time_t prevDisplay = 0;    

SoftwareSerial cameraconnection = SoftwareSerial(6, 7);
Adafruit_VC0706 cam = Adafruit_VC0706(&cameraconnection);

RTC_Millis RTC;

void setup() {
  Serial.begin(38400);
//  Wire.begin();
//  RTC.begin(DateTime(__DATE__, __TIME__));

  Serial.print("Initializing SD card...");
  pinMode(10, OUTPUT);     // change this to 53 on a mega
  digitalWrite(10, HIGH);
  
  //la doppia nizializzazione dava problemi probabilmente il segreto sono le 2 righe sopra
  
  // we'll use the initialization code from the utility libraries
  // since we're just testing if the card is working!
//  if (!card.init(SPI_HALF_SPEED, 4)) {
//    Serial.println("initialization failed. Things to check:");
//    Serial.println("* is a card is inserted?");
//    Serial.println("* Is your wiring correct?");
//    Serial.println("* did you change the chipSelect pin to match your shield or module?");
//    return;
//  } else {
//   Serial.println("Wiring is correct and a card is present."); 
//  }

 if (!SD.begin(4)) {
    Serial.println("initialization failed!");
    return;
  }  else {
   Serial.println("SD.begin fatto"); 
  }

    
   
   // Ethernet shield and NTP setup
   int i = 0;
   int DHCP = 0;
   DHCP = Ethernet.begin(mac);
//   Serial.println("dhcp fatto");
//   Serial.println(DHCP);
   //Try to get dhcp settings 30 times before giving up
   while( DHCP == 0 && i < 30){
     delay(1000);
     DHCP = Ethernet.begin(mac);
     i++;
   }
   if(!DHCP){
    Serial.println("DHCP FAILED");
     for(;;); //Infinite loop because DHCP Failed
   }
   Serial.println("DHCP Success");
   
   //TOGLIENDO QUESTO VA
   //non è vero era la doppia inizializzazione della card
   //Try to get the date and time
   int trys=0;
   while(!getTimeAndDate() && trys<10) {
     trys++;
   }
   
  Serial.println("VC0706 Camera snapshot test");
  // Try to locate the camera
  if (cam.begin()) {
    Serial.println("Camera Found:");
  } else {
    Serial.println("No camera found?");
    return;
  }
  
  // Print out the camera version information (optional)
  char *reply = cam.getVersion();
  if (reply == 0) {
    Serial.print("Failed to get version");
  } else {
    Serial.println("-----------------");
    Serial.print(reply);
    Serial.println("-----------------");
  }

  // Set the picture size - you can choose one of 640x480, 320x240 or 160x120 
  // Remember that bigger pictures take longer to transmit!
  cam.setImageSize(VC0706_640x480);        // biggest
  //cam.setImageSize(VC0706_320x240);        // medium
  //cam.setImageSize(VC0706_160x120);          // small

  // You can read the size back from the camera (optional, but maybe useful?)
  uint8_t imgsize = cam.getImageSize();
  Serial.print("Image size: ");
  if (imgsize == VC0706_640x480) Serial.println("640x480");
  if (imgsize == VC0706_320x240) Serial.println("320x240");
  if (imgsize == VC0706_160x120) Serial.println("160x120");
  
  if (! cam.takePicture()) 
    Serial.println("Failed to snap!");
  else 
    Serial.println("Picture taken!");   
    
    
}

// Do not alter this function, it is used by the system
int getTimeAndDate() {
   int flag=0;
   Udp.begin(localPort);
   sendNTPpacket(timeServer);
   delay(1000);
   if (Udp.parsePacket()){
     Udp.read(packetBuffer,NTP_PACKET_SIZE);  // read the packet into the buffer
     unsigned long highWord, lowWord, epoch;
     highWord = word(packetBuffer[40], packetBuffer[41]);
     lowWord = word(packetBuffer[42], packetBuffer[43]);  
     epoch = highWord << 16 | lowWord;
     epoch = epoch - 2208988800 + timeZoneOffset;
     flag=1;
//     setTime(epoch);
//     ntpLastUpdate = now();
   }
   return flag;
}

// Do not alter this function, it is used by the system
unsigned long sendNTPpacket(IPAddress& address)
{
  memset(packetBuffer, 0, NTP_PACKET_SIZE); 
  packetBuffer[0] = 0b11100011;
  packetBuffer[1] = 0;
  packetBuffer[2] = 6;
  packetBuffer[3] = 0xEC;
  packetBuffer[12]  = 49; 
  packetBuffer[13]  = 0x4E;
  packetBuffer[14]  = 49;
  packetBuffer[15]  = 52;		   
  Udp.beginPacket(address, 123);
  Udp.write(packetBuffer,NTP_PACKET_SIZE);
  Udp.endPacket(); 
}


// Utility function for clock display: prints preceding colon and leading 0
void printDigits(int digits){
  Serial.print(":");
  if(digits < 10)
    Serial.print('0');
  Serial.print(digits);
}



// funzione creazione timestamp file di log

/*
void getFilename(char *filename) {
  DateTime now = RTC.now(); 
  int year = now.year(); 
  int month = now.month(); 
  int day = now.day();
  int hour = now.hour();
  int minute = now.minute();
  
  
  filename[0] = month/10 + '0';
  filename[1] = month%10 + '0';
  filename[2] = day/10 + '0';
  filename[3] = day%10 + '0';
  
  filename[4] = hour/10 + '0';
  filename[5] = hour%10 + '0';
  filename[6] = minute/10 + '0';
  filename[7] = minute%10 + '0';
  filename[8] = '.';
  filename[9] = 'c';
  filename[10] = 's';
  filename[11] = 'v';

  return;
}
*/


// This is where all the magic happens...
void loop() {

}

Take the Ethernet example WebClientRepeating, change the method to post (http://en.wikipedia.org/wiki/POST_%28HTTP%29 and send your picture to your web server.

Doesn't work.

I have a DHCP. I have used:

 Ethernet.begin(mac);
 Ethernet.begin(mac, Ethernet.localIP(), myDns);

The connection is ok, but no other response. I force httpRequest(); and i obtain failed.

i used ip value for the server

//IPAddress server = (64,131,82,241);
char server[] = "64.131.82.241";

and i have the same failed

Ciao

If i use DnsWebClient example works. Also editing server e Get

//char serverName[] = "www.google.com";
char serverName[] = "www.arduino.cc";

...

 if (client.connect(serverName, 80)) {
    Serial.println("connected");
    // Make a HTTP request:
    
    //Esempio per Google
    //client.println("GET /search?q=arduino HTTP/1.0");
    
    client.println("GET /latest.txt HTTP/1.1");
    client.println("Host: www.arduino.cc");
    client.println("User-Agent: arduino-ethernet");
    client.println("Connection: close");
    client.println();
  }

Take the Ethernet example WebClientRepeating, change the method to post (http://en.wikipedia.org/wiki/POST_%28HTTP%29 and send your picture to your web server.

How i send image with a POST?

Nic

To get around your memory problem, try putting as many constant strings as possible into the program memory to free your RAM:

client.println("GET /latest.txt HTTP/1.1");

gets

client.println(F("GET /latest.txt HTTP/1.1"));

This does work for constant strings and if the object is from a class derived from the Print class (usually all that use print() and println() methods). The SD class uses a quarter of the whole RAM for buffering, so you have take care not to use too much memory elsewhere and this is easy to change.

For the POST: you have to encode your request using multipart-formdata about this way:

uint32_t len = size_of_pict + 177; // 177 is the content without the image data
client.println(F("POST /path/to/script.php HTTP/1.0"));
client.println(F("Host: example.com"));
client.println(F("Content-type: multipart/form-data, boundary=UH3xBZZtzewr09oPP"));
client.print(F("Content-Length: "));
client.println(len);
client.println();
client.println(F("--UH3xBZZtzewr09oPP"));
client.println(F("content-disposition: form-data; name=\"picture\"; filename=\"cam.jpg\""));
client.println(F("Content-Type: image/jpeg"));
client.println(F("Content-Transfer-Encoding: binary"));
client.println();
while (has_more_pict_data) {
  client.write(pict_chunk, size_of_pict_chunk);
}
client.println();
client.println(F("--UH3xBZZtzewr09oPP--"));

You have to change the while loop and the size calculation of course to fit the camera needs. I guess you get the way to use the F() macro in this example too.

Thank very much... I try.

N

Hi pylom, i’, tryng but i have some problem
the line:
uint32_t len = jpglen + 177; // 177 is the content without the image data

i must change 177 if i change somothing?
Abode the code

Nic

#include <Adafruit_VC0706.h>
#include <SoftwareSerial.h>    
#include <SPI.h>
#include <Ethernet.h>

/* ******** Ethernet Card Settings ******** */
// Set this to your Ethernet Card Mac Address
//byte mac[] = {  0x00, 0xAA, 0xBB, 0xCC, 0xDE, 0x02 };
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };

SoftwareSerial cameraconnection = SoftwareSerial(6, 7);
Adafruit_VC0706 cam = Adafruit_VC0706(&cameraconnection);


//char serverName[] = "www.arduino.cc";
//char serverName[] = "www.google.com";
char serverName[] = "web1.ogilvy.it";
//   http://web1.ogilvy.it/ARDUINO/
//char serverName[] = "locahost";
//byte mioserver[] = {10,110,9,85};
//byte server[] = { 173, 194, 69, 94 }; // Google

EthernetClient client;


void setup() {
  Serial.begin(38400);

  pinMode(10, OUTPUT);     // change this to 53 on a mega
  digitalWrite(10, HIGH);
  

  if (Ethernet.begin(mac) == 0) {
    Serial.println("Failed to configure Ethernet using DHCP");
    // no point in carrying on, so do nothing forevermore:
    while(true);
  }   
   
  delay(1000);
   
  Serial.println("VC0706 Camera snapshot test");
  // Try to locate the camera
  if (cam.begin()) {
    Serial.println("Camera Found:");
  } else {
    Serial.println("No camera found?");
    return;
  }
  // Print out the camera version information (optional)
  char *reply = cam.getVersion();
  if (reply == 0) {
    Serial.print("Failed to get version");
  } else {
    Serial.println("-----------------");
    Serial.print(reply);
    Serial.println("-----------------");
  }

  // Set the picture size - you can choose one of 640x480, 320x240 or 160x120 
  // Remember that bigger pictures take longer to transmit!
  
  cam.setImageSize(VC0706_640x480);        // biggest
  //cam.setImageSize(VC0706_320x240);        // medium
  //cam.setImageSize(VC0706_160x120);          // small

  // You can read the size back from the camera (optional, but maybe useful?)
  uint8_t imgsize = cam.getImageSize();
  Serial.print("Image size: ");
  if (imgsize == VC0706_640x480) Serial.println("640x480");
  if (imgsize == VC0706_320x240) Serial.println("320x240");
  if (imgsize == VC0706_160x120) Serial.println("160x120");
  
  Serial.println("Snap in 3 secs...");
  delay(3000);  
  if (! cam.takePicture()) 
    Serial.println("Failed to snap!");
  else 
    Serial.println("Picture taken!");
    
  Serial.println("Server connecting...");   

//  if (client.connect(mioserver, 8080)) {

   
  if (client.connect(serverName, 80)) {
    Serial.println("connected");
    // Make a HTTP request:
//    client.println("GET /ARDUINO/savepicture.cfm");
//    client.println();
    
    
  // Get the size of the image (frame) taken  
  uint16_t jpglen = cam.frameLength();
  Serial.print("Storing ");
  Serial.print(jpglen, DEC);
  Serial.print(" byte image.");
  uint32_t len = jpglen + 177; // 177 is the content without the image data  
  
//client.println(F("POST /path/to/script.php HTTP/1.0"));
client.println(F("POST /ARDUINO/savepicture.cfm HTTP/1.1"));
//client.println(F("POST /ARDUINO/savepicture.cfm"));
client.println(F("Host: web1.ogilvy.it"));
client.println(F("Content-type: multipart/form-data, boundary=UH3xBZZtzewr09oPP"));
client.print(F("Content-Length: "));
client.println(len);
client.println();
client.println(F("--UH3xBZZtzewr09oPP"));
client.println(F("content-disposition: form-data; name=\"picture\"; filename=\"cam.jpg\""));
client.println(F("Content-Type: image/jpeg"));
client.println(F("Content-Transfer-Encoding: binary"));
client.println();
  
  
  int32_t time = millis();
  pinMode(8, OUTPUT);
  // Read all the data up to # bytes!
  byte wCount = 0; // For counting # of writes
  while (jpglen > 0) {
    // read 32 bytes at a time;
    uint8_t *buffer;
    uint8_t bytesToRead = min(32, jpglen); // change 32 to 64 for a speedup but may not work with all setups!
    buffer = cam.readPicture(bytesToRead);
    
    //Scrittura
//    imgFile.write(buffer, bytesToRead);
    client.write(buffer, bytesToRead);
    

    if(++wCount >= 64) { // Every 2K, give a little feedback so it doesn't appear locked up
      Serial.print('.');
      wCount = 0;
    }
    //Serial.print("Read ");  Serial.print(bytesToRead, DEC); Serial.println(" bytes");
    jpglen -= bytesToRead;
  }
//  imgFile.close();

client.println();
client.println(F("--UH3xBZZtzewr09oPP--"));


  time = millis() - time;
  Serial.println("done!");
  Serial.print(time); Serial.println(" ms elapsed");
  
    
    
/* CODICE DA BLOG

uint32_t len = size_of_pict + 177; // 177 is the content without the image data
client.println(F("POST /path/to/script.php HTTP/1.0"));
client.println(F("Host: example.com"));
client.println(F("Content-type: multipart/form-data, boundary=UH3xBZZtzewr09oPP"));
client.print(F("Content-Length: "));
client.println(len);
client.println();
client.println(F("--UH3xBZZtzewr09oPP"));
client.println(F("content-disposition: form-data; name=\"picture\"; filename=\"cam.jpg\""));
client.println(F("Content-Type: image/jpeg"));
client.println(F("Content-Transfer-Encoding: binary"));
client.println();
while (has_more_pict_data) {
  client.write(pict_chunk, size_of_pict_chunk);
}
client.println();
client.println(F("--UH3xBZZtzewr09oPP--"));

*/
    
    
    
    
  } 
  else {
    // kf you didn't get a connection to the server:
    Serial.println("connection failed");
  }   
    
    
    

//   File imgFile = SD.open("PIPPO.JPG", FILE_WRITE);    
   
   
  // Get the size of the image (frame) taken  
//  uint16_t jpglen = cam.frameLength();
//  Serial.print("Storing ");
//  Serial.print(jpglen, DEC);
//  Serial.print(" byte image.");

   
}



// This is where all the magic happens...
void loop() {

  
  
  //Preso da DnsWebClient
  if (client.available()) {
    char c = client.read();
    Serial.print(c);
  }

  // if the server's disconnected, stop the client:
  if (!client.connected()) {
    Serial.println();
    Serial.println("disconnecting.");
    client.stop();

    // do nothing forevermore:
    while(true);
  }  
  
}

My PHP developer tell me that the lenght is zero. N

I want to make a test with a file on the SD, because use all togheter i have the usual memory problem. How i send bites to client HTTP?

Ihow must i use the file.read function ti send buffer of bytes

N

My PHP developer tell me that the lenght is zero.

You send it to a ColdFusion URL not PHP. Is he really looking for the right thing? And what length is zero? The one transmitted on the “Content-Length” line? Or the length of the actual image data? Use a sniffer like WireShark to see what’s actually going over the wire. This way you can easily decide if the Arduino is wrong or the server side.

I want to make a test with a file on the SD, because use all togheter i have the usual memory problem.

You haven’t changed your code to use the F() macro. This probably would solve your memory problem.

How i send bites to client HTTP?

You wanna receive bytes on the Arduino? What kind of data do you wanna receive?

how must i use the file.read function ti send buffer of bytes

Exactly the same way as you currently use the camera methods. client.write() is your friend :).

i must change 177 if i change somothing?

Yes, if you change anything after the line

client.println(len);

you have to adjust it to represent the amount of data you send.

I had changed all print with text in print(F(..))

i had made 2 tests.

1) while cam send data with serial i write to HTTP 2) client.write = SD.read (send the file read from SD)

How i must count the bytes of the header? byte to byte ?

My sketch us 30.000 bytes, and if i add some print(F(...))...doesn't work. I think than i'm very near to the memory limit.

My sketch us 30.000 bytes, and if i add some print(F(...))...doesn't work.

Oops, so you have more of a storage problem. The ATmega328p has 32kB of flash storage, about 2kB is used for the bootloader. You should try shorten the sketch. Limit the debugging string length to the bare minimum, usually abbreviations are almost as informative as the whole string. Think about what you really need. Currently you have NTP and RTC in the sketch. Do you really need both? If you really need all that stuff, I'd suggest upgrading to a Mega 2560. That has 256kB flash and 8kB RAM so you have a lot more room for extensions.

How i must count the bytes of the header? byte to byte ?

Yes, and keep in mind, that a println() does send CR AND LF (two characters).

Hi pylon, from where i must start to count 155 char and until where?

Thanks Nic

uint32_t len = size_of_pict + 177; // 177 is the content without the image data client.println(F("POST /path/to/script.php HTTP/1.0")); client.println(F("Host: example.com")); client.println(F("Content-type: multipart/form-data, boundary=UH3xBZZtzewr09oPP")); client.print(F("Content-Length: ")); client.println(len); client.println(); client.println(F("--UH3xBZZtzewr09oPP")); client.println(F("content-disposition: form-data; name=\"picture\"; filename=\"cam.jpg\"")); client.println(F("Content-Type: image/jpeg")); client.println(F("Content-Transfer-Encoding: binary")); client.println(); while (has_more_pict_data) { client.write(pict_chunk, size_of_pict_chunk); } client.println(); client.println(F("--UH3xBZZtzewr09oPP--"));