LOCODUINO

Parlons Arduino => Vos projets => Discussion démarrée par: Dominique Donnat le février 16, 2016, 08:44:16 pm

Titre: Arduino pilotage PN37
Posté par: Dominique Donnat le février 16, 2016, 08:44:16 pm
Bonjour,

comme abordé dans ma présentation, je compte utiliser un arduino uno pour les differentes commandes de mon modulino PN. Pour l'instant, je simule sur breadboard.

En furetant à droite à gauche, j'ai déniché une bibliothèque "Chrono" élaborée par le même auteur que Bounce (anti-rebond). Chrono présente un moyen simple pour écrire des séquences d'événements. Est-ce que quelqu'un utilise cette bibliothèque et les objets chrono concernés ? Une recherche sur le forum ne m'a rien renvoyé.
C'est là : https://github.com/thomasfredericks/Chrono

Je compte l'utiliser pour piloter le mouvement de fermeture et d'ouverture des barrières de PN, avec plusieurs phases (exemple à l'ouverture : accélération sur 5°, vitesse angulaire constante sur 80 °, léger freinage sur 5 °, deux rebonds). L'actionneur sera un servo.

Tout retour d'expérience me sera précieux. Merci.

[Edit] : Je viens de découvrir l'article sur la bibliothèque ScheduleTable qui me semble encore mieux adaptée, au moins pour les séquences d'allumage / extinction des lampes intérieures de la maison de PN. Je vais aussi essayer cette bibliothèque.

Finalement, que pensez-vous de chacune de ces deux bibliothèques ?

Dominique.
Titre: Re : Arduino pilotage PN37
Posté par: bricoleau le février 16, 2016, 11:05:18 pm
Bonjour

ScheduleTable me semble immédiatement adaptée aux besoins d'animations cycliques.

Chrono est à mon sens une bibliothèque plus à destination des arduinistes débutants, pas forcément à l'aise avec l'utilisation directe de la fonction millis().
Dans le même genre, je te suggère de jeter un oeil aux bibliothèques que j'ai postées ici sur le forum (http://forum.locoduino.org/index.php?topic=122.msg985#msg985), et en particulier la librairie simpleMinuteur (elles sont livrées avec plein d'exemples pour comprendre leur utilisation).

Pour la barrière, j'imagine que tu as déjà défini la fonction angulaire dépendante du temps écoulé.
Derrière je pense que tu devras gérer toi-même l'envoi de la consigne au servo et sa réactualisation à fréquence élevée.
Y aura quelques lignes de code à écrire, mais rien de bien méchant.

Cela doit être jouable pour mai  :D
Titre: Re : Arduino pilotage PN37
Posté par: Dominique Donnat le février 17, 2016, 08:55:43 am
Oui, en creusant un peu plus, j'arrive aussi à la conclusion que ScheduleTable est ce qu'il me faut.

Pour le positionnement du servo, j'ai décrit le mouvement : une seconde pour passer de 0 à 5 ° avec une loi parabolique en fn du temps, puis 8 à 9 secondes à ~ 10 °/sec pour passer de 5 ° à 90 °, puis un rebond de 5 ° sur 1 seconde, puis un rebond de 2,5 ° sur une seconde, puis stop.
La question du temps de rafraîchissement : 1/10e de seconde, ça fait un pas de 1 °, et j'ai lu quelque part que cela pouvait paraître saccadé. Mais si je rafraîchis plus souvent, ça fait plus de valeurs à calculer. Je réfléchis en parallèle sur deux concepts :
- Tabuler toutes les valeurs de positionnement dans un tableau au setup, puis le positionnement est simple : au pas n, positionner le servo à l'angle n,
- ou, dans le loop, découper le temps par phase et calculer l'angle "en direct".

Y a-t-il des limitations de taille pour les tableaux ? Une séquence de 10 secondes au 1/20, ça fait 201 valeurs.

J'ai une autre réflexion en cours : j'ai un bouton poussoir qui commande le bouclage entre 4 cycles d'éclairage. Je voudrais l'utiliser pour, à la mise sous tension, ne démarrer le programme qu'après le premier appui (histoire d'être sûr que tout est bien configuré après l'installation du modulino au milieu de ses copains en début d'expo). Ma question : est-ce qu'on peut mettre ce test dans le setup, qui attendrait ce premier appui pour donner la main à la loop, ou bien ça ne marche pas et il faut un flag et un if .. else en début de loop ?
Titre: Re : Arduino pilotage PN37
Posté par: Jean-Luc le février 17, 2016, 09:21:07 am
Pour déplacer ton servos tu peux utiliser SlowMotionServo. Il faut juste avoir la function qui donne la position en fonction du temps.

https://git.framasoft.org/locoduino.org/SlowMotionServo/tree/master
Titre: Re : Re : Arduino pilotage PN37
Posté par: Jean-Luc le février 17, 2016, 09:25:03 am
Ma question : est-ce qu'on peut mettre ce test dans le setup, qui attendrait ce premier appui pour donner la main à la loop, ou bien ça ne marche pas et il faut un flag et un if .. else en début de loop ?

On peut mettre ce que l'on veut dans setup.
Titre: Re : Arduino pilotage PN37
Posté par: bricoleau le février 17, 2016, 09:30:40 am
Je mettrais directement le calcul dans le code.
Le nono tourne quand même à 16 Mhz, cela ne lui posera pas de pb.

La limite de tableau est celle de la ram. 201 octets cela reste raisonnable.
Et pour les tableaux constants on peut les laisser en flash.

Pas sur qu'on puisse aisément commander un servo depuis arduino avec une précision inferieure à 1 degré

Et aucun problème pour un bouton start intégré au setup

a+
Titre: Re : Arduino pilotage PN37
Posté par: Jean-Luc le février 17, 2016, 09:43:56 am
Ça dépend de la qualité du servo. L'arduino se contente de construire une impulsion avec une résolution de 4μs. 0° correspondent grosso modo a 500μs et 180° à 2500μs. On a donc 2000μs pour 180° et donc environ 11μs par degré. La résolution doit être vers les 0,36°
Titre: Re : Arduino pilotage PN37
Posté par: bricoleau le février 17, 2016, 05:59:01 pm
Les saccades peuvent provenir soit d'une imprécision angulaire, soit d'une fréquence de recalcul trop faible ou irrégulière.
Perso je partirais sur une précision au degré et un recalcul toutes les 10 ms soit 10 fois plus que nécessaire, de manière à réduire l'écart avec l'instant du pas théorique
Titre: Re : Arduino pilotage PN37
Posté par: Jean-Luc le février 17, 2016, 10:54:07 pm
En fait dans SlowMotionServo je ne fais pas comme ça.

