Aller au contenu


Contenu le plus aimé


Réseaux de neurones & algorithme génétique d'apprentissage

Publié Harry le 24 mai 2011 - 08:26 in Intelligence Artificielle

Après de longs mois d'inactivité, je suis de retour avec ce petit tutoriel qui vous donnera - je l'espère - le goût du développement d'intelligence(s) artificielle(s). L'objectif de ce tutoriel est de vous expliquer le fonctionnement d'un "cerveau" pour que vous puissiez en développer un pour votre robot, de telle sorte qu'il apprenne de lui-même à éviter les obstacles... Vous avez bien lu : le robot que je vous propose d'étudier pourra éviter les obstacles après avoir appris à le faire, tout seul !

Bref, passons directement dans le vif du sujet !

Sommaire :

1. Constitution du robot
2. Établissement manuel du réseau de neurone
3. Algorithme génétique d'apprentissage

Constitution du robot

Partie "hardware"

Voici les principaux composants de notre robot
 
 
  •  
  • en vert : 2 moteurs à courant continu
  • en jaune, orange et rouge : 6 capteurs de distance
  • non représenté : un micro-rupteur (= interrupteur) qui se déclenche si le bord du robot touche un obstacle.

Image IPB

Je ne détaille pas l'alimentation, l'électronique employée, etc... l'objectif de ce tutoriel étant de comprendre le fonctionnement des réseaux de neurones : ce tutoriel sera donc applicable à n'importe quel robot ayant cette configuration et pouvant être programmé à vos souhaits.

Partie "software" : le réseau de neurone proprement dit

Un réseau de neurone relie les entrées d'un système à ses sorties.

Image IPBLes entrées et les sorties sont appelés des nœuds. Le "lien" qui relie deux nœuds est appelé un axiome. Ceci n'est donné qu'à titre informatif, il n'est pas indispensable de retenir ce vocabulaire pour comprendre ce tutoriel.

Voici un schéma détaillant la notation que l'on va utiliser pour repérer les capteurs et les moteurs :

Image IPB

J'en ai profité pour dessiner notre premier réseau de neurone. Pour simplifier la compréhension, on ne va s'intéresser qu'au moteur gauche de notre robot.

On distingue clairement sur ce schéma - grâce aux traits en gras - que toutes les entrées (les Ci) sont reliées au moteur (M1). Sur chaque lien, on peut voir d'autres notations : P11, P21, P31, P41, P51 et P61 (ou encore les Pik - P indice i indice k - avec i allant de 1 à 6, et k valant 1 puisqu'on n'étudie que le moteur gauche) C'est ce qu'on appelle les poids. Grâce à ces notations, voici l'équation du réseau de neurone que l'on vient de créer - pour le moteur gauche uniquement :

Image IPB

Les valeurs des capteurs sont données par les capteurs eux-même, en fonction de la distance qui les séparent d'un obstacle extérieur. Les valeurs des moteurs sont contrôlées par le logiciel qui est sur votre robot... ici, il sera contrôlé grâce au réseau de neurone, dont on a écrit l'équation juste au-dessus. Il nous manque donc plus qu'à connaître les valeurs des poids (Pik)... c'est justement ces poids que le robot doit apprendre à déterminer, de lui-même ! Pour comprendre comment lui faire faire cela, nous allons d'abord essayer de voir quelles valeurs pourraient fonctionner pour nos Pik, pour que notre robot puisse éviter les obstacles...

Établissement manuel du réseau de neurone

Comportement désiré

Pour que tout le monde suive, on va mettre à plat le comportement du robot. Le robot doit toujours avancer, sauf dans les cas suivant :

  •  
  • si un obstacle se présente sur la gauche, le robot doit tourner à droite (c'est à dire que le moteur gauche doit "avancer" - tandis que le moteur droit doit "reculer")
  • si un obstacle se présente sur la droite, le robot doit tourner à gauche (c'est à dire que le moteur gauche doit "reculer" - tandis que le moteur droit doit "avancer")
Et si un obstacle se présente au centre ? Ceci est un faux problème car les capteurs ne donneront jamais constamment la même valeur à droite et à gauche : on rentrera donc systématiquement dans un des deux cas précédents. Si vraiment cela devait arriver, je suis sûr que vous saurez palier à ce problème une fois que vous aurez compris comment faire un réseau de neurone. Mais pour l'instant, on va simplifier les choses : aucun obstacle ne se présentera pic poil au milieu, et le robot ne PEUT PAS se planter (admettez-le, ou remettez ce problème à plus tard... ne restez pas bloqué à cause de ce cas).

Nous allons donc traiter ces deux cas, l'un après l'autre, ce qui nous permettra de donner des valeurs fonctionnelles pour P11, P21 et P31 d'une part, puis P41, P51 et P61 d'autre part.

Si un obstacle se présente sur la gauche...

... dans ce cas, les capteurs de gauche, C1, C2 et C3 auront une valeur importante (les capteurs de distance renvoie une valeur d'autant plus importante que l'obstacle est proche). Or, on voulait que si un obstacle se présente à gauche, le moteur gauche devait avancer... pour cela, on doit lui envoyer une valeur positive. Je rappelle notre équation du RdN (réseau de neurone) :

Image IPB

Vu ce que l'on cherche à faire, le plus simple pour répondre à cette demande serait - en premier lieu - d'imposer P11 = 1, P21 = 1 et P31 = 1 (ce sont des valeurs possibles). Notre équation devient donc :

Image IPB

Image IPBOui, mais attends, tu en fais quoi des valeurs des 3 autres poids ?

Je ne les ai pas oublié, soyez patients !

Si un obstacle se présente sur la droite...

... alors là, à l'inverse, ce sont les capteurs C4, C5 et C6 qui auront une valeur importante. Or, on voulait que si un obstacle se présente à droite, notre robot doit tourner à gauche, et pour cela, le moteur gauche doit "reculer"... pour cela, il faut lui envoyer une valeur négative. Vous l'aurez compris, on va imposer P41 = -1, P51 = -1 et P61 = -1. Ainsi :

Image IPB

Pour ceux qui auraient des doutes...

Image IPBAttends c'est n'importe quoi ce que tu fais là ! Tu détermines les valeurs de la moitié des poids pour un cas, et l'autre moitié avec un autre cas ! Ca ne pourra jamais marcher... !!!

Je conviens que la méthode employée n'est pas très catholique : cependant, cela fonctionne ! Vérifiez par vous-même... si un obstacle arrive à gauche, C1, C2 et C3 auront une valeur importante, et C4, C5 et C6 auront une valeur faible... d'autant plus faible que l'objet est loin, voire nulle si l'objet est à l'infini... on peut donc considérer que dans le cas où un obstacle arrive sur la gauche, seules les valeurs de C1, C2 et C3 sont pris en compte... et regardez l'équation dans ce cas là :

Image IPB !!! notre moteur gauche va donc "avancer" !

Et ça marche aussi si un obstacle arrive à droite : C1, C2 et C3 sont faibles cette fois-ci, voire négligeable... alors que C4, C5 et C6 auront une valeur importante, et dans ce cas, l'équation devient :

Image IPB !!! notre moteur gauche va donc "reculer" !

Et le moteur droit alors ?

Cela pourrait faire un très bon exercice... je vous laisse chercher (il suffit de suivre exactement le même schéma que précédemment), mais voici la réponse :

Image IPB

Algorithme génétique d'apprentissage

Introduction

Nous avons créé un réseau de neurone, et nous avons trouvé des valeurs possibles pour les poids de ce réseau. Je vous avais pourtant dit au début que votre robot allait apprendre à le faire de lui-même ! Vous aurais-je menti ? Non, mais je voulais que vous ayez bien compris la constitution d'un réseau de neurone et son fonctionnement. Maintenant que cela est fait, nous allons imaginer que nous ne connaissons pas les valeurs de ces poids, et nous allons faire faire ce dur labeur à notre robot.

Image IPBAttends, c'est complètement idiot de faire ça ! On connaît des valeurs qui marchent, pourquoi ne pas lui donner directement les valeurs et tester ?

Vous avez raison : vous pouvez tester ces valeurs sur votre propre robot. Et ça marchera. Très bien même. Et puis vous aurez deux possibilités :
 
  •  
  • vous êtes content de ce que vous avez appris et cela vous suffit : dans ce cas, merci d'avoir lu ce tutoriel et au revoir ! Bonne journée !
  • vous avez envie d'en apprendre plus, en particulier sur l'algorithme génétique d'apprentissage, et vous avez même envie que l'apprentissage se fasse le plus simplement possible : dans ce cas, je vous invite à lire la suite
Et pour ceux qui trouvent que c'est dommage de rester sur le même exemple - déjà résolu qui plus est - pour apprendre le fonctionnement de l'algorithme génétique d'apprentissage, je répondrai ceci : c'est un choix que j'ai fait en toute connaissance de cause. En effet, si on reste sur un exemple déjà bien connu, les termes que je vais employer auront un aspect "concret", tandis que si je pars sur un autre exemple, ce sera un peu plus subjectifs, et certains risquent de ne pas suivre.

Je vous invite donc à rentrer dans le vif du sujet de cette grosse bête qui paraît si méchante... et qui ne l'est pas du tout en fait o_O

Algorithme d'apprentissage simple

Le principe de l'apprentissage simple est le suivant : on choisit des valeurs aléatoires pour les poids, puis le robot le teste de lui-même. Pour qu'il puisse les tester, on va lui dire d'utiliser un capteur qu'on n'a pas encore utilisé, mais que j'ai indiqué au tout départ, souvenez vous :
Citation de : Harry
Citation

Voici les principaux composants de notre robot
  •  
  • en vert : 2 moteurs à courant continu
  • en jaune, orange et rouge : 6 capteurs de distance
  • non représenté : un micro-rupteur (= interrupteur) qui se déclenche si le bord du robot touche un obstacle.
Nous allons donc demander à notre robot d'utiliser ce micro-rupteur : si celui-ci se déclenche, cela voulait donc dire que les valeurs de nos poids (choisis aléatoirement) étaient "mauvais". Il faut donc faire un autre "jet" (c'est à dire qu'on va choisir d'autres valeurs aléatoires pour les poids). Et ainsi de suite... jusqu'à ce que le robot évite tous les obstacles !

Image IPBAttends... mais ça peut prendre un temps fou ça !

Oui, mais observez un bébé qui apprend à attraper un verre : un coup, sa main passe au dessus, le coup d'après sa main se cogne contre la table ("ouille" :mort: "ouinnnn" Image IPB ), le coup d'après il envoie le verre sur la lune (là, c'est le papa qui n'est pas content :colere: -> fessée)... puis après en avoir cassé plusieurs, il arrive enfin à l'attraper ! Tout cela prend du temps ! Si vous voulez, vous pouvez créer un "simulateur de robot" qui pourra vous permettre de tester votre algorithme pour obtenir la valeur des poids plus rapidement ^^

Algorithme génétique d'apprentissage

On a failli oublié la partie "génétique" dans tout ça dites donc... meuh non, ne vous inquiétez pas ! Image IPB

Cependant, la partie "génétique" est tellement simple que j'ai honte de la détailler... faisons le tout de même. Dans la partie précédente, on a effectué une série de jets sur les poids.

Ce que l'on va faire maintenant, c'est d'enregistrer une dizaine de jet, et, pour chaque jet, lancer notre robot dans une arène pendant disons une dizaine de minute. Puis on regarde les résultats obtenus pour le nombre de fois où le robot s'est cogné pour chaque jet. La "sélection génétique" de cette "génération" va consister à sélectionner le jet qui aura obtenu le meilleur score, c'est à dire le jet pour lequel le robot s'est cogné le moins souvent.

Puis on passe à la génération suivante : cette génération est issu du jet "sélectionné". Je veux dire par là qu'au lieu de faire des choix aléatoires pour tous les poids à chaque nouveau jet, on va en conserver 1 (d'une manière aléatoire, mais on en conserve au moins 1 du jet "parent" pour chaque nouveau jet). Puis on re-fait nos tests, et on refait une sélection du meilleur.

A la génération suivante, on va conserver cette fois-ci 2 valeurs de poids...

A la génération suivante, on va en conserver 3...

et ainsi de suite...

