Besoin d'aide pour programmation d'un servomoteur

Bonsoir !
Voilà, je suis sur un projet en ce moment et mon programme consiste à faire tourner un Servomoteur en fonction d'un capteur de luminosité.
voici le programme:

#include <Servo.h>
Servo Servomoteur;

//constantes

const int capteur=0; //constante du capteur et numero de sa broche analogique

//variables
long valeur1 = 0 ;
long valeur2 = 0 ;
long valeur3 = 0 ;
long valeur4 = 0 ;

void setup () {
pinMode(capteur, OUTPUT); //Attacher la pin__ à l'objet Servo
Servomoteur.attach(9); //Angle à 90° on attache le servo a la pin 9
Servomoteur.write(0); //Remettre l'angle à 0°

}

void loop () {

int valeur1=analogRead(capteur) ;//Releve la valeur1
if (valeur1>30000)
{Servomoteur.detach();//arret
}

else if (valeur1<1000)
{Servomoteur.detach();//arret

}

else
{ Servomoteur.write(25);}//Moteur tourne sur un angle de 25°

int valeur2=analogRead(capteur) ;//Releve la valeur2
if (valeur2>30000)
{Servomoteur.detach();//fin
}

else
{ Servomoteur.write(45);}//Moteur tourne sur un angle de 45°

int valeur3=analogRead(capteur); //Releve la valeur3
if (valeur3>30000)
{Servomoteur.detach();//fin

}

else
{ Servomoteur.write(75);}//Moteur tourne sur un angle de 75°

int valeur4=analogRead(capteur); //Releve la valeur4
if (valeur4>30000)
{Servomoteur.detach();//Fin
}

else //moteur retourne à + grande valeur précedente je pense mettre ici une fonction return...

delay(3600000);//Attendre une heure

}

