Aller au contenu


Photo
- - - - -

Télécommander mon robot


17 réponses à ce sujet

#1 Newbies

Newbies

    Membre passionné

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

Posté 28 février 2014 - 05:59

Bonjours à tous :),

J'ai un projet. J'ai fais il y à peut un petit robot éviteur d'obstacles contrôler par une arduino uno et un petit capteur ultrasonique et j'aimerais pouvoir le télécommander via une télécommande de modélisme 2.4Ghz que j'ai déjà? Celle la pour être précis.

Il faudrait pour cela que j'arrive à convertir les signaux PPM du récepteur pour les convertir en PWM afin de contrôler mes moteurs (si j'ai bien compris ).

J'ai donc fais quelques recherches sur le web et j'ai trouvé quelques tutoriaux notamment sur le site de sparkfun mais cela n'a pas marché pour moi. Lien du tutoriel

En effet, au lieu de m'afficher sur le moniteur série des valeur qui varies entre 1000 et 2000 en fonction de la position des sticks de ma télécommande, j'ai eu le droit à des valeurs aléatoires et souvent exorbitantes ( + de 10 000 )

Voila, donc si quelqu'un à une idée de la raison pour laquel cela n'a pas marché ou si quelqu'un à une autre solution, je suis preneur ;)

Merci d'avance ;) ( Des photos du robot arrive )

Voila le code que j'ai essayer :
/*
 RC PulseIn Joystick
 By: Nick Poole
 SparkFun Electronics
 Date: 5
 License: CC-BY SA 3.0 - Creative commons share-alike 3.0
 use this code however you'd like, just keep this license and
 attribute. Let me know if you make hugely, awesome, great changes.
 */

int ch1; // Here's where we'll keep our channel values
int ch2;
int ch3;

void setup() {

pinMode(5, INPUT); // Set our input pins as such
pinMode(6, INPUT);
pinMode(7, INPUT);

Serial.begin(9600); // Pour a bowl of Serial

}

void loop() {
  
  ch1 = pulseIn(5, HIGH, 25000); // Read the pulse width of 
  ch2 = pulseIn(6, HIGH, 25000); // each channel
  ch3 = pulseIn(7, HIGH, 25000);
  
  if(ch1>1000){Serial.println("Left Switch: Engaged");} 
  if(ch1<1000){Serial.println("Left Switch: Disengaged");}
  /* I found that Ch1 was my left switch and that it 
  floats around 900 in the off position and jumps to 
  around 1100 in the on position */

Serial.print("Right Stick X:"); // Ch3 was x-axis 
Serial.println(map(ch3, 1000,2000,-500,500)); // center at 0

Serial.print("Right Stick Y:"); // Ch2 was y-axis
Serial.println(map(ch2, 1000,2000,-500,500)); // center at 0

Serial.println(); //make some room

delay(100);// I put this here just to make the terminal 
           // window happier
}


#2 ChristianR

ChristianR

    Membre passionné

  • Membres
  • PipPipPip
  • 474 messages
  • Gender:Male
  • Location:Isère (38)
  • Interests:Arduino, programmation, électronique...

Posté 28 février 2014 - 06:40

Le code est bon.
Comment est le câblage ?
Christian

#3 Newbies

Newbies

    Membre passionné

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

Posté 28 février 2014 - 09:40

Bon j'ai pas mal avancer et résolut le problème des nombres aléatoires. Il s'agissait bien d'une erreur de connections ( apparemment mes connecteurs femelles commence à être vraiment fatigué :D )

Bref, j'ai donc mes 3 channels qui me donne respectivement une valeur entre 1000 et 2000 en fonction de la position du stick sur la télécommande.

Ce qu'il me reste donc a faire c'est a "maper" c'est valeurs entre -255 et 255 ( dans une variable nommé disons "avancer". Je pourrais ensuite dans mon code dire que, quand mon stick est pousser vers le haut ( commande pour avancer ) la valeur de "avancer" est positive donc mes deux moteur se mette en marche dans le même sens et inversement.

Pour ce qui est de la vitesse, j'ai pensez à, dans mon code, dire que : dans le cas ou "avancer" est positif, la vitesse ( nombre qui doit être compris entre 0 et 255 ) est égal a "avancer". Dans le cas ou "avancer" est négatif, la vitesse est égal à - "avancer".