Petit à petit, vous verrez que les enfants issus des "meilleures" sélections auront les mêmes comportements que ceux de leurs parents, mais améliorés (les parents ont transmis leur "savoir" à leurs enfants qui à leur tours font leur vie et enseignent ce qu'ils ont appris à leurs enfants).

Je trouve ce concept passionnant et pourtant d'une facilité déconcertante une fois qu'on a compris de quoi il s'agissait, n'est-ce pas ?

N'hésitez pas à poser vos questions sur le forum !


Montage d'un Rocbot.

Publié ashira le 13 novembre 2017 - 08:50 in Robot complet

Aide au montage du Rocbot.

 

rocbot3.gif  rocbot1.gif  rocbot2.gif

 

Ce tutoriel vous aidera à construire votre rocbot en illustrant un exemple de montage pas à pas.
Le montage se fait en 2 étapes :
 

  • Montage des éléments électroniques et mécaniques.
  • Programmation du robot.

 
Pour le montage j'ai utilisé :
 

  • Un fer à souder et de l’étain.
  • Une petite pince à bec.
  • Une petite pince coupante.
  • Un tournevis cruciforme.

 Fichier 3D:
Fichier attaché  Rocbot_stl_1.00.zip   350,3 Ko   410 Nombre de téléchargements

Fichier attaché  Rocbot_stl_1.01.zip   426,62 Ko   269 Nombre de téléchargements
 
Programme:
Fichier attaché  Rocbot_BT.zip   499 octets   271 Nombre de téléchargements
 
Première étape : Montage des éléments électroniques et mécaniques.
 
Je commence par souder une arduino pro mini sur le pcb avec des broches. J'utilise la pince à bec pour enfoncer les broches comme sur la photo.
 
1.jpg
 
Le but est de souder ces connecteurs sur l'arduino par le dessus et de garder une longueur suffisante pour connecter autre chose directement sur l'arduino.
 
Je soude les connecteurs 3 par 3 pour pouvoir enlever facilement le plastique noir.
 
2.jpg 3.jpg
 
4.jpg
 
Ensuite je soude l'arduino pro mini sur le pcb.
 
5.jpg
 
Soudure des 3 connecteurs qui serviront à brancher les servomoteurs et du petit condensateur (il n'y a pas de polarisation sur ce condensateur).
 
6.jpg
 
Soudure des connecteurs femelles. 
 
7.jpg 8.jpg
 
9.jpg 10.jpg
 
Maintenant je soude l'autre pcb, en commençant par le chargeur de batterie.
 
11.jpg
 
Soudure de l'interrupteur et des connecteurs mâles.
 
12.jpg
 
13.jpg 14.jpg
 
Soudure de la batterie. 
 
15.jpg 16.jpg
 
17.jpg
 
J'ai fixé la batterie avec un morceau de scotch double face, mais ce n'est pas obligatoire. La partie montage électronique est terminée, je vais monter tout ça sur le châssis du robot .
 
Je commence par visser les 2 supports en nylon.
 
18.jpg
 
Ensuite je fixe le premier pcb avec 2 autres supports en nylon, plus grands que les premiers.
 
19.jpg
 
J'ajoute le 2eme pcb et je le fixe avec 2 visses en nylon. Entre temps on remarque que j'ai ajouté un connecteur femelle sur le premier pcb.
 
20.jpg
 
Je monte les roulements avec une vis et une rondelle montées comme sur la photo.
 
21.jpg
 
Pour monter les barbotins arrières il suffit d'enfoncer les roulements à l’intérieur.
 
J’insère 2 servomoteurs en faisant passer les câbles dans les fentes. On peut les laisser montés serrés ou les fixer à la colle ou avec des petites vis.
 
22.jpg
 
Pour monter les barbotins de devant, j'ai coupé les palonniers des servomoteurs comme sur la photo qui suit.
 
23.jpg
 
Un aperçu du dessus.
 
24.jpg
 
Maintenant je m'occupe du système de tir. J'utilise une vis et un écrou en nylon avec un ressort que je coupe en deux.
 
25.jpg
 
Et je monte le tout de cette manière :
 
26.jpg
 
Je m'aide de la pince et du tournevis.
 
27.jpg
 
Ensuite je coupe un palonnier en forme d'hélice pour le servomoteur de tir.
 
28.jpg
 
Je fixe ce servomoteur avec de la colle ou des vis.Je monte les maillons de chaînes ensembles (16 maillons pour une chaîne) puis je monte les chaînes de chaque côté.
 
29.jpg 30.jpg
 
Dans cet exemple, je choisis de contrôler mon rocbot par bluetouth. Je soude le connecteur du module bluetouth de cette manière :
 
31.jpg
 
Et je le monte sur le robot :
 
32.jpg
 
 
Deuxième étape : programmation du robot.
 
 
Pour connecter le robot au PC, j'utilise un convertisseur FTDI. Pour le sens du branchement : « DTR » à droite, « GND » à gauche.
 
33.jpg
 
Ensuite ouvrez le programme « Rocbot_BT » et dans « outil » sélectionnez la bonne carte arduino et le port COM correspondant.
Téléverser le programme:
 


Pour contrôler le robot j'utilise l'application Bluetouth electronics.
 
34.jpg
 
Installez l'application et configurez votre télécommande, placez un pad et un bouton poussoir.
 
35.jpg
 
Réglez le bouton poussoir comme si dessous en appuyant sur « Edit » en bas à droite de l'écran.
 
36.jpg
 
Ensuite après avoir appairé votre smartphone avec le module hc-05, connectez vous au module avec l'application.
 
37.jpg
 
Démarrez votre télécommande en appuyant sur « run ».
 
38.jpg
 
Vous pouvez maintenant contrôler le robot !
 
 
39.jpg




RobArchi X.XX

Publié Gyro49 le 28 janvier 2017 - 03:09 in Robot complet

Si comme moi vous avez interdiction de faire rouler vos créations dans la maison sous peine d'entendre "Qu'est-ce que c'est que ce truc qui fait du bruit" ou encore "J'ai encore faillit marcher dessus va dehors".
 
Seule solution, en effet, faire rouler mes projets dehors.
 
Problématique d'un robot d'extérieur
 
La garde au sol doit être plus grande que les herbes du jardin.
J'ai bien réalisé un premier projet, mais avec sa garde au sol inférieur à 2 cm, il est juste bon à rouler sur la terrasse.
 
Mots-clés
 
Raspberry, atmega328, ardiuno, batterie 12v, L298N, motoréducteur, I2C
 
Objectifs principaux
 
Disposer d'une base évolutive et pouvant se déplacer en extérieur.
 

 
RobArchi X.XX
 
P1040221.JPG
 
La liste des courses
 
C'est une liste très réduite, il faudra forcément des vis, un clou, des résistance et des condensateurs, sinon principalement il faut :

raspberry pi                                                     50€00 amazon
atmega328P                                                      6€00 amazon
plaque stripboard de 50 x 12cm                      21€00 (chez mon fournisseur local)
deux roues de diam 25cm                               38€00 bricodepot
connecteur à souder                                         2€60 hobbytronics
deux moteurs à engrenage                             35€00  sud-import-express.com
deux engrennages                                            6€00  amazon
deux motoréducteurs                                       14€50 amazon
un L298N                                                          3€52 amazon
une plaque de médium prédécoupé                 5€00 leroymerlin
une batterie 12v 7Ah                                       20€00 amazon
i2c level shifter                                                   4€00 hobbytronics
 
La partie bois
 
Dans la plaque de bois de 80 x 60 cm il faut placer:
- un cercle de 50 cm de diamètre;
- deux rectangles de 13 x 28,2 cm;
- un rectangle de 19 x 12,4 cm
plaque.png
 
Puis dans les rectangles de 13 x 28,2cm. Cette plaque accueillera le moteur.
coté.png
 
Pour finir, afin que les cotés restent perpendiculaire avec le fond du robot il y a une plaque au centre. Les trois gros trous sont là uniquement des passes câbles, donc d'un diamètre libre. 
Attention dans le bas de cette plaque il faudra casser les angles (non dessiné) avec une râpe à bois.
milieu.png
 
Les moteurs + roues
 
De base, le bloc tourne en sortie de réduction à 400 tr/min ce qui est trop important pour le projet.
Le moteur est alimenté en 12V et il a un diamètre de 38mm (3,8cm).
 
P1040222.JPG
 
J'ai donc choisi de mettre à la place un motoréducteur avec 150tr/min en sortie d'arbre ce qui fera à la roue environ 4tr/min.
Je pense qu'un 250 tr/min aurait été plus judicieux.
 
Nouveau moteur et nouveau pignon prennent un axe différent par rapport à l'original. Avec un foret de 10mm il faudra faire un deuxième axe dans la coque plastique.
P1040224.JPG
 
Il faudra également ouvrir le capot du dessus pour laisser passer le pignon qui est trop gros. Ce n'est pas très joli mais il n'y a pas le choix.
P1040227.JPG
 
Pour le raccordement des moteurs, j'ai placé un condensateur 100 micro non polarisé entre les deux bornes d'alimentation.
 
Les roues font donc 25 cm de diamètre avec un axe de 20mm sur roulement à bille.
 
Pour le raccordement au moteur j'ai été au plus simple -> deux bouts de tuyau en PVC de diamètres 50mm et de longueur 5 cm et 4cm.
le tube 1: Le 5 cm sera relié à la roue après avoir fait des encoches.
le tube 2; Le 4cm il faut lui enlever sur la longueur une bande de 2cm environ puis le serrer pour le faire rentrer dans le tube 1 puis lui faire les encoches coté moteur.
P1040230.JPG
 
 
Comme vous pouvez le remarquer, l'axe de la roue c'est du 20mm et celui du groupe-moteur c'est du 12mm.
Donc acheter un tube de 12mm, une plaque de fixation métallique et faire un peu de soudure.
La plaque ne servant qu'au maintien du tube de 12 lors des démontages réguliers.
 
P1040234.JPG
 
A chaque extrémité du tube de 12mm j'ai insérer 8cm de tige filetée en laissant dépasser 15mm. Par la suite il faut percer le tube de par en par avec un foret le plus petit possible, en prenant la tige filetée. Un morceau de clou dans le trou fera office de clavette.
 
Il faut trouver de quoi combler l'espace entre le tube de 12mm et l'intérieur de l'axe de roue.
J'ai donc découpé 10cm d'un tube d'acier diamètre 20 et récupérer une cheville plastique de montage de mes WC suspendu. Il est possible d'utiliser un bout de tube PER d'alimentation en eau récupérer chez un ami qui fait de l'auto construction. Le reste du jeu pourra être comblé par du scotch renforcé.
 
L'électronique
 
Pour l'électronique, j'ai choisi d'utiliser une plaque à bande car tout le monde n'a pas forcément accès à une graveuse.
Donc une plaque stripboard de 17,5 x 12cm.
P1040212.JPG
 
Il faut faire quelques modifications en suivant les croix
stripboard.png
 
composants.png
 
Pour les vérifications j'ai suivi le tuto paperduino.
 
Attention, il ne faut pas oublier le strap sous le support de l'Atmega et les condensateur entourant le quartz sont de 22pf et non 22nf
 
Pour charger le code arduino j'ai suivi le tuto de chez Arduino
 
J'ai placé entre l'Atmega et le Raspberry un i2c level shifter car il travail respectivement en 5V et en 3,3V.
 
J'ai écarté légèrement les pattes du connecteur du raspberry car j'avais peur de faire de mauvaise soudure.
P1040216.JPG
 
Avec des straps, vous avez juste à relier les SDA et les SCL ensemble au travers du I2C level.
De plus la partie de droite sur la photo correspond aussi à la partie de droite sur le plan de grattage de la face cuivré.
J'ai placé à la suite un 7812,7809,7805 et un LD1086v33
P1040235.JPG
 
 
Les codes informatique
J'ai fait l'impasse sur le formatage de la Raspberry et sur l'installation de l'I2C.
 
il y a plusieurs version du code informatique.
Version X.01 -> Test de l'atmega pour le contrôle des moteurs
 
Avec le code suivant les roues vont dans un sens puis dans l'autre.
// moteur droit
int MD = 11;
int in1 =10;
int in2 = 9;
// moteur gauche
int MG =  6;
int in3 = 7;
int in4 = 8;
void setup()
{
  pinMode(MD, OUTPUT);
  pinMode(in1, OUTPUT);
  pinMode(in2, OUTPUT);
  pinMode(MG, OUTPUT);
  pinMode(in3, OUTPUT);
  pinMode(in4, OUTPUT);
}
void demoOne()
{ digitalWrite(in1, LOW);
  digitalWrite(in2, HIGH);//AVANCE
  digitalWrite(in3, LOW);
  digitalWrite(in4, HIGH);//AVANCE
  analogWrite(MD, 250);
  analogWrite(MG, 250);
 
  delay(8000);
  //ARRET TOTAL
  digitalWrite(in1, LOW);
  digitalWrite(in2, LOW);
  digitalWrite(in3, LOW);
  digitalWrite(in4, LOW);
 
}
void demoTwo()
{ 
  digitalWrite(in1, HIGH); //RECUL
  digitalWrite(in2, LOW);
  digitalWrite(in3, HIGH); //RECUL
  digitalWrite(in4, LOW);
  analogWrite(MD, 250);
  analogWrite(MG, 250);
  delay(8000);
 
  //ARRET TOTAL
  digitalWrite(in1, LOW);
  digitalWrite(in2, LOW);
  digitalWrite(in3, LOW);
  digitalWrite(in4, LOW);
}
void loop()
{
  demoOne();
  delay(1000);
  demoTwo();
  delay(1000);
}
Version X.02 -> Test de la connexion I2C entre la Raspberry et d'Atmega
 
Rien de bien compliqué, je tout copier/coller sur le net
 
Code Atmega
#include <Wire.h>

#define SLAVE_ADDRESS 0x12
int dataReceived = 0;

void setup() {
    Serial.begin(9600);
    Wire.begin(SLAVE_ADDRESS);
    Wire.onReceive(receiveData);
    Wire.onRequest(sendData);
}

void loop() {
    delay(100);
}

void receiveData(int byteCount){
    while(Wire.available()) {
        dataReceived = Wire.read();
        Serial.print("Donnee recue : ");
        Serial.println(dataReceived);
    }
}

void sendData(){
    int envoi = dataReceived + 1;
    Wire.write(envoi);
}
Code Raspberry
#!/usr/bin/env python
# coding: utf-8

import smbus
import time

# Remplacer 0 par 1 si nouveau Raspberry
bus = smbus.SMBus(0)
address = 0x12

print "Envoi de la valeur 3"
bus.write_byte(address, 3)
# Pause de 1 seconde pour laisser le temps au traitement de se faire
time.sleep(1)
reponse = bus.read_byte(address)
print "La reponse de l'arduino : ", reponse
Version X.03 -> Commande de RobArchi par ssh
Code Atmega
#include <Wire.h>

#define SLAVE_ADDRESS 0x12
String dataReceived;
String sens;
String angle;

// moteur droit
int MD = 11;
int in1 =10;
int in2 = 9;
// moteur gauche
int MG =  6;
int in3 = 7;
int in4 = 8;

void setup() {
    pinMode(MD, OUTPUT);
    pinMode(in1, OUTPUT);
    pinMode(in2, OUTPUT);
    pinMode(MG, OUTPUT);
    pinMode(in3, OUTPUT);
    pinMode(in4, OUTPUT);
    
    Serial.begin(9600);
    Wire.begin(SLAVE_ADDRESS);
    Wire.onReceive(receiveData);
    Wire.onRequest(sendData);
}

void loop() {
    delay(100);
}

void receiveData(int byteCount){
  dataReceived = NULL;
  int numOfBytes = Wire.available();
  Serial.print("len:");
  Serial.print(numOfBytes);

  byte b = Wire.read();  //cmd
  Serial.print("cmd:");
  Serial.print(b);
  Serial.print(" ");
   // Read serial input:
   for(int i=0; i<numOfBytes-1; i++){
     char c = (char) Wire.read(); // Recevoir un caractere
    dataReceived += (char) c; //Concateneer les caractères reçus
  }
  Serial.print("Donnee recue : ");
  Serial.println(dataReceived);
 
  int str_len = dataReceived.length() + 1;

  // Préparation d'un tableau à la longueur des données reçues
  char char_array[str_len];

  // Copie des données reçues dans le tableau
  dataReceived.toCharArray(char_array, str_len);
 
  // Recupération de la première données
  sens =strtok(char_array,",");
  Serial.println(sens);
 
  // Recupération de la deuxième données
  angle =strtok(char_array,",");
  Serial.println(angle);
 
  if(sens == "g") // G COMM GO DONC AVANCE
    {
    digitalWrite(in1, LOW);
    digitalWrite(in2, LOW);
    digitalWrite(in3, LOW);
    digitalWrite(in4, LOW);
    digitalWrite(in1, LOW);
    
    digitalWrite(in1, LOW);
    digitalWrite(in2, HIGH);//AVANCE
    digitalWrite(in3, LOW);
    digitalWrite(in4, HIGH);//AVANCE
    
    analogWrite(MD, 250);
    analogWrite(MG, 250);    
    }
  else if(sens == "b") // B COMME BACK DONC RECUL
    {
    digitalWrite(in1, LOW);
    digitalWrite(in2, LOW);
    digitalWrite(in3, LOW);
    digitalWrite(in4, LOW);
    
    digitalWrite(in1, HIGH); //RECUL
    digitalWrite(in2, LOW);
    digitalWrite(in3, HIGH); //RECUL
    digitalWrite(in4, LOW);
    
    analogWrite(MD, 250);
    analogWrite(MG, 250);    
    }
  else if(sens == "l") // L COMME LEFT DONC GAUCHE
    {
    digitalWrite(in1, LOW);
    digitalWrite(in2, LOW);
    digitalWrite(in3, LOW);
    digitalWrite(in4, LOW);
        
    digitalWrite(in1, LOW);
    digitalWrite(in2, HIGH);//AVANCE
    digitalWrite(in3, HIGH); //RECUL
    digitalWrite(in4, LOW);
    analogWrite(MD, 250);
    analogWrite(MG, 250);    
    }
  else if(sens == "r") // R COMME RIGHT DONC DROITE
    {
    digitalWrite(in1, LOW);
    digitalWrite(in2, LOW);
    digitalWrite(in3, LOW);
    digitalWrite(in4, LOW);
    
    digitalWrite(in1, HIGH); //RECUL
    digitalWrite(in2, LOW);
    digitalWrite(in3, LOW);
    digitalWrite(in4, HIGH);//AVANCE
    
    analogWrite(MD, 250);
    analogWrite(MG, 250);    
    }
  else
    {
    //ARRET TOTAL
    digitalWrite(in1, LOW);
    digitalWrite(in2, LOW);
    digitalWrite(in3, LOW);
    digitalWrite(in4, LOW);
    }  
}

void sendData(){
  int str_len = dataReceived.length() + 1;

  // Préparation d'un tableau à la longueur des données reçues
  char char_array[str_len];

  // Copie des données reçues dans le tableau
  dataReceived.toCharArray(char_array, str_len);
 
  // Recupération de la première données
  char *envoi =strtok(char_array,",");
  Wire.write(envoi);
}
 
Code Raspberry
#!/usr/bin/env python
# coding: utf-8

import smbus
import time
import os

# display system info
print os.uname()

bus = smbus.SMBus(1)

# I2C address of Arduino Slave
i2c_address = 0x12
i2c_cmd = 0x01

def ConvertStringToBytes(src):
    converted = []
    for b in src:
        converted.append(ord(b))
    return converted

# send welcome message at start-up
bytesToSend = ConvertStringToBytes("S")
bus.write_i2c_block_data(i2c_address, i2c_cmd, bytesToSend)

# loop to send message
exit = False
while not exit:
    r = raw_input('Enter something, "q" to quit"')
    print(r)
    
    bytesToSend = ConvertStringToBytes(r)
    bus.write_i2c_block_data(i2c_address, i2c_cmd, bytesToSend)
    
    if r=='q':
        exit=True
Ca marche, se connecter au raspberry en SSH via le WIFI forcément.
Les commandes sont:
g-> avance
b-> recul
l-> gauche
r-> droite
 
A bientôt pour la version 1.XX qui aura une autonomie avec un capteur ultrason.


Robot Cocotix V2

Publié robocop le 09 mai 2010 - 09:23 in Robot complet

Ca y est, vous avez construit Cocotix, le petit robot coccinelle qui évite les obstacles.
Celui-ci vous a permis de débuter dans la robotique, de vous rendre compte des problèmes mécaniques et de découvrir l'électronique.

Mais voilà, maintenant, il faut progresser, et je vous propose maintenant une nouvelle version de Cocotix.
Ce robot sera un peu plus compliqué de réalisation que le précédent, car il intègrera un circuit imprimé.

Présentation du robot

Eh oui, ce nouveau robot sera capable de suivre la lumière, tout en évitant les obstacles.

Image IPBMais moi, je n'ai pas le matériel pour réaliser un circuit électronique !

Rassurez-vous, le schéma est très simple, et vous pourrez le réaliser sur une simple plaque d'essai en bakélite.

Image IPB
Alors, vous êtes tenté? C'est parti !

Une vidéo

Tout d'abord, je vous propose une petite vidéo du robot, de façon que vous puissiez voir quelles sont ses possibilités et ses fonctions :




Quelques informations techniques...

Pour ce robot, pas besoin de pic, d'atmel ou autres micro-contrôleurs. Toute la partie commande est analogique, à partir de simples transistors. Nous utiliserons des photo-résistances en guise de capteurs de lumière.

Liste des composants

Pour réaliser ce robot, vous aurez besoin de :

petits moteurs
1 interrupteur on/off
4 résistances de 100 ohms
2 résistances de 220 ohms
1 DEL rouge et 1 DEL verte
2 résistances variables de 10 k
2 microrupteurs (type switch)
2 transistors BC547C
2 photorésistances LDR
2 transistors BC557C
1 plaque de bakélite
2 supports à 2 piles AAA

Le schéma électronique

Le schéma électronique est assez simple à comprendre (cliquez sur l'image pour aggrandir le schéma):

Image IPB

Note : GND correspond au 0V ("-" de la pile) et VCC au +V ("+" de la pile).

Commençons par le système pour éviter les obstacles. Il est beaucoup plus simple que celui de Cocotix.

Image IPB
Le courant circule de "C" à "NC" quand l'interrupteur ne détecte pas d'obstacle : le moteur tourne normalement et le robot avance tout droit.

Maintenant, imaginons que l'interrupteur détecte un obstacle.

Le courant circule donc de "C" à "NO" ou plutôt, il ne circule plus, puisque "NO n'est branché à aucun fil".

Conclusion : le moteur s'arrête.
Les fils des interrupteurs seront comme dans la V1 du robot, croisés.

Ainsi, quand l'interrupteur de gauche rencontre un obstacle, le moteur droit s'arrête et le robot tourne à droite : l'obstacle est évité.

Voyons maintenant le système pour suivre la lumière.

Pour chaque commande de moteur, on utilise un transistor BC547C (de type NPN) et un transistor BC557C (de type PNP).

Image IPB

Voici donc l'effet que cela produit :
  • Quand le courant d'entrée (1) est élevé, le courant de sortie (2) est faible.
  • Quand le courant d'entrée (1) est faible, le courant de sortie (2) est élevé.
Ainsi, quand il y a peu de lumière dans une photo-résistance, il y a une forte résistance, et donc un faible courant d'entrée (1).

Résultat : le courant de sortie (2) est élevé et le moteur tourne rapidement.

Au contraire, quand il y a beaucoup de lumière dans une photo-résistance, le courant d'entrée (1) est élevé et le courant de sortie (2) est faible.

Le moteur tourne doucement voir s'arrête : le robot se dirige vers la lumière !

Partie électronique

Nous allons réaliser la carte électronique sur une plaque de bakélite.
Vous pouvez vous aidez de ce schéma, si vous avez du mal à comprendre le schéma vu précédemment :
Image IPB
Un immense merci à Alex93 pour la réalisation de cette image !
Image IPB

Il faut mettre les composants sur la face sans pastille et les souder du côté pastille.

Ensuite, on réalise les pistes en étalant de l'étain sur les pastilles.

Voilà, maintenant que vous avez compris, à vous de jouer.

Image IPBSerrez au maximum : la taille de votre robot dépendra de la taille de votre circuit !

Voilà le mien :

Image IPB

J'ai tellement voulu serrer les composants que l'on ne voit pas grand-chose o_O .

Assemblage des pièces

Cette fois-ci, le support n'est plus un calendrier en carton, mais une plaque de P.V.C.
Ainsi, le robot gagne en solidité Image IPB .

Voici les dimensions du châssis (en mm), mais n'hésitez pas à les adapter à la taille de votre plaque électronique :

Image IPB

Image IPB

Comme dans Cocotix V1, il n'y a pas de roue, et c'est l'axe du moteur qui touche directement par terre. L'interrupteur sert de troisième appui.

Collez les moteurs, les micro-rupteurs, les photo-résistances, le circuit électronique et les deux supports à piles AAA avec de la colle chaude et réalisez les connexions :

Image IPB
Prévoyez également deux trous pour les DEL :
Image IPB

Les 4 piles sont branchées en série.

Derniers réglages


Votre robot est presque opérationnel, encore un petit réglage.

Avec un petit tournevis, régler les résistances variables. Plus la résistance sera petite, plus le robot réagira à la lumière, et moins il ira vite. Le truc, c'est de trouver le réglage parfait pour que le robot ait suffisamment de vitesse pour avancer et qu'il réagisse bien à la lumière.

Enfin, vous pouvez lui rajouter une petite coque en carton, comme sur cocotix V1.

Votre robot est alors terminé !

Voilà, ce tutoriel touche à sa fin. J'espère que vous avez pris plaisir à le lire et à construire ce petit robot.
N'hésitez pas à poser vos questions sur le forum, notamment si vous avez un problème. Montrez-nous vos réalisations Image IPB .


Comment programmer une Arduino connecte en USB a un raspberry PI, depuis son PC.

Publié Bobox le 20 juin 2017 - 09:54 in Programmation

Introduction
 
Comme je le décris un peu dans l'interview qu'à fait Path (lien), je trouve que pour démarrer un robot 'autonome' la combinaison d'une arduino et d'un raspberry PI est une très bonne solution.
L'arduino pour connecter la majorité des capteurs et des drivers moteur, le raspberry PI pour la partie 'cerveau' et connectivité.
Comment faire alors pour programmer cet arduino, sans débrancher et rebrancher le cable USB en permanence.
C'est ce que nous allons voir dans ce tutoriel avec plusieurs méthodes, non exhaustives,  pour programmer une arduino connectée à un raspberry PI, depuis son PC.
 
Pré-requis
 
Je suppose ici que l'arduino est connecté à un raspberry PI par l'un de ses ports USB.
Je suppose aussi que le raspberry PI n'est pas connecté à un écran clavier, mais est accessible par le wifi/ethernet depuis un autre PC, depuis SSH.
Ce tutoriel n'explique pas ces étapes préliminaires.
 
A. Comment copier des fichiers depuis son PC sur le raspberry PI
 
Il est souvent nécessaire de transferer des fichiers depuis votre PC vers le raspberry PI. Vous pouvez le faire à travers le protocol SSH. 
 
Si votre PC tourne sous windows
 
vous pouvez utiliser winSCP (lien).
 
L'addresse IP et les identifiants sont ceux que vous utilisé pour SSH.
 
Si votre PC tourne sous linux
 
vous pouvez directement utilisé la commande 'scp':
scp monfichier  monlogin@addressIpRaspberry:.
Ces solutions sont parfaites pour transferer des fichiers d'installation, voir vos sources. Meme si pour les sources d'autres méthodes seront proposées plus loin.
 
Mais revenons à notre problématique d'origine, la programmation de l'arduino.
 
B. Comment utiliser l'IDE arduino sur le raspberry PI grace à un bureau distant.
 
Avantages:
  • Simple, on utilise l'IDE classique pour programmer l'arduino.
  • La méthode s'applique pour acceder à d'autres application graphique sur le raspberry PI
Inconvénients:
  • Vous etes limité à la résolution graphique de l'OS de votre raspberry PI
  • Utilisé l'IDE arduino sur le raspberry peut-être 'lent'
  • Utilisé d'autres IDE pour éditer vos sources peut-être encore plus lent
  • En fait ça ne marche probablement que si vous avez une raspberry PI 3.
  • Il faut une installation du raspberry PI avec le support graphique
C'est la solution qui je pense nécessite le moins d'apprentissage, parce qu'elle utilise l'habituel IDE arduino.
Elle nécessite que le raspberry PI contienne une installation de linux avec support des applications graphiques. C'est le cas si vous avez installé une Raspian ou une Ubuntu-Mate. Ce n'est pas le cas si votre installation est une Ubuntu-serveur, dans ce cas, voir l'autre solution.
 
Installation d'un bureau distant.
 
Je propose d'utilisé NoMachine (lien)  
Télécharger et installer la version correspondant à l'OS de votre PC depuis le lien.
Télécharger depuis votre PC la version DEB correspondante à votre version et installation de raspberry PI :  armv6 pour Raspian , armv7 pour Ubuntu-mate sur raspberry PI 3.
Transferer le fichier DEB sur votre raspberry PI avec la méthode décrite dans la section précédente par exemple.
 
Après vous être connecté en SSH, lancer l'installation sur le raspberry PI :
sudo dpkg -i nomachine_XXXXXXX_armhf.deb
L'installation sur le raspberry PI installe le client, mais aussi le serveur.
Vous pouvez maintenant lancer NoMachine depuis votre PC, le programme va chercher les PC qui ont un serveur NoMachine sur le réseau local :
Voici ce qu'il trouve pour moi, mon PC fix and ma raspberry PI:
Screenshot from 2017-06-19 22-10-24.png

Double cliquer sur le raspberry PI et c'est parti, vous allez démarrer un bureau distant sur votre petite board. Les login/mot de passe sont ceux que vous utilisez pour SSH.
 
Astuces :
  • La résolution graphique est surement basse, pour changer cela il faut forcer le mode 'hdmi, même s'il n'y a pas d'écran physique de connecté':
    Editez le fichier /boot/config.txt
    Décommenter les ligne :
    hdmi_force_hotplug=1
    hdmi_group=1
    hdmi_mode=31
    Reboot
  • Si vous passez la souris dans le coin en haut à droite de la fenêtre vous pouvez refaire apparaitre le menu de configuration de NoMachine
Programmation de l'arduino
 
Avec le bureau distant vous pouvez maintenant installer l'IDE arduino en ouvrant un navigateur sur le site d'arduino et suivre la procédure standard d'installation.
 
Attention : N'oubliez pas de télécharger la version linux-ARM, c'est la seule compatible avec le raspberry PI
 
C. Comment programmer l'Arduino sur le raspberry PI en ligne de commande.
 
Avant de voir en détails les solutions possible, il faut d'abord se poser une question préliminaire.
 
Comment éditer les fichiers sources des programmes pour l'Arduino
 
Comme nous n'utilisons pas l'IDE dans cette section, il va falloir éditer les sources des programmes autrement.
 
Voici plusieurs solution possible :
  • Vous êtes un guerrier, vous éditez vos sources directement en ligne de commande, sur la raspberry PI !
    Rien besoin de spéciale, un simple SSH et un édieur qui fonctionne dans le terminal comme ne/vim.
  • Vous éditer les fichiers sur le PC avec votre éditeur préféré, et vous les transferer sur le raspberry PI avec winscp
    C'est la méthode de la section A, appliquée aux fichiers sources.
  • Vous êtes un programmeur consciencieux et vous voulez utiliser un gestionnaire de code source avec versioning ! Je vous le dis vous êtes sur la bonne voie.
    Je vous conseille d'utiliser git et github. Voici une vidéo expliquant les principes de base : Github qu'est ce que c'est
    Dans notre cas, on va avoir une version du repository sur votre PC, dans lequel vous éditez les sources.
    On va aussi avoir une version du repository sur le raspberry PI.
    La séquence devient alors :
    Modifier les sources sur le PC
    Pusher les sources sur github depuis le PC
    Puller les sources depuis github sur la raspberry PI
 
Comment compiler les sources et les uploader sur l'arduino
 
Méthode simple
 
Une méthode simple est proposée par Path dans son tutoriel :  Compilation sur rPI et Upload sur arduino directement depuis le PI en ligne de commande
Je la recommande vivement pour commencer, elle est fonctionnelle et relativement facile à mettre en oeuvre.
 
Méthode platformio
 
Je vous propose une deuxième méthode ici, plus générale puisque pouvant s'adapter à la programmation d'autres cartes et microcontrolleur uilisé dans l'embarqué.
Cette méthode s'appuie sur l'environement  platformio core 
 
Installation : 
sudo pip install -U platformio
Vous pouvez l'installer aussi que pour l"utilisateur local, en omettant le 'sudo'
 
Creation d'un projet:
 
Pour chaque nouveau programme que vous voudrez créer pour l'arduino il faut créer un nouveau repertoire projet :
mkdir blinkProject
cd blinkProject
platformio init -b uno
Cette dernière commande initialisee le projet pour une board Arduino uno, si vous avez une autre type de board il faut trouver son nom dans la liste retournée par la commande 'platformio boards'.
 
Modification des sources
 
Le fichier source principale devra etre  'src/main.cpp' il n'y a pas d'extension .ino ici.
Exemple pour notre blink project :
src/main.cpp:
#include "Arduino.h"

void setup() {
    pinMode(13,OUTPUT);
}

void loop() {
    digitalWrite(13,LOW);
    delay(500);
    digitalWrite(13,HIGH);
    delay(500);
}

Compilation du code
 
La compilation du code se fait avec la commande:
platformio run
Si c'est la première compilation pour cette board la commande va télécharger toutes les librairies nécessaires.
 
Upload du code
 
Comme pour l'IDE arduino on peut compiler et uploader dans la même commande
platformio run -t upload
Après ces manipulations de base et pour des usages plus avancés, je vous recommande d'aller voir le site de platformio, qui contient beaucoup d'explication et de documentation sur les différents usages.


Arduino, les servomoteurs et la MLI (PWM)

Publié Hexa Emails le 02 juillet 2012 - 06:26 in Programmation

0) Je ne suis pas prof diplômé... (pas encore)

Je tiens à dire que je fais ce tuto dans le but de rendre service, il n'est pas exhaustif, s'il contient des erreurs veuillez me le signaler, il n'a pas pour but de faire du lecteur un doctorant en électronique numérique, et n'est peut être pas compréhensible par tout le monde (j'essaierai tout de même de faire au plus simple)
Les explications se limitent à l'univers de l'Arduino (bien que cela puisse être sans doute réadapté à pas mal d'autres situations), et aux servomoteurs dits "de modélisme", piloté par un signal bien particulier (voir plus bas) et ne concerne pas les servos contrôlés par I²C par exemple.


1) Qu'est-ce que la MLI (PWM) ?

Bon alors, comme dit Wikipédia, la Modulation de largeur d'Impulsions (MLI, PWM en anglais) c'est une succession de différents états logiques, (0 et 1), de différentes durées, à intervalles réguliers.

Dans le cas de l'Arduino: il s'agit de succession de 0/5V, qui permet, en modifiant la durée de chacun de ces états, de faire que tout se passe comme si on avait une source de tension continue;
Si l'on fait une MLI avec 20% d'états hauts, on aura 20% de 5V et 80% de 0V: on aura l'impression d'avoir 1V.

Il y a deux principales caractéristiques d'une MLI: son rapport cyclique et sa fréquence de découpage;
le rapport cyclique étant la proportion d'état haut par rapport au total (souvent exprimé en %, compris entre 0 et 1)
la fréquence de découpage: ben c'est la fréquence, l'inverse de la période. Une fréquence trop basse et l'on verra les clignotements de la LED, ou le moteur se mettra à vibrer; une fréquence trop haute et l'électronique ne suivra plus.


2) Comment pilote-t-on un servomoteur?

Un servomoteur c'est quoi?
C'est une boite de plastique, avec un rotor en sortie, qui peut être piloté de sorte à obtenir l'angle que l'on souhaite en sortie, entre 0 et 180°; on peut lui dire d'aller à 0°, puis à 153°, puis à 18°... (dans la limite de la précision de la commande ET du servomoteur, et a condition de ne pas éxcéder son couple maximal (l'effort maximum qu'il peut fournir)


Les servos ont trois fils qui sortent (ou entrent, suivant les optimistes/pessimistes) de leur boitier :
2 fils d'alimentation (alimentation entre 6 et 4V continus le plus souvent), et 1 fil de commande, en 0-5V

Et à l'intérieur?
Un moteur (CC à balais le plus souvent), des engrenages (pour augmenter le couple)
De l'électronique, et un capteur (un potentiomètre rotatif le plus souvent)

Quel rapport entre la MLI et les servomoteurs? Hé bien beaucoup moins que certains veulent le faire croire!
voici un signal de commande de servomoteur(pas à l'échelle et fait sous Paint hein):
Image IPB
Comme on peut le voir, on a une succession d'états hauts et d'états bas, la durée de l'état haut permet de dire au servomoteur l'angle que l'on souhaite qu'il atteigne: plus le niveau bas est court, plus l'on se rapproche de 0°, plus il est long, plus l'oon se rapproche de 180°.
On peut dire que ce signal est un peu étrange pour une MLI. Pourquoi?
Parce que l'on reste cantonné à un état haut de durée comprise entre 1 et 2 millisecondes, sur 20ms, soit entre 5% et 10% de la durée totale. Et de plus on peut noter la période de ce signal: 20 ms. Cela peut sembler rapide, mais en électronique c'es plutot lent.



3) A quoi correspondent les Pins notées "PWM" sur mon Arduino?

Les plateformes de prototypage Arduino sont basées sur des microcontrôleurs ( ATMega328, ATMega1280 et ATMega2560 le plus souvent, certaines anciennes versions avec des ATMega168, les autres versions sont VRAIMENT anciennes)
Ces microcontrôleurs permettent de créer facilement des signaux de MLI (ils ont étés conçu, à l'intérieur, avec des portes logiques qui permettent facilement de faire de la MLI).
Ce qui permet d'utiliser l'instruction suivante:
analogWrite(pin_pwm , nombre_entre_0_et_255)
et d'obtenir une MLI sur la broche notée "PWM".
MAIS!
Piloter les servomoteurs avec ces instructions n'est pas une bonne idée. Pourquoi?

a)la fréquence:
Une MLI de base faite avec analogWrite a une fréquence de découpage de 480Hz, voire 1kHz suivant les ports.
Pour piloter un servo il faudrait une fréquence de 50Hz (1/0.02), je ne vais pas m'étendre dessus mais c'est assez compliqué de modifier la fréquence et cela peut empiéter sur d'autre fonctions comme delay(), millis(), car cela oblige (en gros) l'ATMega à compter moins vite...

b)la résolution:
Vous vous souvenez que j'ai dit que le signal de servo n'utilise que 5% de la durée totale de la MLI?
C'est un autre souci. Avec analogWrite(), on peut prendre 256 durées différentes entre 0 et 100%. ça veut dire un peu moins de 13 valeurs différentes entre 5 et 10% ! c'est très peu quand on veut le piloter de 0 à 180°, cela voudrait dire qu'il ne peut prendre que 13 valeurs d'angle différentes, par exemple:
0°, 14°, 28°... (aux arrondis près).
Et il serait impossible de prendre des valeurs entre celles-ci. Pas terrible...

4)Et donc comment je fais?

Pas de panique, l'équipe de développeurs d'Arduino a codé une librairie <servo.h>, qui permet de créer des signaux de commande de servomoteurs, sur n'importe quelle sortie digitale. Ce qui veut dire:
les pins digitaux 0 à x, notés PWM OU PAS;
les pins analogiques A0 à Ax -qui sont des sorties digitales en même temps!-
(sauf les ports A6 et A7 sur les arduinos basés sur un ATMega328 monté en surface, qui ne sont pas des sorties digitales mais uniquement des entrées analogiques)
On peut avoir 12 servos en même temps sur un Arduino basé sur un 328 (et 168), et 48 pour un Arduino basé sur un 2560 (et 1280). Selon moi on pourrait en contrôler encore plus en même temps, mais les devs ont mis cette limite afin de ne pas trop peser sur le reste du programme.

Toutes les infos sur la librairie <servo.h> et les fonctions qu'elle permet d'utiliser sont disponibles à l'adresse suivante(En français, je ne vais pas réinventer le roue non plus...)

5)EN BREF!

