Auteur Sujet: bibliothèque Commanders+Accessoires  (Lu 316 fois)

bagou91

  • Newbie
  • *
  • Messages: 49
    • Voir le profil
bibliothèque Commanders+Accessoires
« le: octobre 17, 2017, 10:34:31 pm »
Bonsoir,

J'ai repris les exemples fournis dans la bibliothèque Accessoires pour actionner un aiguillage type Jouef 2 solenoïdes (via ULN2003).
Je tente de l'actionner avec un bouton poussoir, ou bien un interrupteur et hélas ça ne se passe pas comme prévu  :'(

voici le code:
#include <Commanders.h>
#include "Accessories.h"

ButtonsCommanderPush push;
ButtonsCommanderSwitch boutonAiguillageGauche;

// Accessories
AccessoryMotorTwoWays aiguille;

// Drivers
PortTwoPins port;

#define DCCID_DROIT   DCCINT(20, 0)
#define DCCID_DEVIE   DCCINT(20, 1)

void ReceiveEvent(unsigned long inId, COMMANDERS_EVENT_TYPE inEvent, int inData)
{
  COMMANDERS_PRINT_EVENT(inId, inEvent, inData);
}

void setup()
{
  Serial.begin(115200);
 
  Commanders::begin(ReceiveEvent, LED_BUILTIN);
  Accessories::begin();
 
  I2CCommander.begin(0x10); // I2C Slave identifier.
 
  // Setup of ports
  port.begin(4, 5, DIGITAL);

  // Accessories setups
  push.AddEvent(DCCID_DEVIE);
  push.begin(DCCID_DROIT,8);
 
  boutonAiguillageGauche.AddEvent(DCCID_DROIT, 6);
  boutonAiguillageGauche.AddEvent(DCCID_DEVIE, 7);
  boutonAiguillageGauche.begin();
 
  aiguille.beginTwoWays(&port, DCCID_DROIT, DCCID_DEVIE, 255, 250);
}

void loop()
{
  unsigned long id = Commanders::loop();
 
  if (id != UNDEFINED_ID)
  {
    // Renvoie l'événement reçu de Commanders, vers les accessoires...
    Accessories::RaiseEvent(id, (ACCESSORIES_EVENT_TYPE) Commanders::GetLastEventType(), Commanders::GetLastEventData());
  }
 
  Accessories::loop();
}

j'ai activé le mode debug pour voir ce qu'il se passe sur la console série:
au démarrage:
Commanders V1.40
Developed by Thierry Paris.
(c) Locoduino 2016-2017

*** Setup Commanders started.

Accessories V1.0
Developed by Thierry Paris.
(c) Locoduino 2016-2017

*** Setup Accessories started.
*** Setup Commanders Finished.
Commander event : Address : 20 / MOVE ON
Commander event : Address : 10020 / MOVE OFF
*** Setup Accessories Finished.

Si j'actionne mon interrupteur, rien ne se passe et aucune réaction de la ledbuiltin, ou des sorties vers l'aiguillage.

Si j'appuie sur le bouton poussoir:
Commander event : Address : 10020 / MOVEPOSITIONID
ButtonsCommanderButton id:10020 selected !
Same position : Cant move !
Same position : Cant move !
Same position : Cant move !
Same position : Cant move !
Same position : Cant move !
Same position : Cant move !
....
et au bout de plusieurs dizaine de lignes du même message, l'arduino redémarre (il n'a pas dû aimé :()

Pouvez vous me venir en aide ?

Merci.

PS: quand le TCO local fonctionnera, je voudrais envoyer les ordres via I2C avec un autre Arduino.

Thierry

  • Global Moderator
  • Sr. Member
  • *****
  • Messages: 300
    • Voir le profil
Re : bibliothèque Commanders+Accessoires
« Réponse #1 le: octobre 17, 2017, 11:31:42 pm »
C'est une erreur de ma part, corrigée dans la version 1.01 disponible sur Framagit : https://framagit.org/locoduino.org/Accessories/blob/master/Accessories.zip.

bagou91

  • Newbie
  • *
  • Messages: 49
    • Voir le profil
Re : bibliothèque Commanders+Accessoires
« Réponse #2 le: octobre 18, 2017, 07:26:53 pm »
Thierry,

Je viens de récupérer tes nouvelles sources: ça fonctionne en TCO local !   :D
sortie console:
Citer
Commander event : Address : 20 / MOVEPOSITIONID
ButtonsCommanderButton id:20 selected !
4 / 5 PortTwoPins MoveRightDir()
4 / 5 PortTwoPins MoveStop()
Commander event : Address : 10020 / MOVEPOSITIONID
ButtonsCommanderButton id:10020 selected !
4 / 5 PortTwoPins MoveLeftDir()
4 / 5 PortTwoPins MoveStop()

maintenant je m'attaque à l'envoi/réception par I2C et je rencontre à nouveau des petits soucis:
j'ai repris l'exemple I2CSender.ino de Commanders.
j'ai ajouté quelques lignes de debug dans I2CCommander.cpp pour me sortir les données reçues par I2C.
au 1er appui sur un bouton-poussoir, la sortie d'aiguille réagit bien:
Citer
I2CCommander::ReceiveHandler: chars read : 7
data received from I2C: 20 0 0 0 5 0 0
Commander event : Address : 20 / MOVEPOSITIONID
4 / 5 PortTwoPins MoveRightDir()
4 / 5 PortTwoPins MoveStop()

par contre un second appui sur BP ne donne rien sur la sortie:
Citer
I2CCommander::ReceiveHandler: chars read : 7
data received from I2C: 20 0 0 0 5 1 0
Commander event : Address : 20 / MOVEPOSITIONID
Same position : Cant move !

coté sketch I2CSender.ino, je met juste la commande envoyée:
1er appui: Commanders_I2C_SendEvent(0x10, 20, COMMANDERS_EVENT_MOVEPOSITIONID, 0);
2eme appui:  Commanders_I2C_SendEvent(0x10, 20, COMMANDERS_EVENT_MOVEPOSITIONID, 1);

si par contre pour le 2eme appui je met:
 Commanders_I2C_SendEvent(0x10, 10020, COMMANDERS_EVENT_MOVEPOSITIONID, 1);
ma sortie d'aiguille réagit bien et je peux faire bouger correctement l'aiguillage à chaque appui sur le BP.

Mon interrogation:
Je pensais que le dernier argument de Commanders_I2C_SendEvent() indiquait la sous-fonction à activer sur l'ID indiqué.

De mon point de vue, je trouve bizarre en TCO que l'appui sur le BP fasse changer l'adresse reçue par CommanderEvent,
à moins qu'il n'y ait plus de notion d'adresse mais seulement des ID unique lier aux événements ajouter aux boutons...
mais pourquoi alors déclarer comme ceci les 2 actions que le BP gère:
push.AddEvent(DCCINT(20,1));
push.begin(DCCINT(20,0),PIN_BP);

Peux tu m'éclaircir mon interrogation ?
Merci.
« Modifié: octobre 18, 2017, 07:33:28 pm par bagou91 »

Thierry

  • Global Moderator
  • Sr. Member
  • *****
  • Messages: 300
    • Voir le profil
Re : bibliothèque Commanders+Accessoires
« Réponse #3 le: octobre 18, 2017, 08:31:47 pm »
Je vois que tu progresses, c'est bien. La différence vient de la non utilisation de DCCINT du côté de l'envoyeur. Parce que DCCINT(20,1) donne 10020 ! C'est pour ça que ça marche quand tu mets 10020 du côté de l'envoyeur, interprété ensuite à la réception comme '20,1' . Pour être cohérent, tu devrais ajouter la macro DCCINT trouvée dans DccCommander.hpp, au source de l'envoyeur et l'utiliser pour définir le message à envoyer :

#define DCCINT(id, acc)      ((acc) * 10000UL + (id))

Commanders_I2C_SendEvent(0x10, DCCINT(20,0), COMMANDERS_EVENT_MOVEPOSITIONID, 0);
Commanders_I2C_SendEvent(0x10, DCCINT(20,1), COMMANDERS_EVENT_MOVEPOSITIONID, 0);

Le dernier argument n'a pas de sens pour un moteur à deux positions, c'est l'id de l'événement qui fait le boulot.

Dernier point, je n'avais pas imaginé que quelqu'un ferait un appel à AddEvent avant begin ! Mais je constate avec plaisir que ça marche quand même...

Pour tenter de répondre à ta question que je crains de ne pas avoir totalement comprise, un bouton poussoir dispose d'une liste d'événements. Le begin pose le premier, les AddEvent suivants en ajoutent (ou l'inverse  8) ). Le fait d'appuyer sur ce bouton va envoyer le premier événement. L'appui suivant enverra l'événement suivant, et ainsi de suite jusqu'à la fin de la liste. A ce moment là on recommence au début.

bagou91

  • Newbie
  • *
  • Messages: 49
    • Voir le profil
Re : bibliothèque Commanders+Accessoires
« Réponse #4 le: octobre 18, 2017, 08:46:36 pm »
OK je comprend mieux d'où vient ce "10020" que m'affiche la sortie console.

Je vais faire les modifications pour prendre en compte cette macro.

J'avais bien compris la liste d'événements associé au BP.
Ma dernière question (interrogation) est résolue par ce que tu m'as répondu sur la macro :)

bagou91

  • Newbie
  • *
  • Messages: 49
    • Voir le profil
Re : bibliothèque Commanders+Accessoires
« Réponse #5 le: octobre 18, 2017, 10:03:34 pm »
J'ai réussi à envoyer les commandes correctement par I2C  :D
en PJ le sketch.

Maintenant j'aimerai réutiliser le principe de la librairie Accessoire au niveau des déclarations des boutons et des ID d'événements liés.
Ceci afin de rendre plus propre et plus structurer le code.

Seulement à chaque fois que j'utilise ma fonction d'envoi de trame I2C, l'arduino freeze et ne répond plus et rien ne se passe au niveau réception.
Sur la console, la sortie est incomplète, par exemple:
Citer
10020 5 0
Commander event : Address : 10020 / MOVEPOSITIONID
I2C send Commanders event: 10020/5/0
I2C sender

Voici le code:
#include <Commanders.h>
#include "Accessories.h"
#include <Wire.h>

ButtonsCommanderPush push;

#define CONSOLE

#define ADDR_I2C 0x10

#define DCCID_DROIT   DCCINT(20, 0)
#define DCCID_DEVIE   DCCINT(20, 1)

bool Commanders_I2C_SendEvent(uint8_t inID, unsigned long inEventID, COMMANDERS_EVENT_TYPE inEventType, int inEventData)
{
#ifdef CONSOLE
  Serial.print(F("I2C send Commanders event: "));
  Serial.print(inEventID, DEC);
  Serial.print(F("/"));
  Serial.print((char) ('0' + (char)inEventType));
  Serial.print(F("/"));
  Serial.println(inEventData, DEC);
#endif
 
  Wire.beginTransmission(inID);

  int nb = Wire.write((const uint8_t *)&inEventID, sizeof(unsigned long));
  nb += Wire.write((char )inEventType);
  nb += Wire.write((const uint8_t *)&inEventData, sizeof(int));

#ifdef CONSOLE
  Serial.print(F("I2C sender : nb byte transmitted : "));
  Serial.println(nb, DEC);
#endif

  Wire.endTransmission(true);

  return true;
}

void ReceiveEvent(unsigned long inId, COMMANDERS_EVENT_TYPE inEvent, int inData)
{
  COMMANDERS_PRINT_EVENT(inId, inEvent, inData);
  //if (inId != UNDEFINED_ID){
  //  Commanders_I2C_SendEvent(ADDR_I2C, inId, inEvent, inData);
  //}
}

void setup()
{
  Serial.begin(115200);
 
  Commanders::begin(ReceiveEvent, LED_BUILTIN);
  Accessories::begin();
 
  // Setup of the buttons, one by accessory
  push.AddEvent(DCCINT(20, 1));
  push.begin(DCCINT(20, 0),4);
}

void loop()
{
  unsigned long id = Commanders::loop();
 
  if (id != UNDEFINED_ID)
  {
    //Commanders_I2C_SendEvent(ADDR_I2C, id, Commanders::GetLastEventType(), Commanders::GetLastEventData());
    // Renvoie l'événement reçu de Commanders, vers les accessoires...
    Accessories::RaiseEvent(id, (ACCESSORIES_EVENT_TYPE) Commanders::GetLastEventType(), Commanders::GetLastEventData());
  }
 
  Accessories::loop();
}

J'ai laissé commenter les endroits où j'utilise la fonction d'envoi I2C pour montrer les divers endroits ou j'ai testé sans succès.

Si tu as une idée du problème, je suis preneur :)

Merci de ton aide.

Thierry

  • Global Moderator
  • Sr. Member
  • *****
  • Messages: 300
    • Voir le profil
Re : bibliothèque Commanders+Accessoires
« Réponse #6 le: octobre 20, 2017, 09:20:27 am »
Pour moi, le problème vient de l'utilisation d'Accessories ici qui n'est pas justifié. Le rôle d'Accessories, si on simplifie au maximum, est de recevoir des événements qu'elle va traduire en niveaux HIGH/LOW sur les broches de l'Arduino. Ma version de ton code:

#include <Commanders.h>
#include <Wire.h>

ButtonsCommanderPush push;

#define CONSOLE

#define ADDR_I2C 0x10

#define DCCID_DROIT   DCCINT(20, 0)
#define DCCID_DEVIE   DCCINT(20, 1)

bool Commanders_I2C_SendEvent(uint8_t inID, unsigned long inEventID, COMMANDERS_EVENT_TYPE inEventType, int inEventData)
{
#ifdef CONSOLE
  Serial.print(F("I2C send Commanders event: "));
  Serial.print(inEventID, DEC);
  Serial.print(F("/"));
  Serial.print((char) ('0' + (char)inEventType));
  Serial.print(F("/"));
  Serial.println(inEventData, DEC);
#endif
 
  Wire.beginTransmission(inID);

  int nb = Wire.write((const uint8_t *)&inEventID, sizeof(unsigned long));
  nb += Wire.write((char )inEventType);
  nb += Wire.write((const uint8_t *)&inEventData, sizeof(int));

#ifdef CONSOLE
  Serial.print(F("I2C sender : nb byte transmitted : "));
  Serial.println(nb, DEC);
#endif

  Wire.endTransmission(true);

  return true;
}

void setup()
{
  Serial.begin(115200);
 
  Commanders::begin(LED_BUILTIN);
 
  // Setup of the buttons, one by accessory
  push.begin(DCCINT(20, 0),4);
  push.AddEvent(DCCINT(20, 1));
}

void loop()
{
  unsigned long id = Commanders::loop();
 
  if (id != UNDEFINED_ID)
  {
    Commanders_I2C_SendEvent(ADDR_I2C, id, Commanders::GetLastEventType(), Commanders::GetLastEventData());
  }
}

Le problème du plantage vient peut être de l'utilisation d'Accessories sans aucun accessoires déclaré !

bagou91

  • Newbie
  • *
  • Messages: 49
    • Voir le profil
Re : bibliothèque Commanders+Accessoires
« Réponse #7 le: octobre 20, 2017, 07:03:42 pm »
bonsoir,

Je viens de tester en enlevant la partie Accessoires:
Toujours le même freeze de l'arduino lorsque j'appuie sur le bouton poussoir.

Thierry

  • Global Moderator
  • Sr. Member
  • *****
  • Messages: 300
    • Voir le profil
Re : bibliothèque Commanders+Accessoires
« Réponse #8 le: octobre 22, 2017, 03:23:46 pm »
Je reproduis le freeze sur mon nano. Il semble qu'en réalité la fonction Wire.EndTransmission() attende indéfiniment un accusé de réception ou similaire depuis le bus. Ce qui n'arrive pas puisque, en tout cas chez moi, il n'y a rien au bout...

bagou91

  • Newbie
  • *
  • Messages: 49
    • Voir le profil
Re : bibliothèque Commanders+Accessoires
« Réponse #9 le: octobre 23, 2017, 10:09:46 am »
Sur ma plateforme de test, j'ai bien un device slave sur l'I2C: un arduino nano avec le sketch qui active un aiguillage (celui en début de ce sujet).
Avec le 1er sketch d'envoi I2C que j'ai fait (PJ du 18/10 22h03), cela fonctionne bien.

C'est en essayant d'associer la bibliothèque Commanders et l'envoi I2C avec la fonction récupérer dans l'exemple I2C_Sender que cela freeze.
En recherchant sur le net, je trouve beaucoup de sujets sur des problèmes de freeze similaire en I2C...

Je testerai ce soir avec une librairie I2C alternative et revérifierai le bon fonctionnement avec mon 1er sketch.

bagou91

  • Newbie
  • *
  • Messages: 49
    • Voir le profil
Re : bibliothèque Commanders+Accessoires
« Réponse #10 le: octobre 23, 2017, 09:27:36 pm »
bonsoir,

j'ai revérifié mes 2 sketchs:
dans celui intégrant la librairie Commanders, j'avais oublié Wire.begin() dans le setup()  :-[

Ca fonctionne bien à présent !  :D

je joint le sketch entier.