[RÉSOLU]Aide pour un programme signal PWM

Salut,

Je vais t'expliquer clairement a quoi va servir le montage. Comme ça tu sera tout :stuck_out_tongue:

Il va servir a faire démarrer et arrêter un train de modélisme, sur deux mètres de vois il aura un capteur pour le faire démarrer( c'est ce qui donne l'impulsion) et le relais doit changer a chaque passsage de ce capteur, pour le faire aller dans un sens puis dans l'autre.

Oui ne t'inquiète pas je sais comment on branche le relais, transistor etc, je suis étudiant dans l'électronique je chipote dedans depuis mes 12ans, mais en programmation je débute, je suis de formation sur les automate programmable de Siemens mais c'est pas du tout le même ...

Merci

Je suis pas sur d'avoir compris.
Donc je ne suis pas sur de voir comment t'aider.
Tu peux faire un petit dessin très schématique du principe ?
Le train passe dessus le capteur et là le relai change ?
Mais comment le relai change t'il de nouveau ? Si le train repart dans l'autre sens, comment le train repasse sur le capteur ?

C'est pas clair dans ma tête...

Salut,
Voici un schéma j'ai oublier de préciser un truc il manque de tempo, j'explique
on lance le cycle le train passe sur le bp2 il faudrait une tempo de 5 seconde pour laisser le train s'arrêter ensuite le relais change de position donc le train repart dans l'autre sens et le signal PWM commence augmente puis diminue.
Le train passe sur le bp1 la même chose tempo de 5 secondes pour laisser le train s'arrêter ensuite le relais change de position pour permettre au train de repartir dans l'autre sens et le sigbal PWM commence augment et diminue.

Lien de l'image en grand... : http://img684.imageshack.us/img684/2434/trainrk.png

Ok.
Donc tu as bien définit les étapes.
Donc essaye de traduire cela sous la forme d'un automate

  • les états
  • que fais tu dans chaque état
  • quand et pourquoi passes tu d'un état à un autre

Coté électronique, tes transistors sont mals cablés.
L'emetteur d'un NPN est à relier à la masse et le collecteur vers la charge.
Il faut une résistance (environ 220 à 470 ohms) dans entre la sortie Arduino et la base sous peine de cramer la sortie de l'arduino.

Voila je pense que c'est ce que tu ma démander

Le train passe devant le capteur n°2
tempo de 5 secondes pour laisser s'arrêter le train avec l'inertie
Le relais change de possition car le train dois repartir de l'autre coter
dépard générateur PWM
le train passe devant le capteur n°1
arrêt du signal PWM et tempo de 5 secondes
Changement de l'état du relais
dépard du générateur PWM

Oui mais si le signal PWM descend à 0, le train s'arrête.
D'ailleurs, le train s’arrêtera même avant d'atteindre 0. A mon avis en dessous de

Est-ce que tu ne souhaites pas plutôt être à pleine vitesse entre les 2 capteurs et ralentir du maximum à 0 jusqu'à la position d'arrêt.
De là, inverser le sens, accélérer, dépasser le 1er capteur jusqu'au 2eme capteur à partir duquel tu décélères jusqu'à l’arrêt, etc ...

Ça me semble plus logique, mais tu connais mieux ton circuit ferroviaire que moi.

Comment sont fait les capteurs ?
Est-ce que c'est le passage des roues ? ou de l'avant ou de l'arrière ? qui déclenche le capteur ?

Oui cela peut être une solution de faire comme sa, alors les capteur normalement ce sont des capteurs REED sur le train a l'avant ou au début je ne sais pas encore il aura un aiment coller a celui ci, il faudrait une place bien précise ?

Non pas vraiment.
Après il faut juste les placer correctement.

Sinon est-ce que ma suggestion de séquence correspond.

Je suggère de définir les états suivants :

  • 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
  • CHANGE_DIR_1_VERS_2 : changer le relai pour aller de 1 vers 2
  • ACCELERE_1_VERS_2 : le train accélère jusqu'au maximum

Si cela correspond essaye d'écrire le code de l'automate.

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