Plutot que de déplacer les servos d'un pas fixé et de faire varier l'intervalle de rafraîchissement pour faire varier la vitesse, la bibliothèque calcule la position de chaque servo selon la date lue via millis() à chaque fois que update est appelée. Il suffit juste d'appeler update le plus fréquemment possible dans loop et on ne s'embête pas avec l'intervalle de temps de rafraîchissement.

Ce n'est donc pas sensible à des appels irréguliers tant que l’intervalle de temps d'appel de update n'est pas trop long.
Titre: Re : Arduino pilotage PN37
Posté par: Dominique Donnat le février 18, 2016, 09:26:22 am
Je n'ai peut-être pas bien cherché, mais je n'ai pas trouvé la doc de SlowMotionServo. Et la lecture du code est un peu ardue pour le newbie que je suis. Bref, on trouve un mode d'emploi quelque part ?
Titre: Re : Arduino pilotage PN37
Posté par: Jean-Luc le février 18, 2016, 09:39:01 am
Effectivement je n'ai pas encore rédigés de documentation. Je peux faire ca rapidement. Si c'est en anglais ça va ? En attendant un article sur Locoduino.
Titre: Re : Arduino pilotage PN37
Posté par: Dominique Donnat le février 18, 2016, 11:52:07 am
L'anglais me va très bien.
Titre: Re : Arduino pilotage PN37
Posté par: Jean-Luc le février 18, 2016, 04:02:46 pm
Voilà, c'est fait :

https://git.framasoft.org/locoduino.org/SlowMotionServo/tree/master
Titre: Re : Arduino pilotage PN37
Posté par: Dominique Donnat le février 18, 2016, 07:13:45 pm
Génial, ça marche très bien.

La classe Smooth me va bien telle quelle, je vais l'utiliser pour mes barrières sans changement. Reste à trouver les bonnes valeurs d'angle d'arrivée, le départ étant toujours à zéro.

J'ai essayé une instanciation avec rebond. Comme c'est programmé, le servo revient en arrière après 100 % et s'arrête à l'issue du rebond, à une position ~ 80 %. Moi j'avais imaginé un rebond qui revient à 100 %, et même deux rebonds successifs, un grand et un petit. Mais c'est un raffinement dont je peux me passer, je verrai dans un deuxième temps. C'est pour ça que la fonction sinusoïdale simple me va bien, et me laisse du temps pour le reste. Ça, c'est réglé.

Un truc bizarre quand même : pour bien observer le comportement du rebond, j'avais mis un délai de 2 secondes entre l'aller et le retour. Curieusement, le rebond se produit à l'aller, en fin de mouvement, mais pas au retour. Y a-t-il une explication logique ?

Mon code :
#include <Servo.h>
#include <SlowMotionServo.h>

SMSSmoothBounce myServo; /* Servo with sinusoidal trajectory with bounce */
float target = 0.0;

void setup() {
  myServo.setInitialPosition(target);
  myServo.setMinMax(544, 1500);
  myServo.setPin(2); /* the servo is connected to pin 2 */
}

void loop() {
  if (myServo.isStopped()) {
    delay(2000);
    target = 1.0 - target;
    myServo.goTo(target);
  }

  SlowMotionServo::update();
}

Titre: Re : Arduino pilotage PN37
Posté par: Jean-Luc le février 18, 2016, 07:46:36 pm
Oui c'est normal. SMSSmoothBounce n'a pas la même trajectoire de min vers max et de max vers min. Pour la première, il y a le rebond, pour la seconde, c'est un sinus comme dans SMSSmooth :

float SMSSmoothBounce::slopeUp(float time)
{
  if (time <= 0.79) {
    return (1.0 - cos(time * PI))/1.8;
  }
  else {
    float timeOff = 10.0 * (time - 0.55);
    return (0.834 + 1.0 / (timeOff * timeOff));
  }
}

float SMSSmoothBounce::slopeDown(float time)
{
  return (1.0 - cos(time * PI))/2.265;
}

Au lieu d'un simple bounce, on peut faire un sinus amorti. C'est très rapide à programmer
Titre: Re : Re : Re : Arduino pilotage PN37
Posté par: Dominique Donnat le février 21, 2016, 12:34:30 pm
Ma question : est-ce qu'on peut mettre ce test dans le setup, qui attendrait ce premier appui pour donner la main à la loop, ou bien ça ne marche pas et il faut un flag et un if .. else en début de loop ?

On peut mettre ce que l'on veut dans setup.

Bon, ya pas à dire, il faut monter les marches de l'escalier l'une après l'autre.

Je cherche à faire fonctionner ce morceau d'initialisation de mon projet.
Fonction attendue : après la mise sous tension, le programme doit attendre un premier appui sur un bouton poussoir pour entrer dans le loop. Pour ce test, le programme ne doit qu'allumer une led.

J'ai donc un bouton poussoir relié à une entrée avec pull-up intégrée, et un circuit d'allumage de led sur une sortie pwm.
Partant du conseil ci-dessus, j'ai mis un while dans le setup, et je m'attendais que le programme y reste tant que je n'ai pas actionné mon bouton.

Sauf que ça ne marche pas, il ignore superbement le bouton poussoir et allume la diode tout de suite. J'ai mis des espions avec des Serial.print et, à l'évidence, le programme ne cycle pas à l'intérieur de mon while

Mon code :
/* Programme de test de l'utilisation du bouton poussoir éclairage
pour initialiser le programme une fois que tout est vérifié
Pour ce test on utilise Led0 sur pin 5 - on en profite pour tester le pwm
Dans un premier temps on se contente de lire le bouton */


// Déclaration des constantes
const byte pinEclair=7; // affecte l'E/S 7 au bp cyclage éclairage
const byte pinLed0=3; // affecte l'E/S 3 à la led 0

// Déclaration des variables
byte eclair; // état du bouton poussoir de cyclage de l'éclairage
byte flagInit = 0; // flag pour sortir de la boucle d'initialisation. flagInit = 1 pour sortir
byte pwmLed0=255; // pour régler l'éclairement Led0 - provisoire 100 % (255)

void setup() {
  // put your setup code here, to run once:
pinMode(pinLed0, OUTPUT); // déclare pinLed0 comme sortie ; facultatif pour sortie pwm
pinMode(pinEclair, INPUT_PULLUP); // déclare pinEclair en entrée et active la résistance de pullup interne

while (flagInit == 0)
  {
  digitalRead(eclair);
  if(eclair==LOW) flagInit=1;
    }

}
void loop() {
  // put your main code here, to run repeatedly:
analogWrite(pinLed0,pwmLed0);
}

Je n'ai pas trouvé comment insérer le schéma fritzing sans devoir le télécharger quelque part sur le net, mais je peux le faire si ça vous éclaire.

Mes hypothèses de travail :
- le BP est sur une entrée avec pull-up intégrée, donc l'entrée est à HIGH tant que le BP est relâché, et passe à LOW sur appui.
- la boucle while boucle sur elle-même tant que flagInit est à 0 ; flagInit passe à 1 quand la boucle lit un état LOW sur le bouton poussoir nommé eclair, ce qui provoque la sortie à la boucle suivante.

