Problème programme suiveur solaire

Bonjour,
Je fais un projet où j'ai besoin d'un suivi solaire, que je manœuvre avec deux servomoteurs programmés via Arduino (je me suis inspiré de ce projet : https://ouiaremakers.com/posts/tutor...racker-solaire). J'utilise également 4 ldr (résistance qui varie avec la lumière pour les novices ). Jusque là tout va bien. Le hic c'est que quand je le teste IRL (malheureusement pour l'instant sans le support final), il n'y a qu'un seul servo qui réagit (alors que je les commande pareillement) et il vibre essentiellement (or je souhaite avoir une stabilité optimale). On dirait qu'il ne bouge pas en fonction de la lumière que je fais varier.
Comment est-ce que je pourrais l'améliorer afin qu'il fonctionne ?

#include <Servo.h>

Servo SERVO1; // servo moteur horizontal
Servo SERVO2; //servo moteur vertical

int Servo1=90;  // Variable de position du servo1, de 0 à 179°
int Servo2=90;  // Variable de position du servo2, de 0 à 179°

int  ldr1=0;
int  ldr2=0;
int  ldr3=0;
int  ldr4=0;

int ecart = 0000011110; // écart permis entre les photoresistances sans qu'il y ai d'ajustement des servo (ne pas hesiter a jouer avec cette valeur selon la source lumineuse)

// Photorésistances sur A0, A1, A2 et A3
#define LDR1 A0 //haut-droite
#define LDR2 A1 //bas-droite
#define LDR3 A2 //bas-gauche
#define LDR4 A3 //haut-gauche 
bool mouvement = false; //condition pour mouvement des servo, cela permet d'avoir un mouvement continu
//tant que nous ne somme pas a l'equilibre +/- ecart et d'avoir une tempo lorsque nous avons l'équilibre
//(les servos cherchent moins souvent)

void setup()
{
  Serial.begin(9600);  // Moniteur série
  SERVO1.attach(11);   // Servo1 sur la broche 11
  SERVO2.attach(8);    // Servo2 sur la broche 8
  
  // Servos en position initiale
  SERVO1.write(Servo1);
  delay (1000);
  SERVO2.write(Servo2);
  delay (1000);
}


void loop()
{
  mouvement=false;

  // On lit les photoresistances
  ldr1 = analogRead(LDR1);
  ldr2 = analogRead(LDR2);
  ldr3 = analogRead(LDR3);
  ldr4 = analogRead(LDR4);  

//N.B.: plus une ldr est exposée à la lumière, plus sa résistance diminue
if ((ldr1<ldr2+ecart) && (ldr1<ldr4+ecart)) //il y a plus de soleil sur la ldr1 que sur la ldr2 et ldr4
    {
      if (Servo1<179)
      {
        Servo1++;
        SERVO1.write(Servo1);
        mouvement=true;
      }
      if (Servo2<179)
      {
        Servo2++;
        SERVO2.write(Servo2);
        mouvement=true;
      }
    }
  if ((ldr2<ldr1+ecart) && (ldr2<ldr3+ecart)) //il y a plus de soleil sur la ldr2 que sur la ldr1 et ldr3
    {
      if (Servo1<179)
      {
        Servo1++;
        SERVO1.write(Servo1);
        mouvement=true;
      }
      if (Servo2>0)
      {
        Servo2--;
        SERVO2.write(Servo2);
        mouvement=true;
      }
    }  
  if ((ldr3<ldr2+ecart) && (ldr3<ldr4+ecart)) //il y a plus de soleil sur la ldr3 que sur la ldr2 et ldr4
    {
      if (Servo1>0)
      {
        Servo1--;
        SERVO1.write(Servo1);
        mouvement=true;
      }
      if (Servo2>0)
      {
        Servo2--;
        SERVO2.write(Servo2);
        mouvement=true;
      }
    }
  if ((ldr4<ldr1+ecart) && (ldr4<ldr3+ecart)) //il y a plus de soleil sur la ldr4 que sur la ldr1 et ldr3
    {
      if (Servo1>0)
      {
        Servo1--;
        SERVO1.write(Servo1);
        mouvement=true;
      }
      if (Servo2<179)
      {
        Servo2++;
        SERVO2.write(Servo2);
        mouvement=true;
      }
    }
  if (mouvement == false)
  {
    delay(1000); //si on suit le soleil on peut mettre un long delay, sinon pour plus de reactivité, un faible delay
  }
}

Le circuit :


NB : Les ldr sont séparées par des cloisons opaques
Merci beaucoup du temps que vous m'avez déja accordé et peut être au temps que vous m'accorderez !

Bonjour,

Si le programme n'est pas en cause, il est fort possible que le problème soit lié à une mauvaise connexion (vérifier de nouveau le câblage), ou à une alimentation trop faible en courant pour piloter les servos.

Je vois que le projet d'origine n'utilise que 3 LDR. Il serait bon de tester dans cette configuration pour valider le matériel ;).

Pourriez vous m'éclairer sur la valeur de votre écart (sachant que votre CAN a pour maximum 1023, en sortie d'analogRead())
Et sur sa base? Parce que ça ressemble furieusement à de l'octal
Pour voir, j'ai essayé de l'afficher sur mon PC en décimal

sh-4.1$ cat  t.cpp &&  g++ t.cpp && ./a.exe
#include <stdint.h>
#include <stdio.h>
int16_t ecart = 0000011110;



int main() {
printf("%d\n", ecart);
}
4680

