Auteur Sujet: Un Arduino par canton  (Lu 108086 fois)

simontpellier

  • Full Member
  • ***
  • Messages: 115
    • Voir le profil
Re : Un Arduino par canton
« Réponse #45 le: avril 18, 2020, 03:32:14 pm »
Bonjour Jean-Luc,

Désolé de vous solliciter : j'ai commencé à prendre en main le croquis "AlimentationTraction" (très formateur !) que je vais expérimenter par tranches mais je voulais vous signaler une difficulté.

Pour commencer j'ai trouvé votre librairie : https://framagit.org/locoduino.org/CommandInterpreter
mais qui étrangement provoque cette erreur :
"class CommandInterpreter' has no member named 'readUnsignedLong'; did you mean 'readUnsignedInt'?" ;

Par similitude avec l'existant, j'ai donc tenté d'ajouter dans le CommandInterpreter.h cette ligne :
bool readUnsignedLong(unsigned long& result);et dans le .cpp la fonction bool CommandInterpreter::readUnsignedLong(unsigned long& result)
{
  char **endChar;
  char *arg = mBuffer.getArg();
  if (! isANumber(arg)) return false;
  long longResult = strtol(arg, endChar, 0);
  if (**endChar != '\0' || longResult < 0 || longResult > 65535) return false;
  else {
    result = (unsigned long)longResult;
    return true;
  }
}

Ceci m'a permis de compiler (mais pas d'affirmer que le code ainsi bricolé fonctionne...)
J'espère ne pas être hors du sujet de ce fil, dans ce cas j'effacerai ce message, mais que mon retour d'expérience puisse servir.

Bien cordialement
Philippe








Jean-Luc

  • Global Moderator
  • Hero Member
  • *****
  • Messages: 1714
    • Voir le profil
Re : Un Arduino par canton
« Réponse #46 le: avril 18, 2020, 05:53:34 pm »
Bonjour Philippe,

Effectivement il y avait du code non comité sur mon disque. C'est poussé sur framasoft

Bien cordialement
Cordialement

ramboman

  • Newbie
  • *
  • Messages: 24
    • Voir le profil
Re : Un Arduino par canton
« Réponse #47 le: avril 08, 2021, 11:16:54 am »
Bonjour à tous
Je crains d'avoir raté le train...
Je suis en LGB analogique, j"ai évalué Driving Railway... j'ai tenté Chenevez il y a 50 ans...
Bref... un Arduino par canton et un réseau Can me semble être la solution... mais sans créer une usine à gaz !
Càd pas de PWM... une tension continue "propre" par canton : la pièce manquante.
Pour le reste, l'Arduino du canton peut tout faire
Quelqu'un a-t'il une suggestion ?
Cordialement
Roland

PS: sinon c'est l'arbre à relais et de bons gros transfo LGB
Pour l'nstant c'est un switch par canton "à l'américaine"

msport

  • Global Moderator
  • Hero Member
  • *****
  • Messages: 2217
  • HO avec DCC++ en DIY Réseaux très éphémères
    • Voir le profil