Où est-ce que j'ai faux ?

Désolé de vous mobiliser pour des trucs que  vous devez considérer comme basiques. En attendant je vais aller faire du décor.
Titre: Re : Arduino pilotage PN37
Posté par: Jean-Luc le février 21, 2016, 06:07:43 pm
Bonjour

digitalRead est une fonction qui renvoie la valeur lue

Dans ton cas, il faut écrire :

eclair = digitalRead(pinEclair);

Tel que c'est écrit :

digitalRead(eclair);

la broche de numéro eclair est lue et le résultat est jeté. On ne sait pas ce que contient éclair mais vu le comportement il contient 0. Le test

if (eclair == LOW) { ... }

sera donc vrai car LOW vaut également 0
Titre: Re : Arduino pilotage PN37
Posté par: Dominique Donnat le février 23, 2016, 08:06:38 pm
Je ne t'ai pas remercié, Jean-Luc, mais je me suis baffé pour une erreur aussi basique. Mais c'est comme ça que ça rentre.

Je progresse bien (quoique laborieusement), je maîtrise le bouton poussoir qui allume successivement 4 leds, avec l'antirebond Bounce2.

J'attaque TableSchedule, et je bloque sur la récurrence:

J'ai une séquence de 5 actions sur 16 secondes, que je veux dérouler une fois à chaque fois qu'un interrupteur est basculé sur une certaine position.

J'ai lu qu'on peut demander que la séquence se répète à l'infini ou un certain nombre de fois, donc j'ai tendance à mettre maTable.start(1). Correct ?

mais comment maîtriser le démarrage de la séquence, c'est-à-dire qu'elle se lance  1 fois chaque fois que le fameux interrupteur est basculé, et non pas dès le début du programme ? ? On met un maTable.start(1) à l'endroit prévu dans la loop ?  J'ai fait quelques essais en ce sens mais infructueux.

Merci de vos lumières.

(Je l'aurai ... je l'aurai)

Dominique.

Mon code provisoire :

// Test de la bibliothèque ScheduleTable et de la commande d'un optocoupleur
#include <ScheduleTable.h>
#include <Bounce2.h>

ScheduleTable ouvreSonne(5,4500);  // Création de la table

// Création des objets Bounce que j'appelle inter1, inter2
Bounce inter1; // inter pour programme fermeture barrières avec sonnerie ; LOW pour inter activé, pullup interne au + 5V, fil gris
Bounce inter2; // inter pour programme fermeture barrières sans sonnerie ; LOW pour inter activé, pullup interne au + 5V, fil rouge
const byte pinInter1=13; // affecte l'E/S 13 à l'inter en position 1
const byte pinInter2=12; // affecte l'E/S 12 à l'inter en position 2
const byte pinSonne=8;  // affecte l'E/S 8 au pilotage de la sonnerie via optocoupleur. Pour ce test, l'opto allume une led alimentée séparément

 // déclaration des variables
byte actionPN=0; // variable d'état pour le switchcase de pilotage des barrières
byte prevActionPN=0; // l'état précédent de actionPN
float target = 0.0;
byte sonne=LOW; // variable utilisée pour l'impulsion de commande de la sonnerie.

void pulseOn()
{
  sonne=HIGH;
}

void pulseOff()
{
    sonne=LOW;
}

void basculeTarget()
{
  target = 0.0;
}

void setup() {
  // put your setup code here, to run once:
Serial.begin(9600);
pinMode(pinInter1, INPUT_PULLUP); // déclare pinInter1 en entrée et active la résistance de pullup interne
pinMode(pinInter2, INPUT_PULLUP); // déclare pinInter2 en entrée et active la résistance de pullup interne
inter1.attach(pinInter1);
inter1.interval(10);
inter2.attach(pinInter2);
inter2.interval(10);
pinMode(pinSonne, OUTPUT); // déclare pinSonne comme sortie;

// Table des événements de ouvreSonne: impulsions de 500 ms à t=0 et t = 4000, et assigne la valeur 0.0 à target à t = 2000
ouvreSonne.at(0,pulseOn);
ouvreSonne.at(500,pulseOff);
ouvreSonne.at(2000,basculeTarget);
ouvreSonne.at(4000,pulseOn);
ouvreSonne.at(4500,pulseOff);
ouvreSonne.start(1);
}

void loop() {
  // put your main code here, to run repeatedly:
  // les objets Bounce doivent exécuter leur code interne à chaque loop :
  inter1.update();
  inter2.update();
  int value1 = inter1.read();
  int value2 = inter2.read();
  ScheduleTable::update();


// ici on calcule actionPN en fonction de inter1 et inter2
    if ((value1==HIGH) && (value2==LOW))
    {
      actionPN=2;
    }
    else if ((value1==LOW) && (value2==HIGH))
    {
      actionPN=1;
    }
    else {
      actionPN=0;
    }
 /* Serial.print("inter 1  :  ");
  Serial.print(value1);
  Serial.print("  inter2 :  ");
  Serial.print(value2);
  Serial.print("  actionPN  :  ");
  Serial.print(actionPN);
  Serial.print("  Target  :  ");
  Serial.println(target); */
 
  switch (actionPN) // début du switch case de pilotage des barrières
  {
    case 0: // on ouvre les barrières
        if (actionPN != prevActionPN) {target = 1.0; prevActionPN=actionPN;}
        break;
    case 1: // on ferme les barrières avec sonnerie
        digitalWrite(pinSonne,sonne); // allumage d'une led qui visualise l'impulsion de déclenchement de la sonnerie
        prevActionPN=actionPN;
        break;
    case 2: // on ferme les barrières sans sonnerie
        if (actionPN != prevActionPN) {target = 0.0; prevActionPN=actionPN;}
        break;
  } // fin du switch case de pilotage des barrières
    // SlowMotionServo::update(); en attente pour plus tard

}
Titre: Re : Arduino pilotage PN37
Posté par: Jean-Luc le février 24, 2016, 08:34:52 am
Oui c'est ça. Tu appelles la fonction start dans loop quand tu détectes la pression sur le bouton.
Titre: Re : Re : Arduino pilotage PN37
Posté par: Jean-Luc le février 25, 2016, 08:03:45 am
mais comment maîtriser le démarrage de la séquence, c'est-à-dire qu'elle se lance  1 fois chaque fois que le fameux interrupteur est basculé, et non pas dès le début du programme ? ? On met un maTable.start(1) à l'endroit prévu dans la loop ?  J'ai fait quelques essais en ce sens mais infructueux.