La MLI, c'est une forme de signal digital (ne contenant que des états hauts et bas), et périodique.
Les ports noté PWM sur l'Arduino permettent de faire facilement de la MLI (par l'instruction analogWrite)
La librairie <servo.h> permet de contrôler 12 servomoteurs simultanément (48 sur les MEGA), sur n'importe quelle sortie digitale.


Faire parler un PC avec VB.NET

Publié julkien le 18 juin 2012 - 02:58 in Programmation

Principe

Le but de ce tutoriel est de faire tout simplement parler l'ordinateur en un minimum de lignes
Ici on lui feras simplement annoncer l'heure.


Prérequis

  • VisualBasic 2010 Express
  • WindowsSeven

I) Vérification et configuration des voix pardefault de Windows

Windows ne contient pas par default de langue française,(ben oui il ne parle que l'Américain , ou le chinois ^^) , alors ilfaut ajouter la voix Virginie (de la societe Nuance (ex Scansoft)) en français, cliquer sur ce Mon lien ,decompresser l'archive et installer RSSolo4FrenchVirginie.exe pour tester la voix, appuyer sur la touche Windows* et la touche 'R' pour ouvrir la fenêtre "Exécuter" , taper :"C:\Windows\SysWOW64\Speech\SpeechUX\sapi.cpl" puis cliquer sur ok.

une fenêtre s'ouvre et vous propose plusieurs voix sélectionner: "ScanSoft Virginie_Dri40_16kHz"
rentrer un texte (en français correctement orthographier!;)/> ) et cliquer sur "Tester la voix"
Voilà maintenant que l'on sait que ça marche on vapourvoir coder

*=(la touche Windows est entre la touche 'CTRL' et 'ALT'!:P/>)


II) Créer le projet sous Visual Basic 2010 Express

Ouvrer Visual basic 2010 Express et cliquer sur nouveau projet
Sélectionner : application Windows forms
Renseigner le nom du projet : "Mon_Prog_donne_lheure"et cliquer sur ok
Nous avons donc la form mais elle est un peu vide

Image IPB

Ajoutez un bouton ( il se trouve dans la barre d'outils,un glisser/déposer suffit à le mettre en place )
Ajoutez maintenant une Combo Box
Hein, Quoi ?! Combo Box toi-même ! Non rassurez-vous ce n'est pas une insulte mais juste le menu qui nous permettras de sélectionner nos voix
Il se trouve toujours dans la barre d'outil
Au final on devrais avoir une fenêtre qui ressemble à ça:

Image IPB

Et du coup ça y est on a fini l'interface de commande :)/>.C'est l'avantage de vb.net: facile d'accès, du moins jusque-là ! ( je dis juste ça pour vous faire peur! :P/> )


III) Le code

Contrairement à l'Arduino qui exécute la fonction Loop en boucle, en VB ontravaille par évènement.
Bon ok jusque-là c'est simple mais comment lui dire defaire telle tâche au démarrage ?
Ben en fait c'est vraiment pas compliqué il vous suffitde faire un double clic sur la Form1 précédemment créé !
Et tout d'un coup il nous sort tout un code :

Public Class Form1

Private Sub Form1_Load(ByVal sender AsSystem.Object, ByVal e As System.EventArgs) Handles MyBase.Load

End Sub

End Class


Je ne vais pas vous expliqué en détail le VB il a d'autres sites plus sympas pour apprendre [/font][/size]
Si on décompose le code on trouve 2 groupe [/font][/size]

En première place on trouve la déclaration de la class

PublicClass Form1
End Class


C'est la dedans que l'on met notre code en réalité
En 2eme nous avons la fonction : Chargement de la forme

Private Sub Form1_Load(ByVal senderAs System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
End Sub


Je vous invites à coller dans la place de celui existant ce texte :[/font][/size]


Imports System.Speech

Imports System.Speech.Synthesis

Public Class Form1

Dim s As SpeechSynthesizer = New SpeechSynthesizer() ' declaration du systeme de narration

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load 'au chargementde la forme:

Dim listevoix =s.GetInstalledVoices 'listevoix est egale a la liste des voix installer

For Each v As InstalledVoice In listevoix 'je charge chaque voix installer

ComboBox1.Items.Add(v.VoiceInfo.Name) '

Next

End Sub

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click ' quand je clics sur le bouton1

Dim texte As String = "Il est " & Now.Hour & " heure et " & Now.Minute &"Minute" 'declaration du texte

Dim voix As String = ComboBox1.SelectedItem 'la voixest egale la selection du combobox

s.SelectVoice(voix) ' je choisi la voix

s.Speak(texte) 'je lis le texte

End Sub

End Class


Vous avez remarquer ? il y a des lignes de surligné !
C'est normale
Il nous manque une dll pour que le logiciel parle
Le truc c'est que l'on est sous du code en .net(prononcer DotNet)
Il nous donne pas mal d'avantage et nous offre par la mêmeoccasion tout une bibliothèque lié à Windows
comme par exemple:
des module qui permette l'interaction avec les fichier, réseau,les Port de communication( ah ça sera certainement le sujet d'un autre tuto! ;)/>)
etc


pour ajouter la DLL , il suffit de cliquer sur le menu Projet => Ajouter une référence
une fenêtre s'ouvre cliquer sur l'onglet ".Net"
choisissez dans le menu System.speech et cliquer sur Ok


Conclusion

Voilà on as un programme fonctionnel

Oups, j'ai failli oubliez, cliquez sur le bouton lecture pour lancer l'application
Sélectionner la voix " ScanSoft Virginie_Dri40_16kHz" dans le menu et cliquez sur button1

Elle devrais vous dire avec une voix douce : "il est 12 heures et 21 minutes" ....
Enfin la voix douce et l'heure est relatif :D/>

J'espère que ça aideras !
Merci de m'avoir lu


Julkien


Utilisation du module RTC DS1307

Publié arobasseb le 23 octobre 2017 - 04:53 in Electronique

Bonjour à tous,
 
Aujourd'hui nous allons voir comment utiliser le module RTC DS1307 disponible sur la boutique Robot Maker.
Pour ce tuto nous allons également utiliser : (d'autres composants intéressants sont également disponible sur la boutique, n'hésite pas à y faire un tour ! )
 
Présentation
 
Tout d'abord, qu'est ce qu'un module RTC ? 
 
RTC signifie Real Time Clock soit en français horloge temps réel. 
 
OK, donc je peux l'accrocher dans mon salon ? Pas vraiment Image IPB
 
En fait ce module, une fois configuré, compte le temps qui passe et ce, de façon autonome et précise grâce à sa pile s'il n'est pas branché.
 
Et du coup à quoi ça sert, c'est pas une pendule et on peut déjà compter le temps avec une arduino par exemple ?
 
Avec ce module on peut faire des montages qui agissent en fonction du temps réel, par exemple allumer les lampes à 18h, ou le grille pain à 6h Image IPB mais aussi en fonction du jour, mois, ... en effet il connait la date et l'heure réelle.
Son avantage réside dans le fait qu'en cas de coupure d'alimentation il continue de compter, et aucune instruction ne risque de le ralentir, à l'inverse d'une arduino ou, dans ce cas, il y aurai une dérive de temps. 
Il se pilote via un bus I2C, ce qui le rend facile d'utilisation avec justement une arduino.
 
Quelques photos de notre star du jour : 
 
ds1307_cote.jpg
ds1307_recto.jpg
ds1307_verso.jpg
 
Le montage
 
