Partage
  • Partager sur Facebook
  • Partager sur Twitter

[ARDUINO] Aide Shield Camera

    14 mars 2017 à 7:43:22

    Bonjour,

    Pour mon projet je dois travailler avec ce shield : http://wiki.seeedstudio.com/wiki/Camera_Shield

    J'ai donc pris le code suivant :

    #include "SoftwareSerial.h"
    #include <VC0706_UART.h>
    #include <SD.h>
    #include <SPI.h>
    #define SS_SD  10
    
    //use software serial
    SoftwareSerial cameraconnection(2,3);//Rx, Tx
    VC0706 cam = VC0706(&cameraconnection);
    //use hardware serial
    //VC0706 cam = VC0706(&Serial1);
    
    void setup()
    {
        Serial.begin(9600);
        Serial.println("VC0706 Camera Snapshot Test ...");
       
        if (!SD.begin(SS_SD)) {
            Serial.println("SD Card init failed...");
            return;
        } 
        if(true == cameraInit()){
            snapShot();
        }else{
            Serial.println("camera init error...");
        }
    }
    
    void loop()
    {
        //nothing to do
    }
    
    bool cameraInit()
    {
        cam.begin(BaudRate_19200);
        char *reply = cam.getVersion();
        if (reply == 0) {
            Serial.println("Failed to get version");
            return false;
        } else {
            Serial.println("version:");
            Serial.println("-----------------");
            Serial.println(reply);
            Serial.println("-----------------");
            return true;
        }
    }
    
    void snapShot()
    {
        Serial.println("Snap in 3 secs...");
        delay(3000);
        if (! cam.takePicture()){
            Serial.println("Failed to snap!");
        }else {
            Serial.println("Picture taken!");
        }
        // Create an image with the name IMAGExx.JPG
        char filename[13];
        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);
        Serial.print("create ");
        Serial.println(filename);
        uint16_t jpglen = cam.getFrameLength();
        Serial.print("wait to fetch ");
        Serial.print(jpglen, DEC);
        Serial.println(" byte image ...");
        int32_t time = millis();
        cam.getPicture(jpglen);
        uint8_t *buffer;
        while(jpglen != 0){
             uint8_t bytesToRead = min(32, jpglen);
             buffer = cam.readPicture(bytesToRead);     
             imgFile.write(buffer, bytesToRead);
             //Serial.print("Read ");  Serial.print(bytesToRead, DEC); Serial.println(" bytes");
             jpglen -= bytesToRead;   
        }
        imgFile.close();
        time = millis() - time;
        Serial.println("Done!");
        Serial.print("Took "); Serial.print(time); Serial.println(" ms");
        cam.resumeVideo();   
    }

    Ce code permet de prendre une photo que quand je ferme/ouvre le moniteur série de l'arduino ! mais moi j'aimerais modifier le code de façon à ce que la prise de photo soit par intervalle de temps et ne dépend pas de l'activation moniteur série ! :) 

    J'aimerais juste avoir quelques pistes/indices pour m'aider et je me débrouillerais pour le reste !  ;)

    • Partager sur Facebook
    • Partager sur Twitter
    Blanc Sama is my Senpai
      14 mars 2017 à 9:54:57

      Ton code actuel fait une capture à l'initialisation puis ne fait plus rien.

      Or, quand tu ouvres et ferme le moniteur série, cela fait un reset de la carte arduino donc cela va forcément faire une nouvelle capture.

      Si tu veux faire des captures à interval régulier, il te suffit simplement d'appeler ta fonction snapShot de temps en temps.

      Exemple de code qui fait une pose de 10sec entre 2 appels à ta fonction de capture :

      #include "SoftwareSerial.h"
      #include <VC0706_UART.h>
      #include <SD.h>
      #include <SPI.h>
      #define SS_SD  10
      
      SoftwareSerial cameraconnection(2,3);//Rx, Tx
      VC0706 cam = VC0706(&cameraconnection);
      
      void setup()
      {
          Serial.begin(9600);
          Serial.println("VC0706 Camera Snapshot Test ...");
          
          if (!SD.begin(SS_SD)) {
              Serial.println("SD Card init failed...");
              return;
          }
      
          if(!cameraInit()){
              Serial.println("camera init error...");
              return;
          }
      
      }
       
      void loop()
      {
          Serial.println("snapShot!!!");
          snapShot();
          Serial.println("delay!!!");
          delay(10000);
      }
       
      bool cameraInit()
      {
          [...]
      }
       
      void snapShot()
      {
          [...]
      }

      Après, si tu veux quelque chose de plus précis, il faudrait tenir compte du temps que met une capture à ce faire.

      Pour cela, plutôt que d'utiliser delay pour cadencer ton système dans la fonction loop, tu devrais te baser sur la fonction millis() qui renvoie le nombre de ms écoulé depuis le lancement du programme.

      Ainsi, tu pourrais déclencher une capture à chaque fois que millis dépasse une certaine valeur du genre 10000, 20000, 30000... pour une capture toutes les 10 secondes précisément.

      Je t'invite aussi à revoir le système de nommage des images car actuellement, ton code ne peut sauvegarder que 100 images numérotées de IMAGE00.JPG à IMAGE99.JPG

      Une autre bonne chose à faire serait de virer les Serial.print et delay inutile pour ne garder que le strict nécessaire.

      Je me demande aussi si ton code n'aurais pas un gros problème d'allocation dynamique ou de fuite mémoire sur le buffer utilisé pour lire/écriture l'image.

      -
      Edité par lorrio 14 mars 2017 à 10:03:07

      • Partager sur Facebook
      • Partager sur Twitter
        14 mars 2017 à 11:48:09

        Merci infiniment pour ta réponse lorrio :D , je testerais le delay dans la fonction loop pour voir comment mon sytème réagira, mais il y a quelque chose qui me chiffonne pour le système de nommage si j'enlève tout ce bout de code :

        // Create an image with the name IMAGExx.JPG
            char filename[13];
            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;


        est-ce que ça changera quelque chose au niveau du stockage de la micro SD ? :)

        • Partager sur Facebook
        • Partager sur Twitter
        Blanc Sama is my Senpai
          14 mars 2017 à 12:12:55

          Ce bout de code permet de vérifier l’existence des fichiers IMAGE00.JPG, IMAGE01.JPG, IMAGE02.JPG... jusqu'à trouver un nom de fichier qui n'existe pas.

          Une fois qu'un nom de fichier n'existant pas est trouvé, ce nom de fichier est utilisé pour créer un nouveau fichier qui contiendra l'image.

          Donc si tu supprime cette partie de code, le fichier enregistré sera toujours le même...

          Par contre, il est vrai que faire cette détection avant chaque image à prendre n'est pas très logique.

          Surtout si tu laisses ton code tourner longtemps car cela prendra de plus en plus de temps au fure et à mesure que ta carte SD contient de plus en plus de fichier.

          Il serait plus logique de faire ce test une première fois à l'initialisation (dans le setup) pour ensuite retenir quel numéro d'image il faudra ensuite enregistré.

          Ta fonction snapshot n'aura alors plus à faire cette détection mais simplement enregistrer l'image et incrémenter le numéro pour le prochain enregistrement.

          • Partager sur Facebook
          • Partager sur Twitter
            25 avril 2017 à 6:30:28

            Bonjour je UP ce topic ! 

            J'aimerais savoir si je peux de quelconque façon, afficher les photos stockées dans la carte micro SD du shield  caméra sur une page html liée à l'arduino dans un réseau local ?  :)

            -
            Edité par JustDoIt3 25 avril 2017 à 6:47:12

            • Partager sur Facebook
            • Partager sur Twitter
            Blanc Sama is my Senpai
              25 avril 2017 à 8:43:37

              Oui, c'est possible en émulant un petit serveur WEB sur arduino.

              Mais la puissance de calcul de l'arduino est très limité donc même un simple transfert d'octet de la carte SD vers un shield ethernet prend du temps.

              Après, si ça ne te dérange pas que la page s'affiche en plusieurs secondes, c'est à toi de voir.

              Une RPi serait beaucoup plus appropriée pour ce genre de chose.

              -
              Edité par lorrio 25 avril 2017 à 8:44:01

              • Partager sur Facebook
              • Partager sur Twitter

              [ARDUINO] Aide Shield Camera

              × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
              × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
              • Editeur
              • Markdown