Bonjour à tous, après de nombreuses recherches je bloque toujours sur des servomoteurs que j’utilise pour un projet de suiveur solaire.
Mon projet est le suivant:
-
Un panneau photovoltaïque (6V 160mA) est fixé sur un bras qui possède 2 articulations et 2 servomoteurs permettent des rotations autour de ces articulations. 4 photorésistances sont disposées aux coins du panneau photovoltaïque et je récupère les valeurs des photorésistances, je calcule des moyennes et je fais bouger le PV en conséquence, de manière à suivre la lumière.
-
Le PV est câblé à l’Arduino de manière à lui envoyer la tension, le courant et la puissance produite (que je calcule) pour ensuite être affichés sur un écran LCD.
-
J’ai prévu 2 modes : un mode automatique, qui utilise les 4 capteurs pour suivre automatiquement la lumière et un mode manuel, qui permet de faire bouger le panneau à l’aide d’un joystick.
Mon projet fonctionne globalement assez bien mais j’ai encore 2 soucis à régler pour le finaliser:
1°) Je n’arrive pas à définir de limites pour mes servomoteurs !
Le servomoteur du haut ne doit pas effectuer de rotation de 0° à 180° car vu mon câblage, ça risque d’abîmer le montage (de 0° à 75° serait suffisant).
J’ai essayé de définir des limites (cfr code : servoLimitHigh et servoLimitLow) mais ça ne bloque pas mon servo … j’ai également essayé via la commande monservo.attach(pin, min, max) mais encore une fois, le servo n’a aucune limitation. Auriez-vous une idée de la source de ce problème ?
2°) Pour passer du mode automatique au mode manuel, j’ai prévu une condition en utilisant le bouton poussoir du joystick du genre :
if ( BP == HIGH )
{
routine du mode automatique
}
else
{
routine du mode manuel
}
Cfr code pour plus de compréhension. Mon soucis est que même lorsque j’appuie sur le joystick, rien ne se passe et ma boucle reste continuellement en mode automatique, je suis obligé de modifier la condition de test pour pouvoir rentrer dans le ‘else’ et tester le mode manuel.
Je me doute bien que le BP du joystick fonctionne comme un interrupteur qui s’ouvre ou se ferme en fonction de l’appui dessus, donc je comprends à ce niveau que mon code ne fonctionne pas, auriez-vous une solution à me suggérer ?
Voici des photos du montage et mon code :
#include <Servo.h>
#include <LiquidCrystal.h>
// Création de l'objet écran LCD
LiquidCrystal monEcran(12,11,5,4,3,2);
// Assignation des broches de la led RGB sur les entrées de l'Arduino
int redPin= 13;
int greenPin = 8;
int bluePin = 7;
void setColor(int redValue, int greenValue, int blueValue)
{
analogWrite(redPin, redValue);
analogWrite(greenPin, greenValue);
analogWrite(bluePin, blueValue);
}
// Définition des servomoteurs
Servo servohori;
int servoh = 90;
int servohLimitHigh = 160;
int servohLimitLow = 20;
Servo servoverti;
int servov = 0;
int servovLimitHigh = 70;
int servovLimitLow = 0;
// Assignation des photorésistances sur les entrées de l'Arduino
int ldrtopl = 2; //top left LDR green
int ldrtopr = 1; //top right LDR yellow
int ldrbotl = 3; // bottom left LDR blue
int ldrbotr = 0; // bottom right LDR orange
// Définition des variables du joystick
int VRx = A5;
int VRy = A4;
int SW = 13;
int xPosition = 0;
int yPosition = 0;
int SW_state = 0;
int mapX = 0;
int mapY = 0;
//int test = 0; // variable test pour forcer de rentrer dans le else ... à retirer par la suite
void setup ()
{
//on initialise la communication avec 16 colonnes et deux lignes pour le LCD
monEcran.begin(16,2);
// Valeurs de départ des servomoteurs
servohori.attach(10);
servohori.write(90);
servoverti.attach(9);
servoverti.write(0);
delay(500);
// Pins de l'Arduino en mode OUTPUT pour gérer les broches de la led RGB
pinMode(redPin, OUTPUT);
pinMode(greenPin, OUTPUT);
pinMode(bluePin, OUTPUT);
// Pins de l'Arduino en INPUT pour le joystick
pinMode(VRx, INPUT);
pinMode(VRy, INPUT);
pinMode(SW, INPUT_PULLUP);
}
void loop()
{
servoh = servohori.read();
servov = servoverti.read();
if(SW_state == HIGH) // Mode automatique
//if(test !=0)
{
monEcran.clear(); // on efface l'écran
monEcran.print("Mode auto: P= 0W");
monEcran.setCursor(0,1); //on passe à la ligne suivante
monEcran.print("U= 0V et I= 0mA");
setColor(0, 255, 0); // Led en couleur verte lors du mode automatique
//Récupération des valeurs analogiques de chaque capteur
int topl = analogRead(ldrtopl);
int topr = analogRead(ldrtopr);
int botl = analogRead(ldrbotl);
int botr = analogRead(ldrbotr);
// Calculs des moyennes
int avgtop = (topl + topr) / 2; //moyenne des photorésistances du haut
int avgbot = (botl + botr) / 2; //moyenne des photorésistances du bas
int avgleft = (topl + botl) / 2; //moyenne des photorésistances de gauche
int avgright = (topr + botr) / 2; //moyenne des photorésistances de droite
if (avgbot < avgtop)
{
servoverti.write(servov +1);
if (servov > servovLimitHigh)
{
servov = servovLimitHigh;
}
delay(10);
}
else if (avgtop < avgbot)
{
servoverti.write(servov -1);
if (servov < servovLimitLow)
{
servov = servovLimitLow;
}
delay(10);
}
else
{
servoverti.write(servov);
}
if (avgright > avgleft)
{
servohori.write(servoh +1);
if (servoh > servohLimitHigh)
{
servoh = servohLimitHigh;
}
delay(10);
}
else if (avgleft > avgright)
{
servohori.write(servoh -1);
if (servoh < servohLimitLow)
{
servoh = servohLimitLow;
}
delay(10);
}
else
{
servohori.write(servoh);
}
delay(10);
}
else // Mode manuel
{
monEcran.clear(); // on efface l'écran
monEcran.print("Mode manu: P= 0W");
monEcran.setCursor(0,1); //on passe à la ligne suivante
monEcran.print("U= 0V I= 0mA");
setColor(0, 255, 255); // Led RGB en mauve lors du mode manuel
xPosition = analogRead(VRx);
yPosition = analogRead(VRy);
SW_state = digitalRead(SW);
mapX = map(xPosition, 0, 1023, -512, 512);
mapY = map(yPosition, 0, 1023, -512, 512);
if (yPosition>550)
{
servoverti.write(servov -1);
}
if(yPosition<480)
{
servoverti.write(servov +1);
}
if (xPosition<480)
{
servohori.write(servoh +1);
}
if(xPosition>550)
{
servohori.write(servoh -1);
}
}
delay(25);
}