(pour votre info, j'ai veillé à ce que les entiers soient les mêmes que pour l'arduino (des int16_t)
En passant, je vous conseille de déclarer ecart constante (peut eviter des horreurs)
const int16_t ecart = 0000011110; marche aussi bien (ou mal) sur PC et sur arduino

La base 8 est confirmée par python

sh-4.1$ python
print Python 2.7.3 (default, Dec 18 2012, 13:50:09) 
[GCC 4.5.3] on cygwin
Type "help", "copyright", "credits" or "license" for more information.
>>> print 0000011110
4680
>>>

Bonjour G4NYM3D3

int ecart = 0000011110; // écart permis entre les photoresistances sans qu'il y ai d'ajustement des servo (ne pas hesiter a jouer avec cette valeur selon la source lumineuse)

Cela fait un gros écart ! Faites un print de ecart.

Cordialement,
bidouilleelec

Cela fait un gros écart ! Faites un print de ecart.
C'est fait, en python et en c++ (qui est assez portable): te c'est environ 4 fois la valeur maximale sortie par analogRead.....

Bonjour,
J'avais mis un écart de 30 pour tester mais mon prof m'a dit qu'il fallait le mettre en binaire. Je vais tester vos conseils et je vous tiens au courant ! :slight_smile: Sinon je suis un peu novice en programmation donc qu'entendez vous par "faites un print" ? ^^'
PS : Veuillez m'excuser du temps de réponse mais je pensais recevoir un e-mail de notification donc j'attendais un peu dans le vide... --'

...mais mon prof m'a dit qu'il fallait le mettre en binaire

Bon à savoir, il s'agit d'un travail scolaire........il était temps d'en informer le forum....

"Sinon je suis un peu novice en programmation donc qu'entendez vous par "faites un print" ? ^^'"

Arduino n'a pas de debugger, permettant de suivre finement l'état d'un programme en cours de développement (et les débuggueurs sont difficiles à prendre en main). Par contre, Serial.print est fourni avec l'arduino, ainsi qu'une console série. L'habitude est donc (c'est pareil sur PC, RPi) d'imprimer beaucoup de variables , et d'essayer de tracer celle qui induit un comportement aberrant.

...mais mon prof m'a dit qu'il fallait le mettre en binaire

LE problème, pour mettre en binaire, c'est qu'il n'y a pas de fonction de conversion permettant d'affecter une variable
on peut écrire
a = 123; // base 10
ou
a=0123; // base 8, avec un zero devant
ou
a = 0x123; // base 16.,
mais pas
a=0b0001111; // cette dernière expression est valide en python -31-, mais pas en c(++)

En pratique, on arrive souvent à faire les conversions hexa vers binaire ... de tête (l'octal -base 8 - est plus rarement employé sauf ... chez les gestionnaires de permissions de disque -quii touchent peu au domaine arduino....)

Bonjour,

dbrion06:
, mais pas
a=0b0001111; // cette dernière expression est valide en python -31-, mais pas en c(++)

C'est valide dans les dernières spécifications de C++ en particulier C++11 qui semble être la version implantée dans le compilateur de l'ide arduino (au moins depuis 1.8)

Merci pour la bonne nouvelle (et ça marche sur mon PC, après des années de frustration , pour gcc >= 4.8.0 et g++ >=4.8.0 ... au moins)

al1fch:
Bon à savoir, il s'agit d'un travail scolaire........il était temps d'en informer le forum....

Excusez moi de ne pas vous l'avoir informer mais il ne me semble pas que cela soit essentiel à la résolution du problème. De plus je suis vraiment investi dans le projet donc c'est plus qu'un projet scolaire. ^^

Donc il faudrait que je mette quoi comme valeur dans la variable si je veux un écart de 30 par exemple ? ^^

30 en décimal == 0x1E == 0b0001110
verifié avec python

$ python
Python 2.7.13 (default, Mar 13 2017, 20:56:15)
[GCC 5.4.0] on cygwin
Type "help", "copyright", "credits" or "license" for more information.
>>> 0b0001110
14
>>> 0x1E
30
>>> quit()

Mais peut être que affecter une valeur à une variable dans un programme source , destiné à être relu, se simplifie en utilisant la base 10.... (surtout s'il s'agit de faire des calculs classiques, non d'explorer des (plages de) bits)

Merci beaucoup je ne vais pouvoir essayer tout ça que mardi en espérant que cela fonctionne. Je vous tient au courant bien sûr ^^

1E en hexa c'est 00011110 en binaire

  • 1 = 0001
  • E = 1110
    Mais pourquoi le prof a-t-il demandé de coder cette valeur en binaire ? Elle est utilisée pour des tests comme
    if ((ldr1<ldr2+ecart) && (ldr1<ldr4+ecart))donc ça marche aussi bien en décimal. Le besoin du binaire existe uniquement si on doit faire de l'arithmétique bit par bit.

Si je me souviens bien, c'était parce que les sorties analogiques recevaient de l'analogique mais que la carte ne comprenait que le binaire. Je trouvais ça étrange mais comme il a un peu plus d'expérience que moi je l'ai écouté ^^'.
Sinon j'ai testé le programme avec les modifications que vous m'avez conseillées mais il n'y a toujours qu'un moteur qui réagit (même quand j'intervertis les moteurs et leurs câbles, seul celui commandé par la broche 11 réagit). J'ai également essayé de changer les broches mais rien à faire. Je pense que cela vient du programme mais je ne vois vraiment pas. Cela doit être dû une petite erreur bête... Avez-vous remarqué des incohérences dans le programme ?

Pouvez vous, indépendamment des LDR, agiter comme vous voulez vos servo moteurs?
Pouvez vous sortir sur la ligne serie les valeurs données par vos lectures des LDR? (avec et sans éclairement?)

hello
je suppose que tu travailles avec une UNO
la patte 8 n'est pas PWM. refais un test avec les pattes 11 et 9

Bonjour, j'ai une question !
pourquoi ta utiliser 3 LDR et pas une seul