Je vais essayer ca quand mon Arduino arrêtera de buger...

Cette solution vous parait viable ? Comment l'améliorer ?

Merci :)

#4 Newbies

Newbies

    Membre passionné

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

Posté 01 mars 2014 - 01:39

Ca y est, premier essais plutôt concluant. Demain je rédige le code entier et je vous tien au courant ;)

Voila le code utilisé ( Il est moche mais c'est un code test ^^ ) :
int ch2;
int motor1Pin = 4; // H-bridge leg 1 
int motor2Pin = 5; // H-bridge leg 2 
int speedPin = 3; // H-bridge enable pin 
int speed = 0;

void setup() {
  pinMode(motor1Pin, OUTPUT); 
pinMode(motor2Pin, OUTPUT); 
pinMode(speedPin, OUTPUT);
  pinMode(9, INPUT);
  Serial.begin(9600); // Pour a bowl of Serial

}

void loop() {

 int turn;

  ch2 = pulseIn(9, HIGH, 25000); // each channel
  
 turn = map(ch2,1000,2000,-500,500);
turn = constrain(turn, -255, 255);

if ( turn > 0 ){
digitalWrite(motor1Pin, LOW); // set leg 1 of the H-bridge low
digitalWrite(motor2Pin, HIGH); // set leg 2 of the H-bridge high
speed = turn;
analogWrite (speedPin, speed);
}
if ( turn < 0){
  
  digitalWrite(motor1Pin, HIGH); // set leg 1 of the H-bridge low
digitalWrite(motor2Pin, LOW);
speed = -turn;
analogWrite (speedPin, speed);
}
  Serial.print("Channel 2:");
  Serial.println(turn);


  delay(100); // I put this here just to make the terminal 
              // window happier
}


#5 Mike118

Mike118

    Staff Robot Maker

  • Administrateur
  • PipPipPipPipPip
  • 7 970 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é 01 mars 2014 - 01:42

Cette solution vous parait viable ? Comment l'améliorer ?


Oui ;)
Ne pas faire du tout ou rien mais faire du pwm (ce que tu proposes visiblement ;)) par contre tu peux aussi ne pas faire du "proportionnel" et choisir une loi un peu plus exponentielle pour te permettre d'avoir plus de maniabilité en petite vitesse et pouvoir avoir de belle accélérations ;)

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 !

 

Les réalisations de Mike118  

 

 

 


#6 Newbies

Newbies

    Membre passionné

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

Posté 01 mars 2014 - 09:04

Merci de ta réponce Mike118, j'ai fais un test avec mon code et les résultats sont pas mal du tout. J'ai réussi a contrôler mon moteur dans les deux sens et a faire varié sa vitesse dans les deux sens aussi. En revanche, le moteur ne commence à tourné qu'a partir de environ 70 ( sur 255 ) ce qui crée un petit manque de fluidité dans l'acceleration. Une idée pour paré ce problème ?

par contre tu peux aussi ne pas faire du "proportionnel" et choisir une loi un peu plus exponentielle


Je n'ai pas trop compris. Un truc du genre multiplié la valeur de "avancer" au début du mouvement du stick pour une acceleration un peut plus rapide.

#7 Mike118

Mike118

    Staff Robot Maker

  • Administrateur
  • PipPipPipPipPip
  • 7 970 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é 02 mars 2014 - 10:12

Merci de ta réponce Mike118, j'ai fais un test avec mon code et les résultats sont pas mal du tout. J'ai réussi a contrôler mon moteur dans les deux sens et a faire varié sa vitesse dans les deux sens aussi. En revanche, le moteur ne commence à tourné qu'a partir de environ 70 ( sur 255 ) ce qui crée un petit manque de fluidité dans l'acceleration. Une idée pour paré ce problème ?



Change ta fonction de "mappage" qui te permettra de mapper ta valeur entre -255 à 255 en un mappage entre -255 -70 et 70 255 ... tu décompose ta fonction linéaire en une fonction définie par 2 lois affines sur 2 intervalles différents. juste pour te donner un petit coup de pouce : " si valeur lue > 0 alors valeur à retourner en mappé est k*valeur lue + 70 ... si < 0 .... si 0 valeur mappé = 0 . Je te laisse rédiger le code ;)




