Partage
  • Partager sur Facebook
  • Partager sur Twitter

arduino et modelisme: comment combiner?

    23 octobre 2014 à 12:46:47

    Bonjour,

    je voudrais controler des LED rgb avec le rgb shield et l'arduino uno commander par une radiocommande de modélisme.

    Il y a un signal PWM a la sortie du récepteur si j'ai bien compris. maintenant mon problème est:

    -quel câble je dois brancher ou?

    -il me faut un programme (fini si possible) avec des explications (pour que je comprenne ce que je fait) pour transformer le signal en signal utilisable pour la programmation

    - un programme pour la sortie des LED compatible avec le rgb shield arduino en controlant avec un canal, la couleur et l'autre, l'intensité.

    Merci de votre aide, Audric

    • Partager sur Facebook
    • Partager sur Twitter
      23 octobre 2014 à 13:14:13

      Le récepteur envoie un signal au servo sur 3 fils :

      - fil noir : GND

      - fil rouge +5V

      - fil jaune : PWM


      Pour le fil noir, c'est assez simple, tu le branches sur GND de l'arduino

      Pour le fil rouge, 2 cas possibles :

      - si le récepteur est déjà alimenté (généralement par le variateur du moteur de la voiture), alors tu ne branches pas ce fil

      - si le récepteur n'est pas alimenté, tu dois brancher ce fil sur le +5V de l'arduino (ainsi, l'arduino alimentera le récepteur)

      Pour le fil jaune, tu dois brancher ça sur une pin de l'arduino (peu importe laquelle mais une pin d'interruption serait mieux).


       Concernant le signal PWM, il faut savoir que ça ressemble à ça :

      Toutes les 20ms, il y a un pulse (état HIGH) qui dure entre entre 1 et 2 ms.

      - Si le pulse dure 1 ms, le servo est à fond dans un sens

      - Si le pulse dure 1.5 ms, le servo est au neutre

      - Si le pulse dure 2 ms, le servo est à fond dans l'autre sens

      Pour le reste des valeurs, c'est simplement proportionnel.


      Bref, tu l'as probablement déjà deviné, pour connaitre la position qu'envoie la télécommande, il te faudra mesurer le temps du pulse.

      Tu peux faire ça avec une fonction bloquante du genre :

      unsigned long pulseTime(int pin) {
          while ( digitalRead(pin) == LOW );   // Attente que la pin passe à HIGH
          unsigned long t1 = micros();         // Enregistrement du temps
          while ( digitalRead(pin) == HIGH );  // Attente que la pin repasse à LOW
          unsigned long t2 = micros();         // Enregistrement du temps
          return ( t2 - t1 );                  // Retour du temps du pulse
      }

      Cette fonction devrait te retourner une valeur entre 1000 (à fond dans un sens) et 2000 (à fond dans l'autre sens).

      Par contre, j'insiste sur le fait qu'elle est bloquante : elle va bloquer l'exécution de ton programme pendant les temps d'attente qui peuvent durer jusqu'à 20ms ou une éternité sur le récepteur est HS.

      Le mieux, ce serait de connecter le PWM sur un pin d'interruption et de ce servir de cette interruption pour noter et calculer les temps sans bloquer le reste du programme.

      -
      Edité par lorrio 23 octobre 2014 à 13:17:57

      • Partager sur Facebook
      • Partager sur Twitter
        23 octobre 2014 à 13:22:21

        peut tu m'expliquer ce qu'est un pin d'interruption?

        merci pour cette réponse direct et efficace et tu est tellement actif sur le site!

        • Partager sur Facebook
        • Partager sur Twitter
          23 octobre 2014 à 15:07:07

          http://www.materiel-informatique.be/interruption.php
          • Partager sur Facebook
          • Partager sur Twitter
          projet de création domotique avec beaglebone avec nodejs
            23 octobre 2014 à 15:52:03

            Pour faire simple, une interruption (ou plutôt routine d'interruption) est une fonction qui va temporairement mettre en pause l'exécution du code de base pour exécuter un autre bout de code.

            Généralement, les interruptions sont utilisées pour être très réactif à évènement.


            Petit exemple avec le code suivant :

            int inPin = 2;
            int ledPin = 13;
            
            void setup()
            {
                Serial.begin(9600);
                pinMode(inPin, INPUT);
                pinMode(ledPin, OUTPUT);
            }
            
            void loop()
            {
                digitalWrite(ledPin, digitalRead(inPin));
                Serial.println("Hello World ! How are you World ?");
            }

            C'est plutôt basique : l'arduino recopie l'état de la pin 2 sur la pin 13 en boucle, tout en faisant un println.

            Sauf qu'un println, ça prend du temps ... à 9600b, c'est environ 1ms par caractères ...

            Du coup, si l'utilisateur change l'état de la pin 2 au début du println, le changement de la pin 13 se fera environ 30ms plus tard.


            Il est possible d'être bien plus réactif avec les interruptions :

            int irqId = 0; // IRQ#0 = Pin#2 sur arduino
            int inPin = 2;
            int ledPin = 13;
            
            void processIrq() {
                digitalWrite(ledPin, digitalRead(inPin));
            }
            
            void setup()
            {
                Serial.begin(9600);
                pinMode(inPin, INPUT);
                pinMode(ledPin, OUTPUT);
                attachInterrupt(irqId, processIrq, CHANGE);
            }
            
            void loop()
            {
                Serial.println("Hello World ! How are you World ?");
            }

            Ce code fait exactement la même chose : il écrit sur le Serial en boucle.

            Sauf que grâce au attachInterrupt, dès que la pin 2 change d'état, l'arduino met en pause ce qu'il était en train de faire pour exécuter processIrq qui va changer l'état de la pin 13.

            Avec ce système, le programme est donc extrêmement réactif au changement d'état de la pin 2.

            Par contre, le println peut être être mis en pause en pleins milieux de son action mais ce n'est pas dérangeant car il ne sera interrompu que très peu de temps étant donné que la fonction processIrq est très courte.

            • Partager sur Facebook
            • Partager sur Twitter
              23 octobre 2014 à 16:22:00

              du coup quelle code me conseil tu pour connaitre l'impulsion?

              apres return que doit-je mettre?

              comment utiliser la valeurs reçu?

              question: je n'ai pas comprise l'utilité de ce code:

              Serial.begin(9600);
              Merci beaucoup pour ton aide c'est super!
              • Partager sur Facebook
              • Partager sur Twitter
                23 octobre 2014 à 17:24:51

                Stop!

                Je ne suis pas là pour faire le code à ta place (ni les autres d'ailleurs).

                Les fonctions, les return, le Serial ... c'est la base de la programmation arduino.

                Si tu n'as pas acquis ces bases, je t'invite à relire le tutoriel : http://fr.openclassrooms.com/sciences/cours/arduino-pour-bien-commencer-en-electronique-et-en-programmation

                -
                Edité par lorrio 23 octobre 2014 à 17:25:18

                • Partager sur Facebook
                • Partager sur Twitter
                  23 octobre 2014 à 19:50:17

                  oui oui bien sur! juste des explications...

                  Comment fait on des intervalles car il y a pas vraiment de valeurs exacte ( sa varie entre 1490 et 1510 au point neutre) pour vérifier la valeurs pour l'utiliser? ( ce n'est malheureusement pas expliquer dans le cours.)

                  si je fais mon code comme ceci pour trouver les couleurs a faire:

                  SI la valeurs est entre 990 et 1010  il fait cette couleur SINON rien ne se passe (if ....else)

                  SI la valeurs est entre 1010 et 1020  il fait cette couleur SINON rien ne se passe

                  ...

                  cela va ralentir l’exécution? y a s’il une autre solution?

                  • Partager sur Facebook
                  • Partager sur Twitter
                    23 octobre 2014 à 23:45:41

                    C'est des if/else tout ça ...

                    int val = ...
                    
                    if ( val < 1000 ) {
                        val = 1000; // Correction des valeurs trop basse (1000 mini)
                    } else if ( val > 2000 ) {
                        val = 2000; // Correction des valeurs trop haute (2000 maxi)
                    } else if ( ( val >= 1490 ) && ( val <= 1510 ) ) {
                        val = 1500; // Correction des valeurs centrales (1500)
                    }

                    Avec ce code, tu t'assures que la valeur est entre 1000 et 2000 tout en ayant un beau 1500 en point milieux.


                    Évidement, faire quelques if, ça prend plus de temps que de ne rien faire.

                    Mais bon, si on par du principe que chaque ligne ralenti un peu plus l'exécution, autant ne rien coder, ce sera extrêmement rapide mais pas très efficace ...

                    L'arduino tourne quand même à 16 MHz donc il est capable de faire 16 millions d'opérations par secondes, ce n'est pas un petit if/elseif qui va le déranger.


                    Après, si c'est tout le système qui est instable, tu peux faire un lissage.

                    Par exemple :

                    val = ( 1 nouvelleVal  + 19 * ancienneVal ) / 20;

                    Avec ce code, ton système sera extrêmement lissé donc peu d'oscillation mais moins réactif.

                    Tu peux jouer sur les coefficients pour lisser plus ou moins fort.

                    Exemple de lissage un peu moins fort :

                    val = ( 3 nouvelleVal  + 7 * ancienneVal ) / 10;

                    -
                    Edité par lorrio 23 octobre 2014 à 23:52:32

                    • Partager sur Facebook
                    • Partager sur Twitter
                      24 octobre 2014 à 14:23:17

                      int val=0;
                      int t1=0;
                      int t2=0;
                      void setup()
                      {
                      }
                      void loop()
                      {
                      unsigned long pulseTime(int val); {
                          while ( digitalRead(3) == LOW );   // Attente que la pin passe à HIGH
                          unsigned long t1 = micros();         // Enregistrement du temps
                          while ( digitalRead(3) == HIGH );  // Attente que la pin repasse à LOW
                          unsigned long t2 = micros();         // Enregistrement du temps
                          int val = t2 - t1 ; 
                          return val ;   // Retour du temps du pulse
                      
                      }
                      }

                      je ne comprend pas pourquoi ce code marche pas il m'affiche ceci:


                      sketch_oct23a.ino: In function 'void loop()':
                      sketch_oct23a:15: error: return-statement with a value, in function returning 'void'

                      • Partager sur Facebook
                      • Partager sur Twitter
                        24 octobre 2014 à 14:23:42

                        sinon merci beaucoup pour toutes ton aide!

                        • Partager sur Facebook
                        • Partager sur Twitter
                          24 octobre 2014 à 18:40:23

                          Une fonction, cela s'implémente en dehors d'une autre fonction et s'appelle à l’intérieur d'une fonction.

                          Je ne comprends pas non plus pourquoi tu converti le unsigned long en int pour ensuite faire un return de unsigned long.

                          Au final, le code devrait être comme ceci :

                          int pulsePin = 55; // CHANGER CE 55 AVEC LE NUMERO DE LA PIN !!!
                          
                          void setup()
                          {
                              Serial.begin(9600);
                          }
                          
                          unsigned long pulseTime(int val); {
                              while ( digitalRead(3) == LOW );
                              unsigned long t1 = micros();
                              while ( digitalRead(3) == HIGH );
                              unsigned long t2 = micros();
                              return ( t2 - t1 );
                          }
                          
                          void loop()
                          {
                              int t = pulseTime(pulsePin);
                              Serial.print("Pulse Time = ");
                              Serial.println(t);
                          }
                          



                          • Partager sur Facebook
                          • Partager sur Twitter
                            26 octobre 2014 à 13:07:54

                            lorrio: ligne 8, le point virgule, c'est normal?

                            • Partager sur Facebook
                            • Partager sur Twitter

                            oui. non. enfin je regarde et je te dis.

                              26 octobre 2014 à 19:04:20

                              Non, il n'a rien à faire là.

                              Mais pour ma défense, je dirais que ce n'est qu'un mauvais copié/collé du code qu'il y avait 2 messages plus haut.

                              Et là, je sens venir la moral : "le copié/collé, c'est mal" :D

                              • Partager sur Facebook
                              • Partager sur Twitter
                                29 octobre 2014 à 19:31:54

                                et du coup apres ceci:

                                 
                                
                                    int t = pulseTime(pulsePin);
                                    Serial.print("Pulse Time = ");
                                    Serial.println(t);
                                

                                je met mon programme?

                                et je met if( < t=1020) {}

                                ?
                                Merci beaucoup j'avance!

                                -
                                Edité par audric2000 29 octobre 2014 à 19:32:08

                                • Partager sur Facebook
                                • Partager sur Twitter
                                  29 octobre 2014 à 19:57:33

                                  Tout dépend de ce que tu veux faire.

                                  Tu peux ajouter un if si tu en as envie

                                  Tu peux ajouter un système de lissage si besoin (cf mon message précédant)

                                  Tu peux aussi virer le Serial.print car inutile (sauf pour tester que ça marche)

                                  Tu peux ...

                                  Bref, c'est ton code, tu fais ce que tu veux !

                                  • Partager sur Facebook
                                  • Partager sur Twitter
                                    29 octobre 2014 à 20:34:36

                                    oui tout a fait et la valeur retourner est bien t ?

                                     et il faut pas mettre le compteur des microseconde dans le void loop? car void setup ne fait pas de boucle donc il vérifie seulement le signal au démarrage du programme non?

                                    -
                                    Edité par audric2000 29 octobre 2014 à 20:36:28

                                    • Partager sur Facebook
                                    • Partager sur Twitter
                                      29 octobre 2014 à 20:53:24

                                      Oui, la valeur de retour s'appelle t mais là encore, tu mets ce que tu veux.

                                      Tu peux très bien mettre :

                                      int leTempsDunPulseEnMicroSecondeQueJeCalculAvecLaFonctionPulseTimeJaiCopierCollerSurOpenClassrom = pulseTime(pulsePin);
                                      Serial.print("Pulse Time = ");
                                      Serial.println(leTempsDunPulseEnMicroSecondeQueJeCalculAvecLaFonctionPulseTimeJaiCopierCollerSurOpenClassrom);

                                      Mais faut avouer que ce n'est pas très pratique.


                                      Pour ce que est de l’emplacement, si tu regardes le code d'exemple que j'ai donné, j'appelle bien pulseTime dans le loop donc celle-ci est appelée en boucle.
                                      • Partager sur Facebook
                                      • Partager sur Twitter
                                        29 octobre 2014 à 22:06:45

                                        lorrio a écrit:

                                        Oui, la valeur de retour s'appelle t mais là encore, tu mets ce que tu veux.

                                        Tu peux très bien mettre :

                                        int leTempsDunPulseEnMicroSecondeQueJeCalculAvecLaFonctionPulseTimeJaiCopierCollerSurOpenClassrom = pulseTime(pulsePin);
                                        Serial.print("Pulse Time = ");
                                        Serial.println(leTempsDunPulseEnMicroSecondeQueJeCalculAvecLaFonctionPulseTimeJaiCopierCollerSurOpenClassrom);

                                        Mais faut avouer que ce n'est pas très pratique.


                                        mon dieu que j'ai ri! mais tu avoueras qu'avec de l'autocomplétion, ça passe tout seul, et même presque aussi bien que "t", ça. merci la technologie!

                                        -
                                        Edité par remace 29 octobre 2014 à 22:07:41

                                        • Partager sur Facebook
                                        • Partager sur Twitter

                                        oui. non. enfin je regarde et je te dis.

                                          31 octobre 2014 à 11:35:29

                                          a oui donc il faut bein que je garde Serial.print(pulse time= ")

                                          sinon merci bcp pour votre aide!

                                          • Partager sur Facebook
                                          • Partager sur Twitter

                                          arduino et modelisme: comment combiner?

                                          × 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