Deja, si vous voyez des erreurs ou quelque chose qui fait que le Servomoteur ne tournera pas comme prévu... j'écoute vos remarques :3
De plus, je ne sais pas comment faire revenir le Servomoteur à la meilleures des 4 valeurs préalablement lus par le capteur...
Et c'est là le coeur du projet... Alors je prends toutes idées !
(Si vous souhaitez plus de clarté vis à vis du projet, j'apporterai des précisions)
Merci beaucoup à ceux qui m'aideront certainement :slight_smile:

Le delay(36000000) est un peu bourrin pour attendre une heure (même si ça marche).
La méthode du blinkwithoutdelay est plus propre.

Attention, une fois que tu fais Servomoteur.detach, le servomoteur n'est plus attaché pour la commande de position suivante, il faut le rattacher.

Salut,

Il ne faut pas utiliser detach() en effet. De plus je vois pas pourquoi vous voulez attendre une heure. Ensuite un analogRead() c'est 10 bits, donc valeur max = 1024 donc if (valeur1>30000) n'arrivera jamais.

Enfin pourquoi ne pas simplement calculer l'angle à partir des 4 mesures ? Basiquement si je prend 2 capteur orientés dans deux directions différente de 45° et pleine lumière sur capteur 1 donne 0° sur le servo :

angle = 45 * analogRead(Capteur2) / (analogRead(Capteur1) + analogRead(Capteur2))

Il suffit d'étendre la logique à 4 capteurs, c'est des math

Parce que de ce que je comprend de votre problème il s'agit d'un tracker solaire. Que se passe-t-il si la lumière n'est pas suffisante ? Avec votre algo il ne se passera rien, avec le mien il s'orientera quand même :wink: mais il faudra prendre en compte la nuit aussi

Merci bien pour vos précisions, je vais modifier ces parties du programme alors...
Et justement, le but du programme et que, quand il n'y a plus de lumière, le moteur soit arrêté, de même quand il y en a trop.

Pas compliqué non plus :wink: il suffit simplement de faire la moyenne des 4 capteurs : si elle est dans les bornes (ni trop haute ni trop basse) alors le positionnement est effectué

Pourquoi utiliser 4 capteurs ?
C'est bien un tracker solaire que tu fais ?

Ca peut marcher avec 1 seul capteur orienté par le servomoteur, on mémorise l'éclairement pour chaque angle, et après un balayage de part et d'autre de la zone visée on retourne se caler directement sur l'éclairement maximum.

C'est exactement ça que je souhaiterai faire !
Mais je ne sais donc pas comment retourner avec le programme à la position de la valeur maximale prise par le capteur sur les 4 précédemment prélevées...

Il faudrait que je rajoute :
if (!Servomoteur.attached())Servomoteur.attach(9);

Avant chacun de mes "if", "if else", et "else" alors ?

La question serait plutôt pourquoi les détacher?

je n'ai pas trouvée d'autre moyen pour demander au servomoteur de s'arreter...

Normalement, un servomoteur se déplace jusqu'à la position demandée et s'arrête tant qu'il ne reçoit pas une nouvelle consigne.
Si ton servo tourne tout le temps c'est que tu as une erreur dans ton code.

Tu attache le servomoteur une seule fois, dans le setup.
Ensuite il suffit de lui indiquer l'angle à atteindre. Le principe d'un servo c'est qu'il y a dedans une boucle de rétroaction pour qu'il s'arrête tout seul à la bonne position. (un potentiomètre est lié à l'axe de rotation du moteur et son électronique interne sait sur quel angle il a tourné).

Donc par exemple pour qu'il s'arrête à 0°, j'ai juste à mettre servomoteur.write(0) ?

Oui

Ok, alors quelques autres questions...
Le servomoteur tourne jusqu'à l'angle demandé ou il tourne de x degrés demandé?
Exemple si je suis à 45 degrés et que j'écris servomoteur.write(25) le servomoteur va tourner jusqu'à 25 degrés ou de 25 degrés donc jusqu'à 70degrés?

Et est il possible avec arduino de retenir une position du moteur et lui demander d'y revenir plus tard?
Merci!

Voir ici: Servo - Arduino Reference

Writes a value to the servo, controlling the shaft accordingly. On a standard servo, this will set the angle of the shaft (in degrees), moving the shaft to that orientation. On a continuous rotation servo, this will set the speed of the servo (with 0 being full-speed in one direction, 180 being full speed in the other, and a value near 90 being no movement).

Donc dans le cas d'un servo classique, la valeur donnée correspond à l'angle en degrés.

Le servo va se positionner à l'ange demandé (entre 0 - 180°), en position absolue.
On peut bien sûr mémoriser dans une variable la position en mémoire.

J'ai l'impression que tu n'as pas de servo sous la main, c'est ça ?

D'accord merci :slight_smile:
Et effectivement, je n'ai pas encore de servomoteur sous la main... :~
J'ai fais le programme comme ça alors, si quelqu'un trouve quelque chose à modifier, je suis preneuse :3

#include <Servo.h>
Servo Servomoteur;

//Constantes

const int capteur=0; //Constante du capteur et numéro de sa broche analogique

//Variables
long valeur1 = 0 ;
long valeur2 = 0 ;
long valeur3 = 0 ;
long valeur4 = 0 ;
long valeurmax = 0 ;

//Fonction Setup

void setup (){
pinMode(capteur, OUTPUT); //Attacher la pin __ à l'objet Servomoteur
Servomoteur.attach(9); //Attacher le Servomoteur à la pin9, angle à 90°
Servomoteur.write(0); //Remettre l'angle à 0°

}

//Fonction loop

void loop () {
Servomoteur.write(0);

int valeur=analogRead(capteur); //Relever la valeur1 du capteur
if(valeur1>30000)
{Servomoteur.write(0);} //Le moteur reste à l'arret

else if(valeur1<1000)
{Servomoteur.write(0);} //Le moteur reste à l'arret

else
{valeurmax=valeur1; //La valeurmax prend la valeur1
Servomoteur.write(25);} //Le moteur tourne jusqu'à 25°

int valeur2=analogRead(capteur); //Relever la valeur2 du capteur
if(valeur2>30000)
{Servomoteur.write(25);} //Le moteur reste à l'arret

else if(valeur2>valeurmax)
{valeurmax=valeur2; //La valeurmax prend la valeur2
Servomoteur.write(45);} //Le moteur tourne jusqu'à 45°

else
{Servomoteur.write(45);} //La valeur max est toujours valeur1 le moteur tourne jusqu'à 45°

int valeur3=analogRead(capteur); //Relever la valeur3
if(valeur3>30000)
{Servomoteur.write(45);} //Le moteur reste à l'arret

else if(valeur3>valeurmax)
{valeurmax=valeur3;
Servomoteur.write(75);}

else
{Servomoteur.write(75);} //La valeurmax reste valeur1 ou valeur2, le moteur tourne jusqu'à 75°

int valeur4=analogRead(capteur); //Relever la valeur4
if(valeur4>30000)
{Servomoteur.write(75);} //Le moteur reste à l'arret

else if(valeur4>valeurmax)
{Servomoteur.write(75);} //La valeur4 esr la plus élevée, le moteur reste donc en place

else if(valeurmax=valeur3)
{Servomoteur.write(45);} //La valeur3 est la plus élevée, le moteur tourne jusqu'à la postion v3

else if(valeurmax=valeur2)
{Servomoteur.write(25);} //La valeur2 est la plus élevée, le moteur tourne jusqu'à la postion v2

else
{Servomoteur.write(0);} //La valeur1 est la plus élevée, le moteur retourne à sa position de départ

delay(3600000); //Attendre une heure

}

Je pense qu'il y aura un problème au niveau de mes "int valeur=analogRead(capteur)..."
Parce que je souhaiterai que la suite du programme ne se produise pas si la valeur est >30 000, enfin qu'il passe directement au delay, et redémarre... alors que selon mon programme, apparemment, les autres analogRead seraient quand même effectués, non?

Je crois qu'il faut que tu trouves un servomoteur et que tu essaies...

Ton prog est bourré d'erreurs :

  • doubles déclarations,
  • Tests if(x>30000) alors que x ne dépassera jamais 1023,
  • la condition if(x=y) sera toujours vérifiée...
  • tu ne verras pas le moteur tourner, il restera toujours à 25°.

Les "ordres" que tu envoies s'enchaînent tellement vite que seul le dernier avant delay sera réellement pris en compte.

Et pour commencer, mets un delay(1000), sinon tu risques de trouver le temps long...

Courage!

Super_Cinci:

  • la condition if(x=y) sera toujours vérifiée...

sauf si (y == 0) :stuck_out_tongue: