pixy cmucam 5

Bonjour
J’ai acheté une arduino uno et une pixy cmucam 5:

http://www.robotshop.com/eu/fr/capteur-images-pixy-cmucam5.html

J’ai mis les librairies, la boucle qui affiche "hello world’ qui semble être le seul exemple trouvable sur internet, bref, je l’ai modifié pour en arriver là. La fonction moteur fonctionne, j’envoie l’ordre et les moteurs se mettent en route, mais mon souci n’est pas là. La boucle principale ne fait qu’appeler la fonction cmucam();

Je vous copie colle l’ensemble du code, pardonnez moi pour le côté très scolaire et certainement pas très bien écris. Je prends des bout ça et là et je les adaptes, n’étant vraiment pas connaisseur de C (et curieusement je ne retrouve pas mes marques par rapport au C de mplab que j’utilisais avant).

#include <Servo.h>
#include <SPI.h>
#include <Pixy.h>

//********************constantes ******************************************

const int AV = 1;
const int ARR = 2;
const int STOP = 3;
const int GAV = 4;
const int DAV = 5;
const int GARR = 6;
const int DARR = 7;
const int PG = 8;
const int PD = 9;
const int NEUTRE = 105; //offset postion neutre du servo += si offset positif, -= si offset negatif

//*Declarations

int stby = 2;
int pwma = 3;
int pwmb = 9; //Moteur B à gauche
int in1b = 8;
int in2b = 7;
int in1a = 5; //Moteur A à droite
int in2a = 4;
Servo camera; //Servomoteur de la caméra, pin 6
int pos = NEUTRE;

//**************paramétrage des entrées / sorties

Pixy pixy; //initialisation caméra
void setup()
{
Serial.begin(9600); //initialisation caméra
pixy.init();
pinMode(in1a, OUTPUT);
pinMode(in2a, OUTPUT);
pinMode(in1b, OUTPUT);
pinMode(in2b, OUTPUT);
pinMode(pwma, OUTPUT);
pinMode(pwmb, OUTPUT);
pinMode(stby, OUTPUT);
camera.attach(6); //Connexion de la patte PWM n°6
servomoteur(0);
}

//***********Sous fonctions moteurs

void moteurs(int demande)
{
delay(100); //Pause entre changements d’états
digitalWrite(stby, 0); //Pause entre changements d’états
switch(demande)
{
case AV: //Avance
digitalWrite(in1a, 0);
digitalWrite(in2a, 1);
digitalWrite(in1b, 0);
digitalWrite(in2b, 1);
analogWrite(pwma, 225); //Réglage vitesse moteur droit
analogWrite(pwmb, 255); //Réglage vitesse moteur gauche
digitalWrite(stby, 1);
break;

case ARR: //Recule
delay(1500);
digitalWrite(in1a, 1);
digitalWrite(in2a, 0);
digitalWrite(in1b, 1);
digitalWrite(in2b, 0);
analogWrite(pwma, 225); //Réglage vitesse moteur droit
analogWrite(pwmb, 255); //Réglage vitesse moteur gauche
digitalWrite(stby, 1);
break;

case STOP: //Stop
digitalWrite(in1a, 0);
digitalWrite(in2a, 0);
digitalWrite(in1b, 0);
digitalWrite(in2b, 0);
digitalWrite(stby, 0);
break;

case GAV: //Tourne à Droite, moteur gauche avance
digitalWrite(in1a, 0);
digitalWrite(in2a, 0);
digitalWrite(in1b, 0);
digitalWrite(in2b, 1);
analogWrite(pwma, 0);
analogWrite(pwmb, 190); //Réglage vitesse moteur gauche
digitalWrite(stby, 1);
break;

case DAV: //Tourne à Gauche, moteur droit avance
digitalWrite(in1a, 0);
digitalWrite(in2a, 1);
digitalWrite(in1b, 0);
digitalWrite(in2b, 0);
analogWrite(pwma, 190); //Réglage vitesse moteur droit
analogWrite(pwmb, 0);
digitalWrite(stby, 1);
break;

case GARR: //Tourne à Gauche, moteur gauche recule
digitalWrite(in1a, 0);
digitalWrite(in2a, 0);
digitalWrite(in1b, 1);
digitalWrite(in2b, 0);
analogWrite(pwma, 0);
analogWrite(pwmb, 190); //Réglage vitesse moteur gauche
digitalWrite(stby, 1);
break;

case DARR: //Tourne à Droite, moteur droit recule
digitalWrite(in1a, 1);
digitalWrite(in2a, 0);
digitalWrite(in1b, 0);
digitalWrite(in2b, 0);
analogWrite(pwma, 190); //Réglage vitesse moteur droit
analogWrite(pwmb, 0);
digitalWrite(stby, 1);
break;

case PG: //pivot gauche, moteur droit avance, gauche recule
digitalWrite(in1a, 0);
digitalWrite(in2a, 1);
digitalWrite(in1b, 1);
digitalWrite(in2b, 0);
analogWrite(pwma, 190); //Réglage vitesse moteur droit
analogWrite(pwmb, 190); //Réglage vitesse moteur gauche
digitalWrite(stby, 1);
break;

case PD: //pivot gauche, moteur gauche avance, droit recule
digitalWrite(in1a, 1);
digitalWrite(in2a, 0);
digitalWrite(in1b, 0);
digitalWrite(in2b, 1);
analogWrite(pwma, 190); //Réglage vitesse moteur droit
analogWrite(pwmb, 190); //Réglage vitesse moteur gauche
digitalWrite(stby, 1);
break;

}
}