Je n'ai pas trop compris. Un truc du genre multiplié la valeur de "avancer" au début du mouvement du stick pour une acceleration un peut plus rapide.


presque ça mais pas exactement, le but c'est que tu sois capable d'aller très doucement au début mais que ça puisse augmenter plus vite avec les grande valeur...
genre faire en sorte que si valeur lue = 1000 => avance = 70 si valeur lue = 1200 avancer = 75 si valeur lu = 1400 avancer = 85 si valeur lu = 1600 valeur lue = 105 si valeur lue = 1800 => avance 145 si valeur lue = 200 avance = 255 . N'hésite pas à tracer la courbe " avance " en fonction de "valeur lue" avec les points particulier que je te donne là et lisse la courbe ;) ça te permettra d'avoir un très bon contrôle à faible vitesse sans perdre de réactivité en cas d'imprévu ! =) après faut maîtriser le joystick quand même ;)

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 !

 

Les réalisations de Mike118  

 

 

 


#8 Newbies

Newbies

    Membre passionné

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

Posté 21 mars 2014 - 09:57

J'ai fais pas mal d'essais mais je n'ai pas réussi "mapper" mon signal en deux fois entre -255 à -70 et entre 70 à 255. Donc si quelqu'un peut me donner un petit coup de pouce, je suis preneur ;)

A part cela, j'ai entendu dire que sur certaine télécommande, certaines voies n'étaient pas utiliser et qu'il est donc facile d'en rajouter une ( un interrupteur par exemple ). Info ou intox ?


Juste un dernier truc, j'ai lue sur un forum anglo saxon qu'il fallait mieux, dans mon code faire ca:
turn = map(ch2,1000,2000,-500,500);
turn = constrain(turn, -255, 255);
plutôt que de faire simplement ça :
turn = map(ch2,1000,2000,-255,255);
mais je n'ai pas compris pourquoi. Pour moi cela revient au même. Qu'en pensez vous ?

Merci les gars :D

#9 ChristianR

ChristianR

    Membre passionné

  • Membres
  • PipPipPip
  • 474 messages
  • Gender:Male
  • Location:Isère (38)
  • Interests:Arduino, programmation, électronique...

Posté 21 mars 2014 - 10:06

Ce n'est pas équivalent, dans le premier cas on décale la plage de variation sur -500 +500 puis on retire les extrémités, ça revient à avoir un "point de butée" de chaque côté de la télécommande.
Christian

#10 Mike118

Mike118

    Staff Robot Maker

  • Administrateur
  • PipPipPipPipPip
  • 7 970 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é 22 mars 2014 - 01:18

Alors le plus simple tu fais une fonction de type int qui prend en paramètre ta valeur " VAL " comprise entre 1000 et 2000, et qui te retournera ta valeur entre -255 à -70 et entre 70 à 255.

Cas bateau avec une position point mort au milieu:

if VAL < (1000+490)

Return ((VAL-(1000 + 490) )/490)*(255-70) -70

else if val > ( 2000 - 490)

Return ((VAL-( 2000 - 490))/490)*(255-70) +70

else Return 0

Du coup tu as trois cas avec le cas " point mort qui tourne pas" que tu peux régler comme tu veux ici c'est si tes valeurs sont comprise entre 1490 et 1510 mais à toi de tester et de changer un peu les valeurs.

J'ai fais exprès de pas mettre directement les valeurs de façons à ce que tu puisse voir plus facilement les liens entre les chiffres ;)
là ça te fait une fonction de mappage " en dur dans le code " mais tu peux modifier le code et rajouter des paramètre dans ta fonction pour rendre ta fonction de mappage plus intelligente et moins restrictive ainsi tu pourras l'utiliser dans d'autre projets ;)

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 !

 

Les réalisations de Mike118  

 

 

 


#11 Newbies

Newbies

    Membre passionné

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

Posté 22 mars 2014 - 02:39

Je commence à mieux pigé le truc, je vais essayer ca et je revient :)