Pourrais tu donner le programme qui ne marche pas comme attendu ainsi que le fonctionnement voulu ?
Titre: Re : Arduino pilotage PN37
Posté par: Dominique Donnat le février 25, 2016, 01:19:08 pm
Je ne sais pas quelle fausse manœuvre j'avais faite en bidouillant, mais, en remettant un maTable.start(1) dans le cas 1 qui m'intéresse, ça fonctionne parfaitement. Ça, ça a l'air réglé.

Mais désormais je coince avec le fonctionnement de SlowMotionServo, qui fonctionnait très bien sur le petit programme d'essai.

Le système à piloter : des barrières de PN commandées par un servo, avec un petit module sonore autonome déclenché et arrêté par une impulsion.

La commande est un inter 2 positions, inter1 et inter2. Inter au centre correspond aux barrières levées, inter1 fermé (état LOW car alimenté par pull-up interne) déclenche le cas 1, inter2 fermé déclenche cas 2.  Les 3 états de cet inter déclenchent des séquences du programme via un switchCase. Ça, ça marche, le programme passe bien par où il doit passer.

3 cycles de commande :
cas 0 les barrières s'ouvrent,
cas 1 une sonnerie se déclenche, puis (+5 sec) les barrières se ferment, puis à la fin la sonnerie s'éteint. (Pour le test la séquence est accélérée)
cas 2 les barrières se ferment sans sonnerie et sans attente.

Cas 0 et cas 2, je n'ai pas besoin de TableSchedule, il devrait suffire de changer la valeur de target pour que SlowMotionServo actionne le servo.
Cas 1, je déclenche la séquence décrite dans TableSchedule. Cette séquence se déroule apparemment bien, car les actions qui concernent la sonnerie (simulée par une led) (fonctions pulseOn, pulseOff) fonctionnent comme prévu, les deux impulsions de 0,5 sec se déclenchent aux instants attendus. L'espion série confirme bien que la valeur de target change comme attendu à t = 2s.

Mon problème actuel, c'est que le servo ne réagit pas du tout, dans aucun des cas. Je dois avoir écrit quelque chose de défectueux ou pas où il faut, ou manquant.

Merci de tes lumières.

// Test de la bibliothèque ScheduleTable, de SlowMotionServo et de la commande d'un optocoupleur
#include <ScheduleTable.h>
#include <Bounce2.h>
#include <Servo.h>
#include <SlowMotionServo.h>

// Création des objets
ScheduleTable ouvreSonne(5,5000);  // Création de la table

Bounce inter1; // inter pour programme fermeture barrières avec sonnerie ; LOW pour inter activé, pullup interne au + 5V, fil gris
Bounce inter2; // inter pour programme fermeture barrières sans sonnerie ; LOW pour inter activé, pullup interne au + 5V, fil rouge

SMSSmooth servoPN; /* Servo with sinusoidal trajectory */

// Déclaration des constantes
const byte pinServo=9; // affecte l'E/S 9 au pilotage du servo
const byte pinInter1=13; // affecte l'E/S 13 à l'inter en position 1
const byte pinInter2=12; // affecte l'E/S 12 à l'inter en position 2
const byte pinSonne=8;  // affecte l'E/S 8 au pilotage de la sonnerie via optocoupleur. Pour ce test, l'opto allume une led alimentée séparément


 // déclaration des variables
byte actionPN=0; // variable d'état pour le switchcase de pilotage des barrières
byte prevActionPN=0; // l'état précédent de actionPN
float target = 0.0; // La cible du servo : target = 0.0 pour barrières fermées.
byte sonne=LOW; // variable utilisée pour l'impulsion de commande de la sonnerie.

void pulseOn()
{
  sonne=HIGH;
}

void pulseOff()
{
    sonne=LOW;
}

void basculeTarget()
{
  target = 0.0;
}

void setup() {
  // put your setup code here, to run once:
    Serial.begin(9600);
    pinMode(pinInter1, INPUT_PULLUP); // déclare pinInter1 en entrée et active la résistance de pullup interne
    pinMode(pinInter2, INPUT_PULLUP); // déclare pinInter2 en entrée et active la résistance de pullup interne
    inter1.attach(pinInter1);
    inter1.interval(10);
    inter2.attach(pinInter2);
    inter2.interval(10);
    pinMode(pinSonne, OUTPUT); // déclare pinSonne comme sortie;

    servoPN.setInitialPosition(target);
    servoPN.setMinMax(850, 2100);
    servoPN.setPin(pinServo); /* the servo is connected to pin pinServo */
 
// Table des événements de ouvreSonne: impulsions de 500 ms à t=0 et t = 4000, et assigne la valeur 0.0 à target à t = 2000
    ouvreSonne.at(0,pulseOn);
    ouvreSonne.at(500,pulseOff);
    ouvreSonne.at(2000,basculeTarget);
    ouvreSonne.at(4000,pulseOn);
    ouvreSonne.at(4500,pulseOff);
}

void loop() {
  // put your main code here, to run repeatedly:
  // les objets Bounce doivent exécuter leur code interne à chaque loop :
  inter1.update();
  inter2.update();
  int value1 = inter1.read();
  int value2 = inter2.read();
  ScheduleTable::update();

// ici on calcule actionPN en fonction de inter1 et inter2
    if ((value1==HIGH) && (value2==LOW))
    {
      actionPN=2;
    }
    else if ((value1==LOW) && (value2==HIGH))
    {
      actionPN=1;
    }
    else {
      actionPN=0;
    }
  /* Serial.print("inter 1  :  ");
  Serial.print(value1);
  Serial.print("  inter2 :  ");
  Serial.print(value2);
  Serial.print("  actionPN  :  ");
  Serial.print(actionPN);
  Serial.print("  Target  :  ");
  Serial.println(target);*/

 
  switch (actionPN) // début du switch case de pilotage des barrières
  {
    case 0: // on ouvre les barrières
        if (actionPN != prevActionPN) {target = 1.0; prevActionPN=actionPN;}
        break;
    case 1: // on ferme les barrières avec sonnerie
        if (actionPN != prevActionPN) ouvreSonne.start(1);
        digitalWrite(pinSonne,sonne); // allumage d'une led qui visualise l'impulsion de déclenchement de la sonnerie
        prevActionPN=actionPN;
        break;
    case 2: // on ferme les barrières sans sonnerie
        if (actionPN != prevActionPN) {target = 0.0; prevActionPN=actionPN;}
        break;
} // fin du switch case de pilotage des barrières

  servoPN.goTo(target);
}

