Aller au contenu

Fabrice Teissier

Membre
  • Compteur de contenus

    36
  • Inscription

  • Dernière visite

Messages posté(e)s par Fabrice Teissier

  1. Bonjour tout le monde,

     

    Quelle surprise et plaisir de tomber sur ce fil de discutions par hasard en faisant une recherche sur INDIDUINO pour essayer de comprendre comment interfacer mon flip flat arduino avec INDI.

     

    Et oui, comme vous, je suis en train de réaliser un flip flat à base d’arduino nano pour ma TOA-130.

    Je tiens à préciser pour certains qu’il est plus compliqué et sophistiqué de ceux que j’ai pu voir sur ce fil. Mais bon il est destiné à un poste fixe et j’assume tant qu’il rempli mon cahier des charges conséquent. Et puis je ne vous cache pas que j’avais envie de découvrir les méandres de la programmation et les possibilités de ce micro-contrôleur. Alors j’en ai un peu rajouté

     

    Je vais donc profiter de ce fil pour vous présenter mon projet, en l’état, histoire de partager avec vous nos expériences, idées et solutions.

     

    Je tiens aussi à préciser que je n’ai aucune compétence en programmation n’y en électronique à part savoir manier le fer à souder. Je me suis donc aidé en glanant toutes ces compétences sur internet via des forums et tutos.

     

    Mon cahier des charges :

     

    • Ouvrir et fermer un couvercle en locale ou en remote.
    • Le couvercle doit être étanche à la poussière et à la lumière pour pouvoir faire des darks.
    • Le couvercle doit être équipé d’une source lumineuse réglable en intensité pour faire des flats.
    • En position ouvert, l’intérieur du couvercle doit être protégé de l’humidité et surtout d’éventuels insectes qui viendraient perturber les flats par leur présence.
    • Le système doit être rapidement démontable pour une éventuelle sortie nomade.
    • Le couvercle doit pouvoir se refermer automatiquement en cas de coupure de courant.

     

    Les difficultés rencontrées :

     

    L’auto-reset :

    Je me suis rapidement rendu compte qu’à chaque communication via le port série/usb entre l’ordi et l’arduino nano, ce dernier faisait un reset dévastateur quand les servos étaient restés en position capot ouvert. En effet, mon cahier des charges m’impose l’utilisation de trois servos. Un « servotranslation » qui sert à translater le capot le long de l’axe du tube pour le boucher ou déboucher hermétiquement. Un « servocapot » qui sert à orienter le capot de 180° à l’opposé et un « servorotation » qui sert à replier le capot afin de le protéger. Les séquences d’ouverture et de fermeture doivent impérativement respecter un certain ordre dans les commandes de chaque servo pour éviter tout contact et détérioration matériel.

    Or le reset provoque une réinitialisation de la position de chaque servo, en même temps, à leur position d’origine inscrite dans le setup et si par malheur le capot était resté en position ouverte avant le reset, c’est la cata. Je n’ai pas trouvé de solution logiciel pour régler ce problème. J’ai donc fait une recherche pour éviter cet auto-reset du nano et j’ai trouvé une solution hardware qui consiste à dessouder un micro condensation situé sous le PCB de l’arduino. Reste un reset lors du branchement du cable usb dont je n’ai pas trouvé de solution matériel. Donc, pour éviter que le capot reste en position ouverte sans le savoir, j’ai fait une sécurité qui consiste à fermer le capot lorsque qu’il y à une coupure d’alimentation. Cela nécessite une ou deux piles 9v, un relais et un gros condensateur. Du coup, je ne peux plus débrancher le flip-flat en position ouvert sans qu’il se referme automatiquement. Or, pour le démontage, je souhaiterais qu’il reste en position ouvert qui protège l’intérieur du capot. J’ai donc rajouté un bouton supplémentaire « Park » qui donne l’ordre d’ouvrir le capot et qui condamne  le relais « sécu » pour empêcher l’alimentation de secours de s’activer. En lisant ce fil de discussion, j’ai trouver l’idée de mettre un relais pour couper l’alimentation des servos, lorsqu’ils ne sont pas en fonctionnement, très bonne. Je l’ai donc rajouté.  Me voilà, à priori, bien protégé du reset intempestif.

    Ah… J’oubliais: Comme l’alimentions secours est constituée de piles et comme j’ai quatre led pour indiquer la puissance d’éclairage du panneau EL lorsqu’il est commandé en local, j’en ai profité pour en faire un voltmètre qui mesure l’état de ces piles.

     

    La vitesse des servo:

    Pour préserver un peu le mécanique, il fallait ralentir la vitesse des servos. J’ai donc trouvé un bout de code qui permet de régler cette vitesse aux petits oignons.

     

    La variation lumineuse du panneau EL:

    Le fournisseur du panneau EL propose un variateur 12v à mettre en amont de l’onduleur. Je m’était dit qu’en remplaçant son potentiomètre par un potentiomètre digital commandé par l’arduino devrait faire l’affaire. Mais bon, plutôt que d’avoir plusieurs modules branchés les uns derrière les autre, je me suis dit que de fabriquer ce variateur et l’intégrer au shield serait plus élégant. Après recherches, j’ai trouvé une solution assez simple avec un empli op et un transistor de puissance. Ca marche plutôt bien mais j’ai du rajouter un condensateur pour éviter le flicking à certaines valeurs et ce condensateur modifie la tension de sortie du régulateur de commande du panneau EL. Ce qui a pour conséquence de rendre le réglage de puissance du panneau non linéaire. Pas très grave, il suffit de tâtonner dans le programme pour trouver les bonnes valeurs afin d’avoir quatre niveaux de puissance bien répartis.

     

    La communication via le port série/usb:

    Comme je n’y connais rien en programmation, cela n’a pas été une mince affaire mais je m’en suis sortie grâce à internet. J’ai réussit à faire des scripts python qui me permettent de commander le Flip flat. Mais le plus gros boulot qui me reste à faire. C'est d’intégrer le code dans mon programme pour le rendre compatible avec INDI. D’ou ma présence sur ce fl de discussion.

     

    Voilà donc ce à quoi cela va ressembler :

     

    J’aurais bien aimé pouvoir faire une animation de l’ouverture et la fermeture mais je ne sais pas le faire. J’utilise Freecad pour la modélisation.

     

    1049023185_Flipflatferm.thumb.png.5ae0f6ecb9d2958c3d3c39568f66f3df.png

     

    1342821429_Flipflatdemiouvert.thumb.png.099c67f7b715d4711b098a1c3ee07b9f.png

     

    1994928285_Flipflatouvert.thumb.png.b0bd746fc027046defd04f0f6431a6d6.png

     

    Voilà le schéma réalisé sur EasyEDA:

     

    Schematic_Flip-flat-4_Flip-flat-4_20190616185154.png

     

    Et le PCB toujours réalisé sur EasyEDA:

     

    PCB.thumb.png.55e4f043179f783966acde2b47807145.png

     

    Le code:

     

    Révélation
    
    #include <Arduino.h>
    #include <Servo.h>
     
     
    Servo ServoCapot;
    Servo ServoRotation;
    Servo ServoTranslation;
    const int btn_capot = A0;
    const int btn_voltmetre = A2;
    const int btn_ELpan = A1;
    const int btn_park = A5;
    const int ctc_capot_ouvert = A3;
    const int ctc_capot_ferme = A4;
    const int led_1 = 4;
    const int led_2 = 5;
    const int led_3 = 6;
    const int led_4 = 7;
    const int ELpan = 3;
    const int relais_ELpan = 13;
    const int relais_secu = 8;
    const int relais_servo = 12;
    
    int AngleServoCapot= 0;
    int AngleServoRotation= 137;
    int AngleServoTranslation= 47;
    int reception;
    int compte_btn_ELpan = 0; // le nombre qui sera incrémenté et décrémenté
    int etat_btn_ELpan = LOW; // lecture de l'état des boutons (un seul à la fois donc une variable suffit)
    int etatprecedent_btn_ELpan = LOW; // état relâché par défaut
    int real_vin(); // Variable de la tension mesuré par le voltmetre
    const byte BROCHE_CAPTEUR_VIN = A7; // Le numéro de broche analogique pour la mesure de la tension en VIN
    const float COEFF_PONT_DIVISEUR_VIN = 1.95; // Coefficient diviseur du pont de résistance et étalonnage du volmètre
    String commande;
     
    
    
        
    void setup()
    {
        Serial.begin(115200);
        Serial.flush();
        
        ServoCapot.attach(9, 500, 2475); // init pin
        ServoRotation.attach(10, 500, 2475); // init pin
        ServoTranslation.attach(11, 500, 2475); // init pin
        ServoCapot.write(AngleServoCapot);
        ServoRotation.write(AngleServoRotation);
        ServoTranslation.write(AngleServoTranslation);
        
        pinMode(btn_capot,INPUT);     
        pinMode(btn_voltmetre,INPUT);
        pinMode(btn_ELpan, INPUT);
        pinMode(btn_park, INPUT);
        pinMode(ctc_capot_ouvert, INPUT);
        pinMode(ctc_capot_ferme, INPUT);    
        pinMode(led_1, OUTPUT);
        pinMode(led_2, OUTPUT);
        pinMode(led_3, OUTPUT);
        pinMode(led_4, OUTPUT);
        pinMode(ELpan, OUTPUT);
        pinMode(relais_ELpan, OUTPUT);
        pinMode(relais_secu,OUTPUT);   
        pinMode(relais_servo,OUTPUT);   
        attachInterrupt(digitalPinToInterrupt(2), secu, FALLING); // Fonction de détection d'une entrée peu importe ou en est le programme. Utile pour la détection de chute de tension.
        
    }
     
    unsigned int analogReadReference(void) // Mesure la référence interne à 1.1 volts
    {
      
    // Elimine toutes charges résiduelles
    #if defined(__AVR_ATmega328P__)
      ADMUX = 0x4F;
    #elif defined(__AVR_ATmega2560__)
      ADCSRB &= ~(1 << MUX5);
      ADMUX = 0x5F;
    #elif defined(__AVR_ATmega32U4__)
      ADCSRB &= ~(1 << MUX5);
      ADMUX = 0x5F;
    #endif
      delayMicroseconds(5);
      
    // Sélectionne la référence interne à 1.1 volts comme point de mesure, avec comme limite haute VCC
    #if defined(__AVR_ATmega328P__)
      ADMUX = 0x4E;
    #elif defined(__AVR_ATmega2560__)
      ADCSRB &= ~(1 << MUX5);
      ADMUX = 0x5E;
    #elif defined(__AVR_ATmega32U4__)
      ADCSRB &= ~(1 << MUX5);
      ADMUX = 0x5E;
    #endif
      delayMicroseconds(200);
      
      ADCSRA |= (1 << ADEN); // Active le convertisseur analogique -> numérique
      
      ADCSRA |= (1 << ADSC); // Lance une conversion analogique -> numérique
      
      while(ADCSRA & (1 << ADSC)); // Attend la fin de la conversion
      
      return ADCL | (ADCH << 8); // Récupère le résultat de la conversion
    }
    void loop() 
    {           
     
    // Traitement série pour communiquer via l'interface série de l'arduino ou via des srypts python.
       while (Serial.available() > 0)
        {
        reception = Serial.read();
        commande += char(reception);
        delay(5);
        }
     
       if (commande != "") // Si la commande est différente de rien, on execute la routine "traitementserial"
        {
        traitementserial();
        }
    // Ouverture Fermeture capot    
       if((digitalRead(btn_capot) == HIGH) && (digitalRead(ctc_capot_ouvert) == HIGH) && (digitalRead(btn_park) == LOW))
        {
        fermeture(); 
        }
       if((digitalRead(btn_capot) == HIGH) && (digitalRead(ctc_capot_ferme) == HIGH) && (digitalRead(btn_park) == LOW))
        {
          
        ouverture();
        }
        if((digitalRead(btn_park) == HIGH) && (digitalRead(ctc_capot_ferme) == HIGH))
        {
          
        ouverture();
        }
      
        if (digitalRead(relais_secu)==(HIGH))
          {  
            if (digitalRead(ctc_capot_ouvert) == HIGH)
            {
          fermeture();
          }
          if(digitalRead(ctc_capot_ferme) == HIGH)
        {
          
        delay(1000);    
        digitalWrite(relais_secu,LOW);
        }
          
          }
      
    
    // ELpan
        etat_btn_ELpan = digitalRead(btn_ELpan);
       if (etat_btn_ELpan != etatprecedent_btn_ELpan) // si l'état du bouton a changé
          {
          if (etat_btn_ELpan == HIGH) // et qu'il est haut (= on appuie dessus)
            {
            compte_btn_ELpan++; // on incrémente le compteur
            if (compte_btn_ELpan > 4) // sauf s'il a dépassé 4...
              {
               compte_btn_ELpan = 0; // ...auquel cas on le réinitialise
              }
           }
        
          }
           
         progELpan(); // on execute progELpan
        etatprecedent_btn_ELpan = etat_btn_ELpan; // et on stocke l'atat du bouton pour le prochain tour
       
         
    // Voltmetre
        if (digitalRead(btn_voltmetre) == HIGH)
          {
            delay(100);
          voltmetre(); // On execute volmetre
          }
        else
          {
          analogWrite(led_1,0);
          analogWrite(led_2,0);
          analogWrite(led_3,0);
          analogWrite(led_4,0);
          }
    } 
    void ouverture() // Routine ouverture capot
    { 
     
     
      if (compte_btn_ELpan >= 1)
              {
               
      analogWrite(led_1,0);
      analogWrite(led_2,0);
      analogWrite(led_3,0);
      analogWrite(led_4,0);
      analogWrite(ELpan,0);
      digitalWrite(relais_ELpan,LOW);
      Serial.println("EL panel éteind");  
      }
        digitalWrite(relais_servo,HIGH);
           delay(500); 
      while(!(((AngleServoTranslation)==(137))))
          {
          ServoTranslation.write((AngleServoTranslation) + (1)); 
          AngleServoTranslation += 1;
          delay(20);//_delay(0.02);
          }
           
       delay(1000);//_delay(1);
            
       while(!(((AngleServoCapot)==(180))))
          {
          ServoCapot.write((AngleServoCapot) + (1)); 
          AngleServoCapot += 1;
          delay(20);//_delay(0.02);
          }
            
       delay(1000);//_delay(1);
       while(!(((AngleServoRotation)==(47))))
          {
           ServoRotation.write((AngleServoRotation) - (1)); 
           AngleServoRotation += -1;
           delay(20);//_delay(0.02);
          }
            delay(500); 
             if (digitalRead(ctc_capot_ouvert) == HIGH)
              {
                digitalWrite(relais_servo,LOW);
          Serial.println("Capot ouvert");
              }
         
    }
     
     void fermeture() // Routine fermeture capot 
      { 
      // compte_btn_ELpan = 0; 
         digitalWrite(relais_servo,HIGH);
           delay(500); 
       while(!(((AngleServoRotation)==(137))))
            {
                ServoRotation.write((AngleServoRotation) + (1)); 
                AngleServoRotation += 1;
                delay(20);// _delay(0.02);
            }
            delay(1000);//_delay(1);
            while(!(((AngleServoCapot)==(0))))
            {
                ServoCapot.write((AngleServoCapot) - (1));
                AngleServoCapot += -1;
                delay(20);// _delay(0.02);
            }
            delay(1000);//_delay(1);
            while(!(((AngleServoTranslation)==(47))))
            {
                ServoTranslation.write((AngleServoTranslation) - (1));
                AngleServoTranslation += -1;
                delay(20);// _delay(0.02);
            }
              delay(500); 
               if (digitalRead(ctc_capot_ferme) == HIGH)
              {
                digitalWrite(relais_servo,LOW);
          Serial.println("Capot fermé");
              }
          
        }
     
     void traitementserial() // Routine traitement série
    {
      if (commande == "ouverture")
      {
        ouverture();
      }
     else if (commande == "fermeture")
      {
        fermeture();
      }
      if ((commande == "elpan1") && (digitalRead(ctc_capot_ferme) == HIGH))
      {
        compte_btn_ELpan = 1;
        Serial.println("EL panel allumé à 25%");
         }
      if ((commande == "elpan2") && (digitalRead(ctc_capot_ferme) == HIGH))
      {
        compte_btn_ELpan = 2;
        Serial.println("EL panel allumé à 50%");
         }
         if ((commande == "elpan3") && (digitalRead(ctc_capot_ferme) == HIGH))
      {
        compte_btn_ELpan = 3;
        Serial.println("EL panel allumé à 75%");
         }
         if ((commande == "elpan4") && (digitalRead(ctc_capot_ferme) == HIGH))
      {
        compte_btn_ELpan = 4;
        Serial.println("EL panel allumé à 100%");
         }
        if (((commande == "elpan1")||(commande == "elpan2")||(commande == "elpan3")||commande == ("elpan4")) && (digitalRead(ctc_capot_ouvert) == HIGH))
       {
        Serial.println("Impossible, capot ouvert");
      }
      
      if (commande == "elpanoff")
      {
        compte_btn_ELpan = 0;
        Serial.println("EL panel éteint");
      }
        commande = "";
    }
    void progELpan() // Routine éclairage EL panel
    {
       if ((compte_btn_ELpan >= 1) && (AngleServoTranslation == 47))
            {
            digitalWrite(relais_ELpan,HIGH); // on allume le relai
            }
          else 
            {
            digitalWrite(relais_ELpan,LOW); // on eteind le relai
            } 
     //     if (compte_btn_ELpan == 0)
     // {
      //  analogWrite(led_1,0);
       // analogWrite(led_2,0);
       // analogWrite(led_3,0);
       // analogWrite(led_4,0);
       // analogWrite(ELpan,0);
     // }
          if ((compte_btn_ELpan == 1) && (digitalRead(ctc_capot_ferme) == HIGH))
      {
        analogWrite(led_1,255);
        analogWrite(led_2,0);
        analogWrite(led_3,0);
        analogWrite(led_4,0);
        analogWrite(ELpan,27);
      }
         if ((compte_btn_ELpan == 2) && (digitalRead(ctc_capot_ferme) == HIGH))
      {
        analogWrite(led_1,255);
        analogWrite(led_2,255);
        analogWrite(led_3,0);
        analogWrite(led_4,0);
        analogWrite(ELpan,50);
      }
         if ((compte_btn_ELpan == 3) && (digitalRead(ctc_capot_ferme) == HIGH))
      {
        analogWrite(led_1,255);
        analogWrite(led_2,255);
        analogWrite(led_3,255);
        analogWrite(led_4,0);
        analogWrite(ELpan,90);
      }
        if ((compte_btn_ELpan == 4) && (digitalRead(ctc_capot_ferme) == HIGH))
      {
        analogWrite(led_1,255);
        analogWrite(led_2,255);
        analogWrite(led_3,255);
        analogWrite(led_4,255);
        analogWrite(ELpan,255);
      }
     
    }
    void voltmetre() // Routine voltmetre
    {
     
      // Mesure la tension en VIN et la référence interne à 1.1 volts
      unsigned int raw_vin = analogRead(BROCHE_CAPTEUR_VIN);
      unsigned int raw_ref = analogReadReference();
      
      // Calcul de la tension réel avec un produit en croix
      float real_vin = ((raw_vin * 1.1) / raw_ref) * COEFF_PONT_DIVISEUR_VIN;
      
             if (real_vin >= 6)
      {
        analogWrite(led_1,255);
        analogWrite(led_2,0);
        analogWrite(led_3,0);
        analogWrite(led_4,0);
      }
           if (real_vin >= 7)
      {
        analogWrite(led_1,255);
        analogWrite(led_2,255);
        analogWrite(led_3,0);
        analogWrite(led_4,0);
       }
        if (real_vin >= 😎
      {
        analogWrite(led_1,255);
        analogWrite(led_2,255);
        analogWrite(led_3,255);
        analogWrite(led_4,0);
       }
       if (real_vin >= 9)
      {
        analogWrite(led_1,255);
        analogWrite(led_2,255);
        analogWrite(led_3,255);
        analogWrite(led_4,255);
       }
      
     
      /* Affichage */
      Serial.println(real_vin, 3);
      delay(1000);
    }
    void secu() // Secu fermeture automatique si coupure de courant
      
        {  
           if (digitalRead(btn_park) == LOW)
      {
        digitalWrite(relais_secu,HIGH);
      }
        
     
        }
        

     

     

    Voilà, vous savez tout.

     

    Comme je le disais plus haut, le plus gros qu’il me reste à faire est d’intégrer le code de communication série INDI avec le miens. Et là, je dois dire que ça coince un peu.

     

    Alors, au plaisir d’échanger avec vous pour trouver nos solutions.

     

     

    • J'aime 1
  2. Bon... Je me tâte encore...

    Si j'ai bien compris, le meilleurs choix actuel pour une nafabox est la Tinker Board S mais il semblerait qu'elle soit un peu dépassée en terme de puissance et de connexions USB. Parce que je n'aimerai pas me lancer dans une nafabox qui soit obsolète dans quelques mois.

    En me baladant sur le forum, j'ai découvert d'autres cartes qui sembleraient plus adaptées à nos jouets, en l'occurrence la NANOPI-M4 avec 4 ports USB3.

    Est-ce que certains d'entre vous ont déjà essayé cette carte pour faire une nafabox ?

     

    Par ailleurs, j'ai quelques petites questions concernant la mémoire interne de la nafabox.

    J'ai lu qu'il fallait installer la Système d'exploitation et les softs via une carte micro sd.

    Est-ce que le système et les softs restent sur la carte et la Tinker y accède comme un disque dur ?

    Dans ce cas, quid de la mémoire eMMC embarquée sur la Tinker ?

    A quoi sert la mémoire eMMC ? Peut on y installer le système et les softs ? Comment fait on ?

  3. Bonjour tout le monde !

     

    Je suis passionné par l’astrophoto depuis plus de 15 ans mais j’ai du faire une pause pendant 10 ans pour des raisons personnels. J’ai revendu mon STL11K mais heureusement, j’ai pu garder ma TOA-130, ma Losmandy G11, le Robofocus et l’ordi portable avec tous les softs du genre Maxim, The Sky, image plus, etc…

    J’ai ressorti du placard la TOA et je ne vous cache pas que l’idée de m’y remettre m’a plongé dans des recherches passionnantes, en l’occurrence : le quatuor Kstars, Ekos, Indi et nafabox.

     

    Je suis un Mac friendly depuis toujours mais il y a 15 ans, faire de l’astrophoto avec un Mac était impossible. J’avais donc investi dans un PC portable dans lequel était installé tous les softs nécessaire et je pilotais l’ensemble via mon Mac en VNC.

     

    Maintenant, au vu de ce quatuor, j’aimerais me faire une configuration local avec Kstars et Ekos sur mon Mac et le setup en remote via une nafabox et une configuration nomade avec tout dans la nafabox et une tablette comme interface graphique.

     

    J’ai donc plein de questions dont je n’ai pas encore trouvé de réponses claires :

     

    J’ai installé le trio Kstars, Ekos et indi sur mon Mac pour faire des essais en mode simulation mais on ne peut pas aller très loin dans les essais. J’aimerais donc installer les drivers nécessaire pour utiliser mon robofocus, ma monture Losmandy G11 et un appareil photo Olympus OM-D E-M1 directement sur le Mac avant de me lancer avec une nafabox.

     

    Pour le server Indi sur Mac, je n’ai trouvé que la solution Indigo Server.

    1/ N’y a t-il que se server indi sur Mac?

    2/ Comment puis-je installer les drivers indi robofocus, Losmandy et gphoto2 ou autre pour l’Olympus ?

    Je ne les trouve pas dans les drivers installés par défaut dans indigo server.

     

    Concernant la nafabox, que conseillez vous comme hardware ?

    J’aimerais avoir suffisamment de puissance pour tout faire tourner en local quand je suis en nomade (monture, CCD, Guider, robofocus, rotateur, Kstars, Ekos, indi server) et piloter le tout avec une tablette ou bien en mode local sur le Mac avec Kstars et Ekos et la nafabox en réseau pour la monture, CCD, Guider, robofocus et rotateur.

     

    3/ La Tinker board est-elle assez puissante ?

    4/ Il y a aussi les cartes Odroid ou les mini PC Z83. Qu’en pensez-vous ?

     

    5/ Lors du shooting, peut-on enregistrer les images sur un disque USB sur une nafabox ou doivent-elles nécessairement être enregistrées sur la carte SD ?

     

    Voilà quelques questions pour commencer mais certaines viendront par la suite.

     

    Merci à tous pour votre aide…

×
×
  • Créer...

Information importante

Nous avons placé des cookies sur votre appareil pour aider à améliorer ce site. Vous pouvez choisir d’ajuster vos paramètres de cookie, sinon nous supposerons que vous êtes d’accord pour continuer.