Off the Grid Security

I have created, using an Arduino Uno - WiFi - and camera, a device which upon power start up will snap an image and POST the image to a remote server.

However, the images are corrupted.

I suspect the streaming portion is when the error occurs. I have noticed the client write library accepts one parameter, the data to be written, however my current setup passes in the data to be written and the length of the data.

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);
      //imgFile.write(buffer, bytesToRead);
      
      if(client.connected()){
        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;
    }

If anyone has any ideas, it will be greatly appreciated.

The Ethernet class has a method write(buffer, length), so this is not your problem.

What libraries do you use? (Provide links)

Post the whole code!

What libraries do you use?

I'm using the WiFi library WiFi - Arduino Reference. It would appear only having client.write(data) method.

I think buffering could be the problem as one might notice the right side of image is where the most inconsistencies occur.

#include <SoftwareSerial.h>
#include <Adafruit_VC0706.h>
#include <WiFi.h>
#include <SD.h>

/*********** CAM ***********/
// On Uno: camera TX connected to pin 2, camera RX to pin 3:
SoftwareSerial cameraconnection = SoftwareSerial(2, 3);
Adafruit_VC0706 cam = Adafruit_VC0706(&cameraconnection);

/*********** WiFi ***********/
char ssid[] = "SSID";                     // your network SSID (name) 
char key[] = "******";                       // your network key
int keyIndex = 0;                                // your network key Index number
int status = WL_IDLE_STATUS;                     // the Wifi radio's status
WiFiClient client;
//IPAddress server(xxx.xxx.xxx.xxx);
char server[] = "server.com";
IPAddress ip ;

/*********** SD ***********/
#define chipSelect 4
File imgFile;
    
void setup(){
  Serial.begin(9600);
  Serial.println("MaineDefense");
  Serial.println("-----------------");
  
  // Try to locate the camera
  if (cam.begin()) {
    Serial.println("Camera Found:");
  } else {
    Serial.println("No camera found?");
    return;
  }
  Serial.println("-----------------");
  
  pinMode(10, OUTPUT);
  
  // see if the card is present and can be initialized:
  if (!SD.begin(chipSelect)) {
    Serial.println("Card failed, or not present");
    Serial.println("-----------------");
    // don't do anything more:
    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);
    // 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("-----------------");
  }

  /*********** ***********/
  // attempt to connect to an open network:
  //Serial.print("Attempting to connect to WEP network: ");
  //Serial.println(ssid);
  status = WiFi.begin(ssid, keyIndex, key);

  // if you're not connected, stop here:
  if ( status != WL_CONNECTED) { 
    Serial.println("Couldn't get a wifi connection");
    while(true);
  } 
  // if you are connected :
  else {
    //Serial.println("You're connected to the network");
    //printCurrentNet();
    //printWifiData();
    
    //Serial.println("Attempting to connect to MyIdealDevelopment");
    while(!client.connect(server, 80)){}
    Serial.println("Connected to MyIdealDevelopment"); 
    Serial.println("-----------------");
    delay(1000);
  }
  
}
void loop()
{
  char filename[14];
  /*********** ***********/

  if(!client.connected()){
        Serial.println("resetting server connection");
        client.flush();
        client.stop(); 
        client.connect(server, 80);
    
    
  }
  
  if (!cam.takePicture()){ 
    Serial.println("Failed to snap!");
  }else{ 
    Serial.println("Picture taken!");
  
    // 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;
      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
    imgFile = SD.open(filename, FILE_WRITE);

    // Get the size of the image (frame) taken  
    uint16_t jpglen = cam.frameLength();
    Serial.print("Storing in memory ");
    Serial.print(jpglen, DEC);
    Serial.println(" byte image.");
    
    //pinMode(8, OUTPUT);
    // Read all the data up to # bytes!
    byte wCount = 0; // For counting # of writes
    
    if(client.connected()){
        
        Serial.println("Beginning Post...");
        
        client.println(F("POST /path/script.php HTTP/1.1"));
        client.println(F("HOST: server.com"));
        client.println(F("Content-type: multipart/form-data, boundary=UH3xBZZtzewr09oPP"));
        client.print(F("Content-Length: "));
        client.println((jpglen+177));
        client.println(); //2
        client.println(F("--UH3xBZZtzewr09oPP")); //19 + 2
        client.println(F("content-disposition: form-data; name=\"picture\"; filename=\"cam.jpg\"")); //66 + 2
        client.println(F("Content-Type: image/jpeg")); //24 + 2
        client.println(F("Content-Transfer-Encoding: binary")); //33 + 2
        client.println(); //2
        
    }
    
    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);
      //imgFile.write(buffer, bytesToRead);
      
      if(client.connected()){
        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;
    }
    
    if(client.connected()){
      client.println(); //2
      client.println(F("--UH3xBZZtzewr09oPP--")); //21 + 2
      Serial.println("End Post");
    
      Serial.println("Response From MyIdealDevelopment....");
        while(client.available()){
          if(client.available()){
            char c  =client.read();
            Serial.print(c); 
          }
        } 
    }
    
    //imgFile.close();
  }         
  cam.resumeVideo();           
    
  Serial.println("Looping");
  Serial.println("*************************************************************");
}

/*
Test POST

Serial.println("Still connected");
client.println("POST /path/script.php HTTP/1.1");
client.println("HOST: server.com");
client.println("Connection: Close");
client.println("User Agent: Arduino/1.1");
client.print("Accept: *          /");
client.println("*");
client.print("Content-Type: text/plain");
client.print("Content-Length: ");
client.println(postData.length());
client.println();
client.println(postData);
*/

My guess is another: You're using a SoftwareSerial connection with a speed of 38400 baud. In my experience this tends to transmission errors. 9600 baud usually is fine but everything above that tends to transmission errors if the Arduino is not only doing this task.

Try using the hardware serial interface (do debugging on a SoftwareSerial port) and you probably get correct pictures.

Thank you for the response. I will give it a try.