Messages récents

Pages: [1] 2 3 ... 10
1
Vos projets / Re : AUTOMATISATION D’UN PONT FLEISCHMANN 6152 (HO) AVEC UN ESP32
« Dernier message par bobyAndCo le septembre 22, 2020, 01:16:23 pm »
Bonjours à tous,

Ca y est je viens de publier l'article qui décrit la réalisation: https://www.locoduino.org/spip.php?article257
2
Débuter / Re : analogWrite qui ne fonctionne pas toujours correctement avec des LEDs
« Dernier message par chris_bzg le septembre 22, 2020, 09:30:31 am »
Si, vous auriez fini par trouver de vous-même !  ;)

Il y a deux choses à retenir : d'abord, écrire le programme en suivant les normes de présentation et en commentant de façon précise. On le fait pour soi et aussi pour ceux qui doivent apporter de l'aide. Définir les entrées-sorties par des noms et non par des numéros permet de modifier aisément le montage si celui-ci doit évoluer.

Deuxièmement, quand un programme fonctionne seul mais ne fonctionne plus quand on lui rajoute du code, c'est que le dysfonctionnement vient du code rajouté et c'est donc là qu'il faut chercher. Les PWM sont générées par les timers du microcontrôleur (voir les articles que j'ai écrits sur les timers). Or, certaines bibliothèques utilisent aussi les timers donc il peut y avoir incompatibilité. C'est pourquoi il est nécessaire de toujours se référer à la documentation qu'on trouve sur le site d'Arduino et on peut la traduire si on n'est pas familier de la langue de Newton (restons dans la science !).

Quatre LED sur une sortie, c'est un peu beaucoup. Le mieux est de se limiter à 2, donc il faudra deux sorties si vous voulez avoir quatre feux clignotants. Ce sont les PN modernes qui ont 4 feux clignotants, visibles de toute part. Il y a quelques années, on ne trouvait que deux feux, un de chaque côté de la voie. Selon l'époque de votre réseau, à vous de voir... Mais vous pouvez aussi trouver une sortie PWM pour les deux LED quitte à réaffecter un servo ailleurs. Quant au shield, il faut l'élaborer quand le prototype est au point, pas avant. Mais celui-ci peut facilement se modifier en rajoutant un fil ou en coupant une piste.

Tenez-nous au courant de votre montage : photos ou vidéos bienvenues.
3
Débuter / Re : analogWrite qui ne fonctionne pas toujours correctement avec des LEDs
« Dernier message par Thierry le septembre 22, 2020, 09:23:42 am »
Content que ça marche, c'est bien.
C'est vrai que cela peut sembler fastidieux de coder tout de suite avec des define, plein de lignes, etc... Mais si j'ai retenu une chose de mon métier de programmeur, c'est que la probabilité qu'un programme fonctionne du premier coup est extrêmement faible, aussi simple soit-il ! Alors coder avec les bonnes pratiques rend le debugguage bien plus facile, même longtemps après. Et je ne parle même pas de partager son code avec d'autres, ce que nous pratiquons abondamment ici.
4
Débuter / Re : analogWrite qui ne fonctionne pas toujours correctement avec des LEDs
« Dernier message par hinano70 le septembre 21, 2020, 09:03:52 pm »
Merci Thierry, je n'ai pas trop l'habitude de travailler ainsi (flemme d'écrire du code), les commentaires sont tout à fait justes, au bout de quelques temps on ne sait plus trop ce qu'on voulait faire. J'ai bien sûr pris le code et je vais tâcher de suivre les conseils.
Super chris_bzg, ça fonctionne parfaitement (avec le code de Thierry), je n'aurais jamais trouvé ça ! On doit pouvoir mettre les 4 leds de 2mm + R=470ohm en parallèle sur la sortie 11. Sinon il faut que je réaffecte mes sorties, dommage, j'avais fait un "shield" pour monter le nano et brancher aisément les capteurs, moteurs ...
Encore merci à tous.
5
Débuter / Re : analogWrite qui ne fonctionne pas toujours correctement avec des LEDs
« Dernier message par chris_bzg le septembre 21, 2020, 06:55:20 pm »
Voici d'ailleurs ce qui est dit au sujet de la bibliothèque Servo sur le site arduino.cc (j'ai simplement fait traduire la page en français par mon navigateur) :
Pour voir l'image, il faut être connecté. Pour la lire, il faut l'agrandir en cliquant dessus.
6
Débuter / Re : analogWrite qui ne fonctionne pas toujours correctement avec des LEDs
« Dernier message par chris_bzg le septembre 21, 2020, 06:32:37 pm »
Sur votre schéma, il manque un câble rouge qui reprend l'alimentation 5 V de la ligne rouge d'alimentation du bas de la breadboard pour alimenter la ligne rouge d'alimentation du haut de la breadboard, mais ce câble doit exister sur votre montage puisque les servos fonctionnent (sur le schéma, ils ne sont pas alimentés en +5 V).