Sinon, j'ai un autre problème, j'ai changer l'alim pour une grosse baterrie 12V LIPO ( au lieux d'une 7.4V ) et depuis, le L293D chauffe énormement ( malgrés le dissipateur ). De ce fait, au bout d'une petite minute, les moteurs commences à faiblir et je doit attendre que le CI refroidisse pour repartir. Une idée ?

Sinon, des idées de fonction cool à rajouter sur un petit robot tel que le mien ?

Voila voila :)

#12 Mike118

Mike118

    Staff Robot Maker

  • Administrateur
  • PipPipPipPipPip
  • 7 970 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é 22 mars 2014 - 04:03

Pour évacuer la chaleur tu peux ajouter des dissipateur thermique, ajouter un ventilateur, et mettre un plan de masse sur ton montage au niveau du L293 pour qu'il fasse dissipateur thermique lui aussi. Pour diminuer le courant consommé tu peux diminuer le PWM de manière à ne plus roder autour des 100% mais à rester au niveau des 70% au max.
Tu peux ajouter une résistance de puissance de très faible valeur en série avec ton moteur. Ton moteur tournera poins vite, tu consommera moins de courant par contre bien dimensionner cette résistance de puissance.

Niveau fonctionnalité à ajouter sur ton robot :

Peux tu rappeler l'ensemble des capteurs présent ?
Le plus intéressant à implanter est ce qui est apprentissage et asservissement ;)

essayer de le rendre réactif à la lumière et au son ;)

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 !

 

Les réalisations de Mike118  

 

 

 


#13 Newbies

Newbies

    Membre passionné

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

Posté 23 mars 2014 - 12:02

Bon, je reviens avec quelques news, j'ai essayé et je dit bien essayer de modifier mon code avec la solution proposé par Mike118 et les résultats ne sont pas concluants ( sur le moniteur serie apparaît une valeur proche de 1500 quand le stick est au milieu et quand je le fais bouger à gauche ou à droite, la valeur reste fixe à +70 ou -70 en fonction de la direction du stick ).

Je pense donc m'être trompé dans la rédaction de ce code. En fait, c'est surtout la fonction " Return " que je ne comprend pas. De plus, le compilateur ne l'a pas reconnu en tant que fonction et j'ai donc du la remplacer par quelques choses qui me semblait équivalent ( voir code ).

Sinon pour ce qui est des fonctions de mon robot, il est pour l'instant capable d'être télécommandé ( obviously :D/> ). Il est aussi équipé d'un capteur ultrasonique ( Je vais en commander deux autres à placer sur les cotés et en dessous pour détecter les marches ). Il pourra donc, quand j'aurais récupéré ma télécommande 9 voies, passer en mode autonome depuis la télécommande via un petit bouton.
Je suis en train de réfléchir a un système qui lui permettrais de se remettre droit si il se retourne ( j'ai pensé à l'utilisation d'un petit servo pour ca ).

essayer de le rendre réactif à la lumière et au son ;)/>


Un genre de commande vocal ou quelque chose comme ca ? :)/>


Voila le code :

int VAL;
int motorD1 = 4; // H-bridge leg 1 
int motorD2 = 5; // H-bridge leg 2 
int motorG1 = 6;
int motorG2 = 7;
int speedG = 2;
int speedD = 3; // H-bridge enable pin 