Le schéma :
shema.png
(dans le schéma, le module n'est pas du même fabricant, mais les connections sont les même)
 
En vrai :
ds1307_montage.jpg
 
Le montage est simple grâce à l'I2C ; il faut connecter les broches SDA des 2 modules sur la broche A4 de l'arduino et les broches SCL sur la broche A5 , les broches VCC au 5V et GND au GND Image IPB
Attention pour une utilisation avec une arduino par exemple il faudra utiliser un convertisseur de tension (ce point sera peut-être aborder plus tard)
 
C'est cool tout est branché et maintenant ?
 
La programmation
 
Voici le code avec les commentaires qui suffisent à eux même : 
#include <Wire.h>    // Bibliothèque pour l'I2C
#include "RTClib.h"  // Bibliothèque pour le module RTC
#include <LiquidCrystal_I2C.h> // Bibliothèque pour l'écran

RTC_DS1307 RTC;      // Instance du module RTC de type DS1307
LiquidCrystal_I2C lcd(0x3F, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); ////Instance d'écran

void setup(void) {
  //Initialisation de l'éran
  lcd.begin(16,2);
  lcd.clear();
  lcd.backlight();
  lcd.setCursor(0, 0);
  lcd.setCursor(0, 1);
  
  // Initialise la liaison I2C  
  Wire.begin();
  
  // Initialise le module RTC
  RTC.begin();
 
  //Initialise la date et le jour au moment de la compilation 
  // /!\ /!\ Les lignes qui suivent sert à définir la date et l'heure afin de régler le module, 
  // pour les montages suivant il ne faut surtout PAS la mettre, sans à chaque démarrage 
  // le module se réinitialisera à la date et heure de compilation
  
  DateTime dt = DateTime(__DATE__, __TIME__);
  RTC.adjust(dt);
  
  // /!\
  ////////////////////////////////////////////////////////////////////////////////////////////
}

void loop(){
  
  DateTime now=RTC.now(); //Récupère l'heure et le date courante
  
  affiche_date_heure(now);  //Converti la date en langue humaine
  
  delay(1000); // delais de 1 seconde
}

//Converti le numéro de jour en jour /!\ la semaine commence un dimanche
String donne_jour_semaine(uint8_t j){ 
  switch(j){
   case 0: return "DIM";
   case 1: return "LUN";
   case 2: return "MAR";
   case 3: return "MER";
   case 4: return "JEU";
   case 5: return "VEN";
   case 6: return "SAM";
   default: return "   ";
  }
}

// affiche la date et l'heure sur l'écran
void affiche_date_heure(DateTime datetime){
  
  // Date 
  String jour = donne_jour_semaine(datetime.dayOfWeek()) + " " + 
                Vers2Chiffres(datetime.day())+ "/" + 
                Vers2Chiffres(datetime.month())+ "/" + 
                String(datetime.year(),DEC);
  
  // heure
  String heure = "";
  heure  = Vers2Chiffres(datetime.hour())+ ":" + 
           Vers2Chiffres(datetime.minute())+ ":" + 
           Vers2Chiffres(datetime.second());

  //affichage sur l'écran
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print(jour);
  lcd.setCursor(0, 1);
  lcd.print(heure);
}

//permet d'afficher les nombres sur deux chiffres
String Vers2Chiffres(byte nombre) {
  String resultat = "";
  if(nombre < 10)
    resultat = "0";
  return resultat += String(nombre,DEC);  
}


J'ai joins le fichier de code ainsi que  les librairies pour le module RTC et LCD.
 
une petite vidéo :
 
 
 
N'hésite pas à laisser un commentaire.

Fichier(s) attaché(s)




Roby, mon premier robot Arduino

Publié robocop le 03 octobre 2010 - 11:04 in Robot complet

Bonjour,

Je vous propose ici la construction d'un nouveau robot, Roby, qui pédagogiquement pourra se placer après avec les deux Cocotix, Cocotix V1, et Cocotix V2.
Roby sera programmable avec la plateforme arduino et intègrera différents capteurs : capteurs d'obstacles et de lumière comme dans cocotix V1 et V2, mais également d'autres comme capteurs de distance infrarouge ou ultrason si vous le désirez : le robot se veut extensible.

-------------------------------------
Liste des composants (par microrupteurman2) :

- 2 servomoteurs type s3003 modifiés en rotation continue
- 1 arduino
- 2 micro-rupteurs
- Les piles indiquées sur le schéma avec leur boîtier
- Une plaque d'essai (breadboard)
- Des roues pour servo, facilement réalisables
- Une roulette pour le 3e point d'appui
- fil électrique,
- vis
- matériel de soudure
- 1 interrupteur
- 2 résistances de 10k0
- 1 capteur Sharp Gp2d112
-------------------------------------

Le robot aura comme base mécanique la structure présentée ici.
Bien évidemment, vous pouvez utiliser la structure de votre choix, mais dans le code du robot, j'utiliserai bien deux servomoteurs pour la propulsion.

Image IPB

But du robot

Comme vu sur la vidéo, Roby aura pour but de naviguer dans une pièce, en évitant les obstacles, soit grâce a un capteur infrarouge de distance, soit avec des "antennes", des capteurs de contact.



Roby, robot basé sur une carte arduino

Par la suite, si vous le souhaitez, encore une fois, vous pourrez très simplement rajouter des capteurs, de l'enregistrement de données sur carte SD, une petite caméra, une liaison sans fil, etc.

Tout cela se fait très simplement avec certains modules pour Arduino.

Structure mécanique

Le structure mécanique est axée sur deux servomoteurs modifiés en courant continu.
Si vous n'avez pas d'idées, vous pouvez vous inspirer de ce tutoriel.

Image IPB

L'Arduino

Image IPB

Toute l'électronique du robot sera basée sur la carte Arduino Duemilanove. Arduino Duemilanove est une carte électronique qui comporte un microcontrolleur atmel ATmga328 et des composants supplémentaires pour faciliter la programmation du composant.

Ainsi la carte intègre directement un port usb pour programmer la carte en USB, un quartz 16MHz, un régulateur linéaire de tension 5, différentes LED, un bouton de reset, bref, pleins de bonnes choses pour commencer très rapidement sans soucis.
Cerise sur le gâteau, la carte est très accessible, moins de 30 euros.

Installation de la carte

Pour pouvoir programmer la carte, il faut déjà installer les drivers et les outils de programmation sur votre ordinateur.
La carte fonctionne aussi bien sur une architecture windows que linux.

Pour l'installation, je vous renvoi sur le chapitre dédié à l'installation d'Arduino sur l'ouvrage débuter avec Arduino

Test de la carte

On va voir si l'installation s'est bien passée en faisant clignoter une DEL.
La carte arduino équivalente à une carte clone Arduino Uno intègre d'office une petite DEL sur la patte 13.

On va donc mettre successivement la patte de 0 à 1, et de 1 à 0, toutes les 1.5 secondes.

On ouvre donc leur IDE, et on tape le programme suivant :
Code : C
int ledPin = 13;

void setup() {
// On initialise la patte 13 en pin de sortie
pinMode(ledPin, OUTPUT);
}

void loop()
{
digitalWrite(ledPin, HIGH); // on met la patte à 1
delay(1000); // on attend une seconde
digitalWrite(ledPin, LOW); // on met la patte à 0
delay(1000); // on attend une seconde
}
On remarque que chaque code possède au minimum deux fonctions, setup() et loop().
setup() est appelée au lancement de la carte, et loop() et executée en boucle, tant que la carte reçoit du courant.

Compilez votre code, puis envoyer le sur la carte.
Au bout de quelques secondes, la DEL de la carte devrait clignoter.
 
Ressources


Pour à peu près tout, il existe une librairie pour votre carte arduino : vous pouvez controler un servomoteur avec la librairie de servomoteurs, controler un écran LCD, communiquer avec l'ordinateur à travers le port USB, etc.

Voici un lien qui présente pleins d'exemples amusant à réaliser, et un autre, qui présente rapidement le langage avec lequel vous travaillez.

Amusez-vous bien !

Alimentation

Il y a dans ce robot deux alimentations : une pile 9 V pour alimenter l'arduino et 4 piles 1.5 V en série pour alimenter les servomoteurs et autres capteurs.

L'avantage de ce système, c'est que l'on peut alimenter l'arduino par la prise USB lorsque l'on écrira le programme, tout en gardant alimenté les servomoteurs : le débogage est donc plus aisé.

Attention cependant : il faut faire attention a bien relier les deux masses entre elle, cela peut être source de bogues assez vicieux.
Vous pouvez fixer vos piles commme sur cette photo :

Commencez par fixez les deux alimentation comme sur la photo :

Image IPB

Faites un trou au milieu du robot pour laisser passer les fils de l'alimentation et un trou sur le coté pour fixer l'interrupteur.
L'idéal c'est d'avoir un interrupteur capable d'avoir de couper/alimenter deux circuits à la fois. De cette façon, vous pourrez éteindre ou allumer votre robot en une fois.
Maintenant, si vous n'avez que deux interrupteurs normaux, ça fonctionnera aussi.

Fixez sur le robot l'arduino et la plaque d'essai.

Cablez alors les alimentations, l'arduino et les servomoteurs de cette façon :

Image IPB

Vous avez donc avec ce schéma 6V pour les deux servomoteurs et 9 V pour l'arduino.
Les deux masses sont bien reliées entres elles.
Sur la plaque d'essai, la première ligne correspond donc aux +6V et la deuxième à la masse.
Voici une photo de mon robot à cette étape :

Image IPB

Test des moteurs

On va écrire dans un premier temps un programme qui fait avancer le robot tout droit.

Tout d'abord, nous allons écrire une fonction toute simple, getNeutral(moteur) qui retournera la valeur du neutre de vos servomoteurs :
Code : C++
#include <Servo.h>

#define SERVOG 1
#define SERVOD 0

Servo servog;
Servo servod;

int getNeutral(int s)
{
if(s == SERVOG)
return 86;
else
return 84;
}
Chaque servomoteur est représenté par un entier naturel : le servomoteur gauche 1 et le servomoteur droit 0.
Remplacez les valeurs 86 et 84 respectivement par les valeurs du neutre que vous trouvez pour le servomoteur gauche et pour le servomoteur droit de votre robot.

Essayez de faire bouger vos servomoteurs en utilisant cette fonction.
Tout va bien ? Ok, nous allons écrire une fonction handleS(servomoteur, vitesse) qui envoit une commande au servomoteur. Cette commande est caractérisé par une vitesse qui va de -5 à 5. Si la vitesse est négative, on dira au moteur d'aller dans un sens et si le vitesse est positive on dira au robot d'aller dans l'autre sens.

Les différentes vitesses sont obtenues en se rapprochant du neutre. Je vous conseil de faire vos propres tests.
Attention cependant : nos servomoteurs ne sont pas dans le même sens. Pour avancer tout droit, un des servomoteurs doit aller dans un sens, et l'autre servomoteur doit aller dans l'autre sens.
On ne va donc pas oublier d'inverser le sens de rotation pour un des moteurs.
Code : C++
void handleS(int s, int speed)
{
//Vitesse :
// 0 -> 0; 1 -> 1; 2 -> 3; 3 -> 8; 4 -> 10; v => 5 -> 30
int tab[6] = {0,1,3,8,10,30};
int pos = getNeutral(s);

int acc;
// A chaque vitesse on fait correspondre un nombre qui est la différence de ce que l'on va envoyer au servomoteur par rapport au neutre.
// Les valeurs que je donne sont mes valeurs, je vous conseille de chercher vos propres valeurs, cela dépend de votre servomoteur.
if (speed < 0)
acc = - tab[abs(speed)];
else
acc = tab[speed];

if(s == SERVOG)
servog.write(pos += acc);
// On inverse le sens de rotation pour le moteur droit car les deux servomoteurs ne sont pas montés dans le même sens.
else
servod.write(pos -= acc);
}
A partir de là, on peut écrire une fonction move(direction) qui fait déplacer le robot dans une direction donnée :
Code : C++
#define AVANT 1
#define ARRIERE 0
#define GAUCHE 2
#define DROITE 3

#define VMAX 5

void move(int direction)
{
int m1 = 0, m2 = 0;
switch(direction)
{
case DROITE: m1 = 1; m2 = -1; break;
case GAUCHE: m1 = -1; m2 = 1; break;
case AVANT: m1 = 1; m2 = 1; break;
case ARRIERE: m1 = -1; m2 = -1; break;
}
handleS(SERVOG, m1*VMAX);
handleS(SERVOD, m2*VMAX);
}
Rien de bien compliqué : en fonction du déplacement, on indique dans quel sens doit se déplacer chaque moteur.

Code complet


On va, en utilisant toutes ces fonctions, demander au robot d'avancer tout droit :
Code : C++
#include <Servo.h>

#define AVANT 1
#define ARRIERE 0
#define GAUCHE 2
#define DROITE 3

#define SERVOG 1
#define SERVOD 0

#define VMAX 5

Servo servog;
Servo servod;

int getNeutral(int s)
{
if(s == SERVOG)
return 86;
else
return 84;
}


void handleS(int s, int speed)
{
//Vitesse :
// 0 -> 0; 1 -> 1; 2 -> 3; 3 -> 8; 4 -> 10; v => 5 -> 30
int tab[6] = {0,1,3,8,10,30};
int pos = getNeutral(s);

int acc;
if (speed < 0)
acc = - tab[abs(speed)];
else
acc = tab[speed];

if(s == SERVOG)
servog.write(pos += acc);
else
servod.write(pos -= acc);
}


void move(int direction)
{
int m1 = 0, m2 = 0;
switch(direction)
{
case DROITE: m1 = 1; m2 = -1; break;
case GAUCHE: m1 = -1; m2 = 1; break;
case AVANT: m1 = 1; m2 = 1; break;
case ARRIERE: m1 = -1; m2 = -1; break;
}
handleS(SERVOG, m1*VMAX);
handleS(SERVOD, m2*VMAX);
}



void setup()
{
servog.attach(10);
servod.attach(9);
move(AVANT);
}

void loop()
{
delay(15);
}
Cela est très simple avec la fonction move : move(AVANT);
Maintenant, on va faire faire avancer le robot pendant 8 secondes, lui faire faire un demi-tour, le faire avancer pendant 8 secondes, et ainsi de suite.
Pour faire tourner le robot, on va le faire tourner vers la gauche pendant un certain temps.
Personnellement, je trouve qu'il faut le laisser tourner 2 secondes pour qu'il fasse un demi-tour complet.
Ainsi, tout naturellement, le code est le suivant :
Code : C++
void loop()
{
move(AVANT);
delay(8000);
move(GAUCHE);
delay(2000);
}

Capteurs de contact : détecter les obstacles


Nous allons rajouter des capteurs de contact de type UPDD comme dans Cocotix. Il faut donc les connecter a deux pattes de l'arduino, et nous allons simplement regarder les états des deux pattes de l'arduino : si l'une est à 1, il faut enclencher un virage Image IPB.

Voici donc le schéma de ce montage :

Image IPB

Les deux résistances sont des résistances de "pull-down", reliées à la masse pour éviter d'avoir des pattes flottantes et pour forcer l'état normal des deux pattes à 0.

Le code pour faire éviter les obstacles fait reculer, puis de tourner le robot à la détection de chaque obstacle :
Code : C++
#define UPDDG 3 // on utilise la patte 2 pour le capteur de gauche et 4 pour le capteur de droite.
#define UPDDD 4

void handleUPDD(int updd)
{
if(digitalRead(updd) == HIGH) //Si le capteur est enclenché
{
move(ARRIERE); // on recule d'abord pendant 0.4 sec
delay(400);

if (updd == UPDDG) // Puis on tourne dans le sens inverse du capteur détecté...
{
move(DROITE);
}
else
{
move(GAUCHE);
}
delay(600); // ...pendant 0.6 sec
}
}

Voici le schéma complet du robot à ce stade :

Image IPB

Et le code complet :
Code : C++
 
#include <Servo.h>

#define AVANT 1
#define ARRIERE 0
#define GAUCHE 2
#define DROITE 3

#define SERVOG 1
#define SERVOD 0

#define UPDDG 3
#define UPDDD 4

#define VMAX 5

Servo servog;
Servo servod;

int getNeutral(int s)
{
if(s == SERVOG)
return 86;
else
return 84;
}


void handleS(int s, int speed)
{
//Vitesse :
// 0 -> 0; 1 -> 1; 2 -> 3; 3 -> 8; 4 -> 10; v => 5 -> 30
int tab[6] = {0,1,3,8,10,30};
int pos = getNeutral(s);

int acc;
if (speed < 0)
acc = - tab[abs(speed)];
else
acc = tab[speed];

if(s == SERVOG)
servog.write(pos += acc);
else
servod.write(pos -= acc);
}


void move(int direction)
{
int m1 = 0, m2 = 0;
switch(direction)
{
case DROITE: m1 = 1; m2 = -1; break;
case GAUCHE: m1 = -1; m2 = 1; break;
case AVANT: m1 = 1; m2 = 1; break;
case ARRIERE: m1 = -1; m2 = -1; break;
}
handleS(SERVOG, m1*VMAX);
handleS(SERVOD, m2*VMAX);
}

void handleUPDD(int updd)
{
if(digitalRead(updd) == HIGH)
{
move(ARRIERE);
delay(500);

if (updd == UPDDG)
{
move(DROITE);
}
else
{
move(GAUCHE);
}
delay(800);
}
}



void setup()
{
pinMode(UPDDG, INPUT);
pinMode(UPDDD, INPUT);

servog.attach(10);
servod.attach(9);
move(AVANT);
}

void loop()
{
handleUPDD(UPDDG);
handleUPDD(UPDDD);
move(AVANT);
delay(15);
}

Capteur de distance infrarouge

Pour finir je vous propose de rajouter un capteur de distance pour détecter les obstacles sans les percuter.
Nous allons utiliser un capteur Sharp gp2d120 qui permet de voir de 4 cm à 80 cm.
Le capteur est simplement composé de 3 fils, deux pour l'alimentation (+5v et masse) et un pour la sortie analogique : le capteur renvoie une tension comprise entre 0 et 5v proportionnel à la distance des objets.

Image IPB

Branchez donc le capteur sur l'arduino : le fil rouge sur le +5V, le fil noir à la masse, et le jaune sur la patte 4 de l'arduino, qui est une patte analogique : on peut directement lire la tension envoyée à cette patte.

Vous pouvez le fixer sur le robot comme sur cette image :

Image IPB


Pour lire une patte la valeur de la tension envoyée à la patte 4, il suffit de faire :
Code : C++
int v = analogRead(4);
Après quelques tests de mon capteur, j'ai constaté que si v était supérieur à 180 (obstacle à 10 cm), alors il fallait reculer pour éviter l'obstacle, alors que si v est supérieur à 100 (obstacle à 30 cm) il suffisait de ralentir d'un coté pour éviter l'obstacle.

Voici donc le code que je vous propose :
Code : C++
void sharp()
{
int v = analogRead(4);
if (v >= 180) // si on est à moins de 10 cm d'un obstacle
{
move(ARRIERE); //on recule
delay(300);
move(DROITE); //puis on part sur la droite
delay(900);
}
else if (v >= 100) //sinon si on est à moins de 30 cm d'un obstacle
{
handleS(SERVOG, VMAX);
handleS(SERVOD, 0); // on ralentit simplement la roue droite pour engager un virage en douceur
delay(1500);
}
}
Au final, voici le code complet :
Code : C++
#include <Servo.h>

#define AVANT 1
#define ARRIERE 0
#define GAUCHE 2
#define DROITE 3

#define SERVOG 1
#define SERVOD 0

#define UPDDG 3
#define UPDDD 4

#define SHARP 4

#define VMAX 5

Servo servog;
Servo servod;

int vLdr = 5;

int getNeutral(int s)
{
if(s == SERVOG)
return 86;
else
return 84;
}


void handleS(int s, int speed)
{
//Vitesse :
// 0 -> 0; 1 -> 1; 2 -> 3; 3 -> 8; 4 -> 10; v => 5 -> 30
int tab[6] = {0,1,3,8,10,30};
int pos = getNeutral(s);

int acc;
if (speed < 0)
acc = - tab[abs(speed)];
else
acc = tab[speed];

if(s == SERVOG)
servog.write(pos += acc);
else
servod.write(pos -= acc);
}


void move(int direction)
{
int m1 = 0, m2 = 0;
switch(direction)
{
case DROITE: m1 = 1; m2 = -1; break;
case GAUCHE: m1 = -1; m2 = 1; break;
case AVANT: m1 = 1; m2 = 1; break;
case ARRIERE: m1 = -1; m2 = -1; break;
}
handleS(SERVOG, m1*VMAX);
handleS(SERVOD, m2*VMAX);
}

void handleUPDD(int updd)
{
if(digitalRead(updd) == HIGH)
{
move(ARRIERE);
delay(500);

if (updd == UPDDG)
{
move(DROITE);
}
else
{
move(GAUCHE);
}
delay(800);
}
}

void sharp()
{
int v = analogRead(SHARP);
if (v >= 180)
{
move(ARRIERE);
delay(300);
move(DROITE);
delay(900);
}
else if (v >= 100)
{
handleS(SERVOG, VMAX);
handleS(SERVOD, 0);
delay(1500);
}
}
void setup()
{
pinMode(UPDDG, INPUT);
pinMode(UPDDD, INPUT);

Serial.begin(9600);
servog.attach(10);
servod.attach(9);
move(AVANT);
}

void loop()
{
handleUPDD(UPDDG);
handleUPDD(UPDDD);
sharp();
move(AVANT);
delay(100);
}
Comme vous pouvez le voir, rajouter un capteur n'a pas été difficile Image IPB.

Roby, robot basé sur une carte arduino.

Et voilà, c'est fini pour ce tutoriel.
Évidemment, la réalisation proposée ici n'est qu'une base à améliorer.
N'hésitez pas à nous faire par de vos améliorations, quelles soient électronique ou algorithmique soit en postant sur le forum, soit en créant votre tutoriel Image IPB.

Remerciement : cgizmo, avec qui j'ai écrit le code du robot.


R.Cerda, Un robot Raspberry Pi pour 100-120€

Publié sky99 le 12 avril 2013 - 01:10 in Robot complet

Description: Je vous propose un prototype de robot Raspberry Pi aux alentours d'une centaine d'euros (disons jusqu'à 120) tout compris. Ce tutoriel est fait pour que quelqu'un n'ayant aucune base puisse faire son robot, et le faire fonctionner.
Vous pourrez également trouver une version wiki en plusieurs pages distinctes de ce tutoriel, exportable en PDF, à cette adresse : 
http://nagashur.com/...e:r_cerda:start
R.Cerda, un robot Raspberry Pi à conduite différentielle - Partie 1/5 : Introduction et présentation du robot
Bonjour à tous! Dans ce post, je voudrais vous présenter mon second robot "officiel", cad qui a dépassé le niveau de prototype
de tests. Le précédent était basé sur un Arduino Uno, et m'a permis de comprendre les bases. Maintenant, celui ci est basé
sur un Raspberry Pi, et est une base qui permettra de faire bien plus.



Ce robot utilise deux moteurs DC (à courant continu) commandés par des L293D interfacés au Pi par un MCP23017. Un MCP3008 permet de lire les entrées d'un capteur ultrasonique Maxbotix LV-EZ4.

Le principe général
Ce robot possède deux roues parallèles, entraînées chacune par un moteur électrique DC. On utilise deux puces L293D en parallèle pour commander individuellement les deux moteurs. Le MCP3008 ajoute un convertisseur analogique au Raspberry pi, et grâce à cela, nous pouvons détecter la distance aux obstacles frontaux en utilisant un capteur ultrasonique ou infrarouge. Il y a un MCP23017 pour ajouter des GPIO.
Un ball caster sert de troisième point de contact, et le robot peut ainsi se déplacer, tout en étant stable, avec un minimum de friction.

Il y a 5 batteries dans un compartiment pouvant en accepter 6. Cela sert à avoir une tension de 5 à 6V, qui alimente directement les moteurs.
Dans le même temps, le courant qui sort des batteries est régulé par un petit composant qui s'assure ainsi de fournir du 5V en sorte, de façon stable.
Cette tension est alors fournie au Raspberry Pi, qui peut alors commander les puces et les moteurs. On pourrait envisager deux sources d'alimentation,
une pour le pi, et l'autre pour les moteurs, mais c'est plus simple avec une seule. Le régulateur de tension que j'ai utilisé est très efficace, et ne gaspille donc que très peu d’énergie.

Le capteur ultrasonique est placé sur la face avant du robot, et indique la distance aux obstacles se situant dans l'arc frontal. Ainsi, le robot peut tourner pour les éviter.


Liste du matériel
  • Raspberry Pi modèle B, 512Mo - environ 36€;
  • Carte SDHC 8Go - environ 10€, une 4Go suffit;
  • Une clé USB Wifi - inutile pour le robot même, je m'en sers pour le programmer à distance 10€;
  • Deux moteurs DC avec rapport réducteur 180:1 - environ 8€;
  • Deux roues -~5€;
  • Un "ball caster" -~1€, mais je vous conseille plutôt celui ci, à 3€;
  • Deux puces L293D ~4€;
  • Un MCP23017 pour ajouter 16 GPIO ~2.5€;
  • Un MCP3008 pour ajouter un convertisseur ADC ~ 3€;
  • Un capteur de distance ultrasonique (Maxbotix LV-EZ4) ~20€, mais on peut aussi utililiser un capteur IR ~12€ ;
  • Un convertisseur de tension produisant du 5V ~4€;
  • Une trappe à batteries ~2-3€ en comptant le jack power;
  • 5 Batteries AA ~10€;
  • Quelques fils ~3€;
  • Des "Jumper Wire ~3€".
En pratique, on s'en sort pour 80 à 120€, selon les options, si l'on a déjà des batteries, etc.
Voici une photo de l'ensemble du robot, le module de commande n'étant pas fixé sur le module de propulsion:
Image IPB


Contrôle des moteurs
Les moteurs sont contrôlés par deux puces L293D. Les deux sont en parallèle, car elles peuvent fournir 600mA au maximum par canal, alors que les moteurs en demandent 800. J'ai donc connecté les deux puces en parallèle, elles peuvent ainsi fournir jusqu'à 1200mA par canal, ce qui est largement suffisant. Le Raspberry Pi est connecté à un MCP23017, qui ajoute 16GPIO, et le MCP23017 est connecté aux L293D. Dans l'absolu, on peut se passer du MCP23017, et connecter directement les L293D aux GPIO du Raspberry, mais j'ai choisi d'utiliser cette puce, car j'en ai au moins une pour chacun de mes Pi, et que cela permet d'envisager des extensions ultérieures, en ajoutant par exemples des boutons sur les coins pour détecter d'éventuels contacts.
On peut voir le montage ci dessous :
Image IPB

Capteurs et détection des obstacles
Le principe du fonctionnement est donc d'éviter les obstacles détectés. Pour cela, j'utilise un Maxbotix LV-EZ4, qui détecte les objets grâce à un faisceau à ultrasons entre 6 pouces (environ 15cm) et 6 mètres. Le Pi est connecté à un convertisseur analogique vers numérique (un MCP3008), qui permettra de récupérer les données analogiques du capteur de distance. Le capteur ayant une sortie linéaire, la mesure est directement proportionnelle à la distance.
La puce de gauche sur la photo du dessus est le MCP3008, et on peut voir le capteur de distance à ultrasons sur la photo suivante, à l'avant du robot:
Image IPB
A noter que le gros oeil rouge ne fait pas partie du robot, c'est simplement un autre Raspberry pi.



Alimentation électrique et autonomie
J'ai testé l'autonomie d'un Raspberry Pi modèle alimenté par 5 batteries AA et un convertisseur de tension efficate, et streamant un flux webcam en wifi. Vous trouverez plus de détails sur ce post sur un autre forum (lien externe). On obtenait 3-4 heures d'autonomie. Ici, si on garde la clé Wifi, la consommation devrait être approximativement la même, environ 800mA. La consommation maximale de chaque moteur est de 800mA, ce qui fait qu'en théorie, si les moteurs forcent au maximum en permanence, nous diviserons l'autonomie par 3, soit environ 1h à 1h20.

En pratique, on peut s'attendre à ce que les moteurs ne forcent pas à fond en permanence, donc en étant conservateurs, disons qu'ils seront à 50%.
Cela signifie que nous aurons donc 800mA de consommation pour les deux moteurs, donc un total de 1600mA. Les batteries étant données pour 2700mAh,
on obtient donc théoriquement 2700/1600=1h36minutes. En pratique, si on divise par 2 l'autonomie du pi tout seul, on obtient 1h30 à 2h d'autonomie théorique, donc ça colle assez bien.

Ici, je parle d'un scénario ou le robot roulerait en permanence... En pratique, on peut également s'attendre à ce qu'il ne se déplace pas tout le temps, s'il fait des tâches diverses. Dans ce cas, on gagnerait encore en autonomie. Mais on a une estimation de l'autonomie minimale
Vous pouvez voir sur les images suivantes (cliquables pour une version HD) les batteries et le convertisseur :

Image IPBImage IPB



Le programme
Le programme du robot est alors assez simple, puisqu'il s'agit de l'algo suivant :
boucle infinie :
distanceObstacle=lireDistanceCapteurUltrasons();
Si (distanceObstacle<8pouces) reculer;
Sinon Si (distanceObstacle<12pouces) tourner à gauche;
Sinon avancer;
Attendre(5ms);

Le code est fait en python, et le robot évalue les données toutes les 5ms.
L’étroitesse du faisceau cause quelques problèmes, il faudra sans doute adapter
les distances, ou monter le détecteur sur un servomoteur pour l'orienter.

Plan du tutoriel
Après cette présentation du robot, voyons le plan du tutoriel.
Nous verrons d'abord en page 2 comment choisir les composants du robot, et nous choisirons une configuration type.
Nous verrons ensuite en page 3 le schéma fonctionnel du robot, ainsi que le schéma de la partie électronique.
En page 4 nous détaillerons les instructions d'assemblage et des idées pour faire un châssis économique et solide.
Enfin, en page 5, nous programmerons notre robot qui sera alors assemblé.








=================================================================================================================
=================================================================================================================
=================================================================================================================

Partie 2 - Faire un robot simple mais extensible avec le Raspberry Pi : le choix du matériel
Dans cette partie, nous étudierons une liste de matériel, pièces, et alternatives possibles. Ce n'est pas le robot ultime, ni un cylon, mais un petit robot sympa, sur lequel
on peut se faire la main, et prévu pour pouvoir beaucoup évoluer. Notez bien qu'ici je vais vous présenter une longue liste de matériel, mais que je retiendrai une configuration pour la suite.
Si vous choisissez d'autres solutions, il y aura nécessairement un peu d'adaptation à faire, mais rien d'extrêmement compliqué.
Pour un robot simple, il faut:
  • un système de propulsion;
  • De quoi transformer la rotation des moteurs en mouvement horizontal;
  • un circuit de commande;
  • un système fournissant l'alimentation électrique;
  • éventuellement des capteurs.
Voyons donc ce qu'il faut en faisant "pas cher" (sachant que tout sera réutilisable).


1-Le système de propulsion : motorisation
On part sur un robot à conduite différentielle, c'est à dire disposant de deux moteurs. Pour avancer, les deux moteurs tournent dans le sens A, pour reculer ils tournent dans le sens B, et pour tourner on fait les deux tourner en sens inverse. On peut ainsi avancer, reculer, tourner à droite, et tourner à gauche.
En bref, il faut donc deux moteurs, ou tout autre système capable de tourner dans un sens ou dans l'autre. On a donc plusieurs solutions :
  • La récupération : les lecteurs CD/DVD possèdent chacun un petit moteur DC qui permet d'ouvrir/fermer le chariot, et ce moteur à une petite boite de vitesse. Mon premier robot, R.Berion, utilisait ce genre de systèmes. Il faut toutefois bidouiller un peu, mais c'est une solution qui permet de faire de la récup.
  • Des moteurs DC avec boite de vitesse : c'est une option durable et économique, ce genre de moteurs vaut environ 5$ pièce, donc on s'en sort pour 10$ sans compter les roues.
  • Des servomoteurs à rotation continue : on peut trouver des servomoteurs pouvant tourner à l'infini dans un sens ou dans l'autre. C'est la solution la plus chère, mais c'est extrêmement facile à contrôler, et on élimine le besoin d'avoir un circuit de commande supplémentaire. En revanche, chaque servo vaut environ 14$ sur Adafruit (soit une dépense nécéssaire de 28$), et ces servos ne peuvent pas servir à des usages classiques de servomoteurs, pour orienter un bidule quelconque, puisqu'on a plus d'informations sur l'angle ou est tourné le servo. Ils sont difficilement recyclables pour d'autres projets. D'autre part, on a finalement peu de contrôle sur chaque moteur, car on peut en gros les faire tourner dans un sens, dans l'autre, ou les stopper, mais pas trop contrôler leur vitesse de rotation (ou alors plus difficilement). En outre, il faut faire attention au sens de branchement, sous peine de les brûler. En revanche, ils ont pas mal de couple.
La solution de la récup est intéressante, le problème est donc de pouvoir fixer des roues dessus. Dans mon cas, j'ai trouvé un bout de plastique sur lequel je pouvais visser les roues de mes servos (dont j'avais grillé un des deux, et du coup avec un seul servo on ne peut pas trop avancer ^^). En revanche, comme c'est de la récup, rien n'interdit de coller un vieux CD sur l'axe de rotation pour faire la roue...
Et on peut ajouter un élastique sur le contour du CD pour faire un pneu et avoir un peu d'adhérence.

La solution des moteurs DC est ma préférée, car elle est économique, et pour le prix d'un servo, on a 3 moteurs DC, ce qui permet d'en avoir un de rechange par exemple, mais on peut facilement décider d'en prendre 4 ou 6 pour faire un véhicule à 4 ou 6 roues motrices. De plus, pour ces moteurs, il existe une très grande variété de roues et chenilles adaptées, et le système fait qu'on peut facilement changer les roues. Ces moteurs intègrent une boite de vitesse réductrice avec un rapport X:1, ce qui signifie que quand le moteur fait X tours, l'axe de la roue en fait 1. C'est très important, car sans cela, le couple serait trop faible,et le robot n'avancerait pas. Plus le rapport réducteur est important, moins les roues tourneront vite (et donc plus le robot sera lent), mais plus il aura de couple, et sera capable
d'emporter une charge importante/de continuer à avancer malgré des obstacles. Il existe des moteurs avec boite de vitesse metallique, mais c'est plus cher, au moins 15$ pour les plus petits (par contre, ils sont fatalement plus solides). Je conseillerais des "pololu plastic gearmotors" On en trouve principalement en 120:1 et 180:1. Prenez ceux qui ont le "3mm D-Shaft", il s'agit de l'axe du rotor, qui fait 3mm de diamètre, en forme de D. Prenez ceux qui ont l'axe en métal, ce sera plus solide. L'intérêt c'est qu'on a besoin de rien d'autre pour fixer les roues, et qu'en plus les roues s'enfoncent sur cet axe sans outil, et restent solidement en place. Et en plus il existe une très grande variété de roues adaptées à ces modèles. Je n'ai pas regardé pour les axes de 2mm, ni ceux en plastique. Et en plus, si plus tard vous décidez d'upgrader avec des "micro metal gearmotors", les roues seront compatibles. Pour moi l'idée c'est d'essayer de faire que tous mes robots puissent partager des éléments, ça rend la logistique plus facile Image IPB
 
Pour le choix du site, pololu a pas mal de bidules "robotique". En revanche, ils n'ont pas beaucoup d'autres catégories. Sur pololu, j'ai commandé uniquement mes moteurs et roues. Toutefois, Alpha-Crucis a les moteurs de pololu, leurs roues, mais également tout plein d'autres items. De plus, c'est un site français, qui vous expédie par colissimo, pour 5€ de FDP, et gratuitement au delà de 250€. Bien sur, pour les DOM, ça n'a rien à voir, mais ça reste modéré, avec 30€ de FDP pour une commande d'environ 250€, et je crois bien qu'ils m'ont décompté la TVA, ce qui revient au même (en Guadeloupe on est pas censés payer la TVA "normale", mais la douane peut prélever une taxe à l'arrivée. Toutefois, par colissimo et sur des montants de cet ordre, il ne le font presque jamais. En plus pour des composants électroniques, ça fait une facture avec des dizaines de références à petit coût, le douanier n'aura pas envie de lire tout ça pour calculer les taxes). Bref, j'ai commandé chez eux hier, et ils m'ont l'air vraiment bien, ça risque d'être mon second site apres Adafruit.Seul défaut, les fiches ne sont pas toujours complètes, mais le catalogue est énorme (ils ont AUSSI des trucs d'Adafruit!). Au passage, Snootlab va bientôt distribuer les produits pololu, donc encore une bonne source d'approvisionnement!

Enfin bref, ça fait 3.77€ par moteur sur Alpha-Crucis, ou 5.49$ par moteur chez Pololu. Il en faut au moins 2, donc ça fait 7.54€ pour les moteurs, ou 10.98$ sur pololu. Prenez en bien deux ayant le même rapport réducteur. Le "droit" ou "coudé", c'est à vous de voir. Le droit est plus long, mais moins large, le coudé c'est le contraire. Dans tous les cas, ça ne change pas grand chose, juste peut être l'organisation de l'espace. Moi j'en ai pris de chaque, mais j'aime bien les droits, parcequ'on peut facilement les coller sur le bord du châssis du robot sans avoir a découper le dit châssis. Mais on peut aussi fixer les coudés sous le châssis, sans faire de découpe... Bref, c'est un choix à faire.

2-Transformer la rotation des moteurs en mouvement du robot : transmettre la puissance à la "route".
Maintenant que nous avons des moteurs, il faut transmettre la puissance à la "route", pour faire bouger le robot. On a deux solutions simples :
  • Deux roues, qui seront accompagnées d'une troisième roue omnidirectionnelle (en fait, une bille dans un logement) qui servira de troisième point de contact -le nom anglais c'est "ball caster"-;
  • Des chenilles, qui sont auto-suffisantes.
Pourquoi choisir l'un ou l'autre? Les roues ont l'avantage d'être disponibles en de multiples dimensions, de 2-3cm de diamètre à presque 10. On en trouve des larges, des étroites, avec divers designs. Plus la roue sera grande, plus le robot ira vite. En revanche, le couple disponible sera moins important, puisque la distance à l'axe sera supérieure (le couple est exprimé en g-cm. Si votre moteur à un couple de 1kg-cm, il pourra faire tourner une charge de 1kg à 1cm, 500g à 2cm, etc.) Pour ma part, j'ai pris des roues de 4,6 et 9cm. Plus la roue est petite, plus le bas du robot sera proche du sol, et donc plus les obstacles pourront le bloquer. L'avantage de la roue est donc de pouvoir l'adapter au terrain visé, et pouvoir ainsi ajuster la vitesse/le couple du robot. L’inconvénient, c'est qu'il faut un troisième point de contact, le "ball caster". Et le ball caster franchit bien moins facilement les obstacles que les roues. Cependant, plus le Ball caster est gros, plus ça sera facile.
En face, les chenilles sont disponibles souvent en diverses longueurs, mais pas tellement pour des diamètres de roues différents. En revanche, la chenille est "tout terrain", et il ne faut rien d'autre que le kit de chenilles. Donc sur une surface irrégulière, et même avec des obstacles, la chenille pourra mieux se débrouiller. Elle devrait passer sans problème par dessus un gros câble d'alimentation de PC au sol, la ou la bille du ball caster pourrait rester bloquée. Et s'il s'agit d'aller sur du bitume, de la terre, ou autre, le Ball caster ne passera tout simplement pas. En revanche, la chenille sera sans doute plus lente, du fait du faible diamètre des roues d'entrainement de la chenille. De plus le système de chenille provoque une résistance, et réduit le couple disponible/augmente la puissance consommée pour un couple donné. Par contre la stabilité devrait être impeccable, et il n'y a presque aucun risque de se retrouver coincé.
Notez toutefois qu'avec 4 roues motrices, on évite la nécessite du Ball caster et on peut aller un peu partout, et franchir beaucoup d'obstacles avec de grandes roues. On peut également avoir 4 roues, dont deux motrices. Idéalement il faudrait que les roues non motrices puissent tourner, mais ça peut parfaitement fonctionner même si elles sont fixes.

En bref : en appartement, sur des surfaces relativement régulières, les roues et le ball caster seront plus efficaces, iront plus vite, et gaspilleront moins d'énergie que les chenilles. En revanche, celles ci sont plus adaptées au terrains difficiles, et peuvent franchir des obstacles divers facilement. De plus , si on a le kit de chenilles, il n'est pas nécéssaire d'acheter autre chose, et on a une surface de contact importante avec le sol pour transmettre la puissance, mais également une grande stabilité de ce fait. On risque peu de patiner, glisser, déraper... Sans compter le look "cool" des chenilles.

Donc, au choix :   
Des chenilles de 9cm de long, pour 8.91€ , et les mêmes chenilles de 9cm de long sur pololu pour 12.95$;
Des chenilles plus longues (12-15cm peut être) pour 10.28€ , et les mêmes chenilles longues sur pololu pour 14.95$;
 
Sachant qu'un seul kit est nécessaire, et contient les deux chenilles avec tout l'équipement qui va avec (les "roues" de 35mm d'entrainement et libres, les axes, etc), cela fait environ 9 ou 10€ selon la longueur souhaitée. Pour ma part, je pense qu'il faudrait idéalement que la chenille soit aussi longue ou un peu plus longue que le robot. Ainsi, la partie avant de la chenille peut entrer en contact avec l'obstacle, levant le robot, et permettant le franchissement. Si le bord du robot est devant la chenille, le bord pourra se coincer contre l'obstacle, et le robot ne pourra pas avancer.
OU BIEN
  • n'importe quelle paire de roues de cette section (donc pas les "idler sprockets", elles n'ont pas la fixation pour l'axe de moteur. Au mieux, ça peut faire des roues libres, si vous prenez également deux roues du même diamètre avec la fixation moteur, qui seront entrainées par les deux moteurs. Dans ce cas, vous aurez 4 roues dont 2 motrices, inutle de prendre le ball caster) . Les roues sont vendues par paire, inutile d'en acheter 2 fois Image IPB
  • n'importe quel ball caster de cette section (ou n'importe quel bal caster tout court!), sachant que les plus gros franchissent mieux les obstacles. Je penche pour les 1/2 pouce a 1 pouce.
Cela fait donc 7 à 10$ pour les roues selon la taille (une paire), plus 3 a 7$ pour le ball caster, soit 10 a 17$ pour une configuration complète de roues sur pololu.
Chez alpha-crucis, il faudra de la même façon prendre n'importe quel ball caster (roulette, en français, en fait!) de cette section, pour 2 à 6€;
et l'une de ces paires de roues :
 
De manière générale, les "Pololu wheels". Vérifiez qu'il y a le trou en "D" pour l'axe du moteur, de 3mm.
ça revient donc de 7 à 13.5€ pour les roues et la roulette. Les roues sont également vendues par paire. Pour le choix de la couleur, une couleur claire peut servir
à réfléchir un faisceau, ce qui pourra servir à faire un détecteur permettant de mesurer la rotation de la roue. Toutefois on peut aussi utiliser un faisceau de part
et d'autre qui sera interrompu par les montants de la roue s'il y en a... En pratique, on peut sans doute adapter n'importe quoi à n'importe quel système.
La couleur des roues peut également servir à reconnaitre les robots, ou si on a des roues de couleur différentes, à déterminer de quel coté on voit le robot
(dans une optique "computer vision", ou un algo analyserait avec openCV le flux d'une webcam, et pourrait identifier le sens dans lequel le robot se trouve par ex.
Mais on peut aussi mettre un autocollant différent de chaque coté, ou n'importe quoi d'autre.)