Titre: Re : Arduino pilotage PN37
Posté par: Jean-Luc le février 25, 2016, 01:34:58 pm
À vue de nez tu n'appelles pas SlowMotionServo::update() dans loop  :)
Titre: Re : Arduino pilotage PN37
Posté par: Dominique Donnat le février 25, 2016, 02:56:10 pm
Il y a un progrès, le servo a bougé (il s'est remis une fois à la position zéro - ça doit correspondre à la prise en compte de     servoPN.setInitialPosition(target); à la première boucle),

mais ne réagit toujours pas aux changements de target qui eux se passent bien. Comme si servoPN.goTo(target) qui est en fin de loop était ignoré. Il y a encore autre chose.
Titre: Re : Arduino pilotage PN37
Posté par: Jean-Luc le février 25, 2016, 02:59:24 pm
Le

void basculeTarget()
{
  target = 0.0;
}

Fait que quoique tu fasses, le servo reste à la position 0.0

Ne serait-ce pas plutôt

void basculeTarget()
{
  target = 1.0 - target;
}

De cette manière si target vaut 0.0, le nouveau target vaut 1.0 et si target vaut 1.0, le nouveau target vaut 0.0. Dans ce cas tu aurais effectivement une bascule.
Titre: Re : Arduino pilotage PN37
Posté par: Dominique Donnat le février 25, 2016, 03:37:56 pm
J'y avais pensé (et c'est pour cela que la fonction s'appelle bascule) mais ensuite, j'ai préféré positionner target à la valeur voulue pour une phase donnée.

Et la variable target bouge bien entre 0.0 et 1.0 comme je le souhaite en fonction des inter, je le contrôle par Serial.print.

Je pars de actionPN = 2, les barrières sont baissées
inter 1  :  1  inter2 :  0  actionPN  :  2  prevActionPN  :  2  Target  :  0.00
inter 1  :  1  inter2 :  0  actionPN  :  2  prevActionPN  :  2  Target  :  0.00
inter 1  :  1  inter2 :  0  actionPN  :  2  prevActionPN  :  2  Target  :  0.00
Je bascule inter2, actionPN passe à 0, target passe immédiatement à 1, les barrières sont censées se lever
inter 1  :  1  inter2 :  1  actionPN  :  0  prevActionPN  :  2  Target  :  0.00
inter 1  :  1  inter2 :  1  actionPN  :  0  prevActionPN  :  0  Target  :  1.00
inter 1  :  1  inter2 :  1  actionPN  :  0  prevActionPN  :  0  Target  :  1.00
inter 1  :  1  inter2 :  1  actionPN  :  0  prevActionPN  :  0  Target  :  1.00
inter 1  :  1  inter2 :  1  actionPN  :  0  prevActionPN  :  0  Target  :  1.00
.../...
inter 1  :  1  inter2 :  1  actionPN  :  0  prevActionPN  :  0  Target  :  1.00
inter 1  :  1  inter2 :  1  actionPN  :  0  prevActionPN  :  0  Target  :  1.00
Je positionne inter1 à low, actionPN passe à 1, target reste à 1.0 pendant le nbre de loops correspondant à l'action de ScheduleTable (2s) (65 loops exactement soit une loop de 30 ms) - la sonnerie est censée se déclencher, le barrières ne bougent pas
inter 1  :  0  inter2 :  1  actionPN  :  1  prevActionPN  :  0  Target  :  1.00
inter 1  :  0  inter2 :  1  actionPN  :  1  prevActionPN  :  1  Target  :  1.00
inter 1  :  0  inter2 :  1  actionPN  :  1  prevActionPN  :  1  Target  :  1.00
.../...
inter 1  :  0  inter2 :  1  actionPN  :  1  prevActionPN  :  1  Target  :  1.00
inter 1  :  0  inter2 :  1  actionPN  :  1  prevActionPN  :  1  Target  :  0.00  <-là, les barrières s'abaissent
inter 1  :  0  inter2 :  1  actionPN  :  1  prevActionPN  :  1  Target  :  0.00
etc

Bref, moi dont l'expérience en programmation se résume à des cours de Fortran il y a 40 ans (et un peu de pratique quand même), j'avoue que la programmation objet, c'est un choc culturel !

[Edit : j'ai fait la modif, rien ne change. ]

Qu'est-ce qui peut bien se passer ?
Titre: Re : Arduino pilotage PN37
Posté par: Jean-Luc le février 25, 2016, 04:36:21 pm
Il faut que je regarde SlowMotionServo plus en détails mais il est possible que ca se passe mal d'appeler goTo alors que le servo n'est pas arrêté à une position. Essaye de mettre un if (servoPN.isStopped()) autour de serviPN.goTo pour voir.
Titre: Re : Arduino pilotage PN37
Posté par: Dominique Donnat le février 25, 2016, 05:25:30 pm
Au poil ! Le système réagit exactement comme je voulais. Je peux continuer l'intégration. Merci.

Mais si tu trouves l'explication, je suis preneur. J'aime bien comprendre un minimum (même si je n'en suis pas encore assez avancé).


Et par ailleurs cette méthode .isStopped (tu as dû le faire pour cela) permet que le servo aille au bout de son mouvement, même si on change la consigne en cours de mouvement. Très utile en cas de fausse manœuvre, j'avais cette préoccupation dans un coin de ma to-do list, c'est déjà tout fait ! Merci.
Titre: Re : Arduino pilotage PN37
Posté par: Jean-Luc le février 25, 2016, 05:47:59 pm
À froid je n'ai pas d'explication si ce n'est que quand j'ai écrit SlowMotionServo je n'ai pas prévu un changement de goTo en cours de mouvement. 2 solutions, une pas facile car il faut que je réécrive une partie et en regardant rapidement le code je n'ai pas vu d'où ça pouvait coincer : prendre en compte la nouvelle destination en cours de mouvement. Une facile et plus satisfaisante je pense, si le servo n'est pas stoppé, mettre dans un tampon la nouvelle target et une fois que l'ancienne target est atteinte, la prendre en compte. Ça serait mieux que de bloquer si goTo est appelé de manière imprévue :-)
Titre: Re : Arduino pilotage PN37
Posté par: Dominique Donnat le avril 05, 2016, 12:13:45 pm
Rebonjour à tous,

mon projet de PN a progressé, mais je bute sur un comportement apparemment aléatoire.

Pour mémoire, je pilote un servo qui manœuvre des barrières de PN. La commande du servo fait appel à la bibliothèque SlowMotionServo de Jean-Luc qui fonctionne bien.

Un inter double (1RT, représenté par deux inter inter1 et inter2 sur deux entrées avec pull-up interne activée) pilote le mouvement des barrières. L'un des modes déclenche une séquence (bibliothèque ScheduleTable) avec : déclenchement sonnerie, 5 sec plus tard mouvement de fermeture des barrières qui dure 10 s, puis extinction sonnerie.

La sonnerie est un module externe autonome, le déclenchement et l'extinction se font par mise à la masse impulsionnelle d'une entrée (la même). J'ai installé un optocoupleur pour activer ce "contact".

Mon problème : le déclenchement de la sonnerie par le programme est aléatoire, ou en tout cas réagit à quelque chose que je ne comprends pas.
Après l'init de l'Arduino, la première commande active bien la sonnerie. Puis la sonnerie ne se déclenche plus. La commande issue de l'arduino est correcte (visualisé par une diode, on voit bien les deux impulsions de 0,5sec à chaque cycle). De même, un mise à la masse physique de l'entrée du module sonore active bien la sonnerie.

Je suspecte des problèmes de timing entre le rythme du microcontroleur du module sonore (dont je ne connais rien) et le cycle issu de l'arduino.

Quelqu'un a-t-il déjà rencontré ce genre de problème ? Toute suggestion d'analyse est bonne, merci d'avance.

/* Programme de pilotage du modulino PN37
 *  créé par D. Donnat - février 2016
 */
#include <ScheduleTable.h>
#include <Bounce2.h>
#include <Servo.h>
#include <SlowMotionServo.h>

// Création des objets
    ScheduleTable ouvreSonne(5,18000);  // Création de la table
    Bounce inter1; // inter pour programme fermeture barrières avec sonnerie ; LOW pour inter activé, pullup interne au + 5V, fil gris
    Bounce inter2; // inter pour programme fermeture barrières sans sonnerie ; LOW pour inter activé, pullup interne au + 5V, fil rouge
    Bounce eclair; // instancie un objet bounce pour le bouton poussoir d'éclairage
    SMSSmooth servoPN;

 // déclaration des constantes
    const byte pinServo=9; // affecte l'E/S 9 au pilotage du servo
    const byte pinInter1=13; // affecte l'E/S 13 à l'inter en position 1
    const byte pinInter2=12; // affecte l'E/S 12 à l'inter en position 2
    const byte pinSonne=8;  // affecte l'E/S 8 au pilotage de la sonnerie via optocoupleur
   
    const byte pinLed0=3; // affecte l'E/S 3 à la led 0 lampadaire en façade
    const byte pinLed1=5; // affecte l'E/S 5 à la led 1 grande salle
    const byte pinLed2=6; // affecte l'E/S 6 à la led 2 petite chambre
    const byte pinLed3=11; // affecte l'E/S 11 à la led 3e étage
    const byte pinEclair=7; // affecte l'E/S 7 au bp cyclage éclairage

 // déclaration des variables
    float target = 0.0; // La cible du servo : target = 0.0 pour barrières fermées.
    byte actionPN=0; // variable d'état pour le switchcase de pilotage des barrières
    byte prevActionPN=0; // l'état précédent de actionPN
    byte sonne=LOW; // variable utilisée pour l'impulsion de commande de la sonnerie.
    // byte flagInit = 0; // flag pour sortir de la boucle d'initialisation. flagInit = 1 pour sortir ; à voir plus tard
    byte memoireEclair = HIGH; // état du bouton d'éclairage au cycle précédent
    byte cycleEclair; // compteur de cycle d'éclairage, de 0 à 4 ; 0 = éteint, cycles d'éclairage de 1 à 4
    byte pwmLed0=255; // pour règler l'éclairement Led0 - provisoire 100 % (255)
    byte pwmLed1=255; // pour règler l'éclairement Led1 - provisoire 100 % (255)
    byte pwmLed2=255; // pour règler l'éclairement Led2 - provisoire 100 % (255)
    byte pwmLed3=255; // pour règler l'éclairement Led3 - provisoire 100 % (255)

void pulseOn()
    {
      sonne=HIGH;
    }

void pulseOff()
    {
        sonne=LOW;
    }

void basculeTarget()
    {
      target = 1.0 - target;
    }



void setup() {
  // put your setup code here, to run once:
    Serial.begin(9600);
    servoPN.setInitialPosition(target);
    servoPN.setMinMax(850, 1475);
    servoPN.setPin(pinServo); /* the servo is connected to pin pinServo */

    pinMode(pinInter1, INPUT_PULLUP); // déclare pinInter1 en entrée et active la résistance de pullup interne
    pinMode(pinInter2, INPUT_PULLUP); // déclare pinInter2 en entrée et active la résistance de pullup interne
    pinMode(pinEclair, INPUT_PULLUP); // déclare pinEclair en entrée et active la résistance de pullup interne
    inter1.attach(pinInter1);
    inter1.interval(10);
    inter2.attach(pinInter2);
    inter2.interval(10);
    eclair.attach(pinEclair);
    eclair.interval(10);
    pinMode(pinSonne, OUTPUT); // déclare pinSonne comme sortie;
    pinMode(pinLed0, OUTPUT); // déclare pinLed0 comme sortie
    pinMode(pinLed1, OUTPUT); // déclare pinLed1 comme sortie
    pinMode(pinLed2, OUTPUT); // déclare pinLed2 comme sortie
    pinMode(pinLed3, OUTPUT); // déclare pinLed3 comme sortie
    analogWrite(pinLed0, 0); // on éteint toutes les leds
    analogWrite(pinLed1, 0);
    analogWrite(pinLed2, 0);
    analogWrite(pinLed3, 0);

// Table des événements de ouvreSonne: impulsions de 500 ms à t=500 et t = 16500, et assigne la valeur 0.0 à target à t = 5000
    ouvreSonne.at(500,pulseOn);
    ouvreSonne.at(1000,pulseOff);
    ouvreSonne.at(5500,basculeTarget);
    ouvreSonne.at(16500,pulseOn);
    ouvreSonne.at(17000,pulseOff);
}

void loop() {
  // put your main code here, to run repeatedly:
  // les objets Bounce doivent exécuter leur code interne à chaque loop :
  inter1.update();
  inter2.update();
  eclair.update();
  // Lire la valeur des inter filtrés :
  int value1 = inter1.read();
  int value2 = inter2.read();
  int value3 = eclair.read();

  ScheduleTable::update();
  SlowMotionServo::update();

  // ici on calcule actionPN en fonction de inter1 et inter2
    if ((value1==HIGH) && (value2==LOW))
    {
      actionPN=2;
    }
    else if ((value1==LOW) && (value2==HIGH))
    {
      actionPN=1;
    }
    else {
      actionPN=0;
    }
          Serial.print("inter 1  :  ");
          Serial.print(value1);
          Serial.print("  inter2 :  ");
          Serial.print(value2);
          Serial.print("  actionPN  :  ");
          Serial.print(actionPN);
          Serial.print("  prevActionPN  :  ");
          Serial.print(prevActionPN);
          Serial.print("  Target avant :  ");
          Serial.print(target);

 
  // Code pour gérer le mouvement des barrières
    switch (actionPN) // début du switch case de pilotage des barrières
        {
          case 0: // on ouvre les barrières
              if (actionPN != prevActionPN) {target = 1.0; prevActionPN=actionPN;}
              break;
          case 1: // on ferme les barrières avec sonnerie
              if (actionPN != prevActionPN) ouvreSonne.start(1);
                digitalWrite(pinSonne,sonne); // allumage d'une led qui visualise l'impulsion de déclenchement de la sonnerie
                prevActionPN=actionPN;
               break;
          case 2: // on ferme les barrières sans sonnerie
              if (actionPN != prevActionPN) {target = 0.0; prevActionPN=actionPN;}
              break;
          } // fin du switch case de pilotage des barrières

          Serial.print("  target après :  ");
          Serial.print(target);
          Serial.print("  Sonne  :  ");
          Serial.println(sonne);
    if (servoPN.isStopped()) {
      servoPN.goTo(target);
    }
  // Code pour gérer les séquences d'éclairage
    if ((value3 != memoireEclair) && (value3 == LOW)) cycleEclair++;
    memoireEclair = value3;
    if (cycleEclair > 7) cycleEclair = 0;
   
    switch (cycleEclair)  { // début du switch sur cycleEclair
    case 0: // on n'allume rien
      analogWrite(pinLed0, 0);
      analogWrite(pinLed1, 0);
      analogWrite(pinLed2, 0);
      analogWrite(pinLed3, 0);
      break;
    case 1: // on allume Led0
      analogWrite(pinLed0, pwmLed0);
      break;
    case 2: // on garde Led0 et on allume Led1
      //analogWrite(pinLed0, 0);
      analogWrite(pinLed1, pwmLed1);
      break;
    case 3: // on garde Led0, Led1 et on allume Led2 en plus
      // analogWrite(pinLed1, 0);
      analogWrite(pinLed2, pwmLed2);
      break;
    case 4: // on garde Led0, on éteint Led1 et on garde Led2
      analogWrite(pinLed1, 0);
            break;
    case 5: // on gerde Led0 et Led2, on allume Led3 en plus
      analogWrite(pinLed3, pwmLed3);
      break;
    case 6: // on garde Led0 et Led3, on éteint Led2
      analogWrite(pinLed2, 0);
      break;
    case 7: // on garde Led1, on éteint Led3
      analogWrite(pinLed3, 0);
      break;
  } // fin du switch sur cycleEclair
}
Titre: Re : Arduino pilotage PN37
Posté par: Dominique Donnat le avril 05, 2016, 12:27:46 pm
Mon module son externe, c'est celui-ci ou un très similaire :
http://www.ebay.fr/itm/LSM-01b-Module-Passage-a-niveau-/252205188851?hash=item3ab899c6f3

Je viens de voir que le "fabricant" propose un module d'interface pour déclenchement par autre chose, mais ça n'existait pas quand je l'ai acheté, et en plus on ne le trouve pas sur son site. Et puis, la commande étant une simple mise à la masse d'une entrée, il n'y en a pas vraiment besoin.
Titre: Re : Arduino pilotage PN37
Posté par: Jean-Luc le avril 05, 2016, 01:10:56 pm
Bonjour,

Dans la description du module sonnerie, je vois qu'il y a deux entrées pour démarrer et éteindre la sonnerie. Ça ne colle pas avec ton explication.
Titre: Re : Arduino pilotage PN37
Posté par: Dominique Donnat le avril 05, 2016, 02:52:14 pm
Si si, sur mon module il y a bien deux entrées, qui sont chacune une mise à la masse :
- l'une lance la lecture intégrale de l'enregistrement son, qui dans mon cas fait 25 secondes, trop long pour moi. Une fois la lecture lancée, on ne peut pas l'arrêter,
- l'autre est un flip flop : une impulsion lance, la suivante l'arrête. C'est celle que j'utilise pour maîtriser la durée de sonnerie.

Par ailleurs, en trackant le fonctionnement de mon programme, je mesure une loop de 128 millisecondes. Ça me semble bien long, et du coup ça fait apparaître des saccades dans le mouvement du servo. À la lecture de mon code, vois-tu une anomalie qui expliquerait cette durée ?

Autre info : j'ai utilisé un optocoupleur pour isoler le module sonore de l'arduino, mais je les alimente par la même source primaire de 9 ou 10V. De fait, ils ont donc une masse commune. Est-ce gênant ? Le câblage de l'opto est identique à celui décrit dans le manuel du kit arduino, similaire à cette image, http://sdz-upload.s3.amazonaws.com/prod/upload/optocoupler_sc%C3%A9ma1.jpg avec la connection des pins 5 et 6 à l'entrée de commande et à la masse du module sonore.

Dom

Titre: Re : Re : Arduino pilotage PN37
Posté par: Jean-Luc le avril 05, 2016, 03:08:24 pm
Si si, sur mon module il y a bien deux entrées, qui sont chacune une mise à la masse :
- l'une lance la lecture intégrale de l'enregistrement son, qui dans mon cas fait 25 secondes, trop long pour moi. Une fois la lecture lancée, on ne peut pas l'arrêter,
- l'autre est un flip flop : une impulsion lance, la suivante l'arrête. C'est celle que j'utilise pour maîtriser la durée de sonnerie.

Mais ce n'est pas ce que je lis dans leur descriptif :

Citer
3.Mode automatique avec 2 ILS (Interrupteur reed):
Le son est déclenché par un ILS et éteint par un deuxième ILS. Le son est restitué jusqu'à il est éteint par ILS n°2.

Donc la première entrée démarre le son, la seconde l'arrête. (on passera sur la concordance des temps  ;D)

Citer
Par ailleurs, en trackant le fonctionnement de mon programme, je mesure une loop de 128 millisecondes. Ça me semble bien long, et du coup ça fait apparaître des saccades dans le mouvement du servo. À la lecture de mon code, vois-tu une anomalie qui expliquerait cette durée ?

Oui, l'envoi d'environ 120 à 140 caractères sur la ligne série à 9600 bauds. Disons 1200 bits = 125ms

Citer
Autre info : j'ai utilisé un optocoupleur pour isoler le module sonore de l'arduino, mais je les alimente par la même source primaire de 9 ou 10V. De fait, ils ont donc une masse commune. Est-ce gênant ? Le câblage de l'opto est identique à celui décrit dans le manuel du kit arduino, similaire à cette image, http://sdz-upload.s3.amazonaws.com/prod/upload/optocoupler_sc%C3%A9ma1.jpg avec la connection des pins 5 et 6 à l'entrée de commande et à la masse du module sonore.

Ça n'est pas utile je pense, tu peux connecter directement la sortie de l'Arduino. N'oublie pas de réunir les masses.
Titre: Re : Re : Re : Arduino pilotage PN37
Posté par: Dominique Donnat le avril 05, 2016, 05:10:41 pm
Citation de: Jean-Luc
Mais ce n'est pas ce que je lis dans leur descriptif :
Citer
3.Mode automatique avec 2 ILS (Interrupteur reed):
Le son est déclenché par un ILS et éteint par un deuxième ILS. Le son est restitué jusqu'à il est éteint par ILS n°2.
J'ai écrit "similaire à ... ". À l'évidence, ils ont ou ont eu plusieurs fabrications. Le mien, je l'ai en main et il fonctionne comme je l'ai décrit.


Citation de: Jean-Luc
Citer
.../... une loop de 128 millisecondes.
Oui, l'envoi d'environ 120 à 140 caractères sur la ligne série à 9600 bauds. Disons 1200 bits = 125ms
Bon, ça disparaîtra à la fin. OK.

Citation de: Jean-Luc
Citer
.../... un optocoupleur pour isoler le module sonore de l'arduino,
Ça n'est pas utile je pense, tu peux connecter directement la sortie de l'Arduino. N'oublie pas de réunir les masses.
Je vais essayer, il suffit d'inverser les états HIGH et LOW par rapport à la version avec opto. Mais je ne suis pas électronicien chevronné, n'y a-t-il pas un risque à relier l'entrée du module sonore au +5V arduino ?

En tout cas merci de tes explications et de tes conseils.
Titre: Re : Re : Re : Re : Arduino pilotage PN37
Posté par: Jean-Luc le avril 05, 2016, 05:39:44 pm
J'ai écrit "similaire à ... ". À l'évidence, ils ont ou ont eu plusieurs fabrications. Le mien, je l'ai en main et il fonctionne comme je l'ai décrit.

Ok, donc le problème vient d'ailleurs.

Citer
Je vais essayer, il suffit d'inverser les états HIGH et LOW par rapport à la version avec opto. Mais je ne suis pas électronicien chevronné, n'y a-t-il pas un risque à relier l'entrée du module sonore au +5V arduino ?

Je suppose que l'entrée de commande a une résistance de pullup sinon quand l'ILS ne colle pas l'entrée flotterait.

De ce que je vois sur la carte beige : 4 diodes pour redresser une tension alternative accessoire, 2 condensateur chimique qui doivent normalement se trouver autour d'un régulateur. Je parie que le boitier noir qui ressemble à un transistor est un régulateur faible puissance (100mA). regarde ce qui est inscrit sur la face plate, 78L05 ?

Si tu mets le module sonore seul, que tu l'alimentes et que tu mesures la tension sur cette entrée, qu'y a-t-il ? 
Titre: Re : Arduino pilotage PN37
Posté par: Dominique Donnat le avril 05, 2016, 05:57:59 pm
Oui, il y a un régulateur au dos de la carte, c'est bien un 78M05. Je lis 4,70 V sur l'entrée hors fonctionnement

En fait, en regardant mieux, mon module a l'air conforme à la description. Il y a 3 entrées :
- entrée 1 : lance la lecture complète du fichier son,
- entrée 2 (celle que j'utilise) : flip / flop tel que décrit
- entrée 3 : le son joue tant que l'entrée est mise à la masse. Et je viens de découvrir qu'une impulsion à la masse sur entrée 3 stoppe le son si on l'a lancé par l'entrée 2 ou l'entrée 1 !

Je vais quand même essayer un pilotage direct depuis l'arduino si tu penses que c'est électriquement compatible.
Titre: Re : Arduino pilotage PN37
Posté par: Jean-Luc le avril 05, 2016, 06:07:48 pm
Je ferais comme ça pour commander cette entrée directement :

Tu écrits 0 dans sur la pin alors qu'elle est programmée en entrée (dans setup) avec digitalWrite. Quand tu veux faire un pulse à LOW, tu la programmes en sortie avec pinMode puis en entrée toujours avec pinMode. De cette manière tu n'imposes jamais 5V sur l'entrée du module son.
Titre: Re : Arduino pilotage PN37
Posté par: Dominique Donnat le avril 05, 2016, 06:39:34 pm
J'ai réorganisé le code concerné. Est-ce que j'ai bien compris ?

#include <ScheduleTable.h>
// Création des objets
    ScheduleTable ouvreSonne(5,18000);  // Création de la table

// déclaration des constantes
    const byte pinSonne=8;  // affecte l'E/S 8 au pilotage de la sonnerie sans optocoupleur

// déclaration des variables   
    float target = 0.0; // La cible du servo : target = 0.0 pour barrières fermées.
    byte actionPN=0; // variable d'état pour le switchcase de pilotage des barrières
    byte prevActionPN=0; // l'état précédent de actionPN
   
// fonctions pour SheduleTable
void pulseOn()
    {
      pinMode(pinSonne, OUTPUT);
      digitalWrite(pinSonne, LOW);
    }

void pulseOff()
    {
     pinMode(pinSonne, INPUT);
     digitalWrite(pinSonne, LOW);
    }
void basculeTarget()
    {
      target = 1.0 - target;
    }
void setup() {
  // put your setup code here, to run once:
    pinMode(pinSonne, INPUT); // déclare pinSonne comme entrée à l'init;
    digitalWrite(pinSonne,LOW); // écrit 0 sur pinSonne
   
// Table des événements de ouvreSonne: impulsions de 1000 ms à t=000 et t = 16000, et assigne la valeur 0.0 à target à t = 5000
    ouvreSonne.at(000,pulseOn);
    ouvreSonne.at(1000,pulseOff);
    ouvreSonne.at(5000,basculeTarget);
    ouvreSonne.at(16000,pulseOn);
    ouvreSonne.at(17000,pulseOff);

}

void loop() {
  // put your main code here, to run repeatedly:

 // Code pour gérer le mouvement des barrières
    switch (actionPN) // début du switch case de pilotage des barrières
        {
          case 0: // on ouvre les barrières
              if (actionPN != prevActionPN) {target = 1.0; prevActionPN=actionPN;}
              break;
          case 1: // on ferme les barrières avec sonnerie
              if (actionPN != prevActionPN) ouvreSonne.start(1);
                // digitalWrite(pinSonne,sonne); cette ligne ne semble plus utile, c'est maintenant dans les fonctions
                prevActionPN=actionPN;
               break;
          case 2: // on ferme les barrières sans sonnerie
              if (actionPN != prevActionPN) {target = 0.0; prevActionPN=actionPN;}
              break;
          } // fin du switch case de pilotage des barrières

}
Titre: Re : Arduino pilotage PN37
Posté par: Jean-Luc le avril 05, 2016, 06:43:10 pm
Vérifie avec une LED mais je pense que le digitalWrite(pinSonne, LOW); dans pulseOn() et pulseOff() est de trop (il ne sert pas mais il ne fait pas de mal)

Sinon ça me semble ok
Titre: Re : Arduino pilotage PN37
Posté par: Dominique Donnat le avril 06, 2016, 09:40:32 am
Bon, pas encore ça. Avec une LED, ça fonctionne (en inverse, évidemment), mais en liaison avec le module son,rien ne se passe. Je dois encore chercher le pourquoi du comment.

Je vais câbler le plan B (commande manuelle du module son par bouton-poussoir en façade) et reprendre tout cela après mon expo de mi-mai, vu tout ce qu'il me reste à faire d'ici-là sur le réglage fin du mouvement des barrières, et tout le décor. 5 semaines ne seront pas de trop.

Merci de ton aide, Jean-Luc.