Balancingbot
Sommaire
Projet 2016/2017 : Villette - Vin
Tentative d'équilibre sans troisième roue
Dans cette partie, nous avons tenté de voir si l'équilibre du robot était envisageable sans l'emploi d'une troisième roue. Plusieurs problèmes se sont alors posés :
- La carte de puissance ne commandait qu'un seul moteur
- Le code dans la télécommande et le robot ne fonctionnaient pas
Correction de la carte de puissance
Afin de vérifier si la carte alimentait convenablement le deuxième moteur, nous avons utilisé un voltmètre. Lors de son utilisation, la carte a cessé d'alimenter le deuxième moteur, nous obligeant à changer la carte L298N Shield pour une L298P Shield V1.2. La nouvelle carte de puissance n'alimente pas les cartes Arduino connectées à celle-ci. Il est donc nécessaire de tirer un câble de la batterie jusqu'au Vin de l'Arduino.
Reprogrammation de la carte du robot
L'objectif ici est de programmer le robot de façon à vérifier si celui-ci est capable de tenir en équilibre ou non, et donc si l'ajout d'une troisième roue est nécessaire.
Problème : Durant les tests du programme, une erreur de branchement (12V de la batterie connecté au 5V de l'Arduino) a grillé un ATMEGA328P et l'accéléromètre.
Code Robot
#include "Wire.h"
#include "SPI.h"
#include "Mirf.h"
#include "nRF24L01.h"
#include "MirfHardwareSpiDriver.h"
#include "I2Cdev.h"
#include "MPU6050.h"
//Valeur limite de l'accéléromètre
#define MAX_READ_ABS 16384
//Valeur limite des PWM (commande moteur)
#define MAX_WRITE_ABS 255
//Offset de l'accéléromètre (valeur mesurée lorsque le robot est à l'horizontal)
#define OFFSET -2000
const double MAX_READ_NEG = (-MAX_READ_ABS+OFFSET/2.0); //Valeur maximale réelle négative (avec offset) =-17384
const double MAX_READ_POS = (MAX_READ_ABS+OFFSET/2.0); //Valeur maximale réelle positive (avec offset) =15384
MPU6050 accelgyro;
int16_t ax, ay, az;
int16_t gx, gy, gz;
long accelero;
void setup()
{
Wire.begin();
accelgyro.initialize();
for(unsigned char i = 2 ; i <= 5 ; i++)
{
pinMode(i, OUTPUT);
}
Serial.begin(9600);
}
long getAccelero(long n = 100)
{
long value = 0;
for(long i = 0 ; i < n ; i++)
{
accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);
value += ay;
}
return value/n;
}
void arreter()
{
digitalWrite(2, LOW);
digitalWrite(4, LOW);
}
void avancer(char n = 50)
{
if(n == 0)
{
arreter();
}
else
{
analogWrite(3,(unsigned char)(MAX_WRITE_ABS - MAX_WRITE_ABS*(100-n)/200.0));
analogWrite(5,(unsigned char)(MAX_WRITE_ABS - MAX_WRITE_ABS*(100-n)/200.0));
digitalWrite(2,HIGH);
digitalWrite(4,HIGH);
}
}
void reculer(char n = 50)
{
if(n == 0)
{
arreter();
}
else
{
analogWrite(3,(unsigned char)(MAX_WRITE_ABS*(100-n)/200.0));
analogWrite(5,(unsigned char)(MAX_WRITE_ABS*(100-n)/200.0));
digitalWrite(2,HIGH);
digitalWrite(4,HIGH);
}
}
void tourner(char n = 0)
{
}
void loop()
{
bool _stop = 0;
accelero = getAccelero(1);
Serial.println(accelero);
if(_stop)
{
if(accelero > 0.9*MAX_READ_POS || accelero < 0.9*MAX_READ_NEG)
{
arreter();
}
else
{
if(accelero < OFFSET)
{
reculer(accelero/(0.9*MAX_READ_NEG)*100);
}
else
{
avancer(accelero/(0.9*MAX_READ_POS)*100);
}
}
}
else
{
arreter();
}
}
Limites
- Les tests ont révélé une incompatibilité réactivité/pertinence. L'accéléromètre donnant souvent des valeurs incohérentes, il était nécessaire d'échantillonner ces valeurs. Plus l'échantillon est important et moins le robot était réactif. Mais moins l'échantillon est important, moins le robot se retrouve capable de réagir correctement (il accélère parfois dans le mauvais sens à cause d'une valeur d'accéléromètre erronée).
- Les moteurs ne réagissent pas assez rapidement à une commande, rendant l'équilibre quasi-impossible.
Ajout d'une troisième roue
L'équilibre étant infaisable, nous avons donc ajouté une troisième roue dite "folle". Le côté qui nous a posé le plus de problèmes ici est la programmation du robot. En effet, après avoir « finit » celle-ci, nous avons remarqué que le comportement du robot était aléatoire et instable. Après le test des moteurs, nous en avons conclus que la documentation sur la carte de puissance est erronée, rendant le programme réalisé faux. Les corrections suivantes sont apportées :
- Le sens des moteurs est donné par les pins M1 et M2 ;
- La vitesse des moteurs est commandée en PWM 8bits par les pins E1 et E2 ;
Cette deuxième modification de la documentation apporte un nouveau problème : les pins E1 et E2 sont physiquement reliées aux pattes 5 et 6 qui ne sont pas des PWM. Nous les avons donc reliées aux pattes 9 pour la 5 et 10 pour la 6. Le programme s'en retrouve très simplifié.
Fichier:Remote.zip Fichier:Robot.zip
Code du robot