Auteur Sujet: Va et vient avec gare centrale voie unique  (Lu 51628 fois)

jeff22150

  • Newbie
  • *
  • Messages: 25
    • Voir le profil
Re : Va et vient avec gare centrale voie unique
« Réponse #45 le: décembre 20, 2019, 03:32:58 pm »
Le truc j'ai fait testé avec le train sur les rails et en fonctionnement !

msport

  • Global Moderator
  • Hero Member
  • *****
  • Messages: 2217
  • HO avec DCC++ en DIY Réseaux très éphémères
    • Voir le profil
Re : Va et vient avec gare centrale voie unique
« Réponse #46 le: décembre 20, 2019, 05:48:26 pm »
  sensor.calibrate();

// Cette méthode calibre le point zéro du capteur,

// Assurez-vous qu'aucun courant ne traverse le capteur à ce moment


On peut comprendre (?) que le capteur est étalonné pour indiquer zéro avec le courant de la loco posée sur les rails à ce moment là.

Comme il est dit  // Ce n'est pas nécessaire, ... Faire un essai en le supprimant.

Mais en fait, la bibliothèque de l'ACS712 n'est pas nécessaire, il suffit de lire la tension sur la broche A3,
L' ACS712 5A délivre 0,75V V / A
Le MAX471 0,5 mA / A soit 1V/A avec la résistance de 2K standard.

Il y a une tension à vide, la Base Station mesure la variation par rapport à ce talon, il suffit de le lire pendant le setup.

Edit tardif : la sensibilité est de 185mV /A et la tension à vide est de VCC / 2.
« Modifié: avril 27, 2020, 09:15:08 pm par msport »
Cordialement

jeff22150

  • Newbie
  • *
  • Messages: 25
    • Voir le profil
Re : Va et vient avec gare centrale voie unique
« Réponse #47 le: décembre 24, 2019, 07:23:10 am »
Bonjour
CA MARCHE !!!!

Juste à temps pour le réveillon, mon train fonctionne presque comme je le voulais...
Je n'arrive pas à modifier la vitesse de croisière mais je reverrai cela début janvier (la fin de l'année est très chargée)
Pour ceux qui le souhaite, voici mon programme arduino
#include <Encoder.h>
#include <ACS712.h>

//la représentation physique du rail
// G -- 1 -- 2 -- 3 -- C -- 4 -- 5 -- 6 -- 7 -- D

//Les pins
int pinZG = A0; /*détecteur gare G*/
int pinZ1 = A5; /*détecteur zone 1*/
int pinZ2 = 12; /*détecteur zone 2*/
int pinZ3 = 11; /*détecteur zone 3*/
int pinZC = A1; /*détecteur gare C*/
int pinZ4 = 10; /*détecteur zone 4*/
int pinZ5 = 9;  /*détecteur zone 5*/
int pinZ6 = 8;  /*détecteur zone 6*/
int pinZ7 = 7;  /*détecteur zone 7*/
int pinZD = A2; /*détecteur gare D*/
int pinACS = A3; /*capteur de courant*/
int pinEncP = 2; /*bouton poussoir de l'encodeur - AVEC UNE INTERRUPTION */
int pinEncS = 1; /*encodeur sens de rotation*/
int pinEncR = 3; /*encodeur rotation - AVEC UNE INTERRUPTION */
int pinPWM = 6; /*enB du OKY3195*/
int pinS1 = 5; /*sens direct du courant OKY3195 */ /*ATENTION : ne jamais avoir pinS1 et pinS2 à HIGH en même temps*/
int pinS2 = 4; /*sens opposé du courant OKY3195 */ /*ATENTION : ne jamais avoir pinS1 et pinS2 à HIGH en même temps*/
int pinSeed = A4; /*pour le grain de folie aléatoire*/
Encoder myEnc(pinEncS,pinEncR); /*déclaration de l'encodeur pour la bibliothèque Encoder.h*/
ACS712 sensor(ACS712_05B, pinACS); /* declaration du capteur de courant*/


//Les énumérations
enum zones {gareG,zone1,zone2,zone3,gareC,zone4,zone5,zone6,zone7,gareD}; /*les différentes zones (cantons)*/
enum vitesses {STOP, LENT, ACC, RAPIDE, RAL}; /*les différentes vitesses possibles*/
enum trajets {GC,CG,DC,CD,GD,DG}; /*Les différents trajets possibles (GC = de G à C)*/


