Messages récents

Pages: [1] 2 3 ... 10
1
Débuter / Re : Problème sur pilotage aiguillages par arduino via I2C
« Dernier message par Jean-Luc le avril 26, 2024, 02:43:31 pm »
Bonjour.

La datasheet du MCP23017 stipule que le courant maxi sur une broche en sortie ne doit pas excéder 25mA. C'est du maximum absolute rating, autrement dit c'est la limite à partir de laquelle ça casse. 25mA c'est déjà trop, 20mA est probablement la valeur à ne pas dépasser en fonctionnement normal.

https://ww1.microchip.com/downloads/aemDocuments/documents/APID/ProductDocuments/DataSheets/MCP23017-Data-Sheet-DS20001952.pdf

Un relai HFD3/003 a une bobine qui fait environ 64Ω (https://docs.rs-online.com/90a1/0900766b81663c5b.pdf). Soit un courant de ~47mA sous 3V

Par conséquent vous êtes 2,5 fois au dessus des specs du MCP23017.

Par ailleurs, une bobine de relai est inductive et une diode doit être mise en parallèle de la bobine pour éviter que la tension monte au niveau de la broche de commande quand on coupe la bobine. Cette diode est incorporée dans les ULN qui sont faits pour ça.

Un MCP23017 c'est comme un microcontrôleur, on n'y branche pas directement des charges qui consomment trop. Ils sont quand même de bonne composition en arrivant parfois à commander le relai  :)
2
Débuter / Re : Problème sur pilotage aiguillages par arduino via I2C
« Dernier message par angelow le avril 26, 2024, 02:29:04 pm »
Bonjour à tous,

je me permets de reposter sur ce sujet (j'en créerai un nouveau si besoin mais vu que je me suis pas mal basé sur ce qui a été fait ici, je me suis dit que ce serait pertinent).
Sur le réseau N (aiguillage Fleischmann) j'ai un programme python qui permet en i2c de piloter les aiguillages de deux manières en passant par un MCP23017 :
soit via un ULN2803 qui vient ensuite alimenter en direct les aiguillages.
soit en direct sortie du MCP23017 vers un relai 3.3V type HFD3/003 pour commander simultanément plusieurs aiguillages d'un coup (et éviter une surcharge dans les darlington).
Je suis finalement arrivé à une situation fonctionnelle mais parfois, j'ai une commande de relais qui ne fonctionne plus. le relais ne se ferme pas (il se ferme si je shunte le MCP23017, donc c'est pas un problème de relais). Et je n'ai aucune erreur qui est remontée dans mon programme lors de l'envoi de la commande i2c. Est-ce que le MCP23017 peut dysfonctionner si on lui met une charge induite en direct derrière ? et auquel cas ça m'arrivera à tous mes relais ?

Au niveau de la structure j'ai suivi le dernier schéma posté par l'auteur du fil, bien protégé les MCP23017 à l'aide de capacités, et installé des resistances de pull-up de 4.7kOhm.
Dans mon montage j'ai 5 MCP 23017 en tout dont une petite quinzaine qui entraine en direct des relais. pour l'instant seuls deux ont ce problème. Sur l'un d'eux d'ailleurs le problème est intermittent.

Si vous avez quelquonque proposition de solution ou de piste à étudier je suis preneur. J'ai commandé de nouveaux MCP23017 pour remplacer et vérifier si le problème est "résolu" en changeant de MCP23017. Je vous tiens au courant

Bonne journée !

Florian

3
Vos projets / Re : RailCom: Générateur de CutOut
« Dernier message par trimarco232 le avril 26, 2024, 12:09:46 pm »
j'ai donné toutes mes hypothèses , mais je suis bien d'accord avec toi : il faut aller au + simple :
- ne pas toucher au code DCC-EX , dès qu'il a assez de bits pour le préamble
- choisir un attiny412 (8 broches , récent) , prévoir le téléversement par l'ESP32 , mais aussi et d'abord par un connecteur externe , sur lequel on pourra brancher un convertisseur USB <-> série , que tout le monde a ; l'un ou l'autre composant supplémentaire nécessaire (résistance , diode) étant aussi à ajouter sur la carte
- utiliser le code de lebelge2 , vu qu'il existe et qu'il fonctionne (le code) ; je n'ai pas non plus compris le problème de l'inversion du signal (l'opposé de l'inverse étant identique à la même chose) ... à défaut , je pourrai proposer la variante que j'ai éditée au point 3) de mon post précédent
4
Vos projets / Re : RailCom: Générateur de CutOut
« Dernier message par bobyAndCo le avril 26, 2024, 10:43:06 am »
Merci Marc pour les perspectives que tu apportes.

Dans le cas de laBox qui s’adresse à un public sans compétences particulières, je pense qu’il ne faut pas modifier DCC-Ex. Je pense principalement aux MAJ, car on oublie vite que l’on avait changé tel ou tel paramètre, modifié telle ou telle configuration.