//*******sous fonction servomoteur

void servomoteur(int destination)
{
destination += NEUTRE; //offset postion neutre du servo += si offset positif, -= si offset negatif
if (pos == destination)
{
camera.write(pos);
return;
}
if (pos <= destination)
{
for(; pos <= destination; pos += 1) // position -30, max à droite. position 30, max à gauche.
{
camera.write(pos); // Envoie l’ordre de position au servo
delay(30);
}
}
else
{
for(; pos >= destination ; pos -= 1)
{
camera.write(pos);
delay(30);
}
}
}

//*****sous fonction caméra

int cmucam()
{
static int i = 0;
static int j = 0;
uint16_t blocks;
blocks = pixy.getBlocks(); //capture block par la fonction pixy.getblock

if (blocks) //si blocks différent de 0 → détection
{
i++; //détection ++
if (i%30==0) //toute les 30 détections
{
moteurs(AV);
}
}

else
{
j++;
if (j%30000==0)
{
moteurs(STOP);
}
}
}

//****Boucle principale

void loop()
{
cmucam();
}

/////////////////////////////////////////////

A l’heure actuelle, la fonction moteur fonctionne, la fonction servomoteur fonctionne aussi, bien que dans l’exemple je ne m’en sers pas, et la caméra détecte bien. Mais le hic, c’est que le robot avance lorsqu’il trouve un objet, mais s’arrête, puis repart, s’arrête, repars… alors que l’objet est devant sa camera et que la détection est donc continu, il devrait rouler en permanance.
Lorsque je retire l’objet (une balle verte), le robot s’arrête.

La variable j semble être déterminante. la variable i est à 20 sur le programme que j’ai pris sur internet, moins que ça, l’arduino aurait du mal, de ce que j’ai lu.
Pour en revenir à j, une valeur plus faible engendre une détection plus tardive et des marche/arrêt plus nombreux avec l’objet devant la cam.
une variable j plus grande entraine une détection rapide mais lorsqu’il démarre, et que je lui retire l’objet, le robot mets du temps à s’arreter. l’alternance marche / arret est toujours présente, mais ça met plus de temps entre chaque état.

lorsque j’ai ecris mon programme, j’avais mis modulo 30 pour les 2, mais une oscillation trop rapide entre les 2 états, empeche les moteurs de démarrer. Bref, entre la théorie et la pratique il y a un genre de délai qui se cache quelque part, je n’arrive pas à le trouver.

Si vous avez dévellopper d’autre programmes pour la cmucam5 je suis très intéressé pour voir vos boucles de détection. L’idée est de trouvé un objet de couleur et lui foncer dessus. A terme il y aura donc le servomoteur qui fera pivoter la cam sur +45 et -45 ° pour détecter, puis les moteurs tourneront pour s’alligner et foncer sur l’objet. C’est pas bien compliqué, je suis assez déçu de mes maigre souvenir de C. J’espère que vous pourrez me trouver des axes d’améliorations, des points louche à éclaircir sur mon programme, ou tout autre chose que je ne vois pas.

En vous remerciant !