Voir les contributions

Cette section vous permet de consulter les contributions (messages, sujets et fichiers joints) d'un utilisateur. Vous ne pourrez voir que les contributions des zones auxquelles vous avez accès.


Sujets - Marc-Henri

Pages: [1] 2
1
Bonjour à tous,

Comme annoncé dans le sujet http://forum.locoduino.org/index.php?topic=98.msg8459#new, voici une présentation de mon réseau hivernal en N.

Description du réseau et des cartes de détection
Le réseau dans son état quasi actuel se présente comme suit. Il s'agit d'une gare sur une voie unique avec une gare cachée permettant le croisement.



Le réseau est découpé en zones comme suit:



  • GC1G: gare cachée 1 gauche
  • GC1D: gare cachée 1 droite
  • GC2G: gare cachée 2 gauche
  • GC2D: gare cachée 2 droite
  • L1: ligne
  • L2: ligne
  • G1: gare voie 1
  • G1: gare voie 2

Le réseau est en DCC. Toutes les zones sont équipées pour détecter les trains par consommation de courant. Les zones des 2 gares sont en plus équipées de diodes pour le freinage ABC. Les aiguilles A1 à A5 sont actionnées par une carte à 8 relais.

Les cartes de détection se composent de diodes pour d'une part assurer la détection de la consommation de courant, d'autre part générer l'asymétrie du signal DCC requise pour le freinage. Ces diodes supplémentaires sont commutées par des relais.



La tension de détection actionne un optocoupleur qui génère le signal logique. Le réseau fonctionnant en DCC, la détection est mono-alternance, c'est ensuite par logiciel que l'on assure la continuité de la détection. L'Arduino, un Mega, tourne suffisamment vite pour ne rien manquer.



Programme
La structure du programme s'inspire des principes décrits ici: https://paulmurraycbr.github.io/ArduinoTheOOWay.html.

Classe Tache
La première classe définit la notion de tâche.

class Tache
{
public:
        static Tache *pListeTaches;
        Tache ();
        static void setupTaches (void);
        static void loopTaches (void);

        virtual void setup (void) = 0;
        virtual void loop (void) = 0;

private:
        Tache *pProchaineTache;
};

Toutes les autres classes du projet héritent de Tache et doivent définir les méthodes setup et loop. Le corps de cette classe est:

#include <Arduino.h>

#include "Tache.h"


Tache *Tache::pListeTaches = NULL;

Tache::Tache ()
{
        pProchaineTache = pListeTaches;
        pListeTaches = this;
} // Tache


void Tache::setupTaches (void)
{
        for (Tache *p = pListeTaches; p; p = p->pProchaineTache)
        {
                p->setup ();
        } // for
} // setupTaches


void Tache::loopTaches (void)
{
        for (Tache *p = pListeTaches; p; p = p->pProchaineTache)
        {
                p->loop ();
        } // for
} // loopTaches

À chaque appel du constructeur, la nouvelle tâche est ajoutée en tête de la liste de tâches. Les méthodes de classe setupTaches et loopTaches appelées respectivement dans les fonctions principales setup et loop parcourent cette liste pour appeler les méthodes virtuelles redéfinies par les classes descendantes de celle-ci.

Cette technique est utilisée entre autres dans les bibliothèques Commanders et Accessories de Thierry et dans ScheduleTable, SlowMotionServo et LightDimmer de Jean-Luc.

Classe Led
Il est toujours intéressant de vérifier visuellement que l'Arduino ne s'est pas planté. Faire clignoter la led de la carte est un bon moyen de vérifier cela. Tant qu'elle clignote, aucune tâche ne bloque le processeur et tout va bien.

#include <stdint.h>

#include "Tache.h"

class LED: public Tache
{                   
public:
        LED (uint8_t xPin, uint32_t nxPeriode);
       
        void setup ();
        void loop ();

        void allumer (void);
        void eteindre (void);
        void clignoter (void);

private:
        const uint8_t   Pin;
        uint8_t         eEtat;
        const uint32_t  nPeriode;
        uint32_t        tDernier;
};

#include "LED.h"


