![]() |
Le site de Quentin |
|
|
Voici un petit robot original, vous pouvez le piloter avec votre clavier d'ordinateur, et encore mieux! Vous n'avez meme pas besoins de le voir pour le piloter car grace a son radar rotatif, vous voyez directement sur l'ecran de votre ordinateur les obstacles.
Materiel requis:
1x Arduino UNOCablage pour le robot:
Cablage pour la telecommande:
Programme pour le robot:
Pour pouvoir compiler le programme, vous devez installer la bibliothèque Mirf pour la liaison radio: Dispo ici sur github
//Quentin Lacombe //http://quentin-fr.ddns.net //Programme pour robot Roulant //on inclue les bibliotheques #include <Servo.h> #include <SPI.h> #include <Mirf.h> #include <nRF24L01.h> #include <MirfHardwareSpiDriver.h> //on definis le nom des entrées du pont en H(moteur) #define IN1 4 #define IN2 A1 #define IN3 2 #define IN4 8 //creation d'une structure pour envoyer les infos du radar typedef struct{ int angle = 10; //angle du servomoteur int dist = 8;//distance mesurée par le capteur infrarouge }Cmd; //creation d'une autre structure pour recevoir les ordres(avance,recule,tourne...) typedef struct{ int statut;//variable contenant l'ordre. }Ordre; //déclaration de l'objet myservo Servo myservo; //definition des variables globales int sens = 1;//sens de rotation du servomoteur(1=sens Aig.montre;2=l'inverse) int angle;//contient la position du servomoteur void setup() { //declaration des ports à utiliser pinMode(A0,INPUT); pinMode(7,OUTPUT); pinMode(2,OUTPUT); pinMode(4,OUTPUT); pinMode(5,OUTPUT); pinMode(6,OUTPUT); pinMode(8,OUTPUT); pinMode(A1,OUTPUT); //on definis la vitesse des moteurs analogWrite(5,175); analogWrite(6,175); //on initialise le servomoteur myservo.attach(3); myservo.write(90); //initialisation de la communication radio //initialisation de la communication avec l'arduino Mirf.cePin = 9; Mirf.csnPin = 10; Mirf.spi = &MirfHardwareSpi; Mirf.init(); //definition de cannal utilisé ainsi que la taille max d'un msg Mirf.channel = 1; Mirf.payload = sizeof(Cmd); Mirf.config(); Mirf.setTADDR((byte *) "nrf01"); Mirf.setRADDR((byte *) "nrf02"); //on initialise la liaison série Serial.begin(9600); } void loop() { //on déclare l'objet ordre Ordre ordre; //on attend la reception d'un message while(!Mirf.dataReady()); Mirf.getData((byte *) &ordre); //on test quel ordre a ete envoyé if(ordre.statut == 1)Stop(); if(ordre.statut == 2)Avance(); if(ordre.statut == 3)Recule(); if(ordre.statut == 4)TourneD(); if(ordre.statut == 5)TourneG(); delay(10); //definition de l'objet msg Cmd msg; //on prépare le message à envoyer //on récupère l'angle du servomoteur msg.angle = myservo.read(); //on mesure la distance if(map(analogRead(A0),0,1023,1023,0) > 800){ msg.dist = 1023; } else{ msg.dist = map(analogRead(A0),0,1023,1023,0); } //on envoie le message Mirf.send((byte *)&msg); //on attend la fin de l'envoie while(Mirf.isSending())Serial.println("..."); Serial.println("sent"); delay(10); //on fait tourner le radar d'un degré. myservo.write(angle); if(sens == 1)angle += 3; if(sens == 2)angle -= 3; if(angle > 179)sens = 2; if(angle < 1)sens = 1; } //fonctions pour le déplacement du robot void Stop(){ digitalWrite(IN1,0); digitalWrite(IN2,0); digitalWrite(IN3,0); digitalWrite(IN4,0); digitalWrite(7,0); } void Avance(){ digitalWrite(IN1,1); digitalWrite(IN2,0); digitalWrite(IN3,1); digitalWrite(IN4,0); } void Recule(){ digitalWrite(IN1,0); digitalWrite(IN2,1); digitalWrite(IN3,0); digitalWrite(IN4,1); } void TourneG(){ digitalWrite(IN1,1); digitalWrite(IN2,0); digitalWrite(IN3,0); digitalWrite(IN4,1); } void TourneD(){ digitalWrite(IN1,0); digitalWrite(IN2,1); digitalWrite(IN3,1); digitalWrite(IN4,0); } |
//Quentin Lacombe //http://quentin-fr.ddns.net //Programme pour robot Roulant(télécommande) //on inclue les bibliotheques #include <SPI.h> #include <Mirf.h> #include <nRF24L01.h> #include <MirfHardwareSpiDriver.h> //creation d'une structure pour recevoir les infos du radar typedef struct{ int angle = 0;//angle du servomoteur int dist = 0;//distance mesurée par le capteur infrarouge }Cmd; //creation d'une structure pour stocker le message. typedef struct{ int statut; //variable contenant l'ordre. (avancer,reculer...) }Ordre; //on déclare l'objet msg Cmd msg; void setup() { //on initialise la communication série(/!\TRES IMPORTANT POUR COMMUNIQUER AVEC L'ORDINATEUR/!\ Serial.begin(9600); //initialisation de la communication radio //initialisation de la communication avec l'arduino Mirf.cePin = 9; Mirf.csnPin = 10; Mirf.spi = &MirfHardwareSpi; Mirf.init(); //definition de cannal utilisé ainsi que la taille max d'un msg Mirf.channel = 1; Mirf.payload = sizeof(Cmd); Mirf.config(); Mirf.setTADDR((byte *) "nrf02"); Mirf.setRADDR((byte *) "nrf01"); Serial.println("0,0,"); } void loop() { //declaration de l'objet ordre Ordre ordre; delay(10); //si on recoit des infos depuis la connexion série if(Serial.available()){ //on met le caractere dans la variable c char c = Serial.read(); //on test le caractère pour envoyer l'ordre en conséquent if(c == 'S')ordre.statut = 1; if(c == 'A')ordre.statut = 3; if(c == 'R')ordre.statut = 2; if(c == 'D')ordre.statut = 4; if(c == 'G')ordre.statut = 5; } //on envoie au robot Mirf.send((byte *)&ordre); while(Mirf.isSending());//on attend la fin de l'envoie delay(10); //on attend les infos du radar if(Mirf.dataReady()){ Mirf.getData((byte *) &msg); if(msg.angle < 200 && msg.dist < 1030){ //on envoie à l'ordinateur Serial.print(msg.angle); Serial.print(','); Serial.print(msg.dist); Serial.println(','); } } delay(10); } |
Programme processing pour l'ordinateur:
//Quentin Lacombe //http://quentin-fr.ddns.net //Programme pour afficher le radar d'un robot arduino //on importe la bibliotheque. import processing.serial.*; //on crée un tab pour enreg les distances. int[] dist = new int[300]; //on déclare l'objet mySerial Serial mySerial; int press = 0; void setup(){ size(700,350); smooth(); //initialisation de la communication série mySerial = new Serial(this,Serial.list()[0],9600); mySerial.bufferUntil('\n'); //on efface l'écran background(0); for(int i = 0;i<180;i++){ dist[i] = 350; } delay(1000); mySerial.bufferUntil('\n'); mySerial.readStringUntil('\n'); } void draw(){ //on attend les infos if(mySerial.available() > 0){ String val = ""; val = mySerial.readStringUntil('\n'); textSize(20); if(val != null){ char c = ' '; String val1 = ""; String val2 = ""; int compt = 0; while(c != ',' && compt < val.length()){ c = val.charAt(compt); if(c != ',')val1 = val1 + c; compt++; } c = ' '; while(c != ',' && compt < val.length()){ c = val.charAt(compt); if(c != ',')val2 = val2 + c; compt++; } int angle = int(val1); int distance = int(map(int(val2),0,1023,10,350)); drawGraph(angle,distance); } } bouton(); if(keyPressed == false)press = 0; } //fonctions pour afficher les traits void drawGraph(int angle,int distance){ distance = int(distance); dist[angle] = distance; angle = int(map(angle,180,0,180,360)); background(0,0,255); stroke(0); ellipse(350,350,700,700); stroke(150); ellipse(350,350,600,600); ellipse(350,350,600,600); ellipse(350,350,500,500); ellipse(350,350,400,400); ellipse(350,350,300,300); ellipse(350,350,200,200); ellipse(350,350,100,100); float angleRad = PI * angle / 180; float x = 350 + 350*cos(angleRad); float y = 350 + 350*sin(angleRad); stroke(0); line(350,350,x,y); for(int i = 0; i < 180;i++){ float x2 = 350 + 350*cos(PI * map(i,180,0,180,360) / 180); float y2 = 350 + 350*sin(PI * map(i,0,180,180,360) / 180); float x1 = 350 + dist[i]*cos(PI * map(i,180,0,180,360) / 180); float y1 = 350 + dist[i]*sin(PI * map(i,180,0,180,360) / 180); stroke(255,0,0); line(x1,y1,x2,y2); } } //fonctions pour envoyer les ordres void bouton(){ if(keyPressed == true && press == 0){ press = 1; if(keyCode == UP){ mySerial.write('A'); } if(keyCode == DOWN){ mySerial.write('R'); } if(keyCode == RIGHT){ mySerial.write('D'); } if(keyCode == LEFT){ mySerial.write('G'); } if(key == ' '){ mySerial.write('S'); } if(key == 'l'){ mySerial.write('L'); } delay(100); } } |
Pt'it Forum!
Quentin Lacombe