Aller au contenu


Photo
- - - - -

Contrôe robot par bluetooth


  • Veuillez vous connecter pour répondre
8 réponses à ce sujet

#1 Newbies

Newbies

    Membre passionné

  • Membres
  • PipPipPip
  • 487 messages
  • Gender:Male
  • Location:Paris
  • Interests:Programmation et robotique

Posté 13 juillet 2014 - 11:39

Salut les gars,

Je me suis lancé recement dans un projet qui consiste ( entre autres ) à pouvoir contrôler mon robot depuis une interface graphique sur un écran tactile de ma raspberry pi. Ayant déjà fais l'interface graphique, je me suis lancé hier dans la rédaction du code arduino de mon robot.

Le robot est muni d'un module bluetooth et recevra à terme les commande via la raspberry Pi.

En gros le robot reçoit des valeurs en bluetooth de 1 à 5 ( chaque numero correspondant à un mouvement ) et la valeur 6 correspond au passage du robot en mode "autonome" ( il est muni d'un petit capteur ulrasonique à l'avant ).

Mais voila mon problème : Quand j'envoi une valeur de 1 à 5, tout marche bien, le robot execute ce qui est écrit dans le code. En revanche quand j'envois l'ordre de passer en mode "autonome", le robot bouge n'importe comment...

C'est assez difficile à expliqué mais j'ai en fait l'impression que le robot exécute la fonction "auto_mode" pendant une fraction de seconde quand il en reçoit l'ordre puis le robot reste " bloqué" dans le mouvement qu'il a commencé durant cette fraction de seconde.

Merci d'avance ;)

#include <DistanceSRF04.h>
DistanceSRF04 Dist;
int distance;
int VAL;
int motorD1 = 6; // H-bridge leg 1 
int motorD2 = 7; // H-bridge leg 2 
int motorG1 = 4;
int motorG2 = 5;
int speedG = 2;
int speedD = 3; // H-bridge enable pin 
int vitesse = 130;

void setup() {
  Dist.begin(13,12);
  pinMode(motorD1, OUTPUT); 
  pinMode(motorD2, OUTPUT); 
  pinMode(speedD, OUTPUT);
  pinMode(motorG1, OUTPUT); 
  pinMode(motorG2, OUTPUT); 
  pinMode(speedG, OUTPUT);
  pinMode(9, INPUT);
  pinMode(10, INPUT);
  Serial.begin(9600);
}

void loop() {
   while (Serial.available() == 0); // wait for character to arrive
   char c = Serial.read();
   if(c =='1') {
    digitalWrite(motorD1, HIGH);
    digitalWrite(motorD2, LOW);
    digitalWrite(motorG1, HIGH);
    digitalWrite(motorG2, LOW);
    analogWrite(speedD, vitesse);
    analogWrite(speedG, vitesse);
   }
   if(c == '2'){
    digitalWrite(motorD1, LOW);
    digitalWrite(motorD2, HIGH);
    digitalWrite(motorG1, LOW);
    digitalWrite(motorG2, HIGH);
    analogWrite(speedD, vitesse);
    analogWrite(speedG, vitesse);
   }
   
   if(c == '3'){
    digitalWrite(motorD1, LOW);
    digitalWrite(motorD2, HIGH);
    digitalWrite(motorG1, HIGH);
    digitalWrite(motorG2, LOW);
    analogWrite(speedD, vitesse);
    analogWrite(speedG, vitesse);
   }
   
   if(c == '4'){
    digitalWrite(motorD1, HIGH);
    digitalWrite(motorD2, LOW);
    digitalWrite(motorG1, LOW);
    digitalWrite(motorG2, HIGH);
    analogWrite(speedD, vitesse);
    analogWrite(speedG, vitesse);
   }
   
   if(c == '5'){
    digitalWrite(motorD1, LOW);
    digitalWrite(motorD2, LOW);
    digitalWrite(motorG1, LOW);
    digitalWrite(motorG2, LOW);
    analogWrite(speedD, vitesse);
    analogWrite(speedG, vitesse);
   }
   
   if(c == '6'){
     auto_mode();
   }
   delay(500);
}