Par ailleurs, les trames générées par DCC-Ex sont parfaites !

L’idée de téléverser le soft à partir de l’ESP32 est vraiment intéressante. Pas certain qu’il faille utiliser la même broche pour le téléversement et la liaison série. Il faudra il est vrai ajouter du code dans DCC-Ex pour cela (avec les précautions de MAJ dont je parlais). Je vois bien une commande en synthaxe DCC++, <xx> qui lancerait le processus !!!

Je parle ATTiny ou AVR car c’est ce qui est le plus compatible avec l’environnement Arduino en programmation. Et celui dont je connais le mieux la manipulation des ports  ;D

Il reste à adapter le programme du belge à l’ESP32 et surtout à DCC-Ex, j’avoue ne pas avoir bien compris l’histoire des trames inversées.

Il y a aussi une demande d’adaptation pour placer ce montage, non plus derrière une centrale sans booster, mais derrière un booster.
5
Vos projets / Re : Re : RailCom: Générateur de CutOut
« Dernier message par trimarco232 le avril 26, 2024, 10:26:55 am »
Bonjour ,
Bravo Christophe !
(...)
Je ne serai en effet pas étonné que l'on puisse à terme mettre un ATTiny (modèles récents) à moins d'1€.
on peut , ce serait un petit projet intéressant pour notre ami Laurent
(dans l'idéal , le "mégatiny" se verrait téléversé par une broche de l'ESP32 , on n'aurait pas besoin de connecteur ou programmateur spécial)
après , on a 3 approches :
1) faire générer par le mégatinny , à partir de la sortie DCC de l'ESP32 , les signaux pour le cutout , conformément au soft de lebelge2
2) faire générer au mégatiny toute la trame DCC (il le fera mieux que l'ESP32), à partir d'une liaison série de l'ESP32 , avec petit protocole local adhoc ; (on pourrait utiliser la même broche de l'ESP32 , pour le téléversement et la liaison série) ; c'est techniquement le mieux , mais ça nécessiterait de retoucher le soft de DCC-EX(
3) décoder , à la manière d'un sniffer , le DCC issu de l'ESP32 , puis le reproduire , (avec un packet de retard) , pourvu des signaux qui vont bien ; c'est ma préférence