#define E_OFF   0
#define E_ON    1
#define E_BLINK_ON      2
#define E_BLINK_OFF     3

LED::LED (uint8_t xPin, uint32_t nxPeriode) :
        Pin (xPin),
        nPeriode (nxPeriode) {}


void LED::setup (void)
{
        eEtat = E_OFF;
        pinMode (Pin, OUTPUT);
} // LED::setup


void LED::loop (void)
{
uint32_t nDeltaTemps;

        switch (eEtat)
        {
                case E_OFF:
                break;

                case E_ON:
                break;
               
                case E_BLINK_OFF:                       
                        nDeltaTemps = millis () - tDernier;
                        if (nDeltaTemps > nPeriode)
                        {
                                eEtat = E_BLINK_ON;
                                tDernier = millis ();
                        } // if
                break;

                case E_BLINK_ON:
                        nDeltaTemps = millis () - tDernier;
                        if (nDeltaTemps > nPeriode)
                        {
                                eEtat = E_BLINK_OFF;
                                tDernier = millis ();
                        } // if
                break;
        } // switch

        digitalWrite (Pin, (eEtat == E_ON) || (eEtat == E_BLINK_ON));
} // LED::loop


void LED::allumer (void)
{
        eEtat = E_ON;
} // LED::allumer


void LED::eteindre (void)
{
        eEtat = E_OFF;
} // LED::eteindre


void LED::clignoter (void)
{
        if (eEtat == E_OFF)
        {
                eEtat = E_BLINK_OFF;
                tDernier = millis ();
        }
        else if (eEtat == E_ON)
        {
                eEtat = E_BLINK_ON;
                tDernier = millis ();               
        } // if
} // LED::clignoter

Le constructeur reçoit le numéro de la pin et la période de clignotement en paramètre. Tout se passe principalement dans la méthode loop qui implante une machine d'états. On remarque l'importance de gérer le temps à l'aide de millis () et non avec delay (). Il est en effet important de ne pas bloquer dans cette fonction.

Les états possibles sont définis par des instructions #define plutôt qu'avec un enum. Le but était de s'assurer que les états soient codés dans une variable de type uint8_t. Je ne connaissais pas les enum class de C++ 11 et leur possibilité de spécifier le type sous-jacent lorsque j'ai commencé ce projet !

La led s'utilise comme suit dans le fichier .ino.

---
LED led_board (LED_BOARD, PER_CLIGN);
...
void setup ()
{
   ...
   Tache::setupTaches ();

   led_board.clignoter ();
} // setup

Le prochain post décrira les autres classes plus spécifiques à cette application.

Meilleures salutations.

Marc-Henri

2
Débuter / C++: objets membres d'une classe ?
« le: février 25, 2019, 07:48:35 am »
Bonjour à tous,

J'ai une classe GareCachee dans laquelle je souhaite inclure plusieurs instances d'une classe Zone afin de détecter les trains. Le constructeur de la classe Zone reçoit la pin d'entrée reliée à la zone de détection.

Ayant encore peu d'expérience avec les constructeurs C++, je me demande quelle est la meilleure manière de créer une telle structure.

Objets de classe Zone
class GareCachee
{
...
private:
    Zone zoneG;
    Zone zoneD;
};

Avec cette variante, comment appeler le constructeur Zone en lui passant une pin différente pour zoneG et zoneD ?

Références vers classe Zone
class GareCachee
{
public:
    GareCachee (Zone &xZoneG, Zone &xZoneD) : zoneG (xZoneG), zoneD (xZoneD) {}

private:
    Zone &zoneG;
    Zone &zoneD;
};
...

Zone zG (14);
Zone zD (15);
GareCachee gareCachee (zG, zD);

Cette approche fonctionne bien, mais on doit connaître les objets inclus avant l'appel du constructeur GareCachee.

Pointeurs de classe Zone
class GareCachee
{
public:
    GareCachee ()
    {
        pZoneG = new Zone (14);
        pZoneD = new Zone (15);
    }

private:
    Zone *pZoneG;
    Zone *pZoneD;
};