Si vous optez pour les servomoteurs à rotation continue, il faudra donc également prendre une roulette (n'importe laquelle ira), ou alors des roues libres.

3-Le circuit de commande, et des puces additionnelles facultatives
Nous avons des moteurs, des roues/chenilles adaptées, maintenant il faut commander tout cela. Pour appliquer l'algorithme de conduite différentielle, il faut un circuit capable
de faire tourner les moteurs dans un sens ou dans l'autre à volonté. Nous allons utiliser pour cela des circuits implémentant des ponts en H. On utilisera donc deux puces L293D
pour commander nos moteurs. Pourquoi deux? chaque puce L293D est donnée pour 600mA par canal. Les moteurs que nous avons sélectionné consomment jusqu'à 800mA
s'ils sont bloqués. En mettant les deux L293D en parallèle, on double la puissance disponible, avec du coup 1200mA par canal. On peut aussi prendre un seul L293D, et espérer
qu'il tienne le coup en cas de blocage des moteurs. ça devrait marcher, mais ce n'est pas un comportement garanti. Notez qu'en refroidissant les puces (un petit rad sur la puce)
on peut augmenter la puissance disponible, donc on peut également se contenter d'une puce mieux refroidie. Pour ma part, j'ai pris 2 puces pour avoir plus de puissance disponible,
et les puces étant peu chères, j'ai trouvé plus simple d'en prendre 2.

Il y a déjà un tutoriel sur l'utilisation de la puce L293D pour commander un ou deux moteurs avec le Raspberry Pi sur PCInpact (je le porterai sur ce forum plus tard). La seule différence est qu'ici nous mettrons les deux puces en parallèle. En pratique, le câblage sera le même, sauf qu'on ajoutera une seconde puce en connectant les pattes correspondantes des deux puces entre elles. Mais on verra cet aspect plus tard.

Si vous avez choisi les servomoteurs, ces puces ne sont pas nécessaires.
En pratique, il faudra donc :
  • Deux L293D pour 2.3€ pièce soit 4.6€ au total;
Il existe aussi les puces SN754410, qui sont compatibles broche à broche avec les LM293D (on peut donc utiliser exactement le même câblage d'après pololu). Dans la doc, je lis 1A de courant en sortie. Cependant, je ne parviens toujours pas à comprendre si c'est 1A au total, ou 1A par canal. Si c’est 1A par canal, alors cette puce permet de remplacer les deux L293D dans notre montage, si c'est 1A au total, elle n'a aucun intérêt par rapport aux L293D. J'en ai pris 3, mais je ne les ai pas encore testées. Vous pouvez tenter, si vous comprenez mieux la doc que moi, faites moi signe. j'écrirai à Pololu pour leur demander. Sinon dans le doute, les L293D, je peux vous confirmer qu'elles fonctionneront pour le circuit, pour les avoir testées sur 3 prototypes de robots. Mais si vous commandez chez pololu, seule la SN754410 est disponible, et du coup je vous conseille d'en prendre au moins 2 pour être sur (deux en parallèle, et pourquoi pas une troisième au cas ou, en stock).
Dans tous les cas, le schéma de câblage sera le même.

Ajouter des GPIO au Raspberry Pi (optionnel, mais pratique, facile, et peu coûteux)
Sur le schéma que je vous fournirai dans un premier temps il y aura également une puce MCP23017, qui permet d'ajouter 16GPIO (je ferai un second schéma simplifié sans cette puce). Il est possible de se passer de cette puce, le souci c'est que les puces de contrôle des moteurs utilisent 5 à 6 GPIO sur les 17 du Pi. Avec le MCP23017, on utilise 2GPIO spécifiques, qui restent de plus utilisables par d'autres puces, et on ajoute ainsi 16GPIO protégés, pouvant qui plus est fournir plus de courant que les GPIO normaux. Cette puce ne coûte pas très cher, puisque le MCP23017 est à 2.88€ sur Alpha-Crucis. Si cette puce est trop grosse,
mais que vous voulez quand même utiliser ce principe (ajouter des GPIO protégés), il est possible d'utiliser un MCP3008, qui coute 1.95$ sur Adafruit et ajoute 8GPIO et moins de pattes.

J'ai fait un tutoriel sur le forum de PCInpact sur l'ajout de GPIO au Raspberry Pi en utilisant le MCP23017 ou le MCP23008.

Ajouter un circuit convertisseur analogique-numérique pour lire des capteurs analogiques (optionnel, mais très pratique, simple et économique)
De même, sur le schéma d'un robot de base, je vais utiliser une puce MCP3008, qui permet d'ajouter 8 entrées analogiques au Raspberry Pi. Cette puce n'est pas nécessaire,
et on peut faire un robot télécommandé/contrôlé à distance/utilisant une webcam pour se déplacer, de sorte que le robot n'aura pas de capteurs analogiques à lire.
Toutefois, je recommande fortement cette puce, car le MCP3008 est à 3.22€ sur Alpha-Crucis, et pourrait permettre d'ajouter une grande variété de systèmes extrêmement utiles. Par exemple,
un capteur de distance pour détecter automatiquement les obstacles, mais aussi un capteur infrarouge orienté vers le sol devant le robot, qui permettrait de détecter les trous
pour éviter de tomber dedans, ce qui peut être utile même en contrôle manuel. On peut imaginer toutes sortes de capteurs qui permettraient au robot de s'adapter automatiquement
à diverses situations, ou même tout simplement un capteur de courant pour que le robot puisse mesurer sa consommation, on peut utiliser la puce pour mesurer la tension
des batteries et estimer l'autonomie restante, ou encore utiliser des capteurs divers pour mesurer le nombre de rotations des roues, un accéléromètre, gyroscope ou autres
pour avoir des infos sur le déplacement du robot... Bref, une puce très utile, rajoutant donc 8 entrées analogiques, en échange de 4GPIO.

Il y a un tutoriel sur la façon de connecter un MCP3008 au Raspberry pi pour lire des valeurs analogiques sur le forum de PCinpact, et d'autres tutoriels montrant comment connecter des capteurs dessus (luminosité (lien externe), température (lien externe), distance (lien externe), ...)

4-L'alimentation électrique de l'ensemble
Maintenant, il faut alimenter le Raspberry Pi, mais également les moteurs. Pour cela, il faudra une source électrique de 5V, stable, pour le Raspberry Pi, et
une source de 5 ou 6V non régulée pour les moteurs. On aura besoin d'une puissance de 700mA au minimum pour le Pi, et 800mA au maximum par moteur,
soit 1600mA au maximum pour les moteurs. Il nous faut donc une source capable de débiter 2300mA ou plus. Avec des piles AA rechargeables, il nous en faudrait 5
de 2300mAh ou plus. avec des piles non rechargeables, 4 suffiront. Si on alimente tout avec des piles rechargeables, il faudra un régulateur de tension pour le Raspberry Pi.
La meilleure option que j'ai pu trouver jusqu'ici, c'est le régulateur S7V7F5 de chez pololu, qui vaut 4.95$, et est une petite merveille. Il peut fournir du 5V à partir de tensions allant de 2.7 à 11.8V. Si il fournit une tension supérieure à la tension d'entrée, il peut fournir 500mA. Si il baisse la tension, il fournit 1000mA. Il est réellement minuscule, et ne consomme rien (0.1mA) quand il ne fait rien. Son efficacité énergétique est de 90%, ce qui veut dire qu'il ne gaspille que 10% de l’énergie fournie pour la conversion.Dans le même style, chez Alpha-Crucis, il n'y a malheureusement que le D15V35F5S3, pour 10€. Il est bien plus cher, et ne peut réguler la tension qu'à la baisse, mais a toujours une
efficacité de 90%. Il est un peu plus gros, mais en échange peut fournir jusqu'à 3.5A. On peut donc imaginer s'en servir pour réguler une batterie plus grosse et plus puissante,
et fournir 5V au pi, aux moteurs et à tout autre système 5V.

Une autre solution, très économique, mais peu efficace, est d'utiliser un simple régulateur linéaire, comme le 7805, à 1.2€ sur Alpha-Curcis, très simple a utiliser, mais nécessitant une tension d'entrée plus importante (7V au moins) et gaspillant une partie plus importante de l'énergie, puisque la différence de tension entre l'entrée et la sortie est consommée avec le même courant que ce celui qui est consommé en sortie. Donc à 1A, pour une entrée de 7V, on consomme 2W pour la régulation, et cette énergie est gaspillée en chaleur. La puissance utile disponible est donc de 5W, ce qui fait qu'on gaspille 40% de l'énergie.

On peut également utiliser une source 5V et se passer des régulateurs, comme nous le verrons plus bas.

Il faudra alors un endroit ou mettre les batteries, par exemple:

    Un compartiment pour 6 batteriesAA, qu'on modifiera un peu pour n'en utiliser que 5, pour 4€
    Un compartiment pour 2 batteries AA en série avec un compartiment pour 3 Batteries AA, pour un peu moins de 3€ au total.

Il existe une dernière solution, c'est d'avoir une batterie régulée 5V, telle que celle ci sur Alpha-Crucis, pour 22€. Elle peut fournir 5V avec 2A en sortie, ce qui sera assez pour à la fois
alimenter le pi et les moteurs dans la plupart des cas. Il manque 10% de puissance, mais ça devrait passer. J'en ai commandé 2, je ferai l'essai. Toujours en utilisant cette batterie, il est
également possible d'ajouter une trappe de 4 Batteries AA pour l'alimentation des moteurs (non régulée), et d'alimenter le Pi avec la batterie 5V régulée. Dans les deux cas, on se passe
du régulateur de tension. L'utilisation d'un pack de 4 Batteries AA permet de séparer les deux sources d'alimentations, et c'est en théorie mieux. L'intérêt de la batterie régulée, c'est
qu'elle utilise des batteries au lithium qui sont plus légères à capacité égale. On gagne donc sur la masse du robot, et on peut sans doute démonter la batterie pour enlever le panneau solaire, et
la coque pour réduire la taille si on veut. Attention toutefois au batteries, celles au Lithium étant fragiles et dangereuses quand on les malmène.

Il y a un post décrivant un montage utilisant des batteries AA et un régulateur de tension pour alimenter un Raspberry Pi autonome, ainsi que des tests d'autonomie (lien externe).

5-Les capteurs
On peut se passer de capteurs, et télécommander le robot. On peut également utiliser une webcam pour analyser les images et se déplacer ainsi (plus complexe, il faut maitriser openCV ou autres librairies de vision informatique)
Il est cependant possible d'ajouter des capteurs simples, tels que des capteurs de distance en infrarouge, ou à ultrasons, pour détecter les obstacles Le cout sera de 10 ou 20€.
On peut également utiliser des poutons poussoirs pour faire des capteurs de contact. n'importe quel bouton poussoir fera l'affaire, mais certains sont plus adaptés, tels que ceux ci :
 
    Microswitch avec levier long, pour environ 1.25€
    Microswitch avec levier à roulette, pour 1.6€.
 
Avec deux de ces switches, on peut détecter de quel coté se trouve l'obstacle, et ainsi éviter les obstacles. Pour ces switches, on a pas besoin d'utiliser le convertisseur analogique, uniquement des entrées numériques.
On peut ensuite ajouter de nombreux autres capteurs, par exemple pour détecter les trous, avec un capteur infrarouge à faible portée, un accéléromètre, un gyroscope pour le guidage inertiel, etc...

On peut également trouver des capteurs purement numériques, dont certains utilisent par exemple le protocole I2C pour communiquer. Dans ce cas, on utilisera pas le MCP3008.

Voici au passage un petit récapitulatif sur les divers capteurs les plus courants.
Il y a également un tutoriel sur la lecture d'un bouton poussoir (pour les microswitches), et un autre tutoriel sur l'utilisation d'un capteur de distance ultrasonique ou infrarouge.

Récapitulatif
En fin de compte, voici des "packs" mis a jour, récapitulant le matériel nécéssaire.
Il nous faut bien sur un Raspberry Pi, des jumper wire, une breadboard, une carte SD avec Raspbian (ou autre) dessus, et le câble d'alimentation. Je ne reviendrai pas
la dessus, si vous en êtes à faire un robot, c'est que vous avez déjà probablement ces composants et sans doute déjà essayé divers montages. Passons donc maintenant
aux éléments spécifiques au robot.

Robot de base, avec moteurs DC et chenilles
Il nous faudra donc :
 
    Deux puces L293D - 4,5€
    Deux moteurs DC 120:1 ou 180:1 - 7.5€
    Un kit de chenilles - 10€
    Un circuit à d'alimentation 1-10€
    Une boite à batteries AA - 2€
    5 Piles AA rechargeables - 10€
 
Ces composants sont les composants minimaux pour faire ce robot à chenille. En l'état, il n'aura pas de capteurs, et ne pourra donc être que télécommandé.
On a donc un total de 44€ au maximum si l'on compte les batteries AA. Une autre solution est de remplacer le circuit d'alimentation, la boite à batteries et
les piles rechargeables par une batterie portable USB, ce qui revient à 22€, soit un total d'exactement 44€.

Robot de base, avec moteurs DC et roues+roulette
On conserve le même matériel que pour le précédent, sauf qu'on remplace les chenilles par des roues et une roulette :

    petites roues larges 42*19mm - 5€
    roulette d'un demi pouce, en plastique - 3€

Du coup on passe a 42€.
On peut utiliser de plus grandes roues :

    grandes roues 90*10mm - 7€
    roulette de 0.75 pouces en métal - 3.3€

Pour cette variante, le prix reste à 44€.

Options
Voyons maintenant quelques options intéressantes, qui seront utilisées pour le prochain tutoriel :

    Le MCP3008 pour lire les valeurs de capteurs analogiques, +3.22€
    Le MCP23017 pour ajouter 16GPIO protégés, + 2.88€

Ces deux puces extrêmement utiles augmenteront la facture de 6.1€, ce qui nous fait un total de 50€.
On peut enfin ajouter des capteurs :

    deux Microswitch avec levier long, pour un total de +2.5€
    Un capteur de distance Ultrasonique +20€ ou à infrarouges, +10€
On ajoute donc 22.5€ ou 12.5€ pour un grand total de 72.5€ au maximum (62.5€ en infrarouge, 52.5€ avec juste les capteurs de contact).

A partir de là, vous avez tout le matériel nécessaire à la construction d'un robot (plus ou moins autonome selon les capteurs), et pour chaque élément utilisé, il y a un tutoriel dans (ce fil de discussion (lien externe)). Je vais toutefois faire d'autres tutoriels, spécifiques, reprenant dans les grandes lignes ce qu'il faut faire pour monter ce robot, le programmer, et l'améliorer.


La partie suivante sera consacrée au schéma de principe du robot, et au schéma de montage électronique.




=================================================================================================================
=================================================================================================================
=================================================================================================================
Partie 3/5 : schéma de principe et montage électronique du robot.
Nous allons maintenant détailler le principe général du robot, avant de voir le schéma électronique.
Nous reprenons donc les pièces dont nous avons parlé juste avant, dans la seconde partie.

Pour ce modèle, nous partons sur un robot à deux moteurs (roues ou chenilles, le montage électronique est le même!
Pour cet exemple, le robot sera représenté avec des chenilles, mais le principe est valable pour 2 roues motrices et deux roues libres,
deux roues motrices et une roulette, ou des chenilles. L'important est que les roues motrices doivent être entraînées par des moteurs DC.)

Principe de fonctionnement
Voyons maintenant le principe de fonctionnement général. Pour cela, voici un schéma fonctionnel :
Image IPB

Le Raspberry et l'alimentation
Nous avons donc un Raspberry Pi, modèle A ou B. L'alimentation électrique provient d'une source 5V régulée depuis 5 Batteries AA. Cela nous permet d'avoir entre 5 et 6V (selon la charge des batteries) pour le moteur, et 5V pour le Raspberry Pi. Il est bien sur possible d'utiliser deux sources séparées, ou toute autre configuration compatible avec vos moteurs.

Le MCP23017 : plus de GPIO.
Le Raspberry Pi est connecté à un MCP23017 via le bus I2C, et rajoute 16GPIO. Cela nous permet de prévoir large, et de pouvoir étendre les capacités du robot.
On pourra ainsi, par exemple, ajouter des bumpers (boutons poussoirs) pour détecter les collisions. Comme nous avons 16 GPIO, on peut donc en mettre une bonne quantité, d'autant que ces capteurs sont peu chers.

La commande des moteurs : les L293D
Deux puces L293D sont branchées en parallèle, et connectées à 5 ou 6 broches du MCP23017 (dans le schéma, je connecterai à 6 broches. Cela permet de pouvoir faire fonctionner séparément un moteur ou l'autre. De base, ce n'est pas utile, et on peut commander l'activation des deux moteurs avec un seul GPIO, et simplifier légèrement la programmation. Toutefois, utiliser deux GPIO nous permettra de programmer plus précisément les déplacements, la rotation, et par exemple ajuster la vitesse de chaque roue indépendamment).
Les L293D sont connectés via 4 fils aux deux moteurs, et les commanderont par ce biais. Au passage, les batteries sont connectées directement aux L293D (sans régulation donc) pour fournir le +Vmotor, la tension qui sera appliquée aux moteurs.

Lecture de capteurs analogiques : MCP3008.
Le MCP3008 est connecté au Raspberry par le bus SPI, et permet d'ajouter 8 entrées analogiques. Nous pourrons donc lire les valeurs de 8 capteurs analogiques de cette façon. En pratique, pour ce modèle, nous utiliserons un capteur ultrasonique Maxbotix (cela fonctionne avec d'autres capteurs ultrasoniques), mais il est possible d'utiliser un capteur de distance infrarouge avec le même montage, et un code source sensiblement similaire. Le capteur de distance sera utilisé pour détecter les obstacles. Si toutefois vous décidez d'utiliser uniquement des switchs pour la détection de contact, le MCP3008 n'est plus nécessaire.

Schéma électronique du robot
Voyons maintenant le schéma électronique du robot, décrivant le câblage à réaliser pour faire fonctionner notre robot:
Image IPB
Si vous suivez ce câblage, vous disposerez d'un robot fonctionnel. Une seule chose n'est pas présente sur ce schéma : la méthode utilisée pour mettre les deux L293D en parallèle. Pour cela, il suffit de connecter la patte 1 de la puce A avec la patte 1 de la puce B, et ainsi de suite pour les 15 autres pattes. C'est assez simple à faire avec du jumper wire. Cela permet de cumuler la puissance disponible pour les deux puces.

Il est à noter qu'il s'agit d'UN schéma de câblage possible, mais on peut utiliser n'importe lesquels des GPIO du MCP23017. J'ai utilisé ceux que vous voyez sur le schéma afin de faire en sorte que celui ci soit le plus lisible possible, en minimisant les croisements.

Je ne détaillerai pas outre mesure les câblages, car il s'agit simplement d'une synthèse de tutoriels (liens externes): =================================================================================================================
=================================================================================================================
=================================================================================================================
Partie 4/5 : montage pratique du robot : construction d'un châssis, fixation des roues, etc.
Matériel et matériaux nécessaire
Poursuivons donc sur la configuration précédente. Dans cet exemple, on utilisera deux roues et une roulette.
Avant tout résumons le matériel :
  • Un Raspberry Pi;
  • Une grande breadboard ;
  • Deux L293D;
  • Un MCP23017;
  • Un MCP3008;
  • Un Maxbotix LV-EZ0, 1, 2, 3, ou 4 , ou bien un capteur infrarouge, ou tout autre capteur de distance (facultatif, si vous utilisez uniquement les capteurs de contact);
  • Du fil électrique (pour électronique, pas du gros câble);
  • Une trappe pour 6 batteries AA;
  • Deux roues;
  • Une roulette;
  • Une carte SD;
  • Du jumper wire;
  • un convertisseur DC-DC fournissant du 5V
  • Une planche de bois d'environ 20cm*15-20cm;
  • Une petite planchette pour visser la roulette (récupérez une chute, par ex un bout de 5*5cm);
  • Des vis à bois de 3mm de diametre, et de 12-20mm de long;
  • Deux petites plaques de plexi, plastique, ou n'importe quel matériau que vous pourrez coller sur les moteurs;
  • un câble micro-USB;
  • Un adaptateur power jack-USB (on peut s'en passer si on couple le câble USB pour accéder directement aux fils +5v et à la masse);
  • Un power Jack (on peut également s'en passer dans le même contexte);
  • Deux switches pour les capteurs de contact (facultatif, si vous n'utilisez que le détecteur à distance).
Pour les outils, il nous faudra :
  • Un tournevis;
  • Des ciseaux ou une pince à dénuder/pince coupante;
  • Potentiellement un fer à souder et de l'etain, mais on peut faire sans en torsadant les fils entre eux;
  • De la colle adaptée pour coller les moteurs à leurs supports (j'ai utilisé de la super glu, pour coller le corps en plastique du moteur au plexi).
  • Éventuellement une perceuse si vous prenez des plaquettes de plexi, en bois on peut visser sans percer.
Nous avons maintenant tout ce dont nous pouvons avoir besoin, on peut commencer le montage.

Installation des roues et de la roulette.
La première étape sera de coller les petites plaques sur le corps des moteurs, comme sur ces photos :
Image IPB Image IPB
Vous pouvez voir que dans mon cas, j'ai utilisé du plexiglas, et il y a deux trous qui permettront de fixer le moteur sur le châssis.

Pour le châssis, j'ai simplement pris une planche de bois. On peut voir sur l'image ci dessous que j'ai tracé un trait permettant de
placer les deux moteurs au même niveau, et également un trait perpendiculaire au milieu pour centrer la roulette.
Image IPB
On peut alors visser les moteurs sur le châssis :
http://nagashur.com/...537-300x194.jpg

Pour la roulette, nous allons d'abord visser le support de la roulette sur une planchette, avant de mettre la bille de la roulette en place et de visser la planchette sur le châssis:
http://nagashur.com/...538-150x150.jpg http://nagashur.com/...539-150x150.jpg http://nagashur.com/...540-150x150.jpg http://nagashur.com/...541-150x150.jpg

L'installation des roues sur les moteurs est très simple, car l'axe des moteurs à un profil en D, et il y a un trou de la forme correspondante au centre de la roue.
Il suffit donc d'enficher la roue sur l'axe. On peut donc facilement installer et changer les roues facilement:
http://nagashur.com/...542-300x300.jpg http://nagashur.com/...543-300x221.jpg http://nagashur.com/...553-300x188.jpg
Le moteur est soudé à des fils, avec au bout un connecteur femelle de "jumper wire". J'ai simplement pris deux câbles femelle-femelle, et je les
ai coupés en 2. Il suffit de dénuder le bout coupé, et de le fixer sur le moteur, idéalement, en le soudant.




Partie électronique
Passons maintenant à l'installation des divers éléments électroniques sur l'autre face du châssis.
La breadboard principale contient le régulateur de tension, avec les fils partant vers les batteries, et le jack de sortie,
le MCP23017, le MCP3008, et les deux L293D. Des câbles partent également vers les moteurs, les capteurs, et le Raspberry Pi.
Image IPBImage IPB
Sur l'image de gauche, on voit l'ensemble de la breadboard, et sur celle de droite, on peut voir la méthode utilisée pour
mettre en parallèle les deux L293D : des fils rigides connectent les pattes d'une puce à celle de l'autre. J'ai utilisé une bobine
de fil de fer gaîné pour réaliser ces connections.

Pour fixer la plaque, j'ai utilisé 4 vis à bois, vissées directement dans le bois du châssis. Elles sont vissées de part et d'autre des ergots sur le haut
de la breadboard, de façon à la caler horizontalement. Deux vis en bas bloquent la breadboard dans le sens vertical, de sorte que maintenant celle ci
ne bouge plus :
Image IPBImage IPBImage IPB

On fixe maintenant le Raspberry Pi lui même sur le châssis, en vissant celui ci avec deux vis, en passant par les deux trous prévus à cet effet sur le Raspberry Pi:
Image IPB
On peut maintenant fixer le logement des batteries AA sur le châssis. On notera que sur les 6 emplacements, l'un d'entre eux ne contient pas de batterie,
mais un fil à la place, ce qui permet d'obtenir du 6V au lieu d'avoir du 7.2V. Le logement est vissé au châssis par deux vis, par les trous prévus à cet
effet:
Image IPBImage IPB
Il nous faudra également un câble jack vers USB et un câble micro-USB:
Image IPB
Cependant, il est également possible de couper le câble USB, et d'accéder directement aux fils +5V et masse. Dans ce cas, l'adaptateur USB-PowerJack et le jack power mâle sont superflus.


Les capteurs
Passons maintenant à l'installation des capteurs.
Le capteur à ultrasons est simplement vissé sur la face avant du châssis, et les capteurs de contact sont vissés sous le châssis.
Les boutons poussoirs qui servent de détecteurs de contact possèdent des trous par lesquelles peuvent passer les vis servant à les fixer :
Image IPBImage IPBImage IPB

Le tout en place
On peut voir sur les images ci dessous la disposition des éléments lorsque l'ensemble est en place:
Image IPBImage IPBImage IPB
On note sur la photo de droite que les diodes d'état, et la diode de la clé wifi sont visibles depuis le dessus du robot.

Option Webcam
On peut également ajouter une webcam, sur l'un des ports USB. Pour cela j'utilise une petite équerre en acier, vissée sur
le châssis, sur laquelle la webcam s'accroche :
Image IPBImage IPB













=================================================================================================================
=================================================================================================================
=================================================================================================================
Partie 5/5 : Programmation d'un robot Raspberry Pi R.Cerda pour une exploration automatique avec évitement d'obstacles.
Il est maintenant temps de transformer cet assemblage de matériel en un vrai Robot. Pour cela, nous allons maintenant voir l'ultime étape : la programmation. Nous verrons trois algorithmes, du plus simple au plus avancé. Cela devrait vous permettre d'avoir une base pour programmer votre robot comme vous le souhaitez, et pourquoi pas quelques idées Image IPB/>

Commençons tout de suite, en rentrant dans le vif du sujet. Ce robot utilise le MCP23017 pour commander les L293D qui à leur tour commandent les moteurs. J'ai donc choisi python pour écrire le programme des robots, puisque c'est sur cette base que nous avons vu l'utilisation du MCP23017.
En premier lieu, voici le lien vers le GitHub ou je met les divers fichiers relatifs au code du robot Cerda.

Dans ce dépot, vous trouverez divers fichiers, donc la classe I2C d'Adafruit, et la classe permettant de gérer le MCP23017.
Assurez vous d'avoir ces deux fichiers dans le répertoire contenant les fichiers de votre robot, ils sont nécéssaires pour son fonctionnement,
et doivent être importés dans le script du programme de votre robot.
Vous noterez également un script robotStop.py, qui sert simplement à arrêter les moteurs du robot. Sur mon raspberry pi, j'ai fait un alias de ce script vers la commande stop, ce qui fait que je peux arrêter le déplacement du robot en tapant stop dans un terminal, n'importe ou.

Divers scripts sont présents, pour tester divers éléments : N'hésitez pas à tester vos capteurs avant de lancer le robot, pour vérifier si tout va bien. J'intégrerai également ultérieurement des scripts pour tester les moteurs.

Passons maintenant au programme principal du robot lui même. Voyons d'abord vite fait l'algorithme :
dans une boucle infinie, on répète les instructions suivantes :
Lire la distance mesurée devant le robot par le capteur à ultrasons.
Si cette distance est inférieure à 8 pouces, on recule.
Sinon, si cette distance est inférieure à 16 pouces, on tourne,
Sinon, on avance.

Et c'est tout! Ce simple algorithme suffit déjà à permettre au robot d'éviter des obstacles!
Cet algorithme est implémenté dans le programme r1.py, dont la source se trouve sur le GitHub.

Je vais détailler un peu le code. Au début, vous verrez tous les "import", qui récupèrent les fonctions nécéssaires.
En dessous, vous retrouverez notre fonction "readadc", que nous avons vue avec le MCP3008 (le tuto sur cette puce est disponible ici), qui nous permet de lire une entrée analogique (ici le capteur à ultrasons) sur les 8 que propose le MCP3008. Voyez donc ces deux liens pour plus de détails sur le sujet. En dessous viennent les variables définissant les broches utilisées pour le SPI; je vous renvoie encore aux précédents tutoriels pour plus d'explications. SI vous avez suivi les schémas de montage de R.Cerda, il n'y a rien à changer ici.

Vient ensuite le corps du programme à proprement parler. Vous verrez alors une série de fonctions, dont la fonction "readDistanceInch", qui permet de récupérer la distance en pouces plutot que la valeur brute. SI vous utilisez un autre capteur, il faudra adapter (ou bien utiliser la valeur brute, en faisant des essais). Les fonctions suivantes servent à commander directement le robot :
def moveForward(m1a,m1b,m1e,m2a,m2b,m2e):    
mcp.output(m1a, 1)    
mcp.output(m1b, 0)    
mcp.output(m1e, 1)    
mcp.output(m2a, 1)    
mcp.output(m2b, 0)    
mcp.output(m2e, 1)
Cette fonction par exemple permet mettre les broches de commande du moteur 1 à 1 et 0, la broche enable à 1 pour activer ce moteur, et idem pour le moteur 2. J'ai fait ces fonctions, car si le câblage change, il suffira de modifier les valeurs dans ces fonctions plutot que dans le main. De la même manière, on a une fonction pour reculer, arrêter les moteurs, tourner à gauche, et à droite.
Cette fonction ne définit pas la durée pendant laquelle vous voulez faire une action. Une fois que vous appelerez l'une de ces fonctions, le robot continuera à exécuter cet ordre jusqu'à ce que vous l'arrêtiez. Ce qui veut dire que si vous souhaitez avancer d'une petite distance, vous devrez faire:
moveforward(...)
time.sleep(X)
stopMotors(...)


Plus bas, je définis les broches sur lesquelles sont connectés les détecteurs de contact, et deux fonctions pour lire leur valeur. En pratique, ces fonctions retournent 0 si le contact n'est pas pressé, et 1 si il est pressé, au lieu de 0 si le contact est pressé, et une valeur non nulle dans le cas contraire.

Les broches du MCP23017 qui commandent les deux moteurs sont définies juste en dessous, et on peut alors mettre les broches en sortie pour les moteurs, ou en entrée pour les détecteurs de contact.[/left]
Passons maintenant au corps du programme en lui même :
try:
#boucle principale et infinie du moteur
while (True):
#lecture de la distance de l'obstacle le plus proche
d=readDistanceInch(0, SPICLK, SPIMOSI, SPIMISO, SPICS)
#en dessous de 8 pouces, le robot recule pendant au moins 0.2s
if(d< 8):
    moveBackward(m1a,m1b,m1e,m2a,m2b,m2e)
    #time.sleep(0.2)
#entre 8 et 16 pouces, le robot tourne pendant au moins 0.2s
elif(d<16) :    turnLeft(m1a,m1b,m1e,m2a,m2b,m2e)
    time.sleep(0.2)
#le reste du temps le robot avance pendant 0.05s
else :
    moveForward(m1a,m1b,m1e,m2a,m2b,m2e)
time.sleep(0.05)
    except KeyboardInterrupt:
print "" print "stopping motors"
stopMotors(m1a,m1b,m1e,m2a,m2b,m2e)
print "motors stopped, exiting."
sys.exit(0)
Vous noterez un bloc try et un bloc except. La partie dans "try" est le code du robot à proprement parler.
Il s'agit de l'implémentation de l'algorithme décrit plus haut. On notera toutefois que j'ai introduit un délai quand le robot tourne, pour l'obliger à tourner au moins d'un certain angle. Comme mon robot est large et avec des angles proéminents, ça lui évite de coincer ses coins sur les bords de l'obstacle. La durée d'attente dépend de votre robot, à vous de tester!
Dans tous les cas, avant de recommencer, j'ai mis un temps d'attente de 50ms, à vous de voir si ça vous convient également. C'est une attente que j'ai mise qui correspond à la fréquence de rafraîchissement du capteur de distance que j'utilise.

Le bloc "except KeyboardInterrupt" sert à gérer le CTRL+C qu'on utilise pour quitter le programme. Dans la précédente version, il n'y avait pas ce bloc, et du coup, quand on faisait CTRL+C pour arrêter l'exécution de l'algorithme, le robot restait bloqué sur la denrière instruction, par exemple, avancer, jusqu'à ce qu'on lance la commande robotStop.py.

Ici, il arrêtera les moteurs avant de quitter le programme.

Voici en pratique ce que donne cet algorithme sur mon R.Cerda, sur youtube[/url].


La seconde version de ce code, r2.py, cette fois, tient compte des capteurs de contact, qui sont prioritaires sur le capteur à ultrasons (si un contact est détecté, alors le robot recule, puis tourne dans la direction opposée, quoi que dise le capteur à ultrasons).
Le reste du code est le même qu'avant.

Voici maintenant d'abord le second algorithme tel que décrit ici[/url].[/left]


Nous avons également une troisième version, r3.py, qui introduit le fait qu'au lieu de toujours tourner à droite, le robot tourne un certain nombre de fois du même coté, puis commence à tourner dans l'autre sens pour éviter les obstacles. Il compte comme "tourner d'un coté" comme l'action continue entre le moment ou il commence à tourner et le moment ou il arrête de tourner. Cela évite qu'il fasse des allers retours de gauche à droite.
Mais également la version qui change de coté au bout d'un moment : .




Enfin, la dernière version du robot, r4.py est la plus évoluée. On intègre tout ce qui a été fait avant, mais cette fois ci, quand le robot détecte un obstacle avec le capteur à ultrasons entre 8 et 16 pouces, il tourne à gauche, mesure la distance de ce coté, tourne à droite, mesure la distance de ce coté égalment, et choisit de tourner du coté ou la distance est la plus grande. Pour éviter face à des obstacles équidistants de tourner à gauche puis à droite en boucle, le robot tourne dans la direction qu'il à choisie jusqu'à ce que l'obstacle soit au delà de la distance de 16 pouces. Encore une fois, cela donne de bons résultats, car sur un obstacle rectiligne, le robot tournera du coté ou le mur "s'éloigne", donc choisira le coté ou il a le moins à tourner. Pour certains obstacles, il peut ne pas prendre la décision optimale (obstacle semi circulaire par exemple), mais ne se retrouvera pas bloqué.
Voici une vidéo illustrant le fonctionnement de cet algorithme :


Je ne l'ai pas encore uploadée, manifestement, mais ça sera bientôt fait. Dans une prochaine mise à jour, j'intégrerai le code.
Si des versions plus avancées sont développées, je ne les décrirai pas forcément, mais je les enverrai sur le GitHub. en général j'essaie de faire du code commenté, et clair.

N'hésitez pas à me faire part de vos remarques et questions dans les commentaires Image IPB


Regulateur de tension basique

Publié microrupteurman2 le 14 août 2012 - 04:02 in Electronique - Schémas

Ce montage m'a servi a reguler la tension d'un panneaux solaire (6v-400mah) d'ou l'utilisation d'un regulateur Low dropout voltage, c'est à dire faible tension de chute. Il me permet d'avoir une source de courant de 5v. "Low dropout voltage" : Les regulateurs ont une tension de chute, c'est ce que le regulateur 'consomme' en quelque sorte. Plus la tension de chute est elevée, plus vous perdez d'energie.

Composant necessaire :
- Un regulateur, ici un LM2937-5v ou compatible broche a broche (LM78xx, les xx etant le voltage desiré en sortie ex : LM7805, attention a bien prendre un regulateur de courant positif)
-Une resistance de 100ohm (marron-noir-marron)
-Une led 3mm rouge qui sert de temoin
-2 condensateur de 10µF

Voici la portion de plaque d'essai necessaire (il faut coupé sur le trait) :
Image IPB

Le shema electronique :
Image IPB


Implantation des composant sur la stripboard :


b2 => b3 => b4 : Regulateur
c2 => c3 : condensateur (c2 : +)
c4 => c5 : resistance debout
e3 => e4 : condensateur (c4 : +)
g3 => g5 : led (g5 : +)






Image IPB




Pour tester, il suffit de connecté le fil Vin a une batterie d'au moin 7v pour un lm7805. SI la led s'allume, c'est bon, sinon, ben il y a un souci !



Voici une photo du montage terminé :
Image IPB


MIT Inventor2 - Création Appli Android de pilotage robot mobile

Publié gerardosamara le 17 juillet 2018 - 01:56 in Programmation

Bonjour les makers,
 
Ce tutoriel propose de créer une application de pilotage de robot mobile  à l'aide de l'outil cloud de création d'application MIT Inventor2 , basé sur cet exemple d'écran de pilotage robot  :
 
Screenshot_20180704-074510.png
 
 
Nous suivrons les étapes suivantes du développement de l'application Android :
 
- Prérequis 1 : Ouverture d'un compte MIT Inventor2 et créer  le projet "Tuto appli MIT pilotage robot mobile"
- Prérequis 2 : Installation de l'app Android "MIT A2 Companion" pour installer l 'app de pilotage du robot sur le smartphone Android.
- Prérequis 3 :  Le robot mobile basé RPI est connecté en wifi
- Implanter sur l'écran du smartphone les objets  de type bouton , étiquette , retour vidéo de la caméra PI
- Programmer le fonctionnement attendu de ces objets de pilotage du robot mobile ( programmation par blocks )
-  Mettre en place un protocole de communication en Wifi entre le RPI3 du robot et l'application Android
 
 
Non pris en compte dans le tutoriel  pour le moment :

- Evolutions / améliorations possibles de l'appli MIT ( commande demi-tour .... )
- Amélioration du script python du RPI3 robot pour exécuter les ordres recus ( AV , AR ...)
 
1) Ouverture compte MIT Inventor et création projet "Tuto appli MIT pilotage robot mobile"
 
Pour utiliser MIT Inventor 2 , il faut d'abord aller sur le site ai2.appinventor.mit.edu qui va vous rediriger vers une page de connexion à MIT.edu avec une adresse mail existante "gmail.com"  ou qui va vous permettre la creation de compte gmail.com si vous n'en avez pas ( ....  c'est une appli developpée par Google et maintenu par le MIT donc ..)
 
login mit edu.PNG
 
 
Une fois sur le site MIT App EDU ,  Cliquez sur le bouton "Start new projet "  , un écran de smartphone vide est affichée sur la page du projet 
 
start new projet Mit edu.PNG
 
 
La prochaine étape sera de positionner  sur l'écran du smartphone les différents objets qui serviront à piloter le robot mobile.
 
 
2) Implanter sur l'écran du smartphone les objets  de type bouton , étiquette , retour vidéo de la caméra PI
 
L'outil MIT visualisé contient :
 
- une colonne "palette" avec les objets d'interfaces utilisateur   : bouton ... et connectivity : web
- une colonne de composants  correspondants aux objets interface utilisateurs que nous avons fait glisser de la colonne palette vers l'écran du smartphone , en respectant la position voulue
- une colonne properties pour modifier les paramètres des objets utilisés
 
Dans notre cas cela devrait apparaitre comme ceci , après avoir fait glisser les objets sur l'écran du smartphone à la bonne position et paramétrer les bonnes données "properties" des objets :
 
- TableArrangement = 3 colomns , 2 rows , width = fill parent
- Button 1 à 6 : witdh = 33% pour faire tenir 3 boutons sur une rangée
- Label1 et Label : width = 50% pour ... vous savez pourquoi
- Web ( fonction http post )
 
MIT ecran.PNG
 
 
Reste à renommer les objets pour ( boutons et Etiquettes ) et le titre de l'écran qu'ils correspondent à  l'écran proposé pour le tuto ..... et sauvegarder
 
Tuto MIT Ecran 1.PNG
 
 
 
3)  Programmer le fonctionnement attendu de ces objets de pilotage du robot mobile ( programmation par blocks )
 
Pour accéder au mode  "Block" , quitter le mode Designer en clickant sur le bouton "Block"  .
 
Une page est  affichée avec une colonne de catégories de blocks ( controle , ... )  et un espace vide destiné à recevoir les blocks  ayant été "déposés" de la colonne  Blocks vers l'espace de programmation Blocks.
 
Tuto MIT Ecran 2.PNG
 
A ce stade nous allons mettre le minimum de blocks pour  tester la chaine complète de l'installation de l'appli MIT sur un smartphone  soit :
 
- 2 variables adresse IP:Port du robot  ( rpi et Pi Cam )
- le bouton de retour à l'écran d'accueil  ( fleche arrière sur le smartphone)
- L'affichage du flux video de la PI Cam
 
 
Tuto blocks 1.PNG
 
 
4) Installation de l'app Android "MIT A2 Companion"
 
Sur le play Store , chercher l"application "MIT AI2 Companion" et l'installer  .
A l'ouverture de MIT AI2 Companion , cet écran est affiché .
La fonction "scan QR code" sera utilisé  avec MIT inventor 2 lorque l'application aura été générée afin de l'installer sur le smartphone
Dans l'onglet Connect de MIT Inventor2 , sélectionner MIT AI2 companion
 
 
MIT AI2 Companion.png
 
5) Installation de l'application MIT minimum sur le smartphone Android
 
Le projet  ayant été sauvegardé , lancer  la fabrication de l'appli MIT en sélectionnant l'onglet "Build"  +  app (  Provide Qr code for .apk )
 
Tuto MIT Ecran 3.PNG
 
 Ensuite dans MIT AI2 Comanion ,  Clicker sur "Scan QR Code" pour scanner le QR code affiché dans MIT Inventor 2   et installer l'application sur le smartphone
 
Une fois installée , ouvrir l'application "Tuto App Robot mobile ed1 ".
L'écran ci-dessous doit s'afficher .
Le retour video sera affiché , si vous avez une PI Cam opérationnelle sur le RPI du robot mobile connecté en Wifi.
Le bouton "flèche arrière" du smartphone fonctionne ( fermeture application)
Les boutons ne sont pas encore programmés pour  commander le robot
 
 
tuto app mit.png
 
 
6) Complément de programmation pour les boutons et  affichage de la la trace des messages de commande échangés avec le robot
 
Les blocs  de programmation relatifs aux boutons et étiquttees de visualisation des messages de pilotage du robot ont été ajoutés dans MIT Inventor2  ( pour un bouton seulement )
.
L'application envoie des messages HTTP/POST/Commande robot  vers le robot mobile avec réponse HTTP/200 OK . Cela suppose que le RPI du robot puisse recevoir ces messages de commande du robot ( start , avant .. )  , les traiter et répondre "200 OK"
( voir chapitre 8)
 
 
tuto blocks .png
 
 
7) Présentation des boutons sous forme d'icones
 
 
La présentation des boutons de commande du robot sous forme d'icone  permets d'avoir un design plus "sexy"  et  ajouter cette fonction consiste à :
 
- Télécharger dans MIT Inventor2  / Media les 6 fichiers contenant les icones pour les boutons de commandes
- Dans les propriétés de chaque bouton ( start dans l'exemple ) ,  cliquer sur "Image" pour affecter un fichier image
 
 
icon bouton.PNG
 
 
Pour terminer ce tutoriel , il reste à générer l'application dans MIT inventor2 puis à l'installer sur le smartphonr avc MIT AI2 Companion et à tester.
 
Suite appui sur le bouton "Start" , la commande robot est bien affichée ( <start>  ) mais sans réponse du robot "200 OK"  car la communication avec le robot n'a pas été faite dans le tutoriel pour traiter le message <start>
 
tuto app final.png
 
 
8) Mise en place d'un protocole de communication en WIFI entre le RPI3 et l'application Android
 
Principe :

Un script python installé sur le serveur RPI3 du robot et basé sur le protocole sockets TCP permets de tester entre le Rpi3 et l'app Android pour la transmission des commands du robot ( Start , Stop , AV AR ... ) :

- L'app Android envoie  une requette Http POST recue vers le serveur RPI3
- le serveur RPI3 réponds un HTTP/1.1 200 OK avec les headers à l'app Android
- Le message envoyé et la réponse recue sont affichés dans l'app Android
 
Script python dans le RPI3 du robot


#!/usr/bin/python3.4
# coding: utf-8 # -*-coding:Utf-8 -*

import socket

host = ''
port = 8481

connexion_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connexion_server.bind((host, port))
connexion_server.listen(5)
print("Le serveur écoute à présent sur le port {}".format(port))

connexion_client, infos_connexion = connexion_server.accept()
print(infos_connexion)

msg_recu = b""
# header response code 200
h = 'HTTP/1.1 200 OK\n'
h += 'Server: Simple-Python-HTTP-Server\n'
h += 'Content-Length: 0\n'
h += 'Connection: keep-alive\n\n'
# Boucle  
while msg_recu != b"Stop":
    msg_recu = connexion_client.recv(1024)
    if msg_recu:
         print(msg_recu.decode())
         connexion_client.send(h.encode())
         print(h) # response code 200
         print(infos_connexion)
 
print("Fermeture de la connexion")
connexion_client.close()
connexion_server.close()


 
 

 
 
 
 
 
 
 
 
 
 
 
 
 

 
 
 



RobArchi 1.XX

Publié Gyro49 le 05 janvier 2018 - 04:53 in Robot complet

RobArchi 1.XX

 

 

Ce tutoriel vient en complément du RobArchi X.xx qui était la base de départ.

Cette nouvelle version a pour objectif de proposer une surveillance du niveau de charge de la batterie.

Mots clefs :
Atmega 328p, Raspberry,  I2C, batterie, NPN 2N2222, eeprom, 24LCXXX

Avertissements :
Comme pour la version X.xx, vous ne devez pas chercher, dans RobArchi, la solution à vos problèmes mais plus une approche de laboratoire de test et d'apprentissage.
En effet, multiplier les Atmegas comme je l'ai fait, n'ai pas la solution ultime. En terme de coût, ce n'est pas exorbitant, mais il serait difficile de tous les loger dans un gabarit de robot plus petit.

Objectifs :
Comme présenté ci-dessus la version 1.XX va apporter un contrôle régulier du niveau de charge de la batterie et cela à la demande de la carte Raspberry.

Il me semble qu’un robot d’exploration qui ne surveille pas la décharge de sa batterie prend beaucoup de risque.

Histoire de pousser le vice au maximum, j’ai décidé de jouer également avec une eeprom en I2C.

La carte du X.xx a donc subi une petite modification par l’implantation de l’eeprom 24LC128 juste au-dessus de la carte Pi mais toujours sur la ligne I2C coté 3V (annexe1 et 2 en bas de page).

Préambule :
Lors de mes tests sur la version X.xx je passais mon temps à monter et démonter mon Atméga à chaque modification du code… l’horreur.

Pour cette nouvelle étape je suis passé par un banc de tests : une plaque de test 840 points et Arduino Nano à la place d’un simple Atméga. Et une carte Raspberry avec un connecteur GPIO.

Déroulement du tuto :
Chapitre 1.1 : Création du shield accueillant la gestion de la batterie
Chapitre 1.2 : Mesure de la tension de la batterie arduino uniquement
Chapitre 1.3 : Mesure de la tension de la batterie à la demande du Raspberry
Chapitre 1.4 : Utilisation d’une eeprom entre l’Atmega et la Raspberry
Chapitre 1.5 : Mesure de la tension toutes les deux minutes via un job CRON

Annexes :
Annexe 1 - Mise à jour de la carte Version X.XX - Composants
Annexe 2 - Mise à jour de la carte Version X.XX - Stripboard
Annexe 3 – Création du shield batterie - Composants
Annexe 4 – Création du shield batterie - Stripboard

Chapitre 1.1 - Création du shield accueillant la gestion de la batterie
Je suis donc parti sur un deuxième shield fait maison qui sera ajusté à la carte de la version X.xx.

Les deux plaques sont mises en communication via un groupe de 2x6 « long header » pour envoyer sur le shield batterie l’alimentation et la connexion I2C.
La tension arrive directement sur la plaque 1.xx. Etant du genre distrait, j’ai mis un pont de diode afin de garantir la bonne polarité dans le circuit.
P1040585.JPG
P1040584.JPG

En regardant sur le web il y a beaucoup de référence sur le sujet.
J’ai choisi de suivre le blog suivant :
http://www.chicoree.fr/w/Mesurer_une_tension_avec_un_ATmega328P

Histoire d’éviter une consommation d’énergie trop important, j’ai associé un transistor 2N2222 dans mon circuit afin d’envoyer du 12V dans le pont diviseur uniquement au moment de la mesure.

Voici mon schéma de principe sans le pont de diode.
 
batterie.png

 

Chapitre 1.2 - Mesure de la tension de la batterie
La première étape sera la mesure de la batterie par « l’Atméga batterie ».

Le code arduino de l’Atmega

#include <stdlib.h>

// Constants
const int analogInPin = A0; // Analog pin the voltage divider is attached to
const float Vcc = 5; // µC Vcc (V)
const float R1 = 27000; // Voltage divider R1 (Ohm)
const float R2 = 10000; // Voltage divider R2 (Ohm)

const int pause = 60*1000; // delay between samples (ms)

void setup() {
  // initialize serial communications at 9600 bps:
  Serial.begin(9600);
}

void loop() {
  // read the analog in value:
  int sensorValue = analogRead(analogInPin);

  // Serial.println(sensorValue); // for debug / calibration
  float v_pin = Vcc*sensorValue/1023.;
  float v_bat = v_pin/(R2/(R1+R2));

  // Convert to string using the format ddd.dd
  char buffer[21];
  dtostrf(v_bat, 6, 2, buffer);
  buffer[6] = 0;
 
  // Display result
  Serial.println(buffer);
 
  // wait before the next loop
  delay(pause);
}

Chapitre 1.3 - Mesure de la tension de la batterie à la demande du Raspberry
En reprenant une bonne partie du code de la version X.xx, c’est déjà plus facile.
Les tests ont été effectué sur une carte Arduino Uno puis une Arduino Nano et à mon grand bonheur, pas de difficulté.
Maintenant une fois le code transféré sur Ateméga « baterrie » grosse déception, au lieu de 11.56 V (mesure multimètre) je n’avais que 3.49V. Après trois jours de recherche j’ai capitulé en multipliant par 3.4 la mesure en entrée A0.

int sensorValue = analogRead(analogInPin)*3.4;

Je hercherais un autre jour la solution avec AREF certainement.

Le code arduino de l’Atmega

#include <Wire.h>
#include <stdlib.h>

#define SLAVE_ADDRESS 0x14

String dataReceived;
char dataSend[6] ;
int index = 0;

// Constants
const int analogInPin = A0; 
const int T2N = 9;
const float Vcc = 5;
const float R1 = 26500; // Voltage divider R1 (Ohm)
const float R2 = 9910; // Voltage divider R2 (Ohm)

void setup() {   
  Wire.begin(SLAVE_ADDRESS);
  Wire.onReceive(receiveData);
  Wire.onRequest(sendData);
  
  pinMode(T2N, OUTPUT);  
}
 
void loop() {
	/* Il n'y a rien dans la boucle infinie */
}

void receiveData(int byteCount){
  dataReceived = NULL;
  int numOfBytes = Wire.available();
  
  byte b = Wire.read();  //cmd
  
  for(int i=0; i<numOfBytes-1; i++){
    char c = (char) Wire.read(); 
    dataReceived += (char) c; 
  }
  
  digitalWrite(T2N, HIGH);
  int sensorValue = analogRead(analogInPin)*3.4;

  float v_pin = Vcc*sensorValue/1023;

  float v_bat = v_pin/(R2/(R1+R2));
  
  dtostrf(v_bat, 6, 2, dataSend);
  dataSend[6] = 0;
  digitalWrite(T2N, LOW);  
  }

void sendData(){
  Wire.write(dataSend[index]);
    ++index;
    if (index >= 6) {
         index = 0;
    }
  }

Coté Raspberry

#!/usr/bin/env python

import smbus
import time
import os

bus = smbus.SMBus(1)

# I2C address of Arduino Slave
i2c_add_batterie = 0x14
i2c_cmd = 0x01

def ConvertStringToBytes(src):
  converted = []
  for b in src:
    converted.append(ord(b))
  return converted

data = ""
# loop to send message
exit = False
while not exit:
  r = raw_input('Enter something, "q" to quit"')
  print(r)

  bytesToSend = ConvertStringToBytes(r)
  bus.write_i2c_block_data(i2c_add_batterie, i2c_cmd, bytesToSend)

  time.sleep(0.1)

  for i in range(0, 5):
    data += chr(bus.read_byte(i2c_add_batterie));
  print data
  time.sleep(1);
  data = ""

  if r=='q':
    exit=True

Après connexion au raspberry en SSH, il suffit de taper une lettre pour recevoir de l’atmega la tension de la batterie.

Chapitre 1.4 - Utilisation d’une eeprom entre l’Atmega et la Raspberry

 

Ne fondez pas de grand espoir dans cette partie car si cela fonctionne presque sur la plaque d'essai, c'est une véritable perte de temps après mise en place sur le robot.

Je vous mets les codes pour info ou tout simplement si vous voulez tenter le coup.

Histoire de préparer la version 2.xx j’ai décidé de jouer avec une eeprom en I2C forcément.

Pour la mise en place il y a beaucoup de tuto sur le net, il suffit de taper dans un navigateur :
arduino eeprom I2C

L’eeprom doit être du côté 5v du réseau I2C. En mettant les pins 1 à 4 à la masse, l’eeprom aura l’adresse 0x50.
Contrairement au Raspberry, l’Atmega (ou simplement l’Arduino) peut accepter d’être aussi bien esclave que maître mais forcément pas en même temps.

La démarche et simple, au démarrage, l’Atmega est en esclave jusqu’au moment de recevoir la commande du Raspberry. A ce moment-là, il ouvre une connexion I2C en qualité de maître vers l’eeprom pour y déposer la valeur de la tension de batterie puis revient à l’écoute du Raspberry.

Le raspberry attend 5 secondes puis va voir sur l’eeprom ce qu’a déposé l’atméga.

Dans le pays à Oui-Oui c’est comme ça que ça marche. Maintenant, il y a toujours un problème qui vient contredire la théorie. Dans la pratique, lorsque la Rpi affiche une erreu de connexion avec l’eeprom pour une histoire de délai dépassé. A première vue, l’Atméga semble garder un lien avec l’eeprom même lorsque la connexion est terminée avec :

 

Wire.endTransmission(deviceaddress);

Une solution c’est de rebooter l’Atméga. Coté informatique je n’ai pas trouvé, j’ai donc choisi la méthode électronique. Un 2222 en parallèle du bouton RESET avec une commande depuis le PIN 5. C’est un peu brutal mais ça marche (Sur la plaque d'essai).
 
Le code arduino de l’Atmega

#include <Wire.h>
#include <stdlib.h>

#define SLAVE_ADDRESS 0x14
#define I2C_add_eeprom 0x50

String dataReceived;
char dataSend[6] ;
unsigned int address = 0;

// Constants
const int analogInPin = A0; 
const int T2N = 9;
const int RESET = 13;
const float Vcc = 5;
const float R1 = 26500; // Voltage divider R1 (Ohm)
const float R2 = 9910; // Voltage divider R2 (Ohm)

void setup() {   
  Wire.begin(SLAVE_ADDRESS);
  Wire.onReceive(receiveData); 
  
  pinMode(T2N, OUTPUT);  
  pinMode(RESET, OUTPUT); 
}
 
void loop() {
	/* Il n'y a rien dans la boucle infinie */
}

void receiveData(int byteCount){
  dataReceived = NULL;
  
  int numOfBytes = Wire.available();
  
  byte b = Wire.read();  //cmd
  
  for(int i=0; i<numOfBytes-1; i++){
    char c = (char) Wire.read();
    dataReceived += (char) c; 
  }
  
  digitalWrite(T2N, HIGH);
  
  int sensorValue = analogRead(analogInPin)*3.4;

  float v_pin = Vcc*sensorValue/1023;

  float v_bat = v_pin/(R2/(R1+R2));
  
  dtostrf(v_bat, 6, 2, dataSend);
  dataSend[6] = 0;
  digitalWrite(T2N, LOW);
  	
  writeEEPROM(I2C_add_eeprom, address);
  
  delay(1);
  
  digitalWrite(RESET, HIGH);  
  }

void writeEEPROM(int deviceaddress, unsigned int eeaddress) 
{
  Wire.beginTransmission(deviceaddress);
  Wire.write((int)(eeaddress >> 8));   // MSB
  Wire.write((int)(eeaddress & 0xFF)); // LSB
  for(int i=0; i<strlen(dataSend); i++){
    Wire.write(dataSend[i]);
    }  
  Wire.endTransmission(deviceaddress);
 
  delay(1);
} 

Coté Raspberry

#!/usr/bin/env python

import smbus
import time
import os

bus = smbus.SMBus(1)

# I2C address of Arduino Slave
i2c_add_batterie = 0x14
i2c_add_eeprom = 0x50
i2c_cmd = 0x01

def ConvertStringToBytes(src):
  converted = []
  for b in src:
    converted.append(ord(b))
  return converted

level = ""
# loop to send message
exit = False
while not exit:
  r = raw_input('Enter something, "q" to quit"')
  print(r)

  bytesToSend = ConvertStringToBytes(r)
  bus.write_i2c_block_data(i2c_add_batterie, i2c_cmd, bytesToSend)

  time.sleep(5)
  memory_address = 0
  data=""
  bus.write_byte(i2c_add_eeprom, memory_address >> 8)
  bus.write_byte(i2c_add_eeprom, memory_address & 0xff)
  for i in range(0,10):
    data =bus.read_byte(i2c_add_eeprom)
    if data>45 and data<58:
      level +=chr(data)
  print level
  time.sleep(1)
  data = ""
  level = „“
  if r=='q':
    exit=True
} 

Chapitre 1.5 - Mesure de la tension toutes les deux minutes via un job CRON
Pour terminer cette version 1.xx je voudrais connaître le temps de décharge de la batterie sans surveillance de ma part.
Je vais donc créer un nouveau fichier Python au nom de « batterie.py » qui sera dans le répertoire : /home/pi/batterie.py

 

Je suis reparti sur la base du chapitre 1.3

Ne pas oublier de créer le répertoire data

 

Code Raspberry : fichier batterie.py

#!/usr/bin/env python

import smbus
import time
import os
import datetime

bus = smbus.SMBus(1)

# I2C address of Arduino Slave
i2c_add_batterie = 0x14
i2c_cmd = 0x01

def ConvertStringToBytes(src):
  converted = []
  for b in src:
    converted.append(ord(b))
  return converted

data = ""

bytesToSend = ConvertStringToBytes("m")
bus.write_i2c_block_data(i2c_add_batterie, i2c_cmd, bytesToSend)

time.sleep(0.1)

for i in range(0, 5):
  data += chr(bus.read_byte(i2c_add_batterie));
print data
time.sleep(1);

fichier = open("/home/pi/data/batterie.txt", "w")
fichier.write("\n" + datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") + " " + data)
fichier.close()

Avec la commande « crontab –e » dans le terminal SSH, nous avons accès à la liste des Job CRON.
Il faut mettre cette ligne à la fin du fichier

*/1  *  *  *  *   sudo python /home/pi/batterie.py

Lorsque le fichier batterie.txt ne sera plus rempli, nous pourrons en déduire la tension minimale à la batterie pour que le système fonctionne.

 

Histoire de compléter le système vous pouvez créer un serveur Samba pour accéder facilement au fichier batterie.txt

 

En annexe 5 le fichier batterie.txt avec comme unique consommation électrique le PI et les Atmegas. les moteurs étant débranchés.

Annexes

Fichier attaché  base_composants.pdf   121,37 Ko   289 Nombre de téléchargements

Fichier attaché  base_stripboard.pdf   123,46 Ko   327 Nombre de téléchargements

Fichier attaché  shield_composant.pdf   118,01 Ko   223 Nombre de téléchargements

Fichier attaché  shield_stripboard.pdf   117,03 Ko   260 Nombre de téléchargements

Fichier attaché  batterie.txt   4,19 Ko   216 Nombre de téléchargements

 

 




Registre à décalage 74HC595

Publié arobasseb le 20 août 2017 - 12:12 in Electronique

Aujourd'hui je vous présente un composant fort utile le 74hc595.
 
Qui est-il ? C'est un registre à décalage de 8 bits.
 
A quoi sert-il ? il sert à convertir une information série en parallèle. Mais on l'utilise aussi pour économiser le nombre de broche utilisée en sortie.
C'est d'ailleurs pour ce dernier cas que je vais présenter la chose :).
 
En effet, au dessus de 3 sorties à piloter, il peut être intéressant d'utiliser ce composant afin d'économiser des broches sur votre carte de commande. Pourquoi 3, car c'est le nombre minimum de broche nécessaire au fonctionnement du composant.
 
Comment ça fonctione ? Afin de mieux comprendre le fonctionnment j'ai fait ces quelques images ci-dessous : 
 
Diapositive1.GIF
Diapositive2.GIF
Diapositive3.GIF
Diapositive4.GIF
Diapositive5.GIF
Diapositive6.GIF
 
Comme on peut le voir, il y a 2 grandes phases : 
La première on place les données que l'on veut 
La deuxième est la validation des données
 
Maintenant passons à la pratique.
 
Dans cet exemple, le but sera d'allumer des LED car c'est le plus simple électriquement. En effet, on peut également piloter des moteurs, des relais, des électrovannes, ... mais cela nécessite une interface de puissance, ce qui n'est pas le sujet de ce tutoriel.
 
cablage_74HC595.png
 
comme on peut le voir le schéma est très simple : 
Nous avons d'une part le microcontroleur qui alimente et pilote le 74HC595
puis le 74HC595 qui fait le lien avec les LED
et enfin les LED
 
Il est tant, maintenant, de faire fonctionner tout ça.

//constantes pour les broches de commande du 74HC595
int DS_pin = 8;   // broche de donnée
int STCP_pin = 9; // broche de validation de la donnée
int SHCP_pin = 10;// broche de validation compléte (latch)

boolean registre[8]; //c'est un tableau de 8 bit correspondant aux sorties du 74HC595 à l'état voulu
                      // pour se programme j'ai fait le choix du tableau car cela reste simple pour un tutoriel

void setup()
{
    //configure les broches en sortie
    pinMode(DS_pin,OUTPUT);
    pinMode(STCP_pin,OUTPUT);
    pinMode(SHCP_pin,OUTPUT);
}

//Cette fonction "écrit" le contenu du tableau dans le registre
//pour chaque bit, on met la brohe de validation du bit à 0, on place la broche de donnée à l'état contenu dans le tableau et ensuite on valide le bit
//à la fin on valide le tout
void EcrireRegistre()
{
  
  digitalWrite(STCP_pin, LOW);
  
  for (int i = 7; i>=0; i--)
  {
    digitalWrite(SHCP_pin, LOW);
    digitalWrite(DS_pin, registre[i] );
    digitalWrite(SHCP_pin, HIGH);
  }
  
  digitalWrite(STCP_pin, HIGH);
}


//Dans la boucle du programme plusieurs séquences différentes sont jouées
void loop()
{
   //Allume successivement les sorties
   for(int i = 0; i<8; i++)
   {
    registre[i] = HIGH;
    delay(300);
    EcrireRegistre();
   }

   //éteint successivement les sorties
   for(int i = 7; i>=0; i--)
   {
    registre[i] = LOW;
    delay(300);
    EcrireRegistre();
  
   }

   //séquence qui allume une LED sur 2 alternativement
    bool b = 0;
    for(int i = 0; i<4; i++)
    {
        
      for(int j = 0; j<8; j++)
      {
        registre[j] = j%2 xor b;
      }
      EcrireRegistre();
      b = not b;
      delay(300);
    }

    //remise à zéro de toutes les LED
    for(int j = 0; j<8; j++)
    {
      registre[j] = 0;
    }
    EcrireRegistre();
}

 
 
Pour aller plus loin
 
Je vais vous donner deux astuces afin d'étendre un peu le sujet.
 
Astuce 1 : avoir plus de 8 sorties
 
Pour avoir plus de 8 sorties, naturellement on se dit qu'il faut un deuxième 74hc595 et l'on clône le montage en utilisant les autres pins disponibles. Mais si c'était ça je n'aurai pas pris la peine d'écrire cette astuce.
En effet, vous l'avez peut-être remarqué sur le schéma, il y a une broche Q7'. Et c'est de là que vient l'astuce. En effet on peut chainer les 74HC595 entre eux, en reliant la broche Q7' du premier, sur la broche DS (souvenez-vous la broche de donnée) du suivant.
Enfin, afin de synchroniser les deux 74HC595 il suffit de connecter leurs broches ST_CP et SH_CP entre eux.
 
 
Au niveau du code, au lieu de boucler sur 8 bits, il faut boucler sur 16 bits. Et voilà, avec le même nombre de fils on augmente notre circuit de 8 sorties supplémentaires. 
 
 
En théorie vous pouvez en chainer autant que vous voulez, mais en pratique, avec un arduino le temps de mise à jour des registres deviendra de plus en plus long et donc nuira au fonctionnment du programme.
 
Astuce 2 : s'en servir pour augmenter le nombre d'entrée
 
Les puristes ne vont surement pas aimer, et cette astuce se révèle plus être une bidouille. M'enfin, je me lance :)
 
Imaginons que nous ayons 8 interrupteurs, mais que 4 broches de libres sur notre arduino. On se dit c'est mal barré, on a pas d'autre arduino, c'est fin ; et soudain vous vous souvenez qu'il vous reste un 74HC595. La bidouille peut commencer.
 
Le principe est simple, on va faire se décaler un bit à travers le registre (juste un seul), du coup pour les interrupteurs en sortie, seulement 1 seul sera alimenté et si tous les interrupteurs sont raccordés sur une seule entrée de l'arduino, alors on connait l'état d'interrupteur.
 
 
Bon j'avoue, c'est un peu empirique :)


