Go Down

Topic: Fare una FOTO e mandarla ad un PC - Vari problemi soprattutto di memoria (Read 3817 times) previous topic - next topic

contecavour

Sto cercando di afre in modo che Arduino faccia una foto e la mandi ad un Pc.
Ho una cam seriale Adafruit compatibile e un ethernet shield originale.

Allora sto cercando di mettere insieme un po' di pezzi che da soli funzionavano.
La foto sono riuscito a farla e salvarla sulla SD.
Unendo altre librerie ho problemi di memoria e non va piu niente

Fino a questo punto l'unica cosa che sono riuscito a fare e farla al massimo in 320x240 e mandarla ad un server FTP.
Già facendola 640x480 la connessione con l'FTP cade.
Ho provato a fare un POST su un web serve ma non sono riuscito.

Qualcuno ha idee o sugerimenti?
Sotto il codice.

Ciao
Nic

Code: [Select]
#include <Adafruit_VC0706.h>
#include <SoftwareSerial.h>   
#include <SPI.h>
#include <Ethernet.h>

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };

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

char serverName[] = "web1.ogilvy.it";

EthernetClient client;

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

  pinMode(10, OUTPUT);
  digitalWrite(10, HIGH);

  if (Ethernet.begin(mac) == 0) {
    Serial.println("Failed to configure Ethernet using DHCP");
    while(true);
  }   
   
  delay(1000);
   
  Serial.println("VC0706 Camera snapshot test");

  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("-----------------");
  }
 
  cam.setImageSize(VC0706_640x480);        // biggest
  //cam.setImageSize(VC0706_320x240);        // medium
  //cam.setImageSize(VC0706_160x120);          // small

  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:
   
   
    // 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");
   
  }
  else {
    // kf you didn't get a connection to the server:
    Serial.println("connection failed");
  }   
   
  // 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);
  } 
 
}

contecavour


acik

Io la butto li stupidamente:

Quanto e' grande il file ???
Potresti far "spezzare il jpg" in diversi file da pochi kB.
Poi li invii uno alla volta.
Lato PC prendi i vari file, li unisci.....


contecavour

Allora detto che sono già in crisi di memoria.
E veramnete vedo che aggiungendo una riga di codice tocco il fondo
Volevo evitare di scrivere sulla SD.

N

Madwriter


Io la butto li stupidamente:

Quanto e' grande il file ???
Potresti far "spezzare il jpg" in diversi file da pochi kB.
Poi li invii uno alla volta.
Lato PC prendi i vari file, li unisci.....



o piu semplicemente prendi un arduino mega  :smiley-mr-green:
"Due cose sono infinite: l'universo e la stupidità umana, ma riguardo l'universo ho ancora dei dubbi..." Albert Einstein

contecavour

Infatti mi sa che devo andare sul Mega
Il file comunque è 47kb

N

acik

Beh, se devi comprarti un Mega... Per gli stessi soldi ti compri una webcam motorizzata con Ethernet e WiFi...

Riuscire a far funzionare la tua telecamera su un UNO ti darebbe la soddisfazione di dire cel' ho fatta !!!

leo72

Potresti postare i messaggi di debug che spedisci alla seriale sia nel caso di foto 320x240 che nel caso di foto 640x480?
Almeno per capire qual è il punto in cui dà problemi e se c'è un modo per aggirarlo

contecavour

Quote
Beh, se devi comprarti un Mega... Per gli stessi soldi ti compri una webcam motorizzata con Ethernet e WiFi...

Riuscire a far funzionare la tua telecamera su un UNO ti darebbe la soddisfazione di dire cel' ho fatta !!!


Ma devo far fare anche altre cose.

Quote
Potresti postare i messaggi di debug che spedisci alla seriale sia nel caso di foto 320x240 che nel caso di foto 640x480?
Almeno per capire qual è il punto in cui dà problemi e se c'è un modo per aggirarlo


Adesso non ce l'ho sotto mano ma cose senza senso. Tipo magari cicla sul primo messaggio di errore all'infinito.
O si blocca ad un punto.
e solo cambiando una lettera nel debug cambia l'effetto, come se veramente non riuscisse a seguire il flusso.


lesto

Immagino che il file sia "parcheggiato" sulla SD.

Quote
Potresti far "spezzare il jpg" in diversi file da pochi kB.

questo avviene di già:
Code: [Select]
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;
  }


però c'è già un grosso errore: non vedo nessuna free()! se è così, se inviassi due (o più) foto poccile di fila noteresti lo stesso problema che sull'immagine grossa.

poi un altro fatto, che però il fatto che la foto piccola funzioni mi da l'impressione che ti sia andata di culo:
se la client.write() NON è bloccante, e se la lettura da SD è più veloce della scrittura su TCP, allora incapperesti nello stesso problema di cui sopra, o nel caso di una concatenazione in buffer circolare (caso della Serial dall'ide 1.0) perderesti parte dei dati inviati.
Ma a quanto pare è bloccante (ovvero la funzione non ritorna finchè tutti i dati non sono stati scritti), quindi ti sei salvato.
sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

contecavour

In realtà questo ciclo legge da cam via seriale e cercava di mandare immediatamente al POST.

Su cosa faresti il free ad esempio?

Però sistematicamente con le piccole va (12kb) e con le grande da errore, ma poi la foto è visualizzabile (47kb)
In realtà dopo du po' di prove mi capita che non vada piu niente e non capsico perchè dopo un po ricomincia...

Cosa intendi con bloccante?
N

lesto

quando tu fai
uint8_t *buffer;
uint8_t bytesToRead = min(32, jpglen); // change 32 to 64 for a speedup but may not work with all setups!

viene allocato un buffer di una certa dimensione, che però non viene dritrutto con una free (viene distrutto il puntatore, non l'aria di memoria punatata)

per le funzioni bloccanti:
http://www.ce.unipr.it/didattica/siselab/Tesine/mpichG2/bloccanti.html
sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

contecavour

Quindi tu dici ad ogni ciclo lo ricreo?
Quindi sarebbe meglio crearlo prima del ciclo e nel ciclo riutilizzarlo solo?
Oppure consigli così e fare un free ogni ciclo?
Come si fa il free?

Grazie
N

contecavour

E come faccio a sapere se una funzione è bloccante o no?
Tipo dove vedo che delay lo è e millis no?

N

lesto

ahhh minchiata mia, buffer = cam.readPicture(bytesToRead);
buffer è il valore di ritorno di una funzione, quindi se ricordo bene ha la stessa visibilità di una variabile.. prova comunque a fare una free quando hai finito di usare buffer, giusto per.

per sapoere se una funzione è loccante o è nelel specifiche, oppure lo devi capire da solo
sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

Go Up