Ici on alloue dynamiquement les objets inclus. Une variante aurait été de les instancier hors de la classe et les passer en paramètre à une méthode différente du constructeur qui mettrait à jour pZoneG et pZoneD.


Quelle approche préconisez-vous ?

Un tout grand merci d'avance pour vos suggestions.
Bon début de semaine et meilleures salutations.

Marc-Henri

3
Débuter / Entrée au comportement erratique ?
« le: février 24, 2019, 09:50:39 pm »
Bonsoir à tous,

J'ai rencontré un problème bizarre avec un Arduino Mega 2560.

J'ai défini la pin A5 en INPUT_PULLUP, mais elle ne fonctionne pas. Lorsque sa voisine A4 est définie, j'obtiens des valeurs erratiques à la lecture numérique de A5. Heureusement, il reste des pins disponibles ce qui m'a permis de remplacer A5 par une autre afin de régler le problème. Je vais tester avec une autre carte Mega 2560 pour déterminer si c'est la pin ou un problème logiciel.

Est-ce un effet de bord dû à l'utilisation pourtant parfaitement légitime d'une entrée analogique en numérique ?

Qu'en pensez-vous ?

Merci de vos réponses, bon début de semaine et meilleures salutations.

Marc-Henri

4
Débuter / Carte Arduino plus visible ?
« le: juillet 09, 2018, 11:24:59 am »
Bonjour à tous,

Novice en Arduino ainsi qu'à tout ce qui touche au bootloader, j'ai une carte clone de Leonardo, soudain devenue invisible depuis l'IDE, même après un redémarrage de l'IDE et du PC. J'ai pu utiliser cette carte pendant quelques heures avant cet incident.

Dans les détails:

Environnement
  • PC sous Ubuntu 16.x.
  • IDE 1.8.5.]

Symptômes
  • Avant l'apparition du problème, la carte Leonardo était accessible via /dev/ttyACM0.
  • La carte n'est plus visible, le device /dev/ttyACM0 n'est plus dans la liste des devices (ls -al /dev/ttyA* ne retourne rien).

Vérifications effectuées
  • Changement du câble USB pour relier la carte Leonardo, toujours le même symptôme.
  • Branchement d'une carte clone de Mega, le device /dev/ttyACM0 est visible dans l'IDE, cela exclut donc un problème côté PC.
  • En ligne de commande: dmesg -w. Au branchement de la carte Leonardo, apparition du message unable to enumerate USB device on port.

Je conclus que c'est ma carte Leonardo qui est ko, du moins en ce qui concerne l'USB.

Suite...
  • Se pourrait-il que le bootloader soit corrompu ? Si oui, quelle fausse manip aurais-je pu faire ?
  • Quelles autres vérifications pourrais-je faire ?
  • J'ai un programmateur ICSP, je pourrais le brancher à la carte Leonardo et vérifier ce qu'il y a en mémoire avec avrdude.
  • Je prévois de racheter des cartes Arduino officielles... :)

Merci de votre retour d'expérience sur ce sujet.
Bon début de semaine et meilleures salutations.

Marc-Henri

5
Bonjour à tous,

Après 4 projets d'application des Attiny et Atmega en modélisme ferroviaire, programmés directement en C, je viens de me mettre à l'Arduino.  :)

J'ai l'intention d'en profiter pour me (re-)mettre au C++ pour le système de contrôle de mon nouveau réseau N. Cherchant sur le web, j'ai trouvé un article excellent sur la conception / réalisation de projets Arduino en C++. Je vais essayer cette approche très prochainement.

Voici l'article, en Anglais: https://paulmurraycbr.github.io/ArduinoTheOOWay.html. Je trouve particulièrement futé la création d'une liste d'objet lors de leurs constructions respectives pour ensuite automatiser l'exécution des fonctions setup et loop de chaque objet.

Comparé à la bibliothèque ScheduleTable de Jean-Luc, l'approche est un peu différente. Ici, chaque classe est responsable de gérer ses timeouts avec des appels à millis(), tandis que ScheduleTable centralise cette gestion.

Enfin, tout comme ScheduleTable, il s'agit ici de de multi-tâches non préemptif, aucune instruction bloquante n'est autorisée, surtout pas delay(). Chaque fonction doit s'efforcer de rendre la main le plus rapidement possible.