void auto_mode(){
int distance = Dist.getDistanceCentimeter();
Serial.print("\nDistance in centimers: ");
Serial.print(distance); 
delay(100); //make it readable
// check the average distance and move accordingly
if (distance <= 10){
    digitalWrite(motorD1, LOW);
    digitalWrite(motorD2, HIGH);
    digitalWrite(motorG1, LOW);
    digitalWrite(motorG2, HIGH);
    analogWrite(speedD, vitesse);
    analogWrite(speedG, vitesse);
}
if (distance < 25 && distance > 10) {
    digitalWrite(motorD1, HIGH);
    digitalWrite(motorD2, LOW);
    digitalWrite(motorG1, LOW);
    digitalWrite(motorG2, HIGH);
    analogWrite(speedD, vitesse);
    analogWrite(speedG, vitesse);
}
if (distance > 25) {
    digitalWrite(motorD1, HIGH);
    digitalWrite(motorD2, LOW);
    digitalWrite(motorG1, HIGH);
    digitalWrite(motorG2, LOW);
    analogWrite(speedD, vitesse);
    analogWrite(speedG, vitesse);
}
}
  




#2 Newbies

Newbies

    Membre passionné

  • Membres
  • PipPipPip
  • 487 messages
  • Gender:Male
  • Location:Paris
  • Interests:Programmation et robotique

Posté 13 juillet 2014 - 03:17

Ok je viens d'essayer en rajoutant une boucle while( c == '6'){ la fonction auto tourne en boucle }. Ca marche plutot bien sauf que maintenant, une fois la fonction auto lancé, je peut plus en sortir pour reprendre le contrôle manuel...

Des idées ?
Le code tel qu'il est maintenant :

#include <DistanceSRF04.h>
DistanceSRF04 Dist;
int distance;
int VAL;
int motorD1 = 6; // H-bridge leg 1 
int motorD2 = 7; // H-bridge leg 2 
int motorG1 = 4;
int motorG2 = 5;
int speedG = 2;
int speedD = 3; // H-bridge enable pin 
int vitesse = 130;

void setup() {
  Dist.begin(13,12);
  pinMode(motorD1, OUTPUT); 
  pinMode(motorD2, OUTPUT); 
  pinMode(speedD, OUTPUT);
  pinMode(motorG1, OUTPUT); 
  pinMode(motorG2, OUTPUT); 
  pinMode(speedG, OUTPUT);
  pinMode(9, INPUT);
  pinMode(10, INPUT);
  Serial.begin(9600);
}

void loop() {
   while (Serial.available() == 0); // On attend l'arrivé d'ordre par bluetooth
   char c = Serial.read();
   if(c =='1') { // Si on recoit l'odre 1
    digitalWrite(motorD1, HIGH);  // On avance
    digitalWrite(motorD2, LOW);
    digitalWrite(motorG1, HIGH);
    digitalWrite(motorG2, LOW);
    analogWrite(speedD, vitesse);
    analogWrite(speedG, vitesse);
   }
   if(c == '2'){ // Si on recoit l'ordre 2
    digitalWrite(motorD1, LOW);  // On recule
    digitalWrite(motorD2, HIGH);
    digitalWrite(motorG1, LOW);
    digitalWrite(motorG2, HIGH);
    analogWrite(speedD, vitesse);
    analogWrite(speedG, vitesse);
   }
   
   if(c == '3'){ // si on recoit l'ordre 3
    digitalWrite(motorD1, LOW);  // On tourne a gauche
    digitalWrite(motorD2, HIGH);
    digitalWrite(motorG1, HIGH);
    digitalWrite(motorG2, LOW);
    analogWrite(speedD, vitesse);
    analogWrite(speedG, vitesse);
   }
   
   if(c == '4'){  // Si on recoit l'ordre 4
    digitalWrite(motorD1, HIGH);  // On tourne a droite
    digitalWrite(motorD2, LOW);
    digitalWrite(motorG1, LOW);
    digitalWrite(motorG2, HIGH);
    analogWrite(speedD, vitesse);
    analogWrite(speedG, vitesse);
   }
   
   if(c == '5'){ // Si on recoit l'ordre 5
    digitalWrite(motorD1, LOW); // On stop
    digitalWrite(motorD2, LOW);
    digitalWrite(motorG1, LOW);
    digitalWrite(motorG2, LOW);
    analogWrite(speedD, vitesse);
    analogWrite(speedG, vitesse);
   }
   
  while(c == '6'){  // Si on recoit l'ordre 6
    int distance = Dist.getDistanceCentimeter(); // On passe en mode "autonome"
    if (distance <= 10){
        digitalWrite(motorD1, LOW);
        digitalWrite(motorD2, HIGH);
        digitalWrite(motorG1, LOW);
        digitalWrite(motorG2, HIGH);
        analogWrite(speedD, vitesse);
        analogWrite(speedG, vitesse);
    }
    if (distance < 25 && distance > 10) {
        digitalWrite(motorD1, HIGH);
        digitalWrite(motorD2, LOW);
        digitalWrite(motorG1, LOW);
        digitalWrite(motorG2, HIGH);
        analogWrite(speedD, vitesse);
        analogWrite(speedG, vitesse);
    }
    if (distance > 25) {
        digitalWrite(motorD1, HIGH);
        digitalWrite(motorD2, LOW);
        digitalWrite(motorG1, HIGH);
        digitalWrite(motorG2, LOW);
        analogWrite(speedD, vitesse);
        analogWrite(speedG, vitesse);
    }
    }
    
       Serial.println(c);
       delay(500);
    }