UNE INTERFACE DE PUISSANCE POUR ARDUINO.

Publié Nulentout le 12 avril 2017 - 08:54 in Electronique

Dans l'ouvrage :

 

http://www.robot-maker.com/ouvrages/interface-puissance-arduino/
 
joint je vous propose un didacticiel sur une interface secteur.
 
Ce petit montage très simple vous permettra de piloter avec un quelconque module microcontrôleur un appareil branché sur le secteur électrique 220V alternatif, pouvant consommer jusqu'à 16 ampères soit une puissance maîtrisée de 3,5kW.
Ce tutoriel s'adresse aux débutants. Tout est expliqué de façon théorique et surtout de manière pratique, avec beaucoup de schémas et d'images.
Attention à la facture d'électricité !
 
Amicalement : Nulentout




Introduction à Node JS sur PI

Publié Path le 24 mars 2016 - 10:55 in Programmation

nodejs-logo.png raspberry_pi_logo.png

 
C'est quoi Nodejs ?
 
Nodejs, c'est un portage open source en C++ du moteur d'interpretation et d'exécution javascript que l'on trouve habituellement dans les navigateurs (chrome) : le V8 de google. Nodejs permet de sortir le javascript des navigateurs pour l'exécuter sur une machine windows, mac ou linux en standalone (desktop, serveur ou embarqué). 
 