Meilleures salutations.

Marc-Henri

6
Débuter / Connecteurs câbles
« le: juin 21, 2018, 10:38:18 am »
Bonjour à tous,

Les connecteurs des cartes Arduino et des cartes périphériques, par exemple les cartes à relais, sont au pas de 2.54 mm, mâle ou femelle.

Comment réalisez-vous les câbles de liaison entre ces cartes ?
  • Câbles tout faits ?
  • Réalisation des câbles, à l'aide de connecteurs Dupont ?
  • Autre technique ?

Je n'avais jusqu'alors pas ce problème car toutes mes réalisation étaient en veroboard d'où je partais sur des dominos. Avec l'achat de cartes Arduino et relais, je suis confronté à ce besoin.

Merci d'avance de vos réponses.
Meilleures salutations de Suisse romande.

Marc-Henri

7
Shields et Modules / Connecteurs pour Arduino ?
« le: février 11, 2018, 05:27:08 pm »
Bonjour à tous,

Bien que nous soyons dans la section Shields et Modules, j'aimerais savoir ce que vous utilisez pour connecter des cartes de fabrication maison à un Arduino ?

De telles cartes n'étant pas construites comme un shield mais par exemple en Veroboard, sans possibilité de les enficher sur l'Arduino.

Bon début de semaine à tous.

8
Vos projets / Interface SPI
« le: novembre 02, 2017, 01:00:56 pm »
Bonjour à tous,

L'architecture du système de contrôle de mon nouveau projet de réseau N n'est pas encore complètement fixée. Bien que s'agissant d'un petit réseau, il y a déjà pas mal d'entrées-sorties à prévoir. J'ai évalué plusieurs solutions:

Centralisation et extension d'entrées-sorties
  • Un Arduino équipé d'un Atmeda2650 pour avoir beaucoup d'E/S.
  • Un Atmega32 doté de 32 E/S en boîtier PDIP.
  • Extension d'E/S à l'aide de circuits MCP23008 offrant 8 ports E/S, accessibles en I2C.

Répartition des fonctions en plusieurs microcontrôleurs
  • Un Atmega328 comme gestionnaire principal et un Attiny2313 en périphérie pour gérer les aiguillages. Nécessite une communication entre les 2.
  • Deux cartes identiques avec chacune un Atmega (modèle à préciser) pour gérer la gare cachée d'une part, la gare visible d'autre part. Les 2 cartes peuvent être identiques, mais tous les composants ne seront pas montés sur chaque carte. Communication à prévoir entre les 2 cartes.

La dernière solution me paraît intéressante car une seule carte est à concevoir, de plus elle reviendra moins chère à faire fabriquer à l'unité puisqu'il y en aura 2.

Pour la communication, l'interface SPI me semble plus facile à mettre en oeuvre que l'I2C et bien adaptée pour une distance entre les cartes de 20-30 cm. Je pense mettre un connecteur ICSP qui permettra la programmation du microcontrôleur ou la connexion avec l'autre carte. Je serai ainsi certain de ne rien perturber en programmant le microcontrôleur.

La carte gérant la gare visible aura un rôle de maître au sens SPI tandis que la carte de la gare cachée sera esclave.

Avez-vous de l'expérience avec l'interface SPI et qu'en pensez-vous ?

Meilleures salutations.

9
Bonjour à tous,

Lorsqu'un logiciel doit gérer plusieurs activités en parallèle, il s'avère intéressant de le structurer en tâches donnant l'illusion de se dérouler en parallèle. Plusieurs approches sont possibles et j'aimerais partager l'une d'elles, tout à fait applicable aux microcontrôleurs et à l'Arduino.

Un thread, traduction du mot "fil" ou une tâche est une suite d'instructions. Sur un système à processeur unique, les threads donnent l'illusion de se dérouler en parallèle. En réalité, lorsqu'un thread rend la main, un autre thread continue son exécution. Lorsque le premier thread est à nouveau activé, il reprend l'exécution des instructions où il avait rendu la main.

