Balancingbot

De troyesGEII
Révision datée du 10 janvier 2017 à 12:25 par Balancing (discussion | contributions) (Création du compte rendu Villette - Vin)
Aller à : navigation, rechercher

Projet 2016/2017 : Villette - Vin

Tentative d'équilibre dans deuxième roue

L298N Shield
L298P Shield V1.2

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 :

  1. La carte de puissance ne commandait qu'un seul moteur
  1. 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.

Reprogrammation des deux cartes

Problème : Durant les tests du programme, une erreur de branchement 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.