Les navigateurs étant sécurisés, par exemple, on ne peut pas accéder aux fichiers, à la ligne de commande ou écouter un port. Nodejs ajoute au javascript les fonctions  d'accès au système qui lui faisaient défaut. Nodejs suis les évolutions de la norme ECMAScript (spécifications du langaue) et est devenu une plateforme à la fois simple, léger et mature. Surtout depuis ES6. La doc de l'API exposée par NodeJS en plus du Javascript : https://nodejs.org/d...-v6.x/docs/api/
 
NodeJS est maintenant couramment utilisé dans le monde de l'IT pour des middleware, des web services temps-réel ou en full-stack (coté serveur et coté client) pour des applications web. On le voit aussi beaucoup dans le monde des objets connectés. Il arrive naturellement sur le raspberry PI pour piloter un robot. 
 
Le langage javascript n'est pas un langage simple contrairement à ce qu'on pense généralement. Ce tuto ne couvre pas le javascript. Il faudra pour cela voir de ce coté : http://javascript.de...ppez.com/cours/. C'est faux de croire que l'on connait javascript si on a affiché un bouton dans une page web. En effet le navigateur masque toute la partie interessante de javascript : sa boucle d'évènements. Le code javascript est exécuté dans un seul thread. Mais derrière tous les appels asynchrones, la mécanique du V8 est parallélisée. Mieux que des mots, la meilleure video que je connaisse pour expliquer comment fonctionne javascript.
 

 
Par exemple, hello.js

// attends 1s et affiche le texte
setTimeout (function() {
  console.log("les makers");
},1000);
console.log ("Hello");

$node hello.js (ou C:\node.exe hello.js)

hello.js affiche :
Hello
​les makers
(et pas "les makers Hello")
 
Avertissement
 
Le tuto qui suit montre comment piloter un robot avec NodeJS. Vous l'aurez compris, NodeJS devient intéressant quand on connait javascript.
 
Ce tuto pré-suppose que le raspberry est installé avec la raspbian : https://www.raspberr.../documentation/
 
Ce tuto est destiné aux débutants en robotique. Il est réalisé dans le cadre de la conception du robot Ash : http://www.robot-mak...alancing-robot/
 
Pourquoi PAS NodeJS ?
 
Javascript n'est pas un langage temps-réel.
Javascript n'est pas compilé. Il n'y a pas de vérification du code avant l'exécution.
Javascript est faiblement typé. Il demande un peu d'attention.
 
Alors, plus concrètement,
 
Pourquoi NodeJS ?

  • javascript n'attend pas

Il continue à exécuter le code pendant qu'une instruction asynchrone est en attente. Une lecture de ficher, d'un port série ou réseau. Cela le rend bien plus efficace et performant qu'un système multi-threadé.

  • javascript est un langage à évènements.

Ce n'est pas avec une librairie ou un addon. C'est au coeur du langage.

  • Les streams

L'API stream de NodeJS combine la puissance des évènements avec celle des pipes d'unix. Si vous connaissez les pipes entre les commandes unix, vous savez que c'est une aide précieuse et facile à mettre en place.

  • javascript est full stack

Un seul langage pour le serveur, pour le client et pour les middlewares orienté messages (évènements). 

 
Si on connait son langage, NodeJS est un pont facile à mettre en place entre arduino et une interface de contrôle web. Et disposer d'une interface web permet de ne rien installer sur le terminal de commande (sauf un navigateur) et il est compatible avec tous les smartphone et sur toutes les machines desktop habituels.
 
 
tutorials-9452-0-82260000-1462831177.png
 
NodeJS ouvre le raspberry (et donc le robot qui en est doté) à tout l'Internet domestique ou extérieur.
 
Enfin, Nodejs bénéficie d'une très large communauté. Il est accompagné d'un gestionnaire de packages (librairies) npm. Pour vous faire une idée, voilà ce qu'on trouve déjà concernant le port gpio chez nodejs : https://www.npmjs.com/search?q=gpio
  
  
NPM
 
Node s'install avec son gestionnaire de packages. Voir : https://docs.npmjs.com/
On se contentera de faire des npm install pour obtenir des modules. 
 
Installation de NodeJS et NPM sur Raspberry PI
 
Ajouter le repository nodesource :

sudo curl -sL https://deb.nodesource.com/setup_6.x | sudo -E bash -

Cette commande va aussi  mettre à jour le catalogue.
 
NB. Adafuit mets aussi node à disposition sur un repository similaire. Avec nodesource, on a une version plus à jour. 
NB. Quand la version 8 de NodeJS sera disponible, l'url ci-dessus devra être adaptée. Voir https://github.com/nodejs/LTS/.
 
Installer nodejs :

sudo apt-get install nodejs

NB. npm (le gestionnaire de package de node) est installé automatiquement avec nodejs.
 
Vérification :

pi@raspberrypi:~ $ nodejs -v
v6.2.1
pi@raspberrypi:~ $ npm -v
3.9.3

Source : https://nodejs.org/e...x-distributions

 

Installation d'un module NPM

$npm install <nom du module>

npm va alors créer un répertoire module dans le répertoire courant. Vous devez donc vous placer à la racine de votre projet pour lancer cette commande.

 

Pour plus d'infos sur NPM : https://docs.npmjs.com/

Interface avec Arduino
 
Le plus simple est de conserver le câble USB entre le raspberry et arduino dans le montage définitif du robot. 
 
Compilation
Cela permet de compiler le code arduino sur le raspberry directement et d'uploader le programme compilé sur l'arduino directement depuis le raspberry. Voir http://www.robot-mak...ne-de-commande/
 
Communication
Pour communiquer avec arduino, on utilise toujours le câble USB.
 
Coté raspberry, on utilise le module NPM "serialport" dans une classe utilitaire qui fait l'interface avec Arduino :

Spoiler

 
On utilise cette classe comme ceci :
 

var Arduino = require('./modules/arduino.js');

 
Pour envoyer un message à arduino :

arduino.writeSerial('COMMANDE:DONNEE:DONNEE:DONNEE');

 
Pour recevoir des messages de arduino :
 

arduino.on('ready', function() {
  console.log('Arduino ready');
});

arduino.on('CONSOLE', function(data) {
  console.log('[ARDUINO CONSOLE]'+data.args);
});

arduino.on('COUNTCODER', function(data) {
  console.log('Arduino COUNT left: '+data.args[0])
  console.log('Arduino COUNT right: '+data.args[1])
  (...)
})

 
Du coté Arduino, pour écrire un message à raspberry, on utilisera simplement 

Serial.print();

Pour lire les message envoyé par raspberry, il faut les dé-sérialiser et dispatcher les commandes. Par exemple :



Spoiler

 
Alimentation
Le raspberry peut alimenter l'aduino par le port USB donc dans la limite de 500mA.
 
Note
Le montage par câble USB sera remplacé par un branchement I2C ou SPI pour des besoins plus spécifiques communication en réseau. Arduino pourra être alimenté différemment s'il a besoin de plus de 500 mA.
 
Interface avec les programmes en python
 
Par exemple, on va intercepter les valeurs qui arrivent du capteur IMU du senseHAT. Le senseHAT est fourni avec une API en python. On va appeler la librairie du senseHAT et écrire une valeur sur la sortie standard.

#!/usr/bin/python
# -*- coding: utf-8 -*-

from sense_hat import SenseHat
import time
sense = SenseHat()
sense.set_imu_config(False, True, True)  # compass_enabled, gyro_enabled, accel_enabled
while True:
	# Get orientation from hat
	orientation = sense.get_orientation_degrees()

	roll = orientation["roll"]
	roll = round(roll, 2)
        print(roll)
	time.sleep(.005)
 

Dans NodeJS, on va utiliser le module "python-shell" pour instancier ce programme en python et lire la sortie standard.
 

var PythonShell = require('python-shell');

var pyOptions = {
  mode: 'text',
  pythonPath: '/usr/bin/python',
  pythonOptions: ['-u'],
  scriptPath: '/home/pi/SBR'//,
  //args: ['value1', 'value2', 'value3']
};

var imu = new PythonShell('imu.py', pyOptions);

imu.on('message', function(data) {
    console.log(data); // data contient une ligne de la sortie standard données par imu.py
  });
 

 
 
Interface web
 
Pour servir une page static HTML avec node, c'est très simple. On va utiliser le module "express" pour créer un mini serveur web sur le raspberry. On y ajoutera tout de suite une websocket pour obtenir des informations du robot sur la page web en mode push (à l'initiative du serveur).
 

var app = require('express')();
var server = require('http').createServer(app);
var io = require('socket.io')(server);

io.on('connection', function(socket){

    socket.on('command', function(data) {
      // data contient les données envoyées depuis la page web
    });

    // Pour envoyer des données au navigateur
    io.sockets.emit("COMMAND", data);
});

// Pour servir la page static, on la place dans un répertoire dédié
app.use(express.static(__dirname + '/../static'));

server.listen(3000);

Placez une un fichier nommé index.html dans le répertoire static.
 