La bibliothèque Servo utilise le timer 1 ; justement celui qui délivre la PWM sur la broche 10. Il y a donc incompatibilité.
Branchez votre LED sur la broche 11 du Nano et dites moi si cela fonctionne mieux.
Si oui, il faudra brancher la première LED sur broche 11 et la deuxième LED sur une autre broche PWM sauf la 9 (timer 1 également).
C'est là que vous verrez l'importance de ne pas utiliser les numéros de broches dans un programme !  ;)

Enfin, et contrairement à ce que vous dites, je ne trouve pas que votre programme soit plus clair. Inspirez-vous du programme qu'a fait Thierry : celui-ci est clair et adoptez les bonnes pratiques dès maintenant. Bon, j'ai tout de même compris grâce à vous que "capteur sortie de PN" est bien une entrée. Mais pourquoi ne pas l'écrire en toute lettre puisque c'est en commentaire ? Croyez-moi, en perdant un peu de temps à décrire en détail un programme, on gagne énormément de temps pour sa mise au point (surtout si on reprend le programme un an plus tard pour l'améliorer : du genre "qu'est ce que j'ai bien voulu dire ?"  ???).
7
Débuter / Re : analogWrite qui ne fonctionne pas toujours correctement avec des LEDs
« Dernier message par Thierry le septembre 21, 2020, 06:14:03 pm »
Je me suis permis de rendre le code lisible pour le commun des mortels. C'est bien sûr une proposition, vous en faites ce que vous voulez.

#include <Servo.h>

/* PN double voie A et B
détection par capteur IR de l'arrivée : detect1 passe de 1 à 0
et du passage du dernier wagon : detect2 passe de 0 à 1 avec delai de micro-coupure
*/
Servo servoPNA; // servo voie A
Servo servoPNB; // servo voie B

#define CAPTEUR_ENT_A 2 // détecteur entrée PN voie A
#define CAPTEUR_SOR_A 3 // détecteur sortie PN voie A
#define CAPTEUR_ENT_B 7 // détecteur entrée PN voie B
#define CAPTEUR_SOR_B 8 // détecteur sortie PN voie B

#define LED1  10
#define LED2  11

#define SERVOPNA  5
#define SERVOPNB  6

#define PHASE_CROIT 0
#define PHASE_ALLUME 1
#define PHASE_DECROIT 2
#define PHASE_ETEINT 3

#define ANGLEFERME 50
#define ANGLEOUVERT 140

bool detect1A = false;  //détection des capteurs en entrée du PN (0 si train)
bool detect1B = false;
bool olddetect1A = false;  //dernière détection prise en compte
bool olddetect1B = false;
bool detect2A = false;   // en sortie du PN
bool detect2B = true;
bool olddetect2A = false;
bool olddetect2B = true;
bool lastdetect2A = false;  //dernière détection lue, pas forcément prise en compte (micro coupure due aux inter-wagons)
bool lastdetect2B = true;
bool readingPNA = false;
bool readingPNB = false;
unsigned long lastPNATime = 0;   // derniere fois que les detecteurs ont changes
unsigned long lastPNBTime = 0;
unsigned long PNDelay = 500; // durée maxi des micro-coupures
int avertissement = 2000; // durée avant fermeture
byte phase = 0;  // phase de clignotement (4 phases : croissance-max-decroissance-nulle)
unsigned long fading = 5;  // durée initiale entre 2 éclairages
byte intensite = 0;  //intensite de l'éclairement

unsigned long LedTime = millis();       // timer pour le clignotement
unsigned long PNTime = millis();        // timer pour les moteurs d'aiguillage
bool ferme = false;
bool fermeA = false;
bool fermeB = false;
byte angle = ANGLEOUVERT;   // angle initial barrières ouvertes

void setup()
{
  servoPNA.attach(5);// servo A
  servoPNB.attach(6);// servo B
  //Serial.begin(9600);

  pinMode(CAPTEUR_ENT_A, INPUT); // détecteur entrée PN voie A
  pinMode(CAPTEUR_SOR_A, INPUT); // détecteur sortie PN voie A
  pinMode(CAPTEUR_ENT_B, INPUT); // détecteur entrée PN voie B
  pinMode(CAPTEUR_SOR_B, INPUT); // détecteur sortie PN voie B
  pinMode(LED1, OUTPUT); // 2 Leds clignotantes
  pinMode(LED2, OUTPUT); // 2 Leds clignotantes

  servoPNA.write(ANGLEOUVERT); // barrière A ouverte
  servoPNB.write(ANGLEOUVERT); // barrière B ouverte

  analogWrite(LED1, 0); // 2 Leds coté A éteintes
  analogWrite(LED2, 0); // 2 Leds coté B éteintes
}

void loop()
{
  detect1A = digitalRead(CAPTEUR_ENT_A); //reading=0 si train
  if ((olddetect1A == HIGH && detect1A == LOW) && fermeA == false)
  {  // ferme voie A
    fermeA = true;
    if (fermeB == false)
    {
      PNTime = millis() + avertissement;
      LedTime = millis();
    }
  }
  olddetect1A = detect1A;

  readingPNA = digitalRead(CAPTEUR_SOR_A); //reading=0 si train
  if (readingPNA != lastdetect2A)
  {  //déclenchement chrono
    lastPNATime = millis();
  }

  if ((millis() - lastPNATime) > PNDelay)
  { // si le delai est atteint, le changement est valide sinon le changement est ignore (parasite ou inter-wagon)
    if (readingPNA != detect2A)
    {
      detect2A = readingPNA;
    } // changement valide
  }

  lastdetect2A = readingPNA;
  if (olddetect2A == LOW && detect2A == HIGH)
  {  // ouvre voie A
    fermeA = false;
    lastPNATime = millis();
  }
  olddetect2A = detect2A;

  detect1B = digitalRead(CAPTEUR_ENT_B);
  if ((olddetect1B == HIGH && detect1B == LOW) && fermeB == false)
  {  // ferme voie B
    fermeB = true;
    if (fermeA == fasle)
    {
      PNTime = millis() + avertissement;
      LedTime = millis();
    }
  }
  olddetect1B = detect1B;

  readingPNB = digitalRead(CAPTEUR_SOR_B); //reading=0 si train
  if (readingPNB != lastdetect2B)
  {  //déclenchement chrono
    lastPNBTime = millis();
  }

  // si le delai est atteint, le changement est valide sinon le changement est ignore (parasite ou inter-wagon)
  if ((millis() - lastPNBTime) > PNDelay)
    if (readingPNB != detect2B)
      detect2B = readingPNB; // changement valide

  lastdetect2B = readingPNB;
  if (olddetect2B == LOW && detect2B == HIGH)
  {  // ouvre voie B
    fermeB = false;
    lastPNBTime = millis();
  }

  olddetect2B = detect2B;

  ferme = (fermeA || fermeB);
  if (ferme == true || angle < ANGLEOUVERT)
    clignote();
  else
  {
    Serial.println("ouvert");
    analogWrite(LED1, 0);
    analogWrite(LED2, 0);
    phase = PHASE_CROIT;
    intensite = 0;
    fading = 5;
  }

  if (ferme == true && angle > ANGLEFERME)
    fermePN();

  if (ferme == false && angle < ANGLEOUVERT)
    ouvrePN();

  //Serial.println(angle);
}

void clignote()
{
  //Serial.println(intensite);
  if (millis() > LedTime + fading)     // vitesse de clignotement
  {
    LedTime = millis();   // reinit le timer
 
    switch (phase)
    {
      case PHASE_CROIT:       // croit
        intensite += 10;
        if (intensite == 250)
        {
          phase = PHASE_ALLUME;
          fading = 200;
        }
        break;

      case PHASE_ALLUME:      // allume
        phase = PHASE_DECROIT;
        fading = 5;
        break;

      case PHASE_DECROIT:      // decroit
        intensite -= 10;
        if (intensite == 0)
        {
          phase = PHASE_ETEINT;
          fading = 200;
        }
        break;

      case PHASE_ETEINT:      // eteint
        phase = PHASE_CROIT;
        fading = 5;
        break;
    }
    analogWrite(LED1, intensite);
  }
}

void ouvrePN()
{
  if ((millis() - PNTime) > 20)
  {
    PNTime = millis();
    angle += 1;
    servoPNA.write(angle);
    servoPNB.write(angle);
  }
}

void fermePN()
{
  if (millis() > 20 + PNTime)
  {
    PNTime = millis();
    angle -= 1;
    servoPNA.write(angle);
    servoPNB.write(angle);
  }
}

Le problème vient sans doute de la logique d'enchaînement des phases. En tout cas, la fonction 'clignote' par exemple ne s'occupe que d'une seule led, normal ?
Bien sûr, tout ça n'est ni compilé, ni testé...
8
Débuter / Re : analogWrite qui ne fonctionne pas toujours correctement avec des LEDs
« Dernier message par hinano70 le septembre 21, 2020, 05:10:22 pm »
Je progresse:
Lorsque je neutralise les servomoteurs (il faut que je neutralise les 2):
//Servo servoPNA; // servo voie A
//Servo servoPNB; // servo voie B , etc.....
et bien ça marche ??!!
Par contre si je les enlève physiquement en laissant le code, ça ne marche pas.

8 lignes où ça intervient:
Servo servoPNA; // servo voie A
Servo servoPNB; // servo voie B
....
servoPNA.attach(5);// servo A
servoPNB.attach(6);// servo B
servoPNA.write(140); // barrière A ouverte
servoPNB.write(140); // barrière B ouverte
....
servoPNA.write(angle);  //pour ouvrir ou fermer lentement
servoPNB.write(angle);

Je suis un peu dépassé, donc si qq'un a une idée, merci....
Un passage à niveau sans barrière, c'est quand même embêtant !
9
Débuter / Re : analogWrite qui ne fonctionne pas toujours correctement avec des LEDs
« Dernier message par hinano70 le septembre 21, 2020, 03:47:43 pm »
Merci pour les conseils, j'ai tenu compte des remarques.
Voici le montage joint
J'ai effectivement mis des tests un peu partout :
Serial.println(intensite); pour tester la valeur envoyée sur la sortie 10 PWM de la Led, ça augmente 0>250, puis ça diminue 250>0..., le timing est correct.
Serial.println(angle); pour vérifier la valeur envoyée aux servomoteurs, les barrières se ferment et s'ouvrent.
Tout est normal

Le problème c'est que la Led ne s'allume que si la valeur envoyée est 255 !!! (ce qui n'est pas atteint dans le programme puisque ça va de 0 à 250 par pas de 10, mais que je produis dans mes tests). Alors que le programme clignotement fonctionne très bien tout seul !!!

Est-ce un problème de typage incorrect avec des octets qui viennent en écraser d'autres ?

Je remets le code plus clair :

#include <Servo.h>
/* PN double voie A et B
détection par capteur IR de l'arrivée : detect1 passe de 1 à 0
et du passage du dernier wagon : detect2 passe de 0 à 1 avec delai de micro-coupure
*/
Servo servoPNA; // servo voie A
Servo servoPNB; // servo voie B
boolean detect1A,detect1B;  //détection des capteurs en entrée du PN (0 si train)
boolean  olddetect1A,olddetect1B;  //dernière détection prise en compte
boolean detect2A,detect2B=1;   // en sortie du PN
boolean  olddetect2A,olddetect2B=1;
boolean  lastdetect2A,lastdetect2B=1;  //dernière détection lue, pas forcément prise en compte (micro coupure due aux inter-wagons)
boolean readingPNA,readingPNB;
unsigned long lastPNATime,lastPNBTime;   // derniere fois que les detecteurs ont changes
unsigned long PNDelay = 500; // durée maxi des micro-coupures
int avertissement = 2000; // durée avant fermeture
byte phase = 0;  // phase de clignotement (4 phases : croissance-max-decroissance-nulle)
unsigned long fading = 5;  // durée initiale entre 2 éclairages
byte intensite = 0;  //intensite de l'éclairement
unsigned long LedTime = millis();       // timer pour le clignotement
unsigned long PNTime = millis();        // timer pour les moteurs d'aiguillage
boolean  ferme=false,fermeA=false,fermeB=false;
byte angle=140;   // angle initial barrières ouvertes

void setup()
{
servoPNA.attach(5);// servo A
servoPNB.attach(6);// servo B
//Serial.begin(9600);
pinMode(2,INPUT); // détecteur entrée PN voie A
pinMode(3,INPUT); // détecteur sortie PN voie A
pinMode(7,INPUT); // détecteur entrée PN voie B
pinMode(8,INPUT); // détecteur sortie PN voie B
pinMode(10, OUTPUT); // 2 Leds clignotantes
pinMode(11, OUTPUT); // 2 Leds clignotantes
servoPNA.write(140); // barrière A ouverte
servoPNB.write(140); // barrière B ouverte

analogWrite(10,0);// 2 Leds coté A éteintes
analogWrite(11,0);// 2 Leds coté B éteintes
}
void loop()
{

detect1A = digitalRead(2); //reading=0 si train
if ((olddetect1A==1 && detect1A==0) && fermeA==0) {fermeA=1;
                                                  if (fermeB==0) {PNTime = millis()+avertissement;
                                                  LedTime = millis();} }  // ferme voie A
olddetect1A = detect1A;

readingPNA = digitalRead(3); //reading=0 si train
if (readingPNA != lastdetect2A) {lastPNATime = millis();}  //déclenchement chrono
if ((millis() - lastPNATime) > PNDelay) {// si le delai est atteint, le changement est valide sinon le changement est ignore (parasite ou inter-wagon)
                                        if (readingPNA != detect2A) {detect2A = readingPNA;} // changement valide                                                       
                                        }

lastdetect2A = readingPNA;
if (olddetect2A==0 && detect2A==1) {fermeA=0; lastPNATime = millis();}  // ouvre voie A
olddetect2A=detect2A;


detect1B=digitalRead(7);
if ((olddetect1B==1 && detect1B==0) && fermeB==0) {fermeB=1;
                                                  if (fermeA==0) {PNTime = millis()+avertissement;
                                                  LedTime = millis();} }  // ferme voie B
olddetect1B=detect1B;

readingPNB = digitalRead(8); //reading=0 si train
if (readingPNB != lastdetect2B) {lastPNBTime = millis();}  //déclenchement chrono
if ((millis() - lastPNBTime) > PNDelay) {// si le delai est atteint, le changement est valide sinon le changement est ignore (parasite ou inter-wagon)
                                        if (readingPNB != detect2B) {detect2B = readingPNB;} // changement valide                                                       
                                        }

lastdetect2B=readingPNB;
if (olddetect2B==0 && detect2B==1) {fermeB=0; lastPNBTime = millis();}  // ouvre voie B
olddetect2B=detect2B;

ferme = (fermeA || fermeB);
if ((ferme==1) || (angle<140)) { clignote();}
else {Serial.println("ouvert");
      analogWrite(10,0);
      analogWrite(11,0);
      phase = 0;
      intensite=0;
      fading = 5;}

if ((ferme==1) && (angle>50)) {fermePN();}

if ((ferme==0) && (angle<140)) {ouvrePN();}

//Serial.println(angle);
}


void clignote()
{

//Serial.println(intensite);
if ( millis() > LedTime + fading)     // vitesse de clignotement
   {
   LedTime = millis();   // reinit le timer
 

   switch (phase) {
           case 0 :       // croit
              intensite += 10;
              if (intensite == 250) {phase = 1; fading = 200;}
              break;
           case 1 :      // allume
              phase = 2; fading=5;
              break;
           case 2 :      // decroit
              intensite -= 10;
              if (intensite == 0) {phase = 3; fading = 200;} break;
           case 3 :      // eteint
              phase = 0;
              fading = 5;
              break;
                }
   analogWrite(10,intensite);
   }
}

void ouvrePN()
{
if ((millis() - PNTime) > 20) {PNTime = millis();
                               angle+=1;
                               servoPNA.write(angle);
                               servoPNB.write(angle); }
}

void fermePN()
{
if (millis() > (20+PNTime)) {PNTime = millis();
                             angle-=1;
                             servoPNA.write(angle);
                             servoPNB.write(angle);  }
}
10
Débuter / Re : analogWrite qui ne fonctionne pas toujours correctement avec des LEDs
« Dernier message par msport le septembre 21, 2020, 03:29:27 pm »
Bonjour,
 analogWrite fonctionne mais un problème de logique le fait passer du mini au maxi sans qu'on voit les niveaux intermédiaires.
Des println pour voir ce qui se passe.
Pages: [1] 2 3 ... 10