#3 Mike118

Mike118

    Staff Robot Maker

  • Administrateur
  • PipPipPipPipPip
  • 9 934 messages
  • Gender:Male
  • Location:Anglet
  • Interests:Robotique, Entrepreneuriat, Innovation, Programmation, Résolution de problème, Recherche de solutions, Mécanique, Electronique, Créer, Concevoir

Posté 13 juillet 2014 - 09:35

Et si tu essais un truc comme ça :

#include <DistanceSRF04.h>
DistanceSRF04 Dist;
int distance;
int VAL;
int motorD1 = 6; // H-bridge leg 1 
int motorD2 = 7; // H-bridge leg 2 
int motorG1 = 4;
int motorG2 = 5;
int speedG = 2;
int speedD = 3; // H-bridge enable pin 
int vitesse = 130;
int delais =10; // delais avant de reboucler le mode auto
int nbboucle=100; // nombre de fois où on reboucle
int i =0 ; // variable de comptage du nombre de boucle

void setup() {
  Dist.begin(13,12);
  pinMode(motorD1, OUTPUT); 
  pinMode(motorD2, OUTPUT); 
  pinMode(speedD, OUTPUT);
  pinMode(motorG1, OUTPUT); 
  pinMode(motorG2, OUTPUT); 
  pinMode(speedG, OUTPUT);
  pinMode(9, INPUT);
  pinMode(10, INPUT);
  Serial.begin(9600);
}

void loop() 
{
    while (Serial.available() == 0); // On attend l'arrivé d'ordre par bluetooth
    char c = Serial.read();
    if(c =='1') 
    { // Si on recoit l'odre 1
         digitalWrite(motorD1, HIGH);  // On avance
         digitalWrite(motorD2, LOW);
         digitalWrite(motorG1, HIGH);
         digitalWrite(motorG2, LOW);
         analogWrite(speedD, vitesse);
         analogWrite(speedG, vitesse);
    }
   if(c == '2')
   { // Si on recoit l'ordre 2
         digitalWrite(motorD1, LOW);  // On recule
         digitalWrite(motorD2, HIGH);
         digitalWrite(motorG1, LOW);
         digitalWrite(motorG2, HIGH);
         analogWrite(speedD, vitesse);
         analogWrite(speedG, vitesse);
    }
   
   if(c == '3')
   { // si on recoit l'ordre 3
        digitalWrite(motorD1, LOW);  // On tourne a gauche
        digitalWrite(motorD2, HIGH);
        digitalWrite(motorG1, HIGH);
        digitalWrite(motorG2, LOW);
        analogWrite(speedD, vitesse);
        analogWrite(speedG, vitesse);
   }
   
   if(c == '4')
   {  // Si on recoit l'ordre 4
        digitalWrite(motorD1, HIGH);  // On tourne a droite
        digitalWrite(motorD2, LOW);
        digitalWrite(motorG1, LOW);
        digitalWrite(motorG2, HIGH);
        analogWrite(speedD, vitesse);
        analogWrite(speedG, vitesse);
   }
   
   if(c == '5')
   { // Si on recoit l'ordre 5
       digitalWrite(motorD1, LOW); // On stop
       digitalWrite(motorD2, LOW);
       digitalWrite(motorG1, LOW);
       digitalWrite(motorG2, LOW);
       analogWrite(speedD, vitesse);
       analogWrite(speedG, vitesse);
   }
   
   if(c == '6') // Si on recoit l'ordre 6
   {  
      for ( i=0;i<nbboucle;i++)
      {
          int distance = Dist.getDistanceCentimeter(); // On passe en mode "autonome"
          if (distance <= 10)
          {
              digitalWrite(motorD1, LOW);
              digitalWrite(motorD2, HIGH);
              digitalWrite(motorG1, LOW);
              digitalWrite(motorG2, HIGH);
              analogWrite(speedD, vitesse);
              analogWrite(speedG, vitesse);
           }
           if (distance < 25 && distance > 10) 
           {
              digitalWrite(motorD1, HIGH);
              digitalWrite(motorD2, LOW);
              digitalWrite(motorG1, LOW);
              digitalWrite(motorG2, HIGH);
              analogWrite(speedD, vitesse);
              analogWrite(speedG, vitesse);
            }
            if (distance > 25)
            {
              digitalWrite(motorD1, HIGH);
              digitalWrite(motorD2, LOW);
              digitalWrite(motorG1, HIGH);
              digitalWrite(motorG2, LOW);
              analogWrite(speedD, vitesse);
              analogWrite(speedG, vitesse);
             }
             delay(delais);
        }
     }
     Serial.println(c);
     delay(500);
    
  }