le chois d'un megatiny n'est pas critique , on pourrait aussi envisager , dans le même format à 8 broches cms , un CH32V003 , ou même un STM32 (ce dernier n'ayant toutefois pas ma faveur , car il utilise ("bêtement") , 2 broches au lieu d'1 pour le téléversement

6
J'ai construis mon réseau sur Rocrail et je suis arrivé à le faire fonctionner avec sa centrale virtuelle. Le step suivant pour moi était de connecter la centrale DCC++ en Port série. J'y suis arrivé mais là tout se complique.

Ok, ça se complique mais qu'est-ce qui ce complique à part tout ??? Pas évident de t'aider si tu es si peu précis sur les problèmes que tu rencontres.

RocRail est pourtant simple à configurer avec DCC++ : https://wiki.rocrail.net/doku.php?id=dccpp:dccpp-fr

Je l'utilise également en 3R avec CC-Schnitte relié à l’un des ports USB et à une Geiltsbox de Marklin : https://forum.3rails.fr/t/homemade-marklin-creation-dun-circuit-intelligent/13574/25

Et ça fonctionne très bien.

Est-ce que tu as lu l'article de Michel ? : https://www.locoduino.org/spip.php?article306

Merci d'envoyer précisions et copies d'écrans où il y a des problèmes

Christophe
7
Présentez vous ! / Carte Mega WiFi R3 Atmega2560 et motor shield DCCEX-8874 & Rocrail
« Dernier message par Happybycker le avril 26, 2024, 09:21:00 am »
Bonjour à tous.
Je reviens vers vous je suis novice dans le domaine du digital, j’ai un projet d’un réseau élaboré sur Anyrail ,je suis inscris au Club MTM de Miramas. J'ai donc de l'aide qui ma permis d'arriver jusqu'à la programmation de ma centrale .Je souhaite utiliser Rocrail et là je galère car au club ils ne connaissent pas Rocrail .Ils m'ont proposé JMRI ,je l'ai essayé Le décoder pro il est super mais le Panel pro ne me plait pas. J'ai une voie de programmation ,avec laquelle j'arrive à paramétrer mes 2 locos digitales avec le décoder pro.
J'ai construis mon réseau sur Rocrail et je suis arrivé à le faire fonctionner avec sa centrale virtuelle. Le step suivant pour moi était de connecter la centrale DCC++ en Port série. J'y suis arrivé mais là tout se complique. J'ai donc reconstruit une simple boucle avec deux bloc sans signaux et aiguillages pour limiter les erreurs dans Rocrail et ça plante. Je n'ai pas encore fait la simple boucle en réel car je repare de 0.
1° Je pensais qu'on pouvait faire fonctionner Rocrail en virtuel avec la centrale DCC++ sans réseau est ce possible?
Merci d'avance

 
8
Vos projets / Re : RailCom: Générateur de CutOut
« Dernier message par bobyAndCo le avril 26, 2024, 09:17:26 am »
Bonjour Marcel,

Je n'ai pas beaucoup de temps disponible aujourd'hui mais les équivalence de broche sont dans le commentaire en début du code modifié ci-dessous. Normalement tu vas t'y retrouver sans problème.

Le code ci-dessous est à copier sur un Nano par exemple. Sur le MEGA qui sert de centrale, j'ai copié le code original de DCC++ qui a 22 bits de préambule : https://github.com/DccPlusPlus/BaseStation

Je n'ai pas le temps de faire les tests avec moins de bits dans le préambule, à voir par la suite.

Je précise bien, mais ça ce voit dans le cablage, que le UNO est directement derrière le MEGA et avant le LMD. Cette solution ne convient pas derrière un booster. A voir par la suite.


// RailCom: Programme pour insérer un CutOut dans les trames DCC.  Arduino Uno, Nano, Micro.

// V.1.0.   24-04-24
// lebelge2@yahoo.fr

/*
Modifié pour LMD18200 le 26/04/24

Testé à partir de DCC++ version originale téléchargé sur Arduino MEGA : https://github.com/DccPlusPlus/BaseStation
Ce code téléchargé sur un Arduino Nano.

Cablage :

  MEGA 3 ------> LMD18200 PWM
  MEGA 12 -----> NANO 3
  NANO 4 ------> LMD18200 DIR
  NANO 6 ------> LMD18200 BRAKE
  MEGA GND ----> NANO GND
  MEGA GND ----> LMD18200 GND

*/

volatile uint8_t dccrecState;
volatile uint8_t tempByte;
#define WAIT_PREAMBLE    0
#define WAIT_START_BIT   1
#define WAIT_DATA        2
#define WAIT_END_BIT     3
#define MaxDccSize 6                         // DCC messages can have a length upto this valu
#define PinIn1 3                             // Entrée signalDcc sans CutOut
#define PinOut1 4                            // Sortie signal DCC avec CutOut
#define PinOut2 5                            // Sortie signal DCC inversé avec CutOut
#define PinBrake 6                           // Sortie signal brake

class DccMessage {
  public:
    volatile uint8_t size;
    volatile uint8_t data[MaxDccSize];        // The contents of the last dcc message received
} dccMessage;

struct {
  uint8_t bitCount;                           // Count number of preamble bits / if we have a byte
  volatile uint8_t tempMessage[MaxDccSize];   // Once we have a byte, we store it in the temp message
  volatile uint8_t tempMessageSize;           // Here we keep track of the size, including XOR
} dccrec;                                     // The received DCC message is assembled here

struct {
  uint8_t port;
  uint8_t bit;                                // Bitmask for reading the input Port
  volatile uint8_t *portRegister;
} dccIn;

void setup() {
  Serial.begin(115200);

  DDRD = DDRD | B01110000;  // pin 3 -> input, pin 4 à 6 -> output
  init_timer2();
  attachInterrupt(digitalPinToInterrupt(PinIn1), Dcc_Interrupt, CHANGE );
  Serial.println ("SetUp OK");
}

void loop() {}

void CutOut(void) {
  delayMicroseconds(8);
  PORTD = PORTD | B01010000;
  PORTD = PORTD &= ~ B00100000;
  //
  delayMicroseconds(425);
  PORTD = PORTD | B00100000;
  PORTD = PORTD &= ~ B01010000;
}
//----------------------------------------------------------------------------------------------------------
void init_timer2(void) {
#define T2_PRESCALER   8
#define T2_PRESCALER_BITS   ((0<<CS02)|(1<<CS01)|(0<<CS00))
#define T77US (F_CPU * 77L / T2_PRESCALER / 1000000L)
#if (T77US > 254)
#warning T77US too big, use either larger prescaler or slower processor
#endif
#if (T77US < 32)
#warning T77US too small, use either smaller prescaler or faster processor
#endif
  noInterrupts();              // disable all interrupts
  TCCR2A = 0;                  // should be zero for our purpose
  TCCR2B = 0;                  // 0 => timer is stopped
  TCNT2 = 256L - T77US;        // preload the timer
  TIMSK2 |= (1 << TOIE2);      // the timer is used in overflow interrupt mode
  interrupts();                // enable all interrupts
}
//----------------------------------------------------------------------------------------
void Dcc_Interrupt() {
  if ((PIND & 0x04) >> 2) {
    PORTD = PORTD | B00010000;
    TCCR2B |= (T2_PRESCALER_BITS);  // Start Timer 2
  }
  else {
    PORTD = PORTD &= ~ B00010000;
  }
}
//-----------------------------------------------------------------------------------
ISR(TIMER2_OVF_vect) {
  uint8_t DccBitVal = !(PORTD & (1 << 4));
  TCCR2B = 0;                                    // 0 => timer is stopped
  TCNT2 = 256L - T77US;                          // preload the timer
  dccrec.bitCount++;
  switch (dccrecState) {
    case WAIT_PREAMBLE:
      if (DccBitVal) {                           // a "1" bit is received
        if (dccrec.bitCount >= 10)
          dccrecState = WAIT_START_BIT;
      }
      else
        dccrec.bitCount = 0;                     // not a valid preamble.
      break;
    case  WAIT_START_BIT:
      if ( !DccBitVal ) {                        // a "0" bit is received
        dccrecState = WAIT_DATA;
        dccrec.tempMessageSize = 0;
        uint8_t i;
        for (i = 0; i < MaxDccSize; i++ )
          dccrec.tempMessage[i] = 0;
        dccrec.bitCount = 0;
      }
      break;
    case WAIT_DATA:
      if ( dccrec.bitCount == 8 ) {                 // byte is complete
        if (dccrec.tempMessageSize == MaxDccSize ) { // Packet is too long - abort
          dccrecState = WAIT_PREAMBLE;
          dccrec.bitCount = 0;
        }
        else
          dccrecState = WAIT_END_BIT;              // Wait for next byte or end of packet
      }
      break;
    case WAIT_END_BIT:
      if ( DccBitVal ) {                           // End of packet?
        CutOut();
        dccrecState = WAIT_PREAMBLE;
      }
      else                                         // Get next Byte
        dccrecState = WAIT_DATA;
      dccrec.bitCount = 0;                         // prepare for the next byte
  }
}
9
Vos projets / Re : RailCom: Générateur de CutOut
« Dernier message par CATPLUS le avril 26, 2024, 06:53:07 am »
Bonjour Christophe

Bravo, pourrais-tu stp nous faire un schéma de ton montage.

Marcel
10
Vos projets / Re : RailCom: Générateur de CutOut
« Dernier message par bobyAndCo le avril 25, 2024, 11:52:21 pm »
Bonjour à tous,

J'ai réussi à faire fonctionner le montage avec un LMD18200. C'est tout ce que j'avais sous le coude. Les adresses de locomotives sont bien lue. Je n'ai essayé pour l'instant que avec DCC++ (version originale) qui génère 22 bits de préambule ! J'ai commencé à tester avec DCC-Ex mais je n'avais rien, certainement ce que lebelge soulevait à propos de DCC-Ex, du coup je n'ai pas poursuivis car un peu fatigué.

@lebelge

- LMD18200 :
     Je ne possède pas encore ce module mais d’après le datasheet, au moment du CutOut, il faut que Dir soit à 0 et Brake à 1, il faudra adapter le soft plus deux sorties supplémentaires dédiées à ce module.

J'ai effectivement utilisé une broche supplémentaire, la 6

#define PinIn1 3                              // Entrée signalDcc sans CutOut = Pin DIR du MEGA (pin 12 dans DCC++)
#define PinOut1 4                            // Sortie signal DCC avec CutOut =  Pin DIR du LMD18200
// La sortie 3 du MEGA (PWM) est reliée en direct au PWM du LMD18200
#define PinOut2 5                            // Sortie signal DCC inversé avec CutOut // Je ne l'utilise pas ici
#define PinBrake 6                           // Sortie signal BRAKE = Pin 6 du Nano dans pin BRAKE du LMD18200

et dans la fonction CutOut(), j'active la broche 6 en même temps que la 4

void CutOut(void) {
  delayMicroseconds(8);
  PORTD = PORTD | B01010000;
  PORTD = PORTD &= ~ B00100000;
  //
  delayMicroseconds(425);
  PORTD = PORTD | B00100000;
  PORTD = PORTD &= ~ B01010000;
}

Bon ça mérite encore un peu de travail sur le code mais le principe est bon. C'est une énorme avancée et de belles perspectives pour Railcom sur la Box dans des conditions simples et peu couteuses.

Je ne serai en effet pas étonné que l'on puisse à terme mettre un ATTiny (modèles récents) à moins d'1€.

Merci encore lebelge pour ce partage bénéfique.

PS : Je mesure environ 10% des trames DCC en dehors des spécifications NMRA, et encore de très peu en dehors. Ce qui pour moi est très acceptable et qui est déjà peut-être le cas en sortie directe de DCC++ ce que je pourrai mesurer plus tard.

Christophe

Pages: [1] 2 3 ... 10