Un protothread est un thread ultra simplifié, mécanisme dont on trouve plusieurs réalisations. L'une d'elles, décrite dans http://dunkels.com/adam/pt/ est facile à mettre en oeuvre. Je l'ai décrite sur mon blog à cette adresse https://savignyexpress.wordpress.com/2014/01/17/gare-du-reseau-dun-ami-programmation/.

Ma première utilisation des protothreads est la commande des 2 PN de mon réseau N. 3 protothreads assurent simultanément:
  • la commande des servos qui actionnent les 2 barrières de l'un des PN.
  • le clignotement des signaux du même PN.
  • le clignotement des signaux d'un 2ème PN, lui sans barrières.

Voir le programme C ci-joint pour Attiny2313.

C'est certainement facilement adaptable à l'Arduino. Il n'y a aucune librairie à installer, tout est réalisé sous forme de macros C contenues dans des fichiers *.h. Les protothreads exploitent l'instruction switch du langage C, les étiquettes permettant de reprendre le protothread où il a rendu la main.

Il faut toutefois mentionner quelques restrictions:
  • l'instruction switch étant à la base du mécanisme, il ne faut plus l'utiliser dans le programme et remplacer par des if.
  • il s'agit de multi-tâches coopératif non pré-emptif. Dans certains cas on peut même se passer d'interruptions.
  • les protothreads sont bien adaptés à des tâches très séquentielles. Dans l'exemple du PN: attendre le train, baisser les barrières, attendre, lever les barrières. Si le déroulement est beaucoup plus complexe, une machine à états finis est plus adaptée. Cette dernière peut tout à fait être encapsulée dans un protothread !

Meilleures salutations à tous.

10
Vos projets / TCO avec un Attiny 2313
« le: mars 03, 2017, 09:58:22 pm »
Bonjour à tous,

Après avoir évoqué l'Attiny 2313 utilisé dans mes projets dans le fil Utilisation d'Attiny, je réponds à la demande de Denis au sujet de mon TCO. Le lien ci-après vers l'article de mon blog reprend les messages postés à ce sujet sur le forum du N.

https://savignyexpress.wordpress.com/2016/10/12/mon-reseau-panneau-de-controle-tco/

Bonne lecture, bonne fin de semaine et meilleures salutations.

Marc-Henri

11
Débuter / Avr-gcc, avr libc, avrdude ?
« le: septembre 05, 2016, 08:00:00 am »
Bonjour à tous,

À ce jour, j'ai réalisé mes projets à microcontrôleurs AVR sans passer par une carte Arduino, à l'aide des outils avr-gcc, avr libc et avrdude pour la programmation en ICSP sur les pattes SCK, MOSI, MISO.