Pour se connecter l'interface web, il faudra se connecter à l'IP du raspberry sur le port 3000 depuis un navigateur. (http://w.x.y.z:3000/). Votre navigateur affichera le contenu html de votre index.html.
A noter, socket.io sert son client websocket au navigateur de façon transparente.
 
Votre fichier html de commande peut ressembler à ceci :

 

Sans titre.png

 

Spoiler

 

Pour plus d'infos sur la websocket : https://github.com/socketio/socket.io
Pour plus d'infos sur express : http://expressjs.com/fr/

NB. Il s'agit d'un embryon de serveur web. Mais suffisant pour les besoins de pilotage d'un robot.

 
Pour aller plus loin
 
Le V8 de google : https://fr.wikipedia...eur_JavaScript)
NodeJS : https://nodejs.org/en/about/
Liens utiles NodeJS : https://github.com/s...NodeJS-Learning
Javascript : https://developer.mo.../Web/JavaScript

Thumbnail(s) attaché(s)

  • Ash suite.png



Small bot V2

Publié microrupteurman2 le 17 mars 2013 - 08:01 in Robot complet





Bienvenue dans ce tuto, ici je vous expliquerai comment fabriquer un petit robot.




Materiel necessaire:

-Un atTiny85/45
-Un condensateur seramique 0.047µf
-Un support DIP 8pin
-Un capteur IR
-Des fils electrique
-Un fer a souder
-Un pistolet a colle (colle chaude)
-Un coupleur de pile 3xAA (R6)
- Deux micro servo 9g
-Deux petites roues
-Une portion de stripBoard (14 trous par 8 bandes de cuivre)

Pour la programmation de l'atTiny :

-Une arduino UNO (IDE 1.0)
-Une breadboard
-Deux librairie :
https://github.com/d...hive/master.zip (a decompresser et coller dans /arduino/hardware
http://bateaux.trucs...ftwareServo.zip SoftWare servo a decompresser et copier dans /arduino/librairie


Modification des servo en servo a rotation continue:

-Devisser les 4 vis sous le servo
-Enlever le cache haut et le cache bas.
-Dessolidarisé le circuit imprimer
-Sur l'un des pignon, il y a une butée, la coupé avec un cutter
-Repairer les fils du potentiometre.
-Dessouder celui du milieu du potentiometre sur le circuit imprimé et un des deux autre
-Souder une resistance metal de 10ko ou etait souder les deux fils
-Dessouder le 3e fil du potentiometre du circuit, y souder
une meme resistance vers l'autre patte de la resistance
ou etait le fil du mileu du potentiometre.
-Refermé le tout.

Si vous avez des difficulter, n'hesitez pas a laisser un commentaire ou m'envoyer un mp.

Progammation de l'AtTiny :

-PinOut de l'attiny/25/45/85:

Image IPB


La pin Reset n'est a n'utiliser en aucun cas (sauf lore de la programmation).

-Preparation de la UNO :

Toujours debrancher votre Arduino de la prise usb lors de la manipulation du montage. Vous aurez prealablemet telecharger les deux librairies cité plus haut.

1-Lancer l'IDE arduino (1.0)
2-Cliquez sur Fichier/exemple arduinoISP
3-Selectionné votre carte en cliquant sur outils/type de carte/uno
4-Cliquez sur televerser.

Maintenant votre Arduino est programmé pour programmé les attiny.

Faite le montage suivant :

Image IPB

Le condensateur n'est pas obligatoire.


-Allez dans ( Outils/Type de carte) cliquez sur ( Attiny85 internal 8 MHz clock )
-Allez à nouveau dans ( Outils/Programmateur ) cliquez sur ( Arduino as ISP) pour signaler à l'IDE que l'UNO est utilisé comme programmateur.
-Si votre ATtiny est neuf, et que vous souhaitez le le faire travailler à 8MHz, vous devez maintenant aller sur ( Outils ) et cliquer sur ( Graver la séquence d'initialisation )
-Cliquez sur l'icône vérifier Image IPB
-Cliquez sur Téléverser ou sur l'icône Image IPB
-Debrancher le cable USB, retiré l'AtTiny .




Et televerser y le code suivant :

#include <SoftwareServo.h> // librairie pour controle servo attiny

SoftwareServo servoD;
SoftwareServo servoG;// create servo object to control a servo 
                        // a maximum of eight servo objects can be created 


#define REFRESH_PERIOD_MS 20
int pos = 0; 
int sensorValue;

void setup()
{
servoD.attach(0);
servoG.attach(3);
}
void loop()
{
sensorValue = analogRead(1);

if (sensorValue <10)    // changer cette valeur par celle qui corespond a votre capteur
{
  for(pos = 0; pos < 25; pos += 1)  // goes from 0 degrees to 180 degrees 
  {                                  // in steps of 1 degree 
    servoD.write(150);
  delay(10);
  SoftwareServo::refresh();
  servoG.write(150); 
  delay(10);
  SoftwareServo::refresh();       // generates the servo pulse
  } 
  
}
else
{
  servoD.write(10);
  delay(10);
  SoftwareServo::refresh();
  servoG.write(150); 
  delay(10);
  SoftwareServo::refresh();
}

}



Implementation des composant :

Pour plus de complexiter j'ai cadrillé la stripboard

b5 -> f5 : Strap
b10 -> c10 : condensateur
d2 : cmde Servo 1
f14 : cmde Servo 2
b11-c11-d11: connecteur HE10 male
f4 : Gnd servo 1
f3 : Gnd servo 2
f1 : Gnd (accus)
c12 : +5v servo 1
c13 : +5v servo 2
c14 : +5v (accus)

Ne pas oubler de couper les pistes sous le µc, d'ou le trait.

Image IPB

Une foit ce cricuit realiser, emboiter votre µc dans le support en faisant attention au sens !

Coller a la colle chaude les servo modifier sous l'avant du boitier de pile, fixer les roues sur les servos et ajouter une 3e point apuis (j'ai mis un petit cube de bois) .



Et une petite video pour finir :


https://www.youtube.com/watch?feature=player_detailpage&v=Xhm8_Sl2bZQ





Desoler pour la mise en page, mais j'ai pas pu faire autrement. Je pense continué a amelioré ce tuto, car il manque encore quelques chose.


Trigonométrie

Publié Harry le 14 avril 2016 - 05:53 in Concepts

Bonjour, ce tutoriel est plus une liste de formules très utiles en robotique qu'un vrai tutoriel, mais il peut être très efficace de l'avoir à portée de main...

Voici le cercle trigonométrique, son rayon étant pris égal à 1 :

Image IPB


Image IPB Sur le cercle est positionné l'angle que fait le vecteur OA avec l'horizontale : on l'appelle alpha.

Vous remarquerez que l'angle entre OB et AB est 90° : OAB est donc rectangle en B. Prenons ce triangle rectangle.

On pose trois fonctions indispensables en mathématiques que sont cosinus, sinus et tangente, qui sont écrits, si alpha est un angle : cos(alpha), sin(alpha) et tan(alpha)

Ils sont définis par (à connaître par coeur avec le schéma qui va avec) :
cos(alpha) = côté adjacent / hypoténuse
sin(alpha) = côté opposé / hypoténuse
tan(alpha) = côté opposé / côté adjacent


sachant que dans le triangle rectangle OAB :
côté adjacent = OB
côté opposé = BA
hypoténuse = OA

alors on obtient (à connaître par coeur avec le schéma qui va avec) :
cos(alpha) = OB/OA
sin(alpha) = BA/OA
tan(alpha) = BA/OB


Image IPB

Image IPB Un symbole bizarre (en jaune) est introduit sur le schéma : il s'appelle PI et vaut environ 3,1415... (le nombre de chiffre après la virgule est infini).
L'unité utilisé en trigonométrie pour les angles n'est pas le degré (noté °), mais le radian (noté rad)
Ainsi, PI rad = 180°


Image IPB Le cosinus de l'angle fait entre OA et l'horizontale se trouve en projetant A sur l'horizontale (soit B ce point). Son sinus est trouvé en projetant A sur la verticale (soit C ce point). Certaines valeurs de cosinus et de sinus sont à connaître par cœur :


Image IPBcos (0) = sin(PI/2) = 1
cos(PI/6) = sin(PI/3) = racine(3)/2
cos(PI/4) = sin(PI/4) = racine(2)/2
cos(PI/3) = sin(PI/6) = 1/2
cos(PI/2) = sin ( 0 ) = 0


Image IPBExercice : trouver la valeur des tangentes de ces nombres

Image IPBOn remarque que sin(alpha)/cos(alpha) = tan(alpha) (il suffit d'écrire la relation avec les longueurs pour s'en convaincre). Ainsi, connaissant les valeurs de sin(alpha) et cos(alpha) on retrouve les valeurs facilement.

tan(0) = 0
tan(PI/6) = 1/racine(3)
tan(PI/4) = 1
tan(PI/3) = racine(3)
tan(PI/2) = l'infini



Vous devez retrouver l'équivalent des angles mis sur le schéma suivant, et les connaître par cœur, et savoir les positionner sans problème sur le cercle trigonométrique, ainsi que leurs cosinus, sinus et tangente :

Image IPB

Un sens positif et un sens négatif sont indiqués : en réalité l'angle en radian n'est pas un angle simple. Il est dit "algébrique" car il peut être négatif comme positif. Cela a donc une conséquence sur les valeurs des sinus et des cosinus. En clair, il faut savoir refaire le schéma précédent par cœur.


Formules trigonométriques à savoir - si on prend "a" et "b" deux angles algébriques :

sin(-a) = -sin(a)
cos(-a) = cos(a)
cos (a + B ) = cos(a).cos( B ) - sin(a).sin( B )
sin (a + B ) = sin(a).cos( B ) + cos(a).sin( B )
cos²(a) + sin²(a) = 1
cos(2a) = cos²(a) - sin²(a) = 2.cos²(a) - 1 = 1 - 2.sin²(a) (à savoir retrouver)
sin(2a) = 2.sin(a).cos(a) (à savoir retrouver)


Formules à savoir retrouver (ça peut faire d'excellents exercices) :
cos( PI/2 - a ) = sin(a)
sin( PI/2 - a ) = cos(a)
cos( PI/2 + a ) = sin(a)
sin( PI/2 + a ) = -cos(a)
cos( PI - a ) = -cos(a)
sin( PI - a ) = sin(a)
cos( PI + a ) = -cos(a)
sin( PI + a ) = -sin(a)
cos( a - B ) = cos(a).cos( B ) + sin(a).sin( B )
sin( a - B ) = sin(a).cos( B ) - sin( B ).cos(a)


Très utiles à savoir retrouver :

Image IPB

Formule à utiliser quand vous en aurez besoin :

Image IPB

Loi des sinus : formule valable pour un triangle quelconque ABC(en prenant A, B et C les angles et a, b, c leurs côtés opposés respectifs)

a/sin(A) = b/sin( B ) = c/sin( C ) = 2R


Enfin, loi des cosinus (ou loi d'Al-kashi) : des formules qui donne des relations entre le cosinus d'un angle et les longueurs d'un triangle quelconque ! Extrêmement utile en robotique pour effectuer des calculs sans utiliser des librairies lourdes pour un pic pour calculer des relations particulières :

a² = b² + c² - 2b.c.cos A ==> On en déduit la valeur de cos A
b² = c² + a² - 2c.a.cos B ==> On en déduit la valeur de cos B
c² = a² + b² - 2a.b.cos C ==> On en déduit la valeur de cos C


Voilà, j'espère que cette liste de formules vous sera utile.


[Composant] Le NE555

Publié 4Aklisme le 04 juin 2008 - 05:54 in Electronique

Introduction


Ce tuto va vous faire découvrir un composant : Le NE555.
Vous allez découvrir ce qui se cache derrière ce nom et deux montages de base de ce composant.



Présentation


1-a : Brève Histoire du NE555 :

Image IPB

Le NE555 est un circuit intégré utilisé pour gérer des temps (temporisation, etc...). Il a été créé en 1970 par Hans R. Camenzind et commercialisé en 1971 par Signetics. De nos jours, ce composant est encore très utilisé, car il est simple d'utilisation (idéal dans un but pédagogique) et peu coûteux. Aujourd'hui, la version CMOS de ce circuit est très employée (tel que le MC1455 de Motorola) , cependant il y a eu beaucoup d'améliorations et variations du circuit. Mais malgré les variantes, tous les types sont compatibles entre eux au niveau du brochage.

Plusieurs fabricants réalisent ce circuit sous des appellations différentes dont en voici quelques une :

Motorola -> MC1455
Fairchild -> NE555
Philips -> NE555D
Texas instruments -> SN52555
National -> LM555C

Voici les principales caractéristiques de ce composant :
  • Fonctionne sous des tensions d'alimentation de 4,5V à 16V (compatible TTL).
  • Fréquence max 2 MHz.
  • Stabilité en température 0,005 % par °C.
  • Intensité maximale de sortie de 200 mA.
1-b : Symbole, schéma interne, brochage :

J'ai pour habitude de noter le NE555 de cette façon dans mes schémas (mais il existe d'autres façons de présenter des broches...)

Symbole du NE555 :

Image IPB

Le NE555 contient en fait environ 23 transistors, 2 diodes et environ 16 résistances qui, une fois associés, composent ce schéma (Schéma interne du NE555) :

Image IPB

Voici le brochage du boitier du NE555 :

Image IPB

Description des broches :
  • GND : Masse du boîtier.
  • TRIG : (déclenchement) Commande l'état de sortie. Amorce la temporisation.
  • OUT : Sortie du boîtier.
  • RESET : (RAZ) Remise à zéro du signal de sortie. Stoppe la temporisation.
  • CONT : (référence) Tension de référence. (2/3 de VCC).
  • THRES : (seuil) Commande l'état de sortie. Signalle la fin de la temporisation lorsque la tension dépasse 2/3 de VCC
  • DISCH : (décharge) Décharge le condensateur de temporisation.
  • VCC : Alimentation du boîtier.
1-c : Principe de fonctionnement (en bref) :

Les trois résistances internes au NE555 font un pont diviseur de tension qui permet d'obtenir les tensions 2/3 et 1/3 de VCC, servant de tension de référence pour les 2 comparateurs.

4 cas se présentent à nous :
  • RESET est à un niveau bas : La bascule est remise à zéro et la sortie est au niveau bas.
  • TRIG < à 1/3 de VCC : la bascule est activée (SET) et la sortie est à un niveau haut.
  • THRES > à 2/3 de VCC : la bascule est remise à zéro (RESET) et la sortie est à un niveau bas.
  • THRES < à 2/3 de VCC et TRIG > à 1/3 de VCC : La sortie conserve son état précédent.
Table de vérité :

Image IPB




Montage en Monostable



Petite explication sur le terme monostable :

Un montage monostable signifie que la sortie du montage reste à un niveau logique quand il ne se passe rien sur son entrée de commande. Mais lorsque que l'on met une impulsion sur son entrée de commande, la sortie passe à l'état logique opposé, pendant un temps déterminé (T1).

Exemple quelconque :


Image IPB

2-a : Montage en monostable non re-déclenchable :

Image IPB

Image IPB

La sortie est à '1' pendant un temps 't1', quand on applique une impulsion négative sur l'entrée.
La durée 't1' est déterminée par R1 et C1, dont voici la formule :

Image IPB

Image IPBQuand vous faites les calculs, gardez à l'esprit que les composants ont une certaine tolérance (5% pour les résistances, 10% pour les condensateurs...)

Ce montage est non re-déclenchable car si pendant le temps t1 il y a une nouvelle impulsion en entrée, le temps 't1' ne reprend pas à zéro.

2-a : Montage en monostable re-déclenchable :

Image IPB

Image IPB

La différence avec le montage en monostable non re-déclenchable est que la broche 4 (RESET) est reliée à la broche 2 (TRIG).

La sortie est à '1' pendant un temps 't1', quand on applique une impulsion négative sur l'entrée.
La durée 't1' est déterminée par R1 et C1, dont voici la formule :

Image IPB

Quand vous faites les calculs, gardez à l'esprit que les composants ont une certaine tolérance (5% pour les résistances, 10% pour les condensateurs...)[/color]

Ce montage est re-déclenchable car si pendant le temps 't1' il y a une nouvelle impulsion en l'entrée, le temps t1 reprend à zéro.




Montage en Astable


Petite explication sur le terme astable :

On dit qu'un signal est astable quand celui-ci passe en permanence d'un état logique '1' à un état logique '0'.
Exemple : un signal carré.


Schéma du montage du NE555 en astable :

Image IPB

Image IPB

Grâce à ce montage on va pouvoir générer des créneaux dont on pourra modifier la fréquence ainsi que les temps t1 et t2 correspondant au temps à l'état bas et haut.

t1= temps à l'état bas = Image IPB
t2= temps à l'état haut = Image IPB

Image IPB
Donc
fréquence = Image IPB

et donc :
rapport cyclique = Image IPB

Image IPBQuand vous faites les calculs, gardez à l'esprit que les composants ont une certaine tolérance (5% pour les résistances, 10% pour les condensateurs...)

4 – Exemple d'utilisation : Faire clignoter deux LEDs :

Le montage que je vous propose permet de faire clignoter deux LEDs à une vitesse que l'on choisit en tournant un potentiomètre.
Ce montage fonctionne à l'aide d'une pile 9V.

4-a : Schéma du montage :

Image IPB

4-b : Liste des composants :

Image IPB

4-c : Fonctionnement et explications :

Le NE555 est utilisé en astable.
C'est à dire qu'il va nous fournir un signal carré 0V – 9V.

Donc, quand la sortie OUT sera à 9V, la LED D2 aura une tension positive à ses bornes et sera allumée, tandis que la LED D1 sera éteinte car alimentée en inverse.
Par contre, quand OUT sera à 0V, la LED D1 aura une tension positive à ses bornes et sera allumée tandis que la LED D2 sera éteinte car alimentée en inverse.

Voyons à quelle fréquence peut-on faire clignoter les LEDs :

Rappel de la formule de la fréquence pour le NE555 en montage en astable :
fréquence = Image IPB
Dans le schéma, C2 correspond au C1 des formules !!!


Pour P1 = 0 (minimum) :
Image IPB
Pour P1 = 50 Kohm (maximum) :
Image IPB
Image IPB

Donc en faisant varier P1 de son minimum à son maximum on pourra faire varier la fréquence de clignotement des LEDs entre 1,26 Hz (environ) à 9,86 Hz (environ).

Image IPBJe dit "environ" car les condensateurs et les résistances ont une tolérance pour leur valeur...

Voici la fin de ce tutoriel, j'espère que celui-ci vous sera utile !
Si vous avez des questions, n'hésitez pas à les poser sur le forum !



[Composant] le L298

Publié Mike118 le 19 mai 2016 - 09:22 in Electronique

On a tous au moins un composant qui est super pratique mais mal foutu … Et moi, Mike 118, aujourd’hui je vais vous parler de mon préféré de cette catégorie : Le L298N (plus connu sous sa forme multiwatt 15V …)

 

l298.jpg

 

Tout d’abord pour ceux qui ne le connaissent pas encore : qu’est-ce que c’est que ce composant ? Et bien c’est un double pont en H capable de délivrer 2A par pont fonctionnant jusqu’à 46V ! Il est donc idéal pour une grande gamme de moteurs CC et pas à pas.
Pour ceux qui ne savent pas ce qu’est un pont en H je les invite à se renseigner ici par exemple : http://fr.wikipedia.org/wiki/Pont_en_H.
Autre remarque : je vais employer volontairement des mots anglais afin de vous familiariser un peu avec certains termes employé dans les documentations anglaises en vigueur : aussi appelé les datasheet ! Mais ne vous inquiétez pas cela ne sera que ponctuel !

 

Je vais commencer par décrire un peu le composant :
Comme le composant contient deux ponts en H on les notera pont A et pont B. Le L298 a 15 pattes qui se répartissent ainsi :

  • 3 pattes pour l’alimentation qui est commun aux pont A et B. On a donc la masse : Gnd pour "ground", la tension d’alimentation de forte puissance : VS comprise entre 5 et 50V et la tension d’alimentation « logique » noté Vss = 5V (point très intéressant puisque le composant est donc compatible avec tous vos composants favoris tournant en 5V : Pic, Arduino, Aop, Ne555, etc…)
  • 4 pattes pour les deux paire de sorties que l’on nomme output 1 output 2 output 3 et output 4. Avec output 1 et 2 appartenant au pont A et output 3 et 4 appartenant au pont B. C’est là qu’on va brancher notre moteur par exemple et ce sont ces sorties qui seront capable de délivrer 2A en continue et des pics jusqu’à 3A mais à éviter le plus possible.
  • 4 pattes pour les 2 paires d’entrées que l’on note input 1 input 2 input 3 input 4 de chaque pont, là aussi input 1 et 2 appartenant au pont A et input 3 et 4 appartenant au pont B. C’est sur ces pattes qu’on va brancher nos composants préféré qui vont commander les pont A et B. En effet, imposer une tension de 5V sur input 1 va permettre d’imposer la tension VS sur output 1 et imposer 0V va permettre d’imposer 0V sur output1 … de même pour input 2 sur output 2 etc…
  • Cela fait déjà 11 pattes, et on a vu comment on pouvait utiliser le composant dans ces grandes lignes mais il manque encore 4 pattes …
  • Enable A, enable B, current sensing A, current sensing B

A quoi peuvent-elles bien servirent ?
Tout d’abord, chaque pont est pourvu d’une sécurité, d’où les pattes notées « enable A et enable B ». Pour pouvoir utiliser le pont A : à savoir output 1 et output2, il faut qu’une tension de 5V soit appliqué sur enable A sinon le pont est « en roue libre » et dans ce cas on a donc output 1 et 2 qui ne sont relié à rien du tout ! Ni à la masse ni au 24V quel que soit l’état des input1 et input2. De même pour pouvoir utiliser le pont B il faut 5V sur enable B…

 

Cela fait 2 pattes supplémentaires qu’on peut gérer avec nos composants favoris tournant à 5V ! Très intéressant si on veut ajouter un bouton d’arrêt d’urgence par exemple car il suffit de le relier entre la masse et l’enable du port qu’on veut pouvoir arrêter avec le bouton d’arrêt d’urgence… On peut même relier les deux enables ensemble pour pouvoir couper les deux ponts en même temps !

Notez une chose : Si vous n’en avez pas l’utilité, n’oubliez pas de brancher les enables au 5V !

Bon courage ! Il reste plus que deux pattes …
Ce sont des pattes qui permettent de connaitre le courant I circulant dans chaque pont noté current sensing A et B ! Il suffit pour cela de mettre entre une résistance de valeur R entre curent sensing et la masse et de lire la tension U présente à cette patte : On aura I = U/R. Par contre attention ! Il faut choisir une résistance capable de dissiper suffisamment de puissance (2A ce n’est pas rien ! Petit rappel en notant R la valeur de votre résistance on P = R*I² … Donc avec une résistance de 1ohm et du 2A ça fait déjà au moins 4W à dissiper …) De même il est recommandé de ne pas dépasser les 3V sur cette pattes … donc Il est recommandé d’utiliser dans ce cas une résistance inférieur ou égale à 1 ohm et dissipant suffisamment de puissance pour vos applications ! Comme il ne faut pas dépasser une consommation de 3A, que ces pattes nous permettent de connaître la consommation en temps réel de chaque pont et que les enables nous permettent de couper les ponts si besoin … Il ne faut pas chercher bien loin pour se rendre compte qu’on peut faire une régulation du courant consommée dans les pont du L298 en utilisant ces 4 dernières pattes !

 

Bon maintenant que je vous ais embêté avec ça : sachez que si vous n’avez pas besoin de connaître la consommation en courant dans les ponts vous pouvez tout simplement bancher les current sensing à la masse ! (Et ceci résout le problème du choix de la résistance x). )
Maintenant une petite image pour tout récapituler et montrer qui est où sur le composant :

l298-shema.jpg

 

Pour plus d’info sur le composant je vous invite à lire la datasheet du composant disponible ici : Fichier attaché  l298-sgs-thomson-microelectronics-1.pdf   190,37 Ko   544 Nombre de téléchargements
Bon tout ça c’est bien beau on est d’accord… Vous auriez pu savoir tout ce que je viens de dire en lisant cette datasheet … Mais rappelons-nous j’ai dit que ce composant était « mal foutu »… Pourquoi donc ?
C’est l’organisation de ces pattes ! Sur une seule ligne c’est bien joli :

l298-shema2.jpg

 

Il y a juste la patte VS qui aurait peut-être put être à côté de la masse… mais bon rien de grave !
Le problème voilà… et bien par ce que nous on utilise généralement c’est ce genre de truc :

veroboard-breadboard.jpg

 

Qui eux sont compatible avec le format “Dip” = espacement entre les pattes 2.54mm et dans le cadre de composants sur deux rangées , les deux ranges sont aligéens avec espacement entre 2 rangées de pattes côte à côte 7.62mm (= 3*2.54mm).

 

Or le L298 est ainsi :

l298-shema3.jpg

 

Donc lui aussi est sur 2 rangées, chaque patte de chaque rangé a bien un espacement de 2.54mm mais l’espacement entre les deux rangées n’est pas de 7.62 mais d’environ 5mm. Mais le pire c’est que les deux rangées ne sont pas alignées ! Arg… Pour le rendre compatible il faut plier un peu les pattes … Soit …
On prend donc notre pince préférée si nécessaire, toute notre délicatesse et on s’exécute …

 

N’ayez pas peur ça se fait assez facilement … Les pattes sont plus solides qu’elles en ont l’aire faut juste pas trop répéter l’opération !
La preuve en image , ainsi cela s’adapte parfaitement au standart Dip :

montage-l298-veroboard.jpg

 

Bon c’est cool tout va bien … C’est très simple … Cependant voilà …

 

De manière schématique ce qu’on obtient au choix…

 

l298-l298.jpg

 

Et là stupeur ! nouveau casse tête … Ce qui était si bien ordonné quand tout était en ligne ne l’est plus en deux ligne ! Deux input d’un côté et deux de l’autre … les output de chaques côté … idem pour la masse et le 5V … Et du coup l’interfaçage avec quoi que ce soit et lui aussi un véritable casse tête … C’est la croix et la banière comme diraient certaines … en effet n’aurait il pas tellement été plus simple d’avoir ceci ?

 

schema-l298.jpg

 

Rien de plus simple pourtant … Il suffit de plier les pattes un peu différement !

 

l298-casse.jpg

 

Et c’était jusqu’à maintenant mon petit secret avec ce composant que je vous partage aujourd’hui ! Ce n’est peut-être pas très beau mais c’est monstrueusement efficace !

 

Je ne sais pas vous mais moi mais moi en tout cas je trouve ça 10 fois plus pratique … Et voilà pourquoi avec un petit exemple d’interfaçage :

 

interface.jpg

 

Vous pourrez remarquer que l’interfaçage est beaucoup plus facile : tout ce qui a besoin d’être gérer par nos composants préféré : microcontrôleur etc… est mis du côté droit (représenté en vert). Tout ce qui est sortie et alimentation est du côté gauche… Il ne reste plus qu’à y mettre vos connecteurs préférés et vous avez votre propre shield pour contrôler deux moteurs à courant continu dans les deux sens !
Vous pouvez aussi rajouter 8 diodes rapides 2A au montage afin de protéger le L298 des surintensités dans le cas où un moteur tourne alors qu’il ne devrait pas au vu de la commande… Ce qui arrive en général quand on demande à un moteur de s’arrêter alors qu’il tournait vite … car il met un peu de temps à le faire du à son inertie ! Il faut placer 2 diodes par sortie de la façon ci-contre sur le côté :

2-diodes-par-sortie.jpg

 

De plus je trouve que les pattes inputs et enables sont particulièrement bien agencées ! Cela ne vous rappel pas un autre composant vous ? Moi si ! Quelqu’un me souffle le L297 pour commander les moteurs pas à pas ? Bingo !

 

Regardons de plus près :

 

L297-pour-commander-les-moteurs-pas-a-pas.jpg

 

Et oui !
Correspondance parfaite
pour ces 6 pattes entre
les deux composants !
Voilà aussi de quoi simplifier l’interfaçage entre ces deux composants !