ça donne quoi ?

à toi d'ajuster les les variables nbboucles et delais ! ( ou de les remplacer par des valeurs fixes ! )

Si mon commentaire vous a plus laissez nous un avis  !  :thank_you:

Nouveau sur Robot Maker ? 

Jetez un oeil aux blogs, aux tutoriels, aux ouvrages, au robotscope  aux articles,  à la boutique  et aux différents services disponible !
En attendant qu'une bibliothèque de fichiers 3D soit mise en place n'hésitez pas à demander si vous avez besoin du fichier 3D d'un des produits de la boutique... On l'a peut être ! 
Si vous souhaitez un robot pilotable par internet n'hésitez pas à visiter www.vigibot.com et à lire le sous forum dédié à vigibot!

 

Les réalisations de Mike118  

 

 

 


#4 Newbies

Newbies

    Membre passionné

  • Membres
  • PipPipPip
  • 487 messages
  • Gender:Male
  • Location:Paris
  • Interests:Programmation et robotique

Posté 13 juillet 2014 - 11:50

Je viens d'essayer, quand le robot passe en mode "autonome", il se met à faire n'importe quoi ( même en bidouillant les delays et la valeur de nboucle ) :/ En revanche, cette fois je peut arreté la fonction en envoyant un nouvel ordre :)

Mais je ne comprend surtout pas pourquoi ca ne marche pas avec mon second code :(

#5 Mike118

Mike118

    Staff Robot Maker

  • Administrateur
  • PipPipPipPipPip
  • 9 934 messages
  • Gender:Male
  • Location:Anglet
  • Interests:Robotique, Entrepreneuriat, Innovation, Programmation, Résolution de problème, Recherche de solutions, Mécanique, Electronique, Créer, Concevoir

Posté 14 juillet 2014 - 01:49

Je viens d'essayer, quand le robot passe en mode "autonome", il se met à faire n'importe quoi ( même en bidouillant les delays et la valeur de nboucle ) :/ En revanche, cette fois je peut arreté la fonction en envoyant un nouvel ordre :)/>

Mais je ne comprend surtout pas pourquoi ca ne marche pas avec mon second code :(/>


dans ton second code tu restes bloqué en boucle dans " while (c==6) " Du coup tu ne peux pas en sortir pour changer la valeur de C ...

Concernant la partie "il se met à faire n'importe quoi " , je dirais qu'il se met uniquement à faire ce que tu lui dis de faire ...
après tu peux supprimer le delais et mettre un nnboucle plus petit ... Tu peux aussi ajouter un " c =5 " une fois que le for est fini pour garantir le fait que si pour une raison x ou y le robot programme saute le " while (Serial.available() == 0) " le robot restera immobile ;)

à toi de tester ton mode auto plus en détail pour voir ce qui cloche dedans.

Enfin avec la solution que je te propose ça permet de lancer la boucle mode auto un certain nombre de fois mais ne te permet pas de la coupée à nimporte quelle moment. Par contre si ton but c'est de la couper quand tu veux, le plus propre pour cela serait de le faire via des interruptions.

Si mon commentaire vous a plus laissez nous un avis  !  :thank_you:

Nouveau sur Robot Maker ? 

Jetez un oeil aux blogs, aux tutoriels, aux ouvrages, au robotscope  aux articles,  à la boutique  et aux différents services disponible !
En attendant qu'une bibliothèque de fichiers 3D soit mise en place n'hésitez pas à demander si vous avez besoin du fichier 3D d'un des produits de la boutique... On l'a peut être ! 
Si vous souhaitez un robot pilotable par internet n'hésitez pas à visiter www.vigibot.com et à lire le sous forum dédié à vigibot!

 