/*les différentes allures en fonction des trajets*/
/*                            G       1      2        3      C      4      5      6      7      D      */
const int allures[][10] =   {{LENT , ACC  , RAPIDE , RAL  , STOP , STOP , STOP , STOP  , STOP , STOP},  /*le trajet GC*/
                            {STOP , RAL  , RAPIDE , ACC  , LENT , STOP , STOP , STOP  , STOP , STOP},  /*le trajet CG*/
                            {STOP , STOP , STOP   , STOP , STOP , LENT , RAL  , RAPIDE , ACC , LENT},  /*le trajet DC*/
                            {STOP , STOP , STOP   , STOP , LENT , LENT , ACC  , RAPIDE , RAL , STOP},  /*le trajet CD*/
                            {LENT , ACC  , RAPIDE , RAL  , LENT , LENT , ACC  , RAPIDE , RAL , STOP},  /*le trajet GD*/
                            {STOP , RAL  , RAPIDE , ACC  , LENT , LENT , RAL  , RAPIDE , ACC , LENT}}; /*le trajet DG*/

const int sens[6] = {1,-1,-1,1,1,-1}; /* les sens de trajet : 1 = de G vers D ; -1 = de D vers G */

//les variables
long maxSpeed = 200; /* la vitesse maximale (entre 0 et 250 en PWM) que pourra atteindre le train dans les phases RAPIDE*/
const long minSpeed = 100; /*la vitesse du train dans les phases LENT et au redémarrage*/
long theSpeed;
long stepSpeed =20;

boolean isON = true; /* pour le bouton poussoir : isON = true -> le train a le droit de rouler ; isON = false -> arret d'urgence (PWM à 0)*/

const unsigned long antiRebond = 3; /*délai pour l'anti rebond du bouton poussoir */

int currentTrip;
boolean endTrip;

int currentZone =-999;

//Les fonctions
/*pour changer l'aléatoire de random*/
byte getSeed()
{
  byte seed = 0;
  byte i = 8;
  while (i > 0)
  {
    byte firstBit = analogRead(pinSeed) & 0x01;
    byte secondBit = analogRead(pinSeed) & 0x01;
    if (firstBit != secondBit)
    {
      seed = (seed << 1) | firstBit;
      i--;
    }
  }
  return seed;
}

/*pour savoir où est le train*/
int WhereIsMyTrain(int theZone)
{
  switch(theZone)
  {
    case gareG:
      if (digitalRead(pinZ1)==0) {return zone1;}
      else {return currentZone;}
      break;
    case zone1:
      if (digitalRead(pinZG)==0) {return gareG;}
      else if(digitalRead(pinZ2)==0) {return zone2;}
      else {return currentZone;}
      break;
    case zone2:
      if (digitalRead(pinZ1)==0) {return zone1;}
      else if(digitalRead(pinZ3)==0) {return zone3;}
      else {return currentZone;}
      break;
    case zone3:
      if (digitalRead(pinZ2)==0) {return zone2;}
      else if(digitalRead(pinZC)==0) {return gareC;}
      else {return currentZone;}
      break;
    case gareC:
      if (digitalRead(pinZ3)==0) {return zone3;}
      else if(digitalRead(pinZ4)==0) {return zone4;}
      else {return currentZone;}
      break;
    case zone4:
      if (digitalRead(pinZC)==0) {return gareC;}
      else if(digitalRead(pinZ5)==0) {return zone5;}
      else {return currentZone;}
      break;
    case zone5:
      if (digitalRead(pinZ4)==0) {return zone4;}
      else if(digitalRead(pinZ6)==0) {return zone6;}
      else {return currentZone;}
      break;
    case zone6:
      if (digitalRead(pinZ5)==0) {return zone5;}
      else if(digitalRead(pinZ7)==0) {return zone7;}
      else {return currentZone;}
      break;
    case zone7:
    if (digitalRead(pinZ6)==0) {return zone6;}
      else if(digitalRead(pinZD)==0) {return gareD;}
      else {return currentZone;}
      break;
    case gareD:
      if (digitalRead(pinZ7)==0) {return zone7;}
      else {return currentZone;}
      break; 
    default:
      int firstDetection = -1;
      while(firstDetection == -1)
      {
        if(digitalRead(pinZG)==0) {firstDetection = gareG;}
        else if(digitalRead(pinZ1)==0) {firstDetection = zone1;}
        else if(digitalRead(pinZ2)==0) {firstDetection = zone2;}
        else if(digitalRead(pinZ3)==0) {firstDetection = zone3;}
        else if(digitalRead(pinZC)==0) {firstDetection = gareC;}
        else if(digitalRead(pinZ4)==0) {firstDetection = zone4;}
        else if(digitalRead(pinZ5)==0) {firstDetection = zone5;}
        else if(digitalRead(pinZ6)==0) {firstDetection = zone6;}
        else if(digitalRead(pinZ7)==0) {firstDetection = zone7;}
        else if(digitalRead(pinZD)==0) {firstDetection = gareD;}
      }
      return firstDetection;
  }
}