Hésitant entre un système à plusieurs microcontrôleurs (d'où mes questions sur les bus) et un système unique pour mon nouveau réseau N, j'hésite à acquérir une carte Arduino équipée de l'Atmega 2560 car elle dispose de suffisamment d'entrées-sorties et elle simplifierait le développement matériel. Pour le développement logiciel, j'aimerais continuer à travailler dans mon environnement habituel en C standard avec les outils mentionnés ci-dessus. Avez-vous de l'expérience avec cette approche ?

Bon début de semaine et meilleures salutations.

12
Débuter / Bus I2C, CAN: aide à la mise au point ?
« le: août 15, 2016, 08:31:58 am »
Bonjour à tous,

J'évalue l'utilisation du bus I2C pour mon prochain projet et je me pose la question des outils d'aide à la mise au point. De mon point de vue, il faut être en mesure d'observer le trafic et éventuellement simuler un équipement.

Comment testez-vous vos développements incluant un bus I2C ou CAN ?
Quelqu'un a-t-il de l'expérience avec la carte open source "bus pirate" ?
Quelles sont les alternatives accessibles et pas trop coûteuses pour un usage amateur ?

Je dispose d'un oscillo analogique qui pourrait me permettre de vérifier l'allure générale des signaux et attester de l'activité mais évidemment sans possibilité de décodage des trames.

Merci de votre partage d'expérience.
Bon début se semaine et meilleures salutations.

13
Vos projets / Mesure EMF ?
« le: juin 16, 2016, 10:10:18 am »
Bonjour,

Je souhaite réaliser une alimentation PWM pour commander les moteurs du système Magnorail (www.magnorail.com) sur mon nouveau projet de réseau N.

J'aimerais de plus mettre en place une régulation de vitesse en mesurant la force contre électro-motrice (EMF) du moteur. Je me souviens avoir vu des schémas pour l'amplification de cette tension lorsque le moteur n'est pas alimenté, mais je ne sais plus où. De même pour les algorithmes de régulation, probablement de type PID.

Avez-vous des liens / infos sur ce sujet ?

Merci d'avance pour vos contributions.
Meilleures salutations.

Marc-Henri

14
Débuter / Techniques de mise au point
« le: octobre 27, 2015, 01:45:30 pm »
Bonjour à tous,

En systèmes embarqués tels que l'Arduino, il n'est pas toujours facile de mettre au point les applications. Contrairement à un PC où on peut écrire à l'écran / sur un fichier ou utiliser un debugger, les possibilités de voir ce qui se passe sont beaucoup plus réduites.

Avec ce fil, j'aimerais démarrer un partage sur les techniques que vous utilisez pour la mise au point de vos réalisations. Il peut s'agir d'astuces logicielles aussi bien que matérielles et, bien entendu, une combinaison des deux.

Led clignotante indiquant la bonne santé du système
Je démarre avec la première "recette", par ailleurs décrite dans mon blog à l'adresse: https://savignyexpress.wordpress.com/2014/01/17/gare-du-reseau-dun-ami-programmation/. Il s'agit de prévoir une tâche quasi parallèle qui fait clignoter la led de la carte Arduino ou, dans le cas d'un montage maison, la led que l'on ne manquera pas d'ajouter.

Si on ne veut pas utiliser les protothreads, on peut programmer une tâche quasi-parallèle faisant clignoter une led avec la technique de gestion du temp décrite par Jean-Luc sur le site Locoduino.org http://www.locoduino.org/spip.php?article6.

Une led clignotante est un très bon indicateur de la "santé" du système. Si elle clignote, c'est signe que déjà pas mal de choses fonctionnent bien dans le programme. Si elle reste bloquée allumée ou éteinte, le programme est bloqué quelque part ou il est parti dans une boucle infinie. Pour que cette indication soit pertinente, il ne faut pas gérer cette led dans une routine d'interruption reliée à un timer car on courrait le risque que seule la routine d'interruption fonctionne alors que le reste du programme est bloqué.

Meilleures salutations.

Marc-Henri

15
Shields et Modules / Conception de circuits imprimés et pooling ?
« le: septembre 23, 2015, 11:23:01 am »
Bonjour à tous,

Venant de l'informatique et m'étant sérieusement mis à l'électronique il y a quelques années, je n'ai pas du tout l'expérience de la conception de circuits imprimés. Je réalise mes cartes en Veroboard ou cartes à pastille, mais tout de même dessinées à l'aide de l'outil PCB de KiCad.

Pour certaines réalisation, il me paraîtrait intéressant de passer à de véritables circuits imprimés et les commander par exemple chez http://www.pcb-pool.com/. Je n'envisage pas la fabrication "maison".

J'ai quelques questions à ce sujet.
  • Existe-t-il des tutoriaux en ligne ou des livres (les circuits imprimés pour les nuls n'existe pas à ma connaissance) décrivant à quoi il faut faire attention en concevant un circuit imprimé ? Principes généraux, étapes, règles de conception, bonnes pratiques ?
  • Quelles règles de conception peut-on définir et faire vérifier par un logiciel tel que KiCad ? Espacement entre les pistes, autre ?
  • Quelle est votre expérience des circuits fabriqués en pooling et des fournisseurs de ces services ?
  • Etant localisé hors de l'espace Schengen, savez-vous si les circuits imprimés sont soumis aux taxes douanières ?

Merci d'avance pour les pistes (jeu de mots) que vous pourrez me fournir.  ;)
Meilleures salutations.

Marc-Henri

Pages: [1] 2