Les réalisations de Mike118  

 

 

 


#6 Newbies

Newbies

    Membre passionné

  • Membres
  • PipPipPip
  • 487 messages
  • Gender:Male
  • Location:Paris
  • Interests:Programmation et robotique

Posté 14 juillet 2014 - 12:18

dans ton second code tu restes bloqué en boucle dans " while (c==6) " Du coup tu ne peux pas en sortir pour changer la valeur de C ...


Ah ok, je croyais que si la valeur de c changeait, la condition de la boucle while était brisée et on en sortait donc ;)

Enfin avec la solution que je te propose ça permet de lancer la boucle mode auto un certain nombre de fois mais ne te permet pas de la coupée à nimporte quelle moment. Par contre si ton but c'est de la couper quand tu veux, le plus propre pour cela serait de le faire via des interruptions.


Mon but est effectivement que le mode auto ne s’arrête qu'à l'envoi d'un nouvel ordre. Je me suis donc un peut renseigner sur la fonction interrupt()mais ne vit pas comment l'utiliser dans mon cas :/

#7 Mike118

Mike118

    Staff Robot Maker

  • Administrateur
  • PipPipPipPipPip
  • 9 934 messages
  • Gender:Male
  • Location:Anglet
  • Interests:Robotique, Entrepreneuriat, Innovation, Programmation, Résolution de problème, Recherche de solutions, Mécanique, Electronique, Créer, Concevoir

Posté 14 juillet 2014 - 06:36

Ah ok, je croyais que si la valeur de c changeait, la condition de la boucle while était brisée et on en sortait donc ;)/>


Le truc c'est que pour que la valeur change il faut être sortis de la boucle ... du coup c'est l'histoire du serpent qui se mord la queue

Mon but est effectivement que le mode auto ne s’arrête qu'à l'envoi d'un nouvel ordre. Je me suis donc un peut renseigner sur la fonction interrupt()mais ne vit pas comment l'utiliser dans mon cas :/


Dans ce cas il faut que tu remette ta boucle while à la place du for comme ce que tu avais fait avant mais tu dois changer la condition de sortie de ta boucle while : au lieu de mettre while ( c==6 ) il faudrait mettre un truc genre " while ( auto ) " avec auto étant une variable qui peut être modifié dans tes interruptions . Le but des boucle d'interruptions c'est qu'à intervalle de temps régulier tu ailles dedans quoi que fasse le reste de ton programme et ensuite de reprendre ton programme là où il en était comme si de rien était mais avec les modification effectué dans la boucle d'interruption prise en compte.

Plus d'explications ou c'est assez claire comme ça ?

Si mon commentaire vous a plus laissez nous un avis  !  :thank_you:

Nouveau sur Robot Maker ? 

Jetez un oeil aux blogs, aux tutoriels, aux ouvrages, au robotscope  aux articles,  à la boutique  et aux différents services disponible !
En attendant qu'une bibliothèque de fichiers 3D soit mise en place n'hésitez pas à demander si vous avez besoin du fichier 3D d'un des produits de la boutique... On l'a peut être ! 
Si vous souhaitez un robot pilotable par internet n'hésitez pas à visiter www.vigibot.com et à lire le sous forum dédié à vigibot!

 

Les réalisations de Mike118  

 

 

 


#8 Newbies

Newbies

    Membre passionné

  • Membres
  • PipPipPip
  • 487 messages
  • Gender:Male
  • Location:Paris
  • Interests:Programmation et robotique

Posté 15 juillet 2014 - 03:27

Plus d'explications ou c'est assez claire comme ça ?


Euh... Oui, c'est encore un peut trouble dans mon esprit :unsure: Doit t'on utiliser la fonction Interrupt() pour ca ?

#9 Newbies

Newbies

    Membre passionné

  • Membres
  • PipPipPip
  • 487 messages
  • Gender:Male
  • Location:Paris
  • Interests:Programmation et robotique

Posté 15 juillet 2014 - 03:41

En fait, tout les exemples de code que je trouves utilisant les interruptions utilise des changement d'états provenant de l'exterieur et neccesite donc un "numéro de pin" comme support à AttachIterrupt() :/

Sinon je viens d'essayer d'utiliser break; pour sortir de la boucle while() mais encore une fois, je reste bloqué dedans...




0 utilisateur(s) li(sen)t ce sujet

0 members, 0 guests, 0 anonymous users