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,

J'aimerais tout d'abord adresser un grand bravo à Christian pour les 2 articles sur le BAL analogique à 4 et 8 relais. Ce sont d'excellents 2ème projets à réaliser après les animations lumineuses, un débutant devrait y trouver son bonheur et la motivation d'aller plus loin.

En lisant le programme, j'ai découvert l'existence de la librairie PinChangeInt et cela m'interpelle car je n'ai pratiquement jamais utilisé d'interruptions dans mes projets. Seul mon projet en cours de gestion de ligne à crémaillère sur Attiny 45 a une routine d'interruption sur un timer pour recréer la fonction millis et envoyer des traces à l'oscilloscope. J'ai besoin d'un timing très précis dans ce cas, l'interruption est donc indispensable.

On aboutirait au même résultat en scrutant régulièrement les ILS dans le programme principal ou dans une routine d'interruption unique attachée à un timer. Le processeur tourne suffisamment rapidement pour ne pas manquer les changements d'états des ILS, pour autant qu'il n'y ait pas d'attente bloquante dans le programme principal. Le mode scrutation a l'avantage d'éviter l'accès concurrent aux variables partagées avec la routine d'interruption.

Très bonne journée à tous.

2
Les réseaux / Période de l'avent
« le: novembre 30, 2021, 10:43:14 pm »
Bonjour à tous,

J'ai terminé la réalisation de mon réseau hivernal juste après Noël 2020, donc trop tard pour le dernier Noël, mais suffisamment tôt pour Noël 2021.  :)



En publiant à nouveau cette vidéo, j'aimerais vous souhaiter une belle période de l'avent et surtout de bien vous porter.

3
Vos projets / Gestion ligne à crémaillère
« le: février 26, 2021, 11:00:49 am »
Bonjour à tous,

Mon réseau époque III-IV comporte une ligne à crémaillère complètement indépendante du reste du réseau. Cette ancienne photo datant de la construction du réseau montre l'ensemble de la ligne à crémaillère: départ à gauche de la gare principale, montée, grande courbe à droite et arrivée devant le chalet qui sera un restaurant de montagne.



Les 2 extrémités sont alimentées au travers de diodes afin d'assurer l'arrêt du train et son départ dans le sens montée, respectivement descente. Un temporisateur inverse périodiquement le sens de l'alimentation traction. La zone de pleine voie a des diodes dont le rôle est de réduire la tension en descente.

En montée, la situation est:



En descente, la situation est:



Le fonctionnement obtenu n'est pas satisfaisant, les locos Fleischmann ayant la fâcheuse tendance à s'emballer à la descente. Je viens donc de démarrer un projet basé sur un Attiny45 dont les caractéristiques seront:
  • Réutilisation de l'alimentation traction actuelle basée sur un LM317.
  • Conserver la possibilité d'exploiter manuellement la ligne.
  • Réduire les modifications de câblage de la ligne autant que possible. Probablement que les diodes de pleine voie seront supprimées.
  • Alimentation PWM ou PFM (pulse frequency modulation).
  • Vitesses différentes en montée et en descente avec si possible des phases d'accélération / déccélération.

La 1ère fonction sera réalisée en court-circuitant la résistance R2 du montage à LM317, on réduit la tension de sortie à la tension de référence de 1.25 V. Le schéma ci-après, tiré de la datasheet du LM317 (où les diodes de protection ne sont pas dessinées) montre le principe. Un transistor commandé par un signal logique gère cela.



Les alimentations traction de mon réseau sont regroupées dans un module de 4 alimentations trouvé en occasion sur Internet. La ligne à crémaillère est alimentée par celle de gauche, le potentiomètre linéaire joue le rôle de la résistance R2, un transistor le court-circuitera. En exploitation automatique, il suffira de régler le potentiomètre au maximum. On conserve ainsi la possibilité d'exploiter manuellement. Un bénéfice de ce montage est que le LM317 a une protection contre la surcharge qui s'active en cas de courant supérieur à 1.5 A.



J'ai déjà fait quelques essais qui me confortent dans ce choix pour la PWM. Le LM317 suit bien, mais on reste à des fréquences basses de l'ordre de 100 Hz.

Bonne fin de semaine.

4
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

5
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

6
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

7
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

8
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

9
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

10
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.

11
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.

12
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.

13
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

14
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.

15
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.

Pages: [1] 2