/*choix du trajet suivant*/
int NextTrip(int CurrentTrip)
{
  int newTrip;
  //choix aléatoire d'un nombre
  int choix = random(0,2);
  //choix du nouveau trajet
  if (CurrentTrip == GC || CurrentTrip == DC)
  {
    if (choix == 0) {newTrip = CG;}
    else {newTrip = CD;}
  }
  else if (CurrentTrip == CG || CurrentTrip == DG)
  {
    if (choix == 0) {newTrip = GC;}
    else {newTrip = GD;}
  }
  else if (CurrentTrip == CD || CurrentTrip == GD)
  {
    if (choix == 0) {newTrip = DC;}
    else {newTrip = DG;}
  }

  if (sens[CurrentTrip]!=sens[newTrip])
  {
    /*attention il est impossible d'avoir les deux à HIGH en même temps*/
    /* il faut inverser les deux*/
    if (digitalRead(pinS1)==HIGH)
    {
      digitalWrite(pinS1,LOW);
      digitalWrite(pinS2,HIGH);
    }
    else /*si ce n'est pas S1 à HIGH, c'est forcément S2*/
    {
      digitalWrite(pinS2,LOW);
      digitalWrite(pinS1,HIGH);
    }
  }
  return newTrip;
}


void setup() {
  // initialisation des pins de l'arduino
  pinMode(pinZG,INPUT_PULLUP);
  pinMode(pinZ1,INPUT_PULLUP);
  pinMode(pinZ2,INPUT_PULLUP);
  pinMode(pinZ3,INPUT_PULLUP);
  pinMode(pinZC,INPUT_PULLUP);
  pinMode(pinZ4,INPUT_PULLUP);
  pinMode(pinZ5,INPUT_PULLUP);
  pinMode(pinZ6,INPUT_PULLUP);
  pinMode(pinZ7,INPUT_PULLUP);
  pinMode(pinZD,INPUT_PULLUP);
  pinMode(pinACS,INPUT);
  pinMode(pinEncP,INPUT_PULLUP);
  //pinMode(pinEncS,INPUT); dans la définition de l'encodeur ligne 21
  //pinMode(pinEncR,INPUT); dans la définition de l'encodeur ligne 21
  pinMode(pinPWM,OUTPUT);
  pinMode(pinS1,OUTPUT);
  pinMode(pinS2,OUTPUT);
  pinMode(pinSeed,INPUT);

  randomSeed(getSeed()); /*pour l'aléatoire*/

  endTrip = false;
  currentTrip = GD;
  digitalWrite(pinS2,HIGH);
  digitalWrite(pinS1,LOW);
  theSpeed = minSpeed;
 
  //démarrage du train mais à PWM insuffisant pour faire avancer le train
  analogWrite(pinPWM,80);

  //détection de la zone où se situe le train
  currentZone = WhereIsMyTrain(currentZone);
  Serial.println(currentZone);
  analogWrite(pinPWM,theSpeed);
}

void loop() {

  if(endTrip == true) //le trajet est-il terminée
  {
    currentTrip = NextTrip(currentTrip); //choisir un nouveau trajet
    endTrip = false;
    delay(3000); //attendre trois secondes avant le redémarrage
  }
 
  currentZone = WhereIsMyTrain(currentZone);
 
  switch (allures[currentTrip][currentZone])
  {
    case LENT:
      if (theSpeed != minSpeed && isON == true) {theSpeed = minSpeed;}
      break;
    case RAPIDE:
      if (theSpeed != maxSpeed && isON == true) {theSpeed = maxSpeed;}
      break;
    case ACC:
      if ((theSpeed+stepSpeed)<=maxSpeed && isON == true) {theSpeed = theSpeed+stepSpeed;}
      break;
    case RAL:
      if ((theSpeed-stepSpeed)>=minSpeed && isON == true) {theSpeed = theSpeed-stepSpeed;}
      break;
    case STOP: /*le trajet est terminé*/
      theSpeed = 0;
      endTrip = true;
  }
  analogWrite(pinPWM,theSpeed);
 
}

msport

  • Global Moderator
  • Hero Member
  • *****
  • Messages: 2217
  • HO avec DCC++ en DIY Réseaux très éphémères
    • Voir le profil
Re : Va et vient avec gare centrale voie unique
« Réponse #48 le: décembre 24, 2019, 10:47:50 am »
Félicitations, et merci pour le partage.
Cordialement

jeff22150

  • Newbie
  • *
  • Messages: 25
    • Voir le profil
Re : Va et vient avec gare centrale voie unique
« Réponse #49 le: décembre 24, 2019, 11:27:36 am »
Pour ce qui est du partage, je vous ferai un retour plus approfondi début janvier avec tout le cablage...
Bonne fêtes de fin d'année.