[RÉSOLU]Aide pour un programme signal PWM

Oui c'est correct.

Peux tu un peux m'aiguiller pour le programme j'ai essayer toute la matinée je suis arrivé a rien ?

Ah làlà làlà làlà
Faut tout faire ici :wink:

1er exemple (demo_train.ino)
Un seul gros automate qui gère tout avec :

enum ETATS_APPLICATION {
  CHANGE_DIR_1_VERS_2,  // changer le relai pour aller de 1 vers 2
  ACCELERE_1_VERS_2,    // le train va de 1 vers 2 et accélère jusqu'au maximum
  DE_1_VERS_2,          // le train roule a fond de 1 vers 2
  RALENTIT_EN_2,        // le train a atteint le capteur 2 et ralentit jusqu'à l'arrêt
  CHANGE_DIR_2_VERS_1,  // changer le relai pour aller de 2 vers 1
  ACCELERE_2_VERS_1,    // le train accélère jusqu'au maximum
  DE_2_VERS_1,          // le train roule a fond vers 1
  RALENTIT_EN_1         // le train a atteint le capteur 1 et ralentit jusqu'à l’arrêt
} etat = CHANGE_DIR_1_VERS_2;

Commence par comprendre la logique.
C'est un bon gros exemple avec des états très expensifs, Il y a 4 étapes pour chaque sens :

  • On change de sens
  • On accélère
  • On est stable à fond
  • On ralentit quand on atteint le capteur

Mais comme tu peux le voir il y a beaucoup de code redondant.
Les phases d'accélération et de ralentissement sont identiques pour chacun des sens ce qui est dommage et complique la maintenance du code.

Pour une bonne raison, c'est que cet exemple, bien qu'il mette en oeuvre un automate ne découpe pas bien l'application.

Le 2eme exemple (démo_train2.ino) utilise 2 automate :

  • Un pour gérer le moteur avec 4 phases : arrêt, accélération, au max, décélération
enum ETATS_MOTEUR {
  ARRET,
  ACCELERE,
  AU_MAX,
  RALENTIT
} etat_moteur = ARRET;
  • Un pour le train : part vers le point 2, roule vers le point 2, repart vers le point 1, roule vers le point 2
enum ETATS_TRAIN {
  DEMARRER_VERS_2,
  EN_ROUTE_VERS_2,
  DEMARRER_VERS_1,
  EN_ROUTE_VERS_1
} etat_train = DEMARRER_VERS_2;

L'automate du train est le maître. Ses entrées sont les capteurs et il pilote l'automate du moteur.

Bon je n'ai pas de train, mais j'ai ressortit ma base robot roulant et voilà le résultat ICI (musique: Lat Train to London - Electric Light orchestra /D)

Je n'utilise pas de transistors ni de relai mais un driver de moteur (double pont en H) TB6612FNG (sur un breakout de chez Sparkfun).
Tu peux faire la même chose avec un L298.

demo_train.ino (7.34 KB)

demo_train2.ino (5.99 KB)

Ecoute un grand merci je pensais pas que tu ferais temps . . .

Une dernière petit question pour moi me repérer avec les pins

#define PIN_PWM_MOTEUR 5
#define PIN_RELAI_SENS 6

Les deux la c'est pour la commande relais et moteur sa je suis sur

#define PIN_CAPTEUR_1 2
#define INTR_CAPTEUR_1 0
#define PIN_CAPTEUR_2 3
#define INTR_CAPTEUR_2 1

Mais ici les "INTR" ça correspond a quoi ?

Les capteurs.
Je propose d'utiliser les entrées d'interruptions.

les interruptions permettent d'exécuter un bout de code (fonction dite "routine d'interruption") le plus simple possible mais qui est appelé directement par le processeur change le signal en question change (CHANGE), monte de GND à VCC (RAISING) ou tombe de VCC à GND (FALLING). Cette fonction est exécutée immédiatement lorsque le signal change sans que tu ais besoin de faire un digitalRead() et où que tu sois par ailleurs dans ton code.

