En raison de limitations techniques, la typographie souhaitable du titre, « Travail pratique : Equilibre sur deux roues d'un Robot Micro contrôleurs AVR/Travail pratique/Equilibre sur deux roues d'un Robot », n'a pu être restituée correctement ci-dessus.
Les sites commerciaux ont adoptés l'appellation Robot auto équilibré pour traduire les termes anglo-saxons instabots ou self balancing bot.
Nous allons étudier la mise en œuvre d'un MPU6050 (TP précédent) avec comme application la programmation d'un robot sur deux roues. Le robot que nous allons étudier est vendu en kit (sainsmart balancing robot kit).
Ce robot sera contrôlé par deux cartes Arduino UNO :
la première sera intégrée dans la manette de commande, manette dotée de deux joysticks analogiques, ainsi que d'un module de communication radio ;
la seconde carte sera dans le robot proprement dit (le robot possède son unité centrale, toute la commande de puissance des moteurs et bien sûr un module radio).
/* émission d’une valeur integer via module nRF24L01 */#include<SPI.h> // gestion du bus SPI #include<Mirf.h> // gestion de la communication #include<nRF24L01.h> // définition des registres du nRF24L01 #include<MirfHardwareSpiDriver.h> // communication SPI nRF24L01//Variables joystickintxPinG=A2;intyPinG=A3;intbuttonPinG=3;intxPinD=A0;intyPinD=A1;intbuttonPinD=2;intxPositionG=0;intyPositionG=0;intbuttonStateG=0;intxPositionD=0;intyPositionD=0;intbuttonStateD=0;////int valeur1 = 1; // contient la valeur à envoyer //int valeur2 = 0;byteyPositionG_octet[2];// contient la valeur découpée en octet pour l’envoibyteyPositionD_octet[2];// contient la valeur découpée en octet pour l’envoivoidsetup(){//Initialisation pin JoystickpinMode(xPinG,INPUT);pinMode(yPinG,INPUT);pinMode(xPinD,INPUT);pinMode(yPinD,INPUT);//activate pull-up resistor on the push-button pinpinMode(buttonPinG,INPUT_PULLUP);pinMode(buttonPinD,INPUT_PULLUP);Mirf.cePin=8;// CE sur broche 8 Mirf.csnPin=7;// CSN sur broche 7 Mirf.spi=&MirfHardwareSpi;// utilisation du port SPI hardware Mirf.init();// initialise le module SPI Mirf.channel=0;// utilisation canal 0 pour communiquer (128 canaux disponible, de 0 à 127) Mirf.payload=sizeof(unsignedint);// = 2, déclaration taille du message à transmettre, max 32 octets // RF_SETUP=0000abcd : a=1–>2Mb/s, a=0–>1Mb/s; puissance émission bc=00–>-18 dBm, bc=01–>-12dBm, bc=10–>-6dBm, bc=11–>0dBm; // d=0 pas de gain sur le bruit en réception Mirf.configRegister(RF_SETUP,0x06);// 1 Mb/s et 0 dBm (puissance maximum) Mirf.config();// configure le canal et la taille du message Mirf.setTADDR((byte*)"ardu2");// définition adresse sur 5 octets de la 2ème carte Arduino Mirf.setRADDR((byte*)"ardu1");// définition adresse sur 5 octets de la 1ere carte Arduino }voidloop(){intyPositionG=analogRead(yPinG);intyPositionD=analogRead(yPinD);while(Mirf.isSending()){// en cours d’émission delay(5);}yPositionG_octet[0]=yPositionG&0xFF;// 1er octet yPositionG_octet[1]=(yPositionG&0xFF00)>>8;// 2ème octet Mirf.send(yPositionG_octet);yPositionD_octet[0]=yPositionD&0xFF;// 1er octet yPositionD_octet[1]=(yPositionD&0xFF00)>>8;// 2ème octet Mirf.send(yPositionD_octet);// Serial.print(yPositionD);delay(10);}
/* réception d’une valeur integer via module nRF24L01*/#include<SPI.h> // gestion du bus SPI #include<Mirf.h> // gestion de la communication #include<nRF24L01.h> // définition des registres du nRF24L01 #include<MirfHardwareSpiDriver.h> // communication SPI nRF24L01intyPositionG;// contient la valeur à recevoirbyteyPositionG_octet[2];// contient la valeur découpée en octet pour la réceptionintyPositionD;// contient la valeur à recevoirbyteyPositionD_octet[2];// contient la valeur découpée en octet pour la réceptionintIN1=3;intIN2=4;intENA=9;intIN3=5;intIN4=6;intENB=10;voidsetup(){pinMode(13,OUTPUT);pinMode(IN1,OUTPUT);pinMode(IN2,OUTPUT);pinMode(IN3,OUTPUT);pinMode(IN4,OUTPUT);pinMode(ENA,OUTPUT);pinMode(ENB,OUTPUT);Mirf.cePin=8;// CE sur broche 8Mirf.csnPin=7;// CSN sur broche 7Mirf.spi=&MirfHardwareSpi;// utilisation du port SPI hardwareMirf.init();// initialise le module SPIMirf.channel=0;// utilisation canal 0 pour communiquer (128 canaux disponible, de 0 à 127)Mirf.payload=sizeof(unsignedint);// = 2, déclaration taille du message à transmettre, max 32 octets// RF_SETUP=0000abcd : a=1–>2Mb/s, a=0–>1Mb/s; puissance émission bc=00–>-18 dBm, bc=01–>-12dBm, bc=10–>-6dBm, bc=11–>0dBm;// d=0 pas de gain sur le bruit en réceptionMirf.configRegister(RF_SETUP,0x06);// 1 Mb/s et 0 dBm (puissance maximum)Mirf.config();// configure le canal et la taille du messageMirf.setTADDR((byte*)"ardu1");// définition adresse sur 5 octets de la 2ème carte ArduinoMirf.setRADDR((byte*)"ardu2");// définition adresse sur 5 octets de la 1ere carte ArduinoSerial.begin(9600);pinMode(6,OUTPUT);}voidloop(){while(!Mirf.dataReady()){// pas prêt à recevoirdelay(5);}Mirf.getData(yPositionG_octet);// récupére 2 octetsyPositionG=yPositionG_octet[0]+(yPositionG_octet[1]<<8);// transforme en int/* Serial.println(yPositionG, DEC); Serial.print(" "); // Serial.print(valeur_octet[0]); Serial.print(" "); // Serial.print(valeur_octet[1]); // digitalWrite(6, 1);*/intA=(yPositionG-513)/2;intB=(510-yPositionG)/2;if(yPositionG>530){analogWrite(ENA,A);digitalWrite(IN1,0);digitalWrite(IN2,1);}elseanalogWrite(ENA,0);if(yPositionG<500){analogWrite(ENA,B);digitalWrite(IN1,1);digitalWrite(IN2,0);}while(!Mirf.dataReady()){// pas prêt à recevoirdelay(5);}Mirf.getData(yPositionD_octet);// récupére 2 octetsyPositionD=yPositionD_octet[0]+(yPositionD_octet[1]<<8);// transforme en intintC=(yPositionD-515)/2;intD=(510-yPositionD)/2;if(yPositionD>530){analogWrite(ENB,C);digitalWrite(IN3,0);digitalWrite(IN4,1);}elseanalogWrite(ENB,0);if(yPositionD<510){analogWrite(ENB,D);digitalWrite(IN3,1);digitalWrite(IN4,0);}delay(10);}