void setup() {
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() 
{
VAL = pulseIn(10, HIGH, 25000);

if (VAL < (1000+490))
{
VAL =(((VAL-(1000 + 490) )/490)*(255-70) -70);
digitalWrite(motorD1, LOW);
digitalWrite(motorD2, HIGH);
digitalWrite(motorG1, LOW);
digitalWrite(motorG2, HIGH);
analogWrite (speedD, VAL);
analogWrite (speedG, VAL);
}

else if (VAL > ( 2000 - 490))
{
VAL = (((VAL-( 2000 - 490))/490)*(255-70) +70);
digitalWrite(motorD1, HIGH); 
digitalWrite(motorD2, LOW);
digitalWrite(motorG1, HIGH); 
digitalWrite(motorG2, LOW);
analogWrite (speedD, VAL);
analogWrite (speedG, VAL);
}

else 
{
}
}





#14 ChristianR

ChristianR

    Membre passionné

  • Membres
  • PipPipPip
  • 474 messages
  • Gender:Male
  • Location:Isère (38)
  • Interests:Arduino, programmation, électronique...

Posté 23 mars 2014 - 12:44

VAL =(((VAL-(1000 + 490) )/490)*(255-70) -70);

Quand tu écris ça, tu modifie directement la valeur de VAL (mesure brute du capteur), qui va donc être perturbée pour passer les tests (if) suivants, et ça va faire n'importe quoi.

Il faut séparer clairement "VAL" (= ce que mesure la capteur), et une autre variable, "vitesse" par exemple, qui sera utilisée pour piloter les moteurs.
Christian

#15 Newbies

Newbies

    Membre passionné

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

Posté 23 mars 2014 - 12:49

Un truc plus comme ca ?

void loop() 
{
int avancer;
VAL = pulseIn(10, HIGH, 25000);

if (VAL < (1000+490))
{
avancer =(((VAL-(1000 + 490) )/490)*(255-70) -70);
digitalWrite(motorD1, LOW);
digitalWrite(motorD2, HIGH);
digitalWrite(motorG1, LOW);
digitalWrite(motorG2, HIGH);
analogWrite (speedD, avancer);
analogWrite (speedG, avaancer);
}

else if (VAL > ( 2000 - 490))
{
avancer = (((VAL-( 2000 - 490))/490)*(255-70) +70);
digitalWrite(motorD1, HIGH); 
digitalWrite(motorD2, LOW);
digitalWrite(motorG1, HIGH); 
digitalWrite(motorG2, LOW);
analogWrite (speedD, avancer);
analogWrite (speedG, avancer);
}

else 
{
}
}


#16 ChristianR

ChristianR

    Membre passionné

  • Membres
  • PipPipPip
  • 474 messages
  • Gender:Male
  • Location:Isère (38)
  • Interests:Arduino, programmation, électronique...

Posté 23 mars 2014 - 01:47

analogWrite (speedD, avancer);
analogWrite (speedG, avaancer);

oui avec un "a" en moins :tatice_03:
Christian

#17 Newbies

Newbies

    Membre passionné

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

Posté 23 mars 2014 - 03:07

Je viens d'essayer modification faite et les résultats sont les mêmes :/ ( J'ai oublier de dire mais un seul des moteurs ne marche avec ce code )

Autre problème, en jouant un peut avec mon robot je me suis rendu compte qu'il y a toujours un des moteurs qui commence à tourner avant l'autre. Je me suis d'abord dit que cela devais être du au fait que chaque moteur est différent mais je me suis rendu compte après que ce n'était pas toujours le même donc ca a écarté cette piste. Une idée ?

#18 Mike118

Mike118

    Staff Robot Maker

  • Administrateur
  • PipPipPipPipPip
  • 7 970 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é 25 mars 2014 - 03:38

Je viens d'essayer modification faite et les résultats sont les mêmes :/ ( J'ai oublier de dire mais un seul des moteurs ne marche avec ce code )

Autre problème, en jouant un peut avec mon robot je me suis rendu compte qu'il y a toujours un des moteurs qui commence à tourner avant l'autre. Je me suis d'abord dit que cela devais être du au fait que chaque moteur est différent mais je me suis rendu compte après que ce n'était pas toujours le même donc ca a écarté cette piste. Une idée ?


Pour que ton code soit plus propre et pour identifier et tester plus facilement sépare ton code en 2 fonction :

la fonction avancer d'un côté.
La fonction mapper de l'autre. Avec la fonction mapper qui te retourne la valeur avancer en prenant VAL en entrée.

rajoute des retours dans la fonction mapper qui affiche les valeurs que ta arduino reçoit : VAL et la valeur que tu convertie : avancer sur ton pc ça te permettra de vérifier tes valeurs.

Et ainsi tu verras si tu es bien dans la plage nécessaire que tu as identifier au départ : -255 -70 et 70 255.

Si tu observe que tes résultat sont bien dans cette plage c'est que soit tu as une erreur dans la fonction qui la prend en paramètre : un truc un peu bête du type " avaancer " ;) mais ça on en fait tout le temps ;) Soit que tu as mal identifier ta plage de fonctionnement au départ.

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 !

 

Les réalisations de Mike118  

 

 

 




Répondre à ce sujet



  


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

0 members, 0 guests, 0 anonymous users