L'intérêt dans notre cas ici, c'est que le passage du train sur le capteur REED peut être très court.
En utilisant if ( digitalRead()...) tu risques de tester le signal trop tard (il à changé puis rechangé) et de ne pas voir le passage sur le capteur.
Résultat connu :

En utilisant l'interruption, où que soit le code, quand le train passe sur le capteur, le code est automatiquement détourné sur la routine d'interruption où je mémorise dans une variable globale que le capteur est passé. Puis on reprend l'exécution du programme où l'on était. On peut alors tranquillement tester la variable capteur_X.

Tu ne peux pas utiliser n'importe qu'elle broches pour cela.
La broche d'interruption n°0 est la pin 2.
La broche d'interruption n°1 est la broche 3.
C'est pour cela qu'il y a double définition.

Note que dans mon test je considère que le relai reed est relié vers la masse et qu'il y a une résistance de pull-up vers le VCC.
Ce que tu as bien dans ton dessin sauf que moi j'ai choisit d'avoir 2 broches, une par capteur.

Tu devrais pouvoir t'en sortir avec une seule broche mais fait attention car quand le train va repasser déclencher 2 fois le signal :

  • une fois pendant la phase d'accélération
  • une fois en arrivant a destination
    Je ne commence a tester le signal qu'à la fin de la phase d'accélération mais comme la phase d'accélération dure le même temps que la phase de décélération, il est probable qu'en fin d'accélération le train passe juste devant le 1er capteur. Donc il y a un risque qu'il s'arrête tout de suite.
    Si tu ne peux pas avoir 2 broches différentes, il faudra ajouter une étape tampon de quelques secondes, ou une mesure de temps dans l'état actuel pour être sur d'ignorer le signal tant que tu n'est pas assez loin.

Ah oui j'y avais penser, mais pour l'autre programme car l'autre on avait beau envoyer une deuxième impulsion le cycle continuais.

Mais comment je dois câbler le tout ? Je relis le capteur un a la broche 2 et 0 et le capteur deux a la broche 3 et 1 ?

Je relis le capteur un a la broche 2 et 0 et le capteur deux a la broche 3 et 1 ?

Non, juste capteur UN à la broche 2 (qui est l'interruption 0) et le capteur DEUX à la broche 3 (qui est l'interruption 1).
Je sais, c'est pas de ma faute.
Voir attachInterrupt()

Most Arduino boards have two external interrupts: numbers 0 (on digital pin 2) and 1 (on digital pin 3). The Arduino Mega has an additional four: numbers 2 (pin 21), 3 (pin 20), 4 (pin 19), and 5 (pin 18).

Ah ok j'ai comprit en faite elles sont écrite mais non utilisée

mat0013:
Ah ok j'ai comprit en faite elles sont écrite mais non utilisée

Hum. Que veux tu dire par "écrite mais non utilisée" ?
Je ne fais pas de digitalWrite() sur ces pin. Juste un pinMode( INPUT );
Je ne les lis pas par un digitalRead() il est vrai. C'est l'interruption qui "lit" réellement en hard.

Je dois brancher le capteur un a la broche 2 et le capteur 2 a la broche 3 ça c'est ok ?
Les broches 0 et 1 je les laisse en l'air c'est exact ?

Donc je pensais qu'on était obliger de l'écrire mais qu'on ne les utilisais pas.

Comme dit précédemment :

capteur UN à la broche 2 (qui est l'interruption 0) et le capteur DEUX à la broche 3 (qui est l'interruption 1).

La broche 0 (Di0) c'est le RX de liaison série et la broche 1 (Di1) c'est le TX.

Il ne faut pas confondre :

  • la numérotation des broches digitales Di0 à Di13 (Digital 0 à Digital 13)
  • la numérotation des interruptions

l'interruption 0 (INT0) utilise la broche Di2
l'interruption 1 (INT1) utilise la broche Di3

C'est juste un problème de numérotations différentes.
C'est un peu dommage, çà perd en lisibilité mais c'est comme cela...

Et encore, je ne cite pas la numérotation des broches du composant ATmega....

Oui je vois j'ai comprit, un grand merci