Aller au contenu


Information tutoriel

  • Ajouté le: janv. 28 2017 03:09
  • Date Updated: févr. 09 2017 09:50
  • Lectures: 2576
 


* * * * *
0 Notes

RobArchi X.XX

Cette base roulante porte l'extension X.XX car elle est le point de départ de plusieurs évolutions en fonction de capteurs et de programmes.

Posté par Gyro49 on janv. 28 2017 03:09
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.