Re : Un Arduino par canton
« Réponse #48 le: avril 08, 2021, 12:33:17 pm »
Ne connaissant pas la contrainte sur le PWM, on peut juste suggérer de lisser ce PWM avec une constante de temps bien supérieure aux 550 Hz (si c'est celle utilisée), pour obtenir une tension continue "propre" et piloter avec celle-ci une alimentation programmable linéaire.
Cordialement

Pierre34

  • Newbie
  • *
  • Messages: 28
    • Voir le profil
Re : Un Arduino par canton
« Réponse #49 le: avril 29, 2021, 02:19:40 pm »
Bonjour Jean Luc

J'essaie d'utiliser la bibliothèque SyncPWM. Sur les cartes cantons esclaves arduino nano j'ai inclus les deux lignes
#include <SyncPWM.h>
SyncPWM pwmsynchro;

et ces deux là dans le setup
  pwmsynchro.begin(6); // Start a synchronized PWM with sync on pin 6           
  pwmsynchro.analogWrite(30);

à la compilation j'ai ce message d'erreur:

Arduino : 1.8.13 (Mac OS X), Carte : "Arduino Nano, ATmega328P (Old Bootloader)"

In file included from /Users/Pierre/Library/Arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino7/avr/include/avr/io.h:99:0,
                 from /Users/Pierre/Library/Arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino7/avr/include/avr/pgmspace.h:90,
                 from /Users/Pierre/Library/Arduino15/packages/arduino/hardware/avr/1.8.3/cores/arduino/Arduino.h:28,
                 from /Users/Pierre/Documents/Arduino/libraries/SyncPWM-master/SyncPWM.h:24,
                 from /Users/Pierre/Documents/Arduino/libraries/SyncPWM-master/SyncPWM.cpp:24:
/Users/Pierre/Documents/Arduino/libraries/SyncPWM-master/SyncPWM.cpp:123:29: error: stray '$' in program
         TIMSK2 = _BV(OCIE2A=$);
                             ^
/Users/Pierre/Documents/Arduino/libraries/SyncPWM-master/SyncPWM.cpp: In member function 'void SyncPWM::begin(byte)':
/Users/Pierre/Documents/Arduino/libraries/SyncPWM-master/SyncPWM.cpp:123:18: error: expected primary-expression before ')' token
         TIMSK2 = _BV(OCIE2A=$);
                  ^
exit status 1
Erreur de compilation pour la carte Arduino Nano

Et là j'avoue que cela dépasse mes compétences.

Ai je oublié d'inclure une bibliothèque?
Dans la bibliothèque avr je n'ai pas de io.h et dans pgmspace.h il n'y a pas de ligne 99 cela s'arrête à la ligne 44

Jean-Luc

  • Global Moderator
  • Hero Member
  • *****
  • Messages: 1714
    • Voir le profil
Re : Un Arduino par canton
« Réponse #50 le: avril 29, 2021, 02:28:31 pm »
Bonjour Pierre

Sans doute une faute de frappe de ma part. Je venais de tester avec l'ATMega32u4 et je suis passé à côté.

Retirez le =$ ligne 123 de manière à ce que vous ayez :

TIMSK2 = _BV(OCIE2A);

Dites moi si c'est ok;
Cordialement

Pierre34

  • Newbie
  • *
  • Messages: 28
    • Voir le profil
Re : Un Arduino par canton
« Réponse #51 le: avril 30, 2021, 01:40:39 am »
Merci pour cette réponse rapide.

J'ai fait la modification indiquée et cela compile parfaitement et sur le maitre et sur l'esclave.

Parfait et bravo.

Cordialement

Pierre

Pierre34

  • Newbie
  • *
  • Messages: 28
    • Voir le profil
Re : Un Arduino par canton
« Réponse #52 le: mai 10, 2021, 08:59:37 pm »
bonsoir Jean Luc,

Après avoir utiliser la bibliothéque PWM Freq qui fonctionne parfaitement, barvo, j'essaye toujours d'intégrer Syncpwm à mes programmes de cartes canton bâties autour d'un arduino nano et d'un LMD 18200. J'ai lu que les deux bibliothèques sont incompatibles j'en ai tenu compte.

J'ai compris qu'il fallait un arduino maitre sur lequel j'installe le programme Masterclock comme cité dans les exemples.
Je récupère une horloge maitresse sur la pin 3 de cet arduino maitre.
J'ai 17 cartes cantons. J'envoie l'horloge maitresse par 17 fils en parallèles sur la broche 8.
Je récupère la PWM de chaque carte canton esclave sur la pin 3 et c'est elle que je connecte au LMD18200. 

J'ai fait l'essai avec un arduino maitre n'ayant que le programme master clock téléchargé.

Constat: je ne peux pas régler la vitesse. Je suis toujours à vitesse max.

Question 1 :ai je bien compris le câblage?
Question 2: cet arduino maitre peut il être une des cartes cantons?
Question 3 : que fais je de mal pour ne plus pouvoir régler la vitesse?
Question 4: mes cartes sont malheureusement déjà cablées avec la pwm entre arduino et le LMD18200 sur la broche 11 compatible comme la broche 3 avec le timer 2. Pour pouvoir utiliser la broche 11 au lieu de la 3 pour la PWM suffit il de changer dans Syncpwm.cpp en lignes 59 et 86 le chiffre 3 par 11? Cela a t il une influence sur la pin de sortie de la masterclock?

Question 5: pour récupérer l'horloge maitresse sur la pin 6 au lieu de la pin 8 suffit il d'écrire pwm.begin(6)?

Beaucoup de questions en fait

Merci par avance
Bien cordialement
Pierre

Jean-Luc

  • Global Moderator
  • Hero Member
  • *****
  • Messages: 1714
    • Voir le profil
Re : Re : Un Arduino par canton
« Réponse #53 le: mai 11, 2021, 09:11:51 am »
Bonjour Pierre

Constat: je ne peux pas régler la vitesse. Je suis toujours à vitesse max.

Que faites vous pour régler la vitesse ?

Citer
Question 2: cet arduino maitre peut il être une des cartes cantons?

Non

Citer
Question 3 : que fais je de mal pour ne plus pouvoir régler la vitesse?

Je ne sais pas car je n'ai pas compris exactement comment vous vous y prenez

Citer
Question 4: mes cartes sont malheureusement déjà cablées avec la pwm entre arduino et le LMD18200 sur la broche 11 compatible comme la broche 3 avec le timer 2. Pour pouvoir utiliser la broche 11 au lieu de la 3 pour la PWM suffit il de changer dans Syncpwm.cpp en lignes 59 et 86 le chiffre 3 par 11?

Non. Il faut changer le code de SyncPWM::startPWM, de SyncPWM::analogWrite et de l'ISR. Actuellement OCR2A est utilisé pour maintenir le timer synchrone et OCR2B sert pour la PWM. Il faudrait échanger les deux.

Citer
Cela a t il une influence sur la pin de sortie de la masterclock?

Oui puisque SyncPWM::beginMasterClock appelle startPWM

Citer
Question 5: pour récupérer l'horloge maitresse sur la pin 6 au lieu de la pin 8 suffit il d'écrire pwm.begin(6)?

Oui

Cordialement
Cordialement

Pierre34

  • Newbie
  • *
  • Messages: 28
    • Voir le profil
Re : Un Arduino par canton
« Réponse #54 le: mai 11, 2021, 01:39:13 pm »
Bonjour Jean Luc,

Merci pour cette réponse rapide.

Pour la vitesse j'utilise un potentiomètre de 10kohms sur la broche A6 et le programme suivant:


void potreglagevitesse ()
{   
   Serial.println("lecture réglage potentiomètre");
   mesure_potreglage = analogRead(pot_reglage);      //    lecture de la valeur du potar réglage valeur max de la pwm
   valeurmaxpwm = map(mesure_potreglage,0,1023,0,255);  // transfert de cette valeur en valeur correspondant à celle le la pwm
   vitesse = valeurmaxpwm;
   analogWrite (PWM, vitesse);
}

Pour le câblage ai je bien compris?

Bien cordialement
« Modifié: mai 11, 2021, 01:43:52 pm par Pierre34 »

Jean-Luc

  • Global Moderator
  • Hero Member
  • *****
  • Messages: 1714
    • Voir le profil
Re : Un Arduino par canton
« Réponse #55 le: mai 11, 2021, 01:44:55 pm »
Sur l'Arduino qui envoie la clock ?
Cordialement

Pierre34

  • Newbie
  • *
  • Messages: 28
    • Voir le profil
Re : Un Arduino par canton
« Réponse #56 le: mai 11, 2021, 06:19:14 pm »
Non sur les arduino canton. Sur l'arduino qui envoie le clock je n'ai mis que le programme master clock et rien d'autre

#include <SyncPWM.h>

SyncPWM sp;

void setup() {
  sp.beginMasterClock();  // start a master clock on PWM pin 3 on Uno/Nano
                          // pin 6 on a Leonardo
}

void loop() {
}

Jean-Luc

  • Global Moderator
  • Hero Member
  • *****
  • Messages: 1714
    • Voir le profil
Re : Un Arduino par canton
« Réponse #57 le: mai 11, 2021, 06:23:59 pm »
Ok.

Le premier problème que je vois est que il devrait y avoir un objet SyncPWM du côté du sketch des Arduino de canton également. Vous pouvez me mettre le sketch complet ?
Cordialement

Pierre34

  • Newbie
  • *
  • Messages: 28
    • Voir le profil
Re : Un Arduino par canton
« Réponse #58 le: mai 11, 2021, 06:48:03 pm »
désolé c'est un peu long. Je joins le setup et le loop. Il y a aussi plusieurs fonctions. Je compte ouvrir un projet sur le forum dés que j'aurai réussi cette intégration.

// déclaration des variables

#include <SyncPWM.h>
SyncPWM pwmsynchro;


const int pot_inertie_ACC = A0; // Règle l'inertie a l'accélération
int val_inertie_ACC; // Variable pour lire la valeur de pot_inertie_acc

const int detecteur_en_ZA = A1; // Détecteur produisant un signal 0v
bool etat_ZA = true; // si un train est à l'arrêt en ZA true sinon false

const int detecteur_en_ZT = A2; // Détecteur produisant un signal 0v
bool etat_ZT = true; // si un train est à l'arrêt en ZA, il l'est aussi en ZT true sinon false

const int pot_reglage = A6;  // potar pour régler la valeur max de la pwm et donc la vitesse

const int MarcheArret = A4; // Interrupteur marche arrêt

const int pot_inertie_FREIN = A5; // Règle l'inertie au freinage
int val_inertie_FREIN; // Variable pour lire la valeur de pot_inertie_frein

// A6 libre
// A7 libre

// LIBRE pour l'instant const int reglagevitesse = 2; // sur la pin 2 ou 3 exclusivement pour les interruption

const int led_feuxrouges = 4; // Led rouge si à l'arrët - Feu rouge
const int led_feuxoranges = A3; // Led orange si ralenti
const int led_feuxverts = 5; // Led verte si en marche - Feu vert

const int occup_canton_n1 = 13; // occupation du canton n1
const int occup_canton_n = 7; //  occupation du cabton n

const int led_A_B = 8; // Led sens de A vers B

//N1 et N2 correspondent aux bornes d'un pont en H L298N sont remplacés par DIR et PWM
const int BRAKE = 9; // Utilisation de BRAKE pour l'arrêt et le démarrage
const int DIR = 10; // Utilisation du PWM pour la direction
const int PWM = 3; // changer en 3 pour test syncpwm// Utilisation du PWM pour la valeur de PWM moteur analogique

const int LedMarcheArret = 12;
bool EtatMarcheArret = false; // on initialise Etat marche arrêt sur arrêt

int vitesse;
int vitesseralenti; // pour la vitesse de ralenti
int vitessearret; //pour mise en route
int vitessetest = 200;
int vitessetestetape6 = 50;
int mesure_potreglage = 0; // valeur pour mesurer la valeur du potar de réglage de la valeur max de la pwm
int mesure_potreglageancien = 0;

int etatinterruption = LOW;

int valDIR = 0;
int valPWM = 0;
int valBRAKE = 0;
int valeurmaxpwm =0;

bool sens_A_vers_B; // vrai si sens gare A vers gare B

int compteur; // pour suivre dans le monniteur l'avancement du programme
int timer = 3000;

int etat_detecteuren_ZA; // mémorise l'état du détecteur utilisé dans les tests HIGH si le détecteur a été actif
int etat_detecteuren_ZT; // quand N1 est libre le mettre systématiquement à LOW car nous l'utilisons pour un test qui provoque le ralenti du train.
                         //Si n1 devient libre avant l'arrêt du train il faut réinitialiser cette variable

//*************************************************************
void setup()
{
pinMode (BRAKE, OUTPUT);
digitalWrite (BRAKE,HIGH);
pinMode (DIR,OUTPUT);
pinMode (PWM, OUTPUT);
digitalWrite (DIR,LOW);
digitalWrite (PWM,LOW);
pinMode (MarcheArret,INPUT);
pinMode (LedMarcheArret,OUTPUT);
digitalWrite (LedMarcheArret,HIGH);

EtatMarcheArret= digitalRead (MarcheArret);
while (EtatMarcheArret == LOW)               // tant que le bouton marche arrêt n'est pas sur marche il ne se passe rien
{
EtatMarcheArret= digitalRead (MarcheArret);
}
// on passe l'état marche arrêt qui est devenu marche en ligne ci-dessus à arrêt pour mesurer plus tard le changement d'état du bouton marche arrêt

delay(300);

Serial.begin(9600);
digitalWrite (LedMarcheArret,LOW);
Serial.println("Etat Marche Arret");
Serial.println (EtatMarcheArret);

Serial.println( "demarrage du programme");

// Changement de fréquence du PWM
//TCCR1B &= 0xF8;
//TCCR1B |= B00000010;

  pwmsynchro.begin(6); // Start a synchronized PWM with sync on pin 6           
  pwmsynchro.analogWrite(30);

pinMode (occup_canton_n, OUTPUT);
digitalWrite (occup_canton_n, HIGH); // LOW pour libre, HIGH pour occupé

pinMode (occup_canton_n1, INPUT);

pinMode (pot_inertie_ACC, INPUT);
pinMode (pot_inertie_FREIN, INPUT);

valDIR = digitalRead (DIR);
Serial.println ("valeur DIR =");
Serial.println (valDIR);

valPWM = analogRead (PWM);
Serial.println ("valeur PWM =");
Serial.println (valPWM);
 
pinMode (detecteur_en_ZA, INPUT);
pinMode (detecteur_en_ZT, INPUT);

pinMode (led_A_B,OUTPUT); //  led de sens bicolore
digitalWrite (led_A_B,LOW);

pinMode (led_feuxrouges,OUTPUT);
digitalWrite (led_feuxrouges,HIGH);
pinMode (led_feuxverts,OUTPUT);
digitalWrite (led_feuxverts,LOW);
pinMode (led_feuxoranges,OUTPUT);
digitalWrite (led_feuxoranges,LOW);

analogWrite (vitesse,0);         // initialisation de la vitesse à 0                               

//attachInterrupt (0,Marche_Arret,FALLING); // validation du changement de vitesse ( commandé par le potentiomètre vitesse)
                                            // sur le réseau. mettre 0 si pin 2 et 1 si pin 3 V6 je change le nom de la fonction sans les ()

compteur =1;
etat_detecteuren_ZA = LOW; // ou = digitalRead (detecteur_en_ZA) mais le détecteur ne détecte pas si loco à l'arrêt
etat_detecteuren_ZT = LOW; //digitalRead (detecteur_en_ZT)

Serial.print ("test sur mise en route");
Serial.println (); 

 mise_en_route(); // cette fonction met les feux au rouge ou au vert et libère le brake pour que le LMD soit opérationnel

 //potreglagevitesse ();
   Serial.println("lecture réglage potentiomètre");
   mesure_potreglage = analogRead(pot_reglage);      //    lecture de la valeur du potar réglage valeur max de la pwm
   valeurmaxpwm = map(mesure_potreglage,0,1023,0,255);  // transfert de cette valeur en valeur correspondant à celle le la pwm
   Serial.print(valeurmaxpwm);
 
}
//*******************************************************
void loop()
{
  delay (30);// lorsque qu'une carte n'est pas une Arduino ou une Genuino

Serial.print ("passage dans le loop");
Serial.println ();

  Marche_Arret(); // arrêt d'urgence
  digitalRead(occup_canton_n1);
  Serial.print("occupation canton n1 = ");
  Serial.println(digitalRead(occup_canton_n1));
  digitalRead(occup_canton_n);
  Serial.print("occupation canton n = ");
  Serial.println(digitalRead(occup_canton_n));
  Serial.print("vitesse ");
  Serial.println (vitesse);
   Serial.print("lecture réglage potentiomètre");
   
   mesure_potreglage = analogRead(pot_reglage);      //    lecture de la valeur du potar réglage valeur max de la pwm
   valeurmaxpwm = map(mesure_potreglage,0,1023,0,255);  // transfert de cette valeur en valeur correspondant à celle le la pwm
   
   Serial.print("vitesse début loop ");
   Serial.println(vitesse);
   analogWrite(PWM,vitesse); // c'est celui ci qui me redonne la vitesse en fin étape 4 à l'initialisation
  detection();
}
« Modifié: mai 11, 2021, 08:42:13 pm par bobyAndCo »

Jean-Luc

  • Global Moderator
  • Hero Member
  • *****
  • Messages: 1714
    • Voir le profil
Re : Un Arduino par canton
« Réponse #59 le: mai 11, 2021, 06:51:47 pm »
Ok

Donc votre PWM il faut la régler avec

pwmsynchro.analogWrite(vitesse);

Partout

Si vous utilisez le analogWrite qui vient avec le logiciel Arduino, vous cassez la synchro (Je suppose, j'ai pas regardé ce que ça fait)
Cordialement