Caméra série SEN0099

Et vous avez quoi comme code fusionné, faudrait partir de là pour voir ce qui se passe.

Ôte-moi un doute !!
Vous utilisez les librairies softwareSerial, SD et Ethernet sur une UNO?
Je pense que vous devez très certainement vous trouver à court de mémoire. Toutes ces librairies utilisent des tampons de données de taille conséquente pour assurer les échanges entre le soft et les périphériques.
Pour s'en assurer, voir là:
http://playground.arduino.cc/Code/AvailableMemory
un outil qui permet d'afficher la mémoire disponible.

Et ça ne pose pas de problème à la carte d'avoir plusieurs protocoles de communication en même temps?
Il ne faut pas les lancer les uns après les autres pour éviter les conflits?

Voila le code fusionné :wink:
J'ai crée des sous fonctions:
-Prise photo
-Ethernet
Ensuite dans mon LOOP je l'ai envois séparement donc je ne comprends pas...
Pour ce qui est de la memoire je ne pense pas avoir de probleme, sinon je ne pourrais pas le compiler non ?

#include <Adafruit_VC0706.h>
#include <SD.h>
#include <SPI.h>
#include <Ethernet.h>
#include <Servo.h> 

Servo microservo; 
int pos = 0; 
int fsrAnalogPin2 = A1;
byte mac[] = { 0x90, 0xA2, 0xDA, 0x0E, 0xA6, 0x0D };   //physical mac address
byte ip[] = { 169, 254, 73, 50 };                      // ip in lan (that's what you need to use in your browser. ("192.168.1.178")
byte gateway[] = { 192, 168, 1, 1 };                   // internet access via router
byte subnet[] = { 255, 255, 255, 0 };                  //subnet mask
EthernetServer server(80);                             //server port     
String readString;
///////////capteur de présence d'entrée/////////////////////
  int fsrAnalogPin = A0; 
///////////capteur lumineu + LED flash//////////
int photocellPin = A2; // the cell and 10K pulldown are connected to a0
const int diode_flash=5;
////////////////////////////Fonction prise de photo////////////////////////
void prise_de_photo ()
{
  #define chipSelect 4
  #include <SoftwareSerial.h> 
  SoftwareSerial cameraconnection = SoftwareSerial(2, 3);  
  Adafruit_VC0706 cam = Adafruit_VC0706(&cameraconnection);
  #if !defined(SOFTWARE_SPI)
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
  if(chipSelect != 53) pinMode(53, OUTPUT); // SS on Mega
#else
  if(chipSelect != 10) pinMode(10, OUTPUT); // SS on Uno, etc.
#endif
#endif
  
  Serial.println("VC0706 Camera snapshot test");
  
  // see if the card is present and can be initialized:
  if (!SD.begin(chipSelect)) {
    Serial.println("Card failed, or not present");
    // don't do anything more:
    return;
  }  
  if (!SD.begin(chipSelect)) {
    return;
  }  
  if (cam.begin()) {

  } 
  char *reply = cam.getVersion();
  if (reply == 0) {
    
  } 
  
  cam.setImageSize(VC0706_640x480);     
  uint8_t imgsize = cam.getImageSize();

  if (! cam.takePicture()) 
    Serial.println("Failed to snap!");
  else 
    Serial.println("Picture taken!");
  
  // Create an image with the name IMAGExx.JPG
  char filename[13];
    if (SD.exists("IMAGE00.JPG"))
    {
        SD.remove("IMAGE00.JPG");
    }
  strcpy(filename, "IMAGE00.JPG");
 /* for (int i = 0; i < 100; i++) {
    filename[5] = '0' + i/10;
    filename[6] = '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
  File imgFile = SD.open(filename, FILE_WRITE);

  // Get the size of the image (frame) taken  
  uint16_t jpglen = cam.frameLength();


  int32_t time = millis();
  // 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);
    imgFile.write(buffer, bytesToRead);
    if(++wCount >= 64) { // Every 2K, give a little feedback so it doesn't appear locked up
      wCount = 0;
    }
    //Serial.print("Read ");  Serial.print(bytesToRead, DEC); Serial.println(" bytes");
    jpglen -= bytesToRead;
  }
  imgFile.close();

 
  Serial.println("done!");
  delay (500);
  asm volatile ("  jmp 0"); 
  
}


//////////////////////////////////void ethernet//////////////
void ethernet ()
{
   // Create a client connection
  EthernetClient client = server.available();
  if (client) {
    while (client.connected()) {   
      if (client.available()) {
        char c = client.read();
     
        //read char by char HTTP request
        if (readString.length() < 100) {
          //store characters to string
          readString += c;
          //Serial.print(c);
         }

         //if HTTP request has ended
         if (c == '\n') {          
           Serial.println(readString); //print to serial monitor for debuging
     
           client.println("HTTP/1.1 200 OK"); //send new page
           client.println("Content-Type: text/html");
           client.println();     
           client.println("<HTML>");
           client.println("<HEAD>");
           client.println("<meta name='apple-mobile-web-app-capable' content='yes' />");
           client.println("<meta name='apple-mobile-web-app-status-bar-style' content='black-translucent' />");
           client.println("<link rel='stylesheet' type='text/css' href='http://randomnerdtutorials.com/ethernetcss.css' />");
           client.println("<TITLE>AUTOBARRIGO</TITLE>");
           client.println("</HEAD>");
           client.println("<BODY>");
           client.println("<H1>Autobarrigo : simulation de passage</H1>");
           client.println("<hr />");
           client.println("
");  
           client.println("
");     
           client.println("
"); 
           client.println("<a href=\"/03312203011191tmm\"\">Ouverture</a>");
           client.println("
"); 
           client.println("</BODY>");
           client.println("</HTML>");
     
          delay(1);
           //stopping client
          client.stop();
           //controls the Arduino if you press the buttons
 
           if (readString.indexOf("03312203011191tmm") >0){
                for(pos = 53; pos < 143; pos += 5)  // goes from 0 degrees to 180 degrees 
                {                                  // in steps of 1 degree 
                  microservo.write(pos);              // tell servo to go to position in variable 'pos' 
                  delay(100);                       // waits 15ms for the servo to reach the position 
                } 
           }
            //clearing string for next read
            readString="";  
           
         }
       }
    }
}
             
              if (analogRead(fsrAnalogPin2) > 400)
           {
                for(pos = 143; pos>=53; pos-=5)     // goes from 180 degrees to 0 degrees 
                {                                
                  microservo.write(pos);              // tell servo to go to position in variable 'pos' 
                  delay(100);                       // waits 15ms for the servo to reach the position 
                } 
           }
        
}

/////////////////////void setup/////////////////////////////

void setup(void) {
    Ethernet.begin(mac, ip, gateway, subnet);
    delay (1000);
    Serial.begin(9600);          
    
   server.begin();
   while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }
    microservo.attach(9);
    pinMode(diode_flash, OUTPUT);
 }
 
 ////////////////////////////////LOOP/////////////////////////  


void loop(void) {
  
    digitalWrite(diode_flash,LOW);
  if(analogRead(fsrAnalogPin) >= 400 && analogRead(photocellPin) <= 200)
    {
    digitalWrite(diode_flash,HIGH);  
    prise_de_photo();
    digitalWrite(diode_flash,LOW);
    } 
  else if(analogRead(fsrAnalogPin) >= 400 && analogRead(photocellPin) >= 200)
    {
    digitalWrite(diode_flash,LOW);    
    prise_de_photo();
    }
    delay (2000);
ethernet();
}

Pour la freeMemory j'ai fais le test : 1821

Veknar:
Pour la freeMemory j'ai fais le test : 1821

Gros doutes.
La UNO a 2K de RAM la librairie SD doit déjà avoir un buffer de 512 octets et l'Ethernet doit aussi gérer un buffer de la taille des paquets à manipuler donc je serais très surpris que le programme n'utilise que 200 octets.
Il y a beaucoup de fonctions qui font de l'allocation dynamique de mémoire donc il faut faire afficher la mémoire disponible en différents points du programme.

Il y a aussi des trucs comme ça qui m'interpelle:

  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(++wCount >= 64) { // Every 2K, give a little feedback so it doesn't appear locked up

buffer est un pointeur, un pointeur c'est juste une adresse vers un bloc de données. Qui fait l'allocation des 32 octets, la méthode readPictures()? Parce que si ce n'est pas elle tu piques de la mémoire on ne sait pas trop où. Et si c'est readPictures() qui fait l'allocation, qui est-ce qui rend la mémoire?
edit je viens de regarder la librairie, c'est elle qui gère le buffer.

Donc cela viens de quoi exactement ? :slight_smile:

Les librairies utilisent peut être la mémoire RAM dynamiquement.

et voyez vous une solution ? :cold_sweat:

Auriez vous une idée pour résoudre ce problème ?*

Cdt

Voilà le résultat de la compilation de ton code. Il reste 318 octets et c'est juste les données globales. Donc si une fonction alloue un quelconque tampon tu n'as plus de RAM.
La solution? Passer à une Mega2560 ou mettre moins de choses dans ton programme.

Merde :frowning:

Pourrait-on stocker du programme dans la carte SD, pour palier au problème ?

fdufnews:
Voilà le résultat de la compilation de ton code. Il reste 318 octets et c'est juste les données globales. Donc si une fonction alloue un quelconque tampon tu n'as plus de RAM.
La solution? Passer à une Mega2560 ou mettre moins de choses dans ton programme.

Comment tu fais pour avoir autant d'infos sur les variables globales, les locales la RAM dispo et tout et tout!
Moi j'ai pas tout ça, j'ai juste la première ligne?

C'est du fait que je suis avec l'IDE 1.0.3?

:wink:

Là on ne parle pas de mémoire programme (Flash), on parle de mémoire data (RAM).
Pour réduire l'empreinte en RAM il faut diminuer drastiquement la quantité de variables globales. Le problème c'est qu'une bonne partie de ces variables globales sont créées dans les librairies. Ceci oblige à mettre le nez dans les librairies et en profondeur. Ce n'est pas un truc que l'on fait en 5 minutes. Il faudrait analyser l'utilisation des données entre les différentes librairies et voir s'il y aurait moyen de mutualiser du stockage en partageant des zones mémoire pour y placer des tampons de données qui ne sont pas utilisées en même temps. C'est une refonte en profondeur des librairies et la mise au point n'est pas facile.

Si tu n'as pas de problème de budget, le passage à une mega est la solution la moins hasardeuse (et la plus rapide).

john_lenfr:

fdufnews:
Voilà le résultat de la compilation de ton code. Il reste 318 octets et c'est juste les données globales. Donc si une fonction alloue un quelconque tampon tu n'as plus de RAM.
La solution? Passer à une Mega2560 ou mettre moins de choses dans ton programme.

Comment tu fais pour avoir autant d'infos sur les variables globales, les locales la RAM dispo et tout et tout!
Moi j'ai pas tout ça, j'ai juste la première ligne?

C'est du fait que je suis avec l'IDE 1.0.3?

:wink:

Jaloux.
C'est une fonctionnalité qui est ajoutée dans les dernières version de l'IDE. Si tu regardes en haut de la recopie d'écran c'est la version 1.5.4. C'est bien pratique.

Merci pour vos réponses. :wink:
Nous n'aurons pas le temps trifouiller dans les librairies.
Nous allons donc utiliser deux arduino uno avec leurs supports ethernet shield.

A bientôt
Cordialement
Veknar.

Effectivement, si vous avez une autre UNO c'est le plus simple puisque les programmes fonctionnaient chacun de leur coté.

fdufnews:
C'est bien pratique.

Clair! Pourquoi ils l'ont pas mis avant! :smiley:

EDIT: c'est génial ces infos ça permet de se passer du freeRAM!

john_lenfr:

fdufnews:
C'est bien pratique.

Clair! Pourquoi ils l'ont pas mis avant! :smiley:

EDIT: c'est génial ces infos ça permet de se passer du freeRAM!

On ne voit que les données statiques. Si le programme fait de l'allocation dynamique on a besoin de freeRam.
Par contre, après compilation, on sait déjà si on flirte dangereusement ou pas avec les limites.