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
#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);
}
}
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.....
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.....
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
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.
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.
Potresti far "spezzare il jpg" in diversi file da pochi kB.
questo avviene di già:
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.
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...
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)
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?
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
Si ce l'ho fatta con un POST su una pagina PHP.
Come al solito il problema è mettere un po insieme tutto.
Ho usato un'altra libreria che era compatibile con la mia fotocamera e poi ci sono riuscito.
Nel frattempo sono anche passato al Mega perchè l'UNO era un po' limitato per altre cose che dovevo usare.