Voici mon problème , je dois réaliser un programme permettant le contrôle d'un robot suiveur de ligne , pour apprendre comment fonctionne le module QTR 8A Pololu, j'ai installer sur l'IDE Arduino la librairie de celui-ci, et je me suis basé sur l'exemple donnée avec cette librairie pour faire tourner la roue droite lorsque les l'un des 3 capteur droit reçois un signal signalant une bande noir et de meme pour la roue gauche.
Cependant le servo gauche ne tourne que lorsque le capteur numéro 5 (sachant qu'il n'y a que les 6 capteur sur 8 de connectée) est actif et uniquement lorsque celui est actif, ou les 2 roue tourne lorsque tout les capteurs sont actif. Je n'arrive pas a comprendre d'où vient le problème sachant que les servo moteurs et le module Pololu sont correctement branché.
Voici le code :
#include <QTRSensors.h>
#include <Servo.h>
// This example is designed for use with six analog QTR sensors. These
// reflectance sensors should be connected to analog pins A0 to A5. The
// sensors' emitter control pin (CTRL or LEDON) can optionally be connected to
// digital pin 2, or you can leave it disconnected and remove the call to
// setEmitterPin().
//
// The main loop of the example reads the raw sensor values (uncalibrated). You
// can test this by taping a piece of 3/4" black electrical tape to a piece of
// white paper and sliding the sensor across it. It prints the sensor values to
// the serial monitor as numbers from 0 (maximum reflectance) to 1023 (minimum
// reflectance).
QTRSensors qtr;
const uint8_t SensorCount = 6;
uint16_t sensorValues[SensorCount];
Servo myservo;
Servo myservo1;
void setup()
{
// configure the sensors
qtr.setTypeAnalog();
qtr.setSensorPins((const uint8_t[]){A0, A1, A2, A3, A4, A5}, SensorCount);
qtr.setEmitterPin(2);
Serial.begin(9600);
}
void loop()
{
myservo.attach(5);
myservo1.attach(3);
// read raw sensor values
qtr.read(sensorValues);
// print the sensor values as numbers from 0 to 1023, where 0 means maximum
// reflectance and 1023 means minimum reflectance
for (uint8_t i = 0; i < SensorCount; i++)
{
Serial.print(sensorValues[i]);
Serial.print('\t');
if(sensorValues[i]<200){
if(i<3 && i>=0){
myservo1.write(0);
Serial.println(i);
}
else if(i>2 && i<6) {
myservo.write(0);
Serial.println(i);
}
else{
myservo.write(90);
myservo1.write(90);
}
}
else{
myservo.write(90);
myservo1.write(90);
}
}
Serial.println();
delay(250);
}
Ici mes servos sont calibrée a 90 pour signalée l'arrêt !
Voici aussi un lien pour une vidéo montrant le probléme :
Pour la valeur des capteurs j'ai utiliser 200 approximativement car lorsque le capteur est au dessus d'une surface clair il est environ a 1400, et lorsque je le met sur une ligne noir il m'affiche moins de 200, 200 n'est pas représentatif c'est seulement pour le test !
D'accord merci , en revanche mon module sur mon robot est connecter sur les pin analogique dans l'introduction du code il parle de pin digital je pense que c'est le calibrage pour le QTR 8RC, dois-je modifier le code ?
Le code en utilisant la calibration fonctionne parfaitement ! Merci
En revanche j'ai essayé certains asservissement PID pour mon robot, le problème étant que les codes présents sur internet ne sont pas compatible avec les servomoteurs, par exemple celui-ci :
J'ai essayé d'appliquer cette bibliothèque a mon montage en m'inspirant d'autre code ,
Voici mon code :
#include <QTRSensors.h>
#include <Servo.h>
#include <PID_v1.h>
double Setpoint ; // 2500
double Input; // QTR 8A
double Output ; //SERVO
//PID parameters
double Kp=10, Ki=0.1, Kd=5;
PID myPID(&Input, &Output, &Setpoint, Kp, Ki, Kd, DIRECT);
// This example is designed for use with six analog QTR sensors. These
// reflectance sensors should be connected to analog pins A0 to A5. The
// sensors' emitter control pin (CTRL or LEDON) can optionally be connected to
// digital pin 2, or you can leave it disconnected and remove the call to
// setEmitterPin().
//
// The setup phase of this example calibrates the sensors for ten seconds and
// turns on the Arduino's LED (usually on pin 13) while calibration is going
// on. During this phase, you should expose each reflectance sensor to the
// lightest and darkest readings they will encounter. For example, if you are
// making a line follower, you should slide the sensors across the line during
// the calibration phase so that each sensor can get a reading of how dark the
// line is and how light the ground is. Improper calibration will result in
// poor readings.
//
// The main loop of the example reads the calibrated sensor values and uses
// them to estimate the position of a line. You can test this by taping a piece
// of 3/4" black electrical tape to a piece of white paper and sliding the
// sensor across it. It prints the sensor values to the serial monitor as
// numbers from 0 (maximum reflectance) to 1000 (minimum reflectance) followed
// by the estimated location of the line as a number from 0 to 5000. 1000 means
// the line is directly under sensor 1, 2000 means directly under sensor 2,
// etc. 0 means the line is directly under sensor 0 or was last seen by sensor
// 0 before being lost. 5000 means the line is directly under sensor 5 or was
// last seen by sensor 5 before being lost.
QTRSensors qtr;
const uint8_t SensorCount = 6;
uint16_t sensorValues[SensorCount];
Servo myservoLeft;
Servo myservoRight;
int compteurButton = 0;
int tour = 1;
int myservoLeftspeed = 180;
int myservoRightspeed = 0;
void setup()
{
myservoLeft.attach(5);
myservoRight.attach(3);
pinMode(10, INPUT_PULLUP);
Setpoint = 2500;
//Turn the PID on
myPID.SetMode(AUTOMATIC);
//Adjust PID values
myPID.SetTunings(Kp, Ki, Kd);
myPID.SetSampleTime(1);
myPID.SetOutputLimits(0, 180);
}
void loop()
{
int test = digitalRead(10);
if(test == LOW){
compteurButton = compteurButton + 1;
delay(1000);
}
myservoLeft.write(90);
myservoRight.write(90);
if(compteurButton == 1 && tour == 1){
tour = tour + 1;
// configure the sensors
qtr.setTypeAnalog();
qtr.setSensorPins((const uint8_t[]){A0, A1, A2, A3, A4, A5}, SensorCount);
qtr.setEmitterPin(2);
delay(500);
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, HIGH); // turn on Arduino's LED to indicate we are in calibration mode
myservoLeft.write(92);
myservoRight.write(92);
// analogRead() takes about 0.1 ms on an AVR.
// 0.1 ms per sensor * 4 samples per sensor read (default) * 6 sensors
// * 10 reads per calibrate() call = ~24 ms per calibrate() call.
// Call calibrate() 400 times to make calibration take about 10 seconds.
for (uint16_t i = 0; i < 100; i++)
{
qtr.calibrate();
if(i>25){
myservoLeft.write(88);
myservoRight.write(88);
}
if(i>75){
myservoLeft.write(90);
myservoRight.write(90);
}
}
digitalWrite(LED_BUILTIN, LOW); // turn off Arduino's LED to indicate we are through with calibration
// print the calibration minimum values measured when emitters were on
Serial.begin(9600);
for (uint8_t i = 0; i < SensorCount; i++)
{
Serial.print(qtr.calibrationOn.minimum[i]);
Serial.print(' ');
}
Serial.println();
// print the calibration maximum values measured when emitters were on
for (uint8_t i = 0; i < SensorCount; i++)
{
Serial.print(qtr.calibrationOn.maximum[i]);
Serial.print(' ');
}
Serial.println();
Serial.println();
delay(1000);
}
// read calibrated sensor values and obtain a measure of the line position
// from 0 to 5000 (for a white line, use readLineWhite() instead)
// print the sensor values as numbers from 0 to 1000, where 0 means maximum
// reflectance and 1000 means minimum reflectance, followed by the line
// position
uint16_t position = qtr.readLineBlack(sensorValues);
if(compteurButton == 2){
Input = position;
double errorMotor = Output;
int servoLeftSpeed = myservoLeftspeed - errorMotor;
int servoRightSpeed = myservoRightspeed + errorMotor;
if(servoLeftSpeed < 90)servoLeftSpeed = 90;
if(servoRightSpeed > 90)servoRightSpeed = 90;
Serial.print("Input ");
Serial.println(Input);
Serial.print("Servo L ");
Serial.println(servoLeftSpeed);
Serial.print("Servo R ");
Serial.println(servoRightSpeed);
Serial.print("Error ");
Serial.println(errorMotor);
}
}
Cependant mon Output ne varie jamais elle reste constamment a 0, j'ai essayer de modifier les paramètres Kp Ki Kd mais rien ne change ..
En gros j'utilise un bouton poussoir pour contrôler mon robot .. lors du premier appuie, il fait la calibration, lors du second, il débute son suivie de ligne.
En effet j'ai oublier la ligne :myPID.Compute();:
Mon robot qui est un suiveur de ligne doit être le plus lisse possible d'ou la régulation PID, mon entrée est le module capteur QTR 8A et ma sortie les servomoteurs,
mon entrée équivaut a 2500 lorsque la ligne et au milieu du capteur donc c'est mon setPoint !
Bramsoo216:
En gros j'utilise un bouton poussoir pour contrôler mon robot .. lors du premier appuie, il fait la calibration, lors du second, il débute son suivie de ligne
OK - ce serait plus simple de garder cela dans le setup, non ?
Mon Output varie seulement de 0 a 180 sans intermédiaire
soit c'est que vous n'échantillonez pas suffisamment souvent pour que le PID comprenne l'effet de ses corrections, soit que vos constantes de PID font du "swing" (vous overshootez puis undershootez)
cherchez en ligne des explications sur comment tuner son PID (voici un exemple de doc mais il y en a plein)