Forums LR PRESSE

Où il est question de trains, petits et grands

  • Advertisement

Aller-Retour Automatique

Toutes les discussions sur l'Arduino !

Modérateur: MOD

Aller-Retour Automatique

Publié: Jeu 26 Jan 2017, 21:39 
Bonsoir à tous,
Afin d'assurer un mouvement sans pour autant être en permanence devant le réseau en exposition, j'ai décidé d'installer un aller-retour automatique sur mon réseau en construction (cf. http://forums.e-train.fr/viewtopic.php? ... 01&start=0)
J'utilise une centrale Digitrax depuis près de 20 ans qui me donne toute satisfaction. Et de fait, j'ai à disposition le bus de signalisation Loconet.

J'ai repris avec quelques modifications toutefois l'interface Arduino Loconet conçue pour un autre projet (cf. http://forums.e-train.fr/viewtopic.php?f=63&t=75470).
J'ai en fait intégré des borniers à vis pour sécuriser les connexions.

Image

Qui dit aller retour automatique dit détection. Il existe différents types de détection (diode, barrière infra-rouge,...). Sur les conseils avisés de Marcel, j'ai opté pour la détection par diode, un grand classique.

Image

Et le programme qui n'est en fait qu'une simple séquence dans une boucle.

Code: Tout sélectionner
// DCC-ARC-System

// DCC Digitrax automatic reverse circuit
// Detection with DIODE

// Fabrice Fayolle, January 2017
// Version 1.1 for Arduino Uno

// Arduino Uno
// Pin                  -> Use for                      -> Connect to
// 0
// 1
// 2
// 3                    -> ACR On                       -> SPDT
// 4
// 5
// 6                    -> ACR Indicator                -> Red LED (with a 220 ohms resistor)
// 7                    -> LocoNet Transmit pin         -> Locoshield PCB Tx pin
// 8                    -> LocoNet Receive pin          -> Locoshield PCB Rx pin
// 9
// 10
// 11
// 12
// 13
// 14 to 19             -> Detection Input              -> DIODE

// INPUT
// ACR
// ACR On -> SPDT ON-ON
// 5V -> Not activated / 0V -> Activated
// Detection : DIODE
// Not detected -> HIGH
// Detected -> LOW
// OUTPUT
// Digitrax LocoNet message

// Global constants and variables
const int ACR_On = 3;
const boolean Not_Activated = HIGH;
const boolean Activated = !(Not_Activated);
const int Min_Time = 2500;
const int Max_Time = 7500;
int Stop_Time;
const int ACR_Indicator = 6;
const boolean On = HIGH;
const boolean Off = !(On);

// DIODE
// Define constants
const int Detect_West1_PIN = 14;
const int Detect_West2_PIN = 15;
const int Detect_East1_PIN = 17;
const int Detect_East2_PIN = 18;

// Throttle
// Define used slots table
int used_SLOT[120];
// Define the address of the loco DCC decoder you want to use for ACR system
const int ADR_Loco = 3;
// Define the loco speed
const int Speed_Loco = 0x25;

// LocoNet
#include <LocoNet.h>
// Define LocoNet Transmit Pin
#define LN_TX_PIN     7
// Pointer to a received LocoNet packet
lnMsg  *LnPacket;
void slot_Init()
// Initiliaze all slots
{
  for (int slot = 0; slot < 120; slot++)
  {
    sendOPC_xxx(OPC_RQ_SL_DATA, slot, 0);
  }
}
void sendOPC_x(int OPC_Type)
// OPC_GPOFF - OPC_GPON - OPC_IDLE LocoNet Message
{
  lnMsg SendPacket;
  SendPacket.data[0] = OPC_Type;
  LocoNet.send( &SendPacket );
  switch (OPC_Type)
  {
    case OPC_GPOFF:
      // OPC_GPOFF -> Power OFF
      Serial.print("OPC_GPOFF");
      break;
    case OPC_GPON:
      // OPC_GPON -> Power ON
      Serial.print("OPC_GPON");
      break;
    case OPC_IDLE:
      // OPC_IDLE -> Emergency Stop_Time
      Serial.print("OPC_IDLE");
      break;
  }
  Serial.println(" LocoNet message sent");
  delay(250);
  return;
}
void sendOPC_xxx(int OPC_Type, int Arg1, int Arg2)
// OPC_LOCO_SPD - OPC_LOCO_DIRF - OPC_LOCO_SND - OPC_SW_REQ - OPC_MOVE_SLOTS - OPC_RQ_SL_DATA - OPC_LOCO_ADR LocoNet Message
{
  lnMsg SendPacket;
  SendPacket.data[0] = OPC_Type;
  SendPacket.data[1] = Arg1;
  SendPacket.data[2] = Arg2;
  LocoNet.send( &SendPacket );
  switch (OPC_Type)
  {
    case OPC_LOCO_SPD:
      // OPC_LOCO_SPD
      Serial.print ("SLOT ");
      Serial.print(Arg1);
      Serial.print(" : OPC_LOCO_SPD");
      break;
    case OPC_LOCO_DIRF:
      // OPC_LOCO_DIRF
      Serial.print ("SLOT ");
      Serial.print(Arg1);
      Serial.print(" : OPC_LOCO_DIRF");
      break;
    case OPC_LOCO_SND:
      // OPC_LOCO_SND
      Serial.print ("SLOT ");
      Serial.print(Arg1);
      Serial.print(" : OPC_LOCO_SND");
      break;
    case OPC_SW_REQ:
      // OPC_SW_REQ
      Serial.print ("Turnout Adr ");
      Serial.print(Arg1 + 1);
      Serial.print(" : OPC_SW_REQ");
      break;
    case OPC_MOVE_SLOTS:
      // OPC_MOVE_SLOTS
      Serial.print ("SLOT ");
      Serial.print(Arg1);
      Serial.print(" : OPC_MOVE_SLOTS");
      break;
    case OPC_RQ_SL_DATA:
      // OPC_RQ_SL_DATA
      Serial.print ("SLOT ");
      Serial.print(Arg1);
      Serial.print(" : OPC_RQ_SL_DATA");
      break;
    case OPC_LOCO_ADR:
      // OPC_LOCO_ADR
      Serial.print ("DCC Adr ");
      Serial.print(Arg2);
      Serial.print(" : OPC_LOCO_ADR");
      break;
  }
  Serial.println(" LocoNet message sent");
  delay(250);
  return;
}
void LocoNet_Message_For_Lever(int SLever_dcc, int SLever_type, boolean SLever_state)
{
  int sw1 = 0x00;
  int sw2 = 0x00;
  switch (SLever_type)
  {
    case 0 :
      // 0 -> Not use
      break;
    case 1 :
      // 1 -> Point
      SLever_dcc = SLever_dcc - 1;
      if (SLever_state)
      {
        sw1 |= B00100000;
        sw2 |= B00100000;
      }
      sw1 |= B00010000;
      sw1 |= (SLever_dcc >> 7) & 0x0F;
      sw2 |= (SLever_dcc >> 7) & 0x0F;
      sendOPC_xxx(OPC_SW_REQ, SLever_dcc & 0x7F, sw1);
      sendOPC_xxx(OPC_SW_REQ, SLever_dcc & 0x7F, sw2);
      break;
    case 2:
      // 2 -> FPL
      break;
    case 3:
      // 3 -> Signal
      break;
    case 4:
      // 4 -> Block signal
      break;
  }
  return;
}

// Object "Throttle"
class Throttle
{
  private:
    int SLOT;
    int ADR;
    int SPD;
    int DIRF;
    int SND;
  public:
    void Setup(int SADR);
    void Change_SPD(int SSPD);
    void Change_DIRF(int SDIRF);
    void Change_SND(int SSND);
}
;
void Throttle::Setup(int SADR)
{
  sendOPC_xxx(OPC_LOCO_ADR, 0, SADR);
  LnPacket = LocoNet.receive() ;
  while ((LnPacket->data[0] != 0xE7) | (LnPacket->data[4] != SADR))
  {
    sendOPC_xxx(OPC_LOCO_ADR, 0, SADR);
    LnPacket = LocoNet.receive();
  }
  Serial.print(LnPacket->data[0], HEX);
  Serial.print(" LocoNet Message Received -> DCC Adr ");
  Serial.print(LnPacket->data[4]);
  Serial.print(" was found in SLOT ");
  Serial.println(LnPacket->data[2]);
  SLOT = LnPacket->data[2];
  ADR = LnPacket->data[4];
  SPD = 0x00;
  DIRF = 0x30;
  SND = 0x00;
  sendOPC_xxx(OPC_MOVE_SLOTS, SLOT, SLOT);
  sendOPC_xxx(OPC_LOCO_DIRF, SLOT, DIRF);
  sendOPC_xxx(OPC_LOCO_SPD, SLOT, SPD);
  sendOPC_xxx(OPC_LOCO_SND, SLOT, SND);
  Serial.println("Communication initialized");
  int i = 0;
  while (used_SLOT[i] != 0)
  {
    i = i + 1;
  }
  used_SLOT[i] = SLOT;
  return;
}
void Throttle::Change_SPD(int SSPD)
{
  SPD = SSPD;
  Serial.print("SPD at ");
  Serial.print((SPD * 100) / 128);
  Serial.println("%");
  sendOPC_xxx(OPC_LOCO_SPD, SLOT, SPD);
}
void Throttle::Change_DIRF(int SDIRF)
{
  DIRF = DIRF + SDIRF;
  Serial.print("DIRF:");
  Serial.print(DIRF);
  Serial.print("\t\tDirection: ");
  Serial.print(((DIRF & 0x20) == 0) ? "<-" : "->");
  Serial.print("\tFunction(s): ");
  Serial.print(((DIRF & 0x10) == 0) ? "" : "F0 ");
  Serial.print(((DIRF & 0x01) == 0) ? "" : "F1 ");
  Serial.print(((DIRF & 0x02) == 0) ? "" : "F2 ");
  Serial.println(((DIRF & 0x04) == 0) ? "" : "F3");
  sendOPC_xxx(OPC_LOCO_DIRF, SLOT, DIRF);
}
void Throttle::Change_SND(int SSND)
{
  SND = SND + SSND;
  Serial.print("SND:");
  Serial.println(SND);
  sendOPC_xxx(OPC_LOCO_DIRF, SLOT, SND);
}
Throttle Loco_Throttle;


void setup()
{
  // Initialize Serial Port USB at 57600 baud
  Serial.begin(57600);
  Serial.println("Monitor ready");
  // LocoNet
  LocoNet.init(LN_TX_PIN);
  // DCC
  DCC_On();
  // ACR
  pinMode(ACR_On, INPUT);
  digitalWrite(ACR_On, HIGH);
  // Initialize Detection Input
  pinMode(Detect_West1_PIN, INPUT);
  digitalWrite(Detect_West1_PIN, Not_Activated);
  pinMode(Detect_West2_PIN, INPUT);
  digitalWrite(Detect_West2_PIN, Not_Activated);
  pinMode(Detect_East1_PIN, INPUT);
  digitalWrite(Detect_East1_PIN, Not_Activated);
  pinMode(Detect_East2_PIN, INPUT);
  digitalWrite(Detect_East2_PIN, Not_Activated);
  // ACR Indicator
  pinMode(ACR_Indicator, OUTPUT);
  digitalWrite(ACR_Indicator, Off);
  // Initialize Loco Throttle
  Loco_Throttle.Setup(ADR_Loco);
  // Initialize Random Stop_Time Time Variable
  randomSeed(1000);
  // System initialized
  Serial.println("System ACR initialized");
}

void ACR_Detection_Indicated()
{
  int delay_time = 250;
  digitalWrite(ACR_Indicator, Off);
  delay(delay_time);
  digitalWrite(ACR_Indicator, On);
  delay(delay_time);
  digitalWrite(ACR_Indicator, Off);
  delay(delay_time);

}

void ACR_loop()
{
  while ((digitalRead(Detect_West1_PIN) == Not_Activated) && (digitalRead(Detect_West2_PIN) == Not_Activated))
  {
    delay(100);
  }
  Serial.println("Loco on West detector");
  Loco_Throttle.Change_SPD(0x00);
  ACR_Detection_Indicated();
  Stop_Time = random(Min_Time, Max_Time);
  Serial.print("Stop during ");
  Serial.print(Stop_Time);
  Serial.println(" ms");
  delay(Stop_Time);
  Loco_Throttle.Change_DIRF(-0x20);
  Loco_Throttle.Change_SPD(Speed_Loco);
  while ((digitalRead(Detect_East1_PIN) == Not_Activated) && (digitalRead(Detect_East2_PIN) == Not_Activated))
  {
    delay(100);
  }
  Serial.println("Loco on East detector");
  Loco_Throttle.Change_SPD(0x00);
  ACR_Detection_Indicated();
  Stop_Time = random(Min_Time, Max_Time);
  Serial.print("Stop during ");
  Serial.print(Stop_Time);
  Serial.println(" ms");
  delay(Stop_Time);
  Loco_Throttle.Change_DIRF(0x20);
  Loco_Throttle.Change_SPD(Speed_Loco);
  if (digitalRead(ACR_On) == Activated)
  {
    ACR_loop();
  }
  else
  {
    delay(2500);
    Loco_Throttle.Change_SPD(0x00);
    Serial.println("System ACR stopped");
  }
}

void loop()
{
  while (digitalRead(ACR_On) == Not_Activated)
  {
  }
  // Initialize Automatic Circuit Reverse
  // Loco must have activated West 1 detector to initialize the system
  Serial.println("Waiting for System ACR activation");
  while (digitalRead (Detect_West1_PIN) == Not_Activated)
  {
    digitalWrite(ACR_Indicator, On);
    delay(250);
    digitalWrite(ACR_Indicator, Off);
    delay(250);
  }
  // System initialized
  Serial.println("System ACR activited");
  digitalWrite(ACR_Indicator, On);
  ACR_loop();
  digitalWrite(ACR_Indicator, Off);
}

void DCC_On()
// DCC Power ON
{
  sendOPC_x(OPC_GPOFF);
  sendOPC_x(OPC_GPON);
  return;
}


Des questions?
Des commentaires?
Fabrice Fayolle
Avatar de l’utilisateur
ffayolle
Causant
 
Messages: 234
Inscrit le: Mar 09 Mai 2006, 19:55
Localisation: Amiens, Somme, Picardie
Âge: 50

Re: Aller-Retour Automatique

Publié: Jeu 26 Jan 2017, 22:46 
Perso, j'ai acheté le module "va et vient automatique n°112" d'Intégral© qui fonctionne en DCC même sans centrale, en gardant la sonorisation et les feux et j'y ai rajouté l'option "module aiguillage" avec relais, qui me permet de faire circuler 2 convois alternativement sur un tronçon de voie unique muni à chaque extrêmité d'une aiguille et de 2 tiroirs.

Et ceci, sans graver de circuit imprimé ni rentrer une ligne de code Arduino ... :mrgreen:
Briques et vapeur ...
cdz183
Éloquent
 
Messages: 363
Inscrit le: Lun 21 Mars 2011, 01:22
Localisation: 89- Auxerre
Âge: 54
Echelle pratiquée: zéro Nord 56-64
Prénom: Nicolas
Club: RMC59 / CdZ / AATY

Re: Aller-Retour Automatique

Publié: Ven 27 Jan 2017, 11:10 
cdz183 a écrit:Perso, j'ai acheté le module "va et vient automatique n°112" d'Intégral© qui fonctionne en DCC même sans centrale, en gardant la sonorisation et les feux et j'y ai rajouté l'option "module aiguillage" avec relais, qui me permet de faire circuler 2 convois alternativement sur un tronçon de voie unique muni à chaque extrêmité d'une aiguille et de 2 tiroirs.

Et ceci, sans graver de circuit imprimé ni rentrer une ligne de code Arduino ... :mrgreen:


Nous sommes contents pour vous ! Mais il n'y a pas de quoi en être fier... :oops:

Si tous ceux qui achètent tout fait dans le commerce devaient s'exprimer sur ce fil, le trafic augmenterait considérablement mais ce fil n'aurait plus aucun intérêt pour les autres.

Alors bravo à ffayolle qui a conçu et réalisé quelque chose, et merci à lui d'en faire profiter les autres. :applause:

En digital, un va et vient a besoin sans doute de détection pour savoir quand envoyer l'ordre de changement de sens à la locomotive ; en analogique, c'est plus simple, il suffit d'inverser le courant dans les rails qui sont pourvus de deux sections d'arrêt à chaque bout. Suivant le temps qu'on règle pour inverser le courant, la locomotive restera plus ou moins longtemps à chaque bout du va et vient. Ceci a été décrit dans le N°805 de LR (août 2014) (va et vient réalisé en analogique à base d'Arduino).

Mais c'est très intéressant d'avoir des réalisations pour le numérique qui est de plus en plus adopté par les modélistes. C'est d'ailleurs la tendance de ceux qui pratiquent Arduino aujourd'hui.
Avatar de l’utilisateur
Arduino
Démonstratif
 
Messages: 1528
Inscrit le: Mer 25 Sep 2013, 17:14

Re: Aller-Retour Automatique

Publié: Ven 27 Jan 2017, 12:16 
ffayolle a écrit:Bonsoir à tous,
Afin d'assurer un mouvement sans pour autant être en permanence devant le réseau en exposition, j'ai décidé d'installer un aller-retour automatique sur mon réseau en construction (cf. viewtopic.php?f=14&t=82901&start=0)


Je suis allé voir ton fil sur ton réseau. J'aime beaucoup de plan de voies et je pense que pour ce genre de réseau, le DCC est idéal. Et j'ai toujours beaucoup d'admiration pour ceux qui posent leur voie eux-mêmes. C'est superbe et tu me donnerais presque l'envie de faire du 0. Je vais suivre la suite avec beaucoup d'intérêt. Bonne continuation. :wink:
Avatar de l’utilisateur
Arduino
Démonstratif
 
Messages: 1528
Inscrit le: Mer 25 Sep 2013, 17:14

Re: Aller-Retour Automatique

Publié: Ven 27 Jan 2017, 12:27 
cdz183 a écrit:Perso, j'ai acheté le module "va et vient automatique n°112" d'Intégral© qui fonctionne en DCC même sans centrale, en gardant la sonorisation et les feux et j'y ai rajouté l'option "module aiguillage" avec relais, qui me permet de faire circuler 2 convois alternativement sur un tronçon de voie unique muni à chaque extrêmité d'une aiguille et de 2 tiroirs.

Et ceci, sans graver de circuit imprimé ni rentrer une ligne de code Arduino ... :mrgreen:



Je ne connaissais pas mais j'aime bien "m'embêter".
:siffle: :siffle: :siffle:
Cela me fait réfléchir et maintient mon éveil. N'est-il pas, docteur?
Fabrice Fayolle
Avatar de l’utilisateur
ffayolle
Causant
 
Messages: 234
Inscrit le: Mar 09 Mai 2006, 19:55
Localisation: Amiens, Somme, Picardie
Âge: 50

Re: Aller-Retour Automatique

Publié: Ven 27 Jan 2017, 12:28 
Arduino a écrit:Je suis allé voir ton fil sur ton réseau. J'aime beaucoup de plan de voies et je pense que pour ce genre de réseau, le DCC est idéal. Et j'ai toujours beaucoup d'admiration pour ceux qui posent leur voie eux-mêmes. C'est superbe et tu me donnerais presque l'envie de faire du 0. Je vais suivre la suite avec beaucoup d'intérêt. Bonne continuation. :wink:


Merci
Fabrice Fayolle
Avatar de l’utilisateur
ffayolle
Causant
 
Messages: 234
Inscrit le: Mar 09 Mai 2006, 19:55
Localisation: Amiens, Somme, Picardie
Âge: 50

Re: Aller-Retour Automatique

Publié: Dim 26 Fév 2017, 14:40 
Bonjour,
Le système est opérationnel. Mais à l'utilisation, dommage de ne pas pouvoir choisir l'engin moteur à piloter ainsi que sa vitesse sans parler de la possibilité d'utiliser ou non les fonctions sonores.

Les 2 derniers points sont déjà mis en œuvre.
Le son : un simple interrupteur permet d'utiliser ou non les fonctions sonores.
La vitesse : un potentiomètre permet d'ajuster la vitesse de l'engin (lecteur analogique d'une valeur comprise en 0 (0V) en 1023 (5V)).

Le code mis à jour :

Code: Tout sélectionner
// DCC-ARC-System

// DCC Digitrax automatic reverse circuit
// Detection with DIODE

// Fabrice Fayolle, February 2017
// Version 2.0 for Arduino Uno

// Arduino Uno
// Pin                  -> Use for                      -> Connect to
// 0
// 1
// 2
// 3                    -> ACR On                       -> SPDT
// 4                    -> DCC Sound                    -> SPDT
// 5                    -> Speed Loco                   -> Potentiometer
// 6                    -> ACR Indicator                -> Red LED (with a 220 ohms resistor)
// 7                    -> LocoNet Transmit pin         -> Locoshield PCB Tx pin
// 8                    -> LocoNet Receive pin          -> Locoshield PCB Rx pin
// 9
// 10
// 11
// 12
// 13
// 14 to 19             -> Detection Input              -> DIODE

// INPUT
// ACR
// ACR On -> SPDT ON-ON
// 5V -> Not activated / 0V -> Activated
// DCC
// DCC Sound -> SPDT ON-ON
// 5V -> Not activated / 0V -> Activated
// Speed loco -> Potentiometer 10K
// Detection : DIODE
// Not detected -> HIGH
// Detected -> LOW
// OUTPUT
// Digitrax LocoNet message

// Global constants and variables
const int ACR_On_Pin = 3;
const int Sound_On_Pin = 4;
const int Speed_Loco_Pin = 5;
boolean Sound_Activated;
const boolean Not_Activated = HIGH;
const boolean Activated = !(Not_Activated);
const int Min_Time = 6000;
const int Max_Time = 12000;
const int Detect_Time = 1250;
const int ACR_Indicator = 6;
const boolean On = HIGH;
const boolean Off = !(On);

// DIODE
// Define constants
const int Detect_West1_PIN = 14;
const int Detect_West2_PIN = 15;
const int Detect_East1_PIN = 17;
const int Detect_East2_PIN = 18;

// Throttle
// Define used slots table
int used_SLOT[120];
// Define the address of the loco DCC decoder you want to use for ACR system
const int ADR_Loco = 12;
// Define the loco speed
int Speed_Loco = 0x00;

// LocoNet
#include <LocoNet.h>
// Define LocoNet Transmit Pin
#define LN_TX_PIN     7
// Pointer to a received LocoNet packet
lnMsg  *LnPacket;
void slot_Init()
// Initiliaze all slots
{
  for (int slot = 0; slot < 120; slot++)
  {
    sendOPC_xxx(OPC_RQ_SL_DATA, slot, 0);
  }
}
void sendOPC_x(int OPC_Type)
// OPC_GPOFF - OPC_GPON - OPC_IDLE LocoNet Message
{
  lnMsg SendPacket;
  SendPacket.data[0] = OPC_Type;
  LocoNet.send( &SendPacket );
  switch (OPC_Type)
  {
    case OPC_GPOFF:
      // OPC_GPOFF -> Power OFF
      Serial.print("OPC_GPOFF");
      break;
    case OPC_GPON:
      // OPC_GPON -> Power ON
      Serial.print("OPC_GPON");
      break;
    case OPC_IDLE:
      // OPC_IDLE -> Emergency Stop_Time
      Serial.print("OPC_IDLE");
      break;
  }
  Serial.println(" LocoNet message sent");
  delay(250);
  return;
}
void sendOPC_xxx(int OPC_Type, int Arg1, int Arg2)
// OPC_LOCO_SPD - OPC_LOCO_DIRF - OPC_LOCO_SND - OPC_SW_REQ - OPC_MOVE_SLOTS - OPC_RQ_SL_DATA - OPC_LOCO_ADR LocoNet Message
{
  lnMsg SendPacket;
  SendPacket.data[0] = OPC_Type;
  SendPacket.data[1] = Arg1;
  SendPacket.data[2] = Arg2;
  LocoNet.send( &SendPacket );
  switch (OPC_Type)
  {
    case OPC_LOCO_SPD:
      // OPC_LOCO_SPD
      Serial.print ("SLOT ");
      Serial.print(Arg1);
      Serial.print(" : OPC_LOCO_SPD");
      break;
    case OPC_LOCO_DIRF:
      // OPC_LOCO_DIRF
      Serial.print ("SLOT ");
      Serial.print(Arg1);
      Serial.print(" : OPC_LOCO_DIRF");
      break;
    case OPC_LOCO_SND:
      // OPC_LOCO_SND
      Serial.print ("SLOT ");
      Serial.print(Arg1);
      Serial.print(" : OPC_LOCO_SND");
      break;
    case OPC_SW_REQ:
      // OPC_SW_REQ
      Serial.print ("Turnout Adr ");
      Serial.print(Arg1 + 1);
      Serial.print(" : OPC_SW_REQ");
      break;
    case OPC_MOVE_SLOTS:
      // OPC_MOVE_SLOTS
      Serial.print ("SLOT ");
      Serial.print(Arg1);
      Serial.print(" : OPC_MOVE_SLOTS");
      break;
    case OPC_RQ_SL_DATA:
      // OPC_RQ_SL_DATA
      Serial.print ("SLOT ");
      Serial.print(Arg1);
      Serial.print(" : OPC_RQ_SL_DATA");
      break;
    case OPC_LOCO_ADR:
      // OPC_LOCO_ADR
      Serial.print ("DCC Adr ");
      Serial.print(Arg2);
      Serial.print(" : OPC_LOCO_ADR");
      break;
  }
  Serial.println(" LocoNet message sent");
  delay(250);
  return;
}
void LocoNet_Message_For_Lever(int SLever_dcc, int SLever_type, boolean SLever_state)
{
  int sw1 = 0x00;
  int sw2 = 0x00;
  switch (SLever_type)
  {
    case 0 :
      // 0 -> Not use
      break;
    case 1 :
      // 1 -> Point
      SLever_dcc = SLever_dcc - 1;
      if (SLever_state)
      {
        sw1 |= B00100000;
        sw2 |= B00100000;
      }
      sw1 |= B00010000;
      sw1 |= (SLever_dcc >> 7) & 0x0F;
      sw2 |= (SLever_dcc >> 7) & 0x0F;
      sendOPC_xxx(OPC_SW_REQ, SLever_dcc & 0x7F, sw1);
      sendOPC_xxx(OPC_SW_REQ, SLever_dcc & 0x7F, sw2);
      break;
    case 2:
      // 2 -> FPL
      break;
    case 3:
      // 3 -> Signal
      break;
    case 4:
      // 4 -> Block signal
      break;
  }
  return;
}

// Object "Throttle"
class Throttle
{
  private:
    int SLOT;
    int ADR;
    int SPD;
    int DIRF;
    int SND;
  public:
    void Setup(int SADR);
    void Change_SPD(int SSPD);
    void Change_DIRF(int SDIRF);
    void Change_SND(int SSND);
}
;
void Throttle::Setup(int SADR)
{
  sendOPC_xxx(OPC_LOCO_ADR, 0, SADR);
  LnPacket = LocoNet.receive() ;
  while ((LnPacket->data[0] != 0xE7) | (LnPacket->data[4] != SADR))
  {
    sendOPC_xxx(OPC_LOCO_ADR, 0, SADR);
    LnPacket = LocoNet.receive();
  }
  Serial.print(LnPacket->data[0], HEX);
  Serial.print(" LocoNet Message Received -> DCC Adr ");
  Serial.print(LnPacket->data[4]);
  Serial.print(" was found in SLOT ");
  Serial.println(LnPacket->data[2]);
  SLOT = LnPacket->data[2];
  ADR = LnPacket->data[4];
  SPD = 0x00;
  DIRF = 0x00;
  SND = 0x00;
  sendOPC_xxx(OPC_MOVE_SLOTS, SLOT, SLOT);
  sendOPC_xxx(OPC_LOCO_DIRF, SLOT, DIRF);
  sendOPC_xxx(OPC_LOCO_SPD, SLOT, SPD);
  sendOPC_xxx(OPC_LOCO_SND, SLOT, SND);
  Serial.println("Communication initialized");
  int i = 0;
  while (used_SLOT[i] != 0)
  {
    i = i + 1;
  }
  used_SLOT[i] = SLOT;
  return;
}
void Throttle::Change_SPD(int SSPD)
{
  SPD = SSPD;
  Serial.print("SPD at ");
  Serial.print((SPD * 100) / 128);
  Serial.println("%");
  sendOPC_xxx(OPC_LOCO_SPD, SLOT, SPD);
}
void Throttle::Change_DIRF(int SDIRF)
{
  DIRF = DIRF + SDIRF;
  Serial.print("DIRF:");
  Serial.print(DIRF);
  Serial.print("\t\tDirection: ");
  Serial.print(((DIRF & 0x20) == 0) ? "<-" : "->");
  Serial.print("\tFunction(s): ");
  Serial.print(((DIRF & 0x10) == 0) ? "" : "F0 ");
  Serial.print(((DIRF & 0x01) == 0) ? "" : "F1 ");
  Serial.print(((DIRF & 0x02) == 0) ? "" : "F2 ");
  Serial.println(((DIRF & 0x04) == 0) ? "" : "F3");
  sendOPC_xxx(OPC_LOCO_DIRF, SLOT, DIRF);
}
void Throttle::Change_SND(int SSND)
{
  SND = SND + SSND;
  Serial.print("SND:");
  Serial.println(SND);
  sendOPC_xxx(OPC_LOCO_DIRF, SLOT, SND);
}
Throttle Loco_Throttle;


void setup()
{
  // Initialize Serial Port USB at 57600 baud
  Serial.begin(57600);
  Serial.println("Monitor ready");
  // LocoNet
  LocoNet.init(LN_TX_PIN);
  // DCC
  DCC_On();
  // ACR
  pinMode(ACR_On_Pin, INPUT);
  digitalWrite(ACR_On_Pin, HIGH);
  // DCC Sound
  pinMode(Sound_On_Pin, INPUT);
  digitalWrite(Sound_On_Pin, HIGH);
  // Speed Loco
  pinMode(Speed_Loco_Pin, INPUT);
  // Initialize Detection Input
  pinMode(Detect_West1_PIN, INPUT);
  digitalWrite(Detect_West1_PIN, Not_Activated);
  pinMode(Detect_West2_PIN, INPUT);
  digitalWrite(Detect_West2_PIN, Not_Activated);
  pinMode(Detect_East1_PIN, INPUT);
  digitalWrite(Detect_East1_PIN, Not_Activated);
  pinMode(Detect_East2_PIN, INPUT);
  digitalWrite(Detect_East2_PIN, Not_Activated);
  // ACR Indicator
  pinMode(ACR_Indicator, OUTPUT);
  digitalWrite(ACR_Indicator, Off);
  // Initialize Loco Throttle
  Loco_Throttle.Setup(ADR_Loco);
  // Initialize Random Stop_Time Time Variable
  randomSeed(1000);
  // System initialized
  Serial.println("System ACR initialized");
}

void ACR_Detection_Indicated(int delay_time, int nb)
{
  for (int x = 0; x < nb; x++)
  {
    digitalWrite(ACR_Indicator, Off);
    delay(delay_time);
    digitalWrite(ACR_Indicator, On);
    delay(delay_time);
  }
  return;
}

void Stop_Time(int delay_time)
{
  Serial.print("Stop during ");
  Serial.print(delay_time);
  Serial.println(" ms");
  delay(delay_time);
  return;
}

void Whistle(int i)
{
  for (int x = 0; x < i; x++)
  {
    Loco_Throttle.Change_DIRF(0x02);
    Loco_Throttle.Change_DIRF(-0x02);
  }
  return;
}

void ACR_loop()
{
  while ((digitalRead(Detect_West1_PIN) == Not_Activated) && (digitalRead(Detect_West2_PIN) == Not_Activated))
  {
    delay(100);
  }
  Serial.println("Loco on West detector");
  ACR_Detection_Indicated(250, 2);
  delay(Detect_Time);
  Loco_Throttle.Change_SPD(0x00);
  Stop_Time(random(Min_Time, Max_Time));
  Loco_Throttle.Change_DIRF(-0x20);
  delay(1000);
  if (Sound_Activated)
  {
    Whistle(1);
    delay(2500);
  }
  Loco_Throttle.Change_SPD(Speed_Loco);
  while ((digitalRead(Detect_East1_PIN) == Not_Activated) && (digitalRead(Detect_East2_PIN) == Not_Activated))
  {
    delay(100);
  }
  Serial.println("Loco on East detector");
  ACR_Detection_Indicated(250, 2);
  delay(Detect_Time);
  Loco_Throttle.Change_SPD(0x00);
  Stop_Time(random(Min_Time, Max_Time));
  if (digitalRead(ACR_On_Pin) == Activated)
  {
    Loco_Throttle.Change_DIRF(0x20);
    delay(1000);
    if (Sound_Activated)
    {
      Whistle(2);
      delay(2500);
    }
    Loco_Throttle.Change_SPD(Speed_Loco);
    ACR_loop();
  }
  else
  {
    delay(2500);
    Loco_Throttle.Change_SPD(0x00);
    Serial.println("System ACR stopped");
  }
  return;
}

void loop()
{
  while (digitalRead(ACR_On_Pin) == Not_Activated)
  {
  }
  // Initialize Automatic Circuit Reverse
  // Sound
  if (digitalRead(Sound_On_Pin) == Activated)
  {
    Sound_Activated = HIGH;
    Serial.println("Sound activated");
  }
  else
  {
    Sound_Activated = LOW;
    Serial.println("Sound not activated");
  }
  // Speed Loco
  Speed_Loco = analogRead(Speed_Loco_Pin) / 4;
  Serial.print("Speed loco defined at ");
  Serial.print(Speed_Loco * 100 / 128);
  Serial.println("%");
  // Loco must have activated West 1 detector to initialize the system
  Serial.println("Waiting for System ACR activation");
  while (digitalRead (Detect_West1_PIN) == Not_Activated)
  {
    ACR_Detection_Indicated(100, 1);
  }
  // System initialized
  Serial.println("System ACR activited");
  digitalWrite(ACR_Indicator, On);
  Serial.print("Loco ADR ");
  Serial.print(ADR_Loco);
  Serial.println(" -> USED");
  delay(Detect_Time);
  Loco_Throttle.Change_SPD(0x00);
  delay(2500);
  Loco_Throttle.Change_DIRF(0x30);
  if (Sound_Activated)
  {
    delay(1000);
    Loco_Throttle.Change_DIRF(0x01);
    delay(5000);
  }
  ACR_loop();
  if (Sound_Activated)
  {
    delay(1000);
    Loco_Throttle.Change_DIRF(-0x01);
    delay(5000);
  }
  Loco_Throttle.Change_DIRF(-0x10);
  Serial.print("Loco ADR ");
  Serial.print(ADR_Loco);
  Serial.println(" -> NOT USED");
  digitalWrite(ACR_Indicator, Off);
}

void DCC_On()
// DCC Power ON
{
  sendOPC_x(OPC_GPOFF);
  delay(500);
  sendOPC_x(OPC_GPON);
  return;
}


Pour le 1er point, le choix de l'engin, cette modification va m'obliger à revoir mon code plus en profondeur mais rien d'impossible!!!

A suivre...
Fabrice Fayolle
Avatar de l’utilisateur
ffayolle
Causant
 
Messages: 234
Inscrit le: Mar 09 Mai 2006, 19:55
Localisation: Amiens, Somme, Picardie
Âge: 50

Re: Aller-Retour Automatique

Publié: Mer 01 Mars 2017, 12:19 
Bonjour,
Ci-joint le code fonctionnel et testé
Possibilité de choisir une adresse parmi 4 et une vitesse parmi 4

Extrait du code :
Code: Tout sélectionner
// Define the address of the loco DCC decoder you want to use for ACR system
const int ADR_Loco_Pin = 16;
const int ADR_Loco_Tab[4] = {12, 3, 11, 13};
int ADR_Loco = 12;
// Define the loco speed
const int Speed_Loco_Pin = 19;
const int Speed_Loco_Tab[4] = {0x1B, 0x03, 0x0F, 0x29};
int Speed_Loco = 0x1B;


Code complet:
Code: Tout sélectionner
// DCC-ARC-System

// DCC Digitrax automatic reverse circuit
// Detection with DIODE

// Fabrice Fayolle, February 2017
// Version 2.0 for Arduino Uno

// Arduino Uno
// Pin                  -> Use for                      -> Connect to
// 0
// 1
// 2
// 3                    -> ACR On                       -> SPDT
// 4                    -> DCC Sound                    -> SPDT
// 5                    -> Speed Loco                   -> Potentiometer
// 6                    -> ACR Indicator                -> Red LED (with a 220 ohms resistor)
// 7                    -> LocoNet Transmit pin         -> Locoshield PCB Tx pin
// 8                    -> LocoNet Receive pin          -> Locoshield PCB Rx pin
// 9
// 10
// 11
// 12
// 13
// 14 to 15             -> Detection Input (West)       -> DIODE
// 16                   -> ADR Loco selection           -> Potentiometer
// 17 to 18             -> Detection Input (East)       -> DIODE
// 19                   -> Speed Loco selection         -> Potentiometer

// INPUT
// ACR
// ACR On -> SPDT ON-ON
// 5V -> Not activated / 0V -> Activated
// DCC
// DCC Sound -> SPDT ON-ON
// 5V -> Not activated / 0V -> Activated
// Speed Loco selection -> Potentiometer 10K
// ADR Loco selection -> Potentiometer 10K
// Detection : DIODE
// Not detected -> HIGH
// Detected -> LOW
// OUTPUT
// Digitrax LocoNet message

// Global constants and variables
const int ACR_On_Pin = 3;
const int Sound_On_Pin = 4;

boolean Sound_Activated;
const boolean Not_Activated = HIGH;
const boolean Activated = !(Not_Activated);
const int Min_Time = 6000;
const int Max_Time = 12000;
const int Detect_Time = 1250;
const int ACR_Indicator = 6;
const boolean On = HIGH;
const boolean Off = !(On);

// DIODE
// Define constants
const int Detect_West1_PIN = 14;
const int Detect_West2_PIN = 15;
const int Detect_East1_PIN = 17;
const int Detect_East2_PIN = 18;

// Throttle
// Define used slots table
int used_SLOT[120];
// Define the address of the loco DCC decoder you want to use for ACR system
const int ADR_Loco_Pin = 16;
const int ADR_Loco_Tab[4] = {12, 3, 11, 13};
int ADR_Loco = 12;
// const int ADR_Loco = 12;
// Define the loco speed
const int Speed_Loco_Pin = 19;
const int Speed_Loco_Tab[4] = {0x1B, 0x03, 0x0F, 0x29};
int Speed_Loco = 0x1B;
// const int Speed_Loco = 0x1B;

// LocoNet
#include <LocoNet.h>
// Define LocoNet Transmit Pin
#define LN_TX_PIN     7
// Pointer to a received LocoNet packet
lnMsg  *LnPacket;
void slot_Init()
// Initiliaze all slots
{
  for (int slot = 0; slot < 120; slot++)
  {
    sendOPC_xxx(OPC_RQ_SL_DATA, slot, 0);
  }
}
void sendOPC_x(int OPC_Type)
// OPC_GPOFF - OPC_GPON - OPC_IDLE LocoNet Message
{
  lnMsg SendPacket;
  SendPacket.data[0] = OPC_Type;
  LocoNet.send( &SendPacket );
  switch (OPC_Type)
  {
    case OPC_GPOFF:
      // OPC_GPOFF -> Power OFF
      Serial.print("OPC_GPOFF");
      break;
    case OPC_GPON:
      // OPC_GPON -> Power ON
      Serial.print("OPC_GPON");
      break;
    case OPC_IDLE:
      // OPC_IDLE -> Emergency Stop_Time
      Serial.print("OPC_IDLE");
      break;
  }
  Serial.println(" LocoNet message sent");
  delay(250);
  return;
}
void sendOPC_xxx(int OPC_Type, int Arg1, int Arg2)
// OPC_LOCO_SPD - OPC_LOCO_DIRF - OPC_LOCO_SND - OPC_SW_REQ - OPC_MOVE_SLOTS - OPC_RQ_SL_DATA - OPC_LOCO_ADR LocoNet Message
{
  lnMsg SendPacket;
  SendPacket.data[0] = OPC_Type;
  SendPacket.data[1] = Arg1;
  SendPacket.data[2] = Arg2;
  LocoNet.send( &SendPacket );
  switch (OPC_Type)
  {
    case OPC_LOCO_SPD:
      // OPC_LOCO_SPD
      Serial.print ("SLOT ");
      Serial.print(Arg1);
      Serial.print(" : OPC_LOCO_SPD");
      break;
    case OPC_LOCO_DIRF:
      // OPC_LOCO_DIRF
      Serial.print ("SLOT ");
      Serial.print(Arg1);
      Serial.print(" : OPC_LOCO_DIRF");
      break;
    case OPC_LOCO_SND:
      // OPC_LOCO_SND
      Serial.print ("SLOT ");
      Serial.print(Arg1);
      Serial.print(" : OPC_LOCO_SND");
      break;
    case OPC_SW_REQ:
      // OPC_SW_REQ
      Serial.print ("Turnout Adr ");
      Serial.print(Arg1 + 1);
      Serial.print(" : OPC_SW_REQ");
      break;
    case OPC_MOVE_SLOTS:
      // OPC_MOVE_SLOTS
      Serial.print ("SLOT ");
      Serial.print(Arg1);
      Serial.print(" : OPC_MOVE_SLOTS");
      break;
    case OPC_RQ_SL_DATA:
      // OPC_RQ_SL_DATA
      Serial.print ("SLOT ");
      Serial.print(Arg1);
      Serial.print(" : OPC_RQ_SL_DATA");
      break;
    case OPC_LOCO_ADR:
      // OPC_LOCO_ADR
      Serial.print ("DCC Adr ");
      Serial.print(Arg2);
      Serial.print(" : OPC_LOCO_ADR");
      break;
  }
  Serial.println(" LocoNet message sent");
  delay(250);
  return;
}
void LocoNet_Message_For_Lever(int SLever_dcc, int SLever_type, boolean SLever_state)
{
  int sw1 = 0x00;
  int sw2 = 0x00;
  switch (SLever_type)
  {
    case 0 :
      // 0 -> Not use
      break;
    case 1 :
      // 1 -> Point
      SLever_dcc = SLever_dcc - 1;
      if (SLever_state)
      {
        sw1 |= B00100000;
        sw2 |= B00100000;
      }
      sw1 |= B00010000;
      sw1 |= (SLever_dcc >> 7) & 0x0F;
      sw2 |= (SLever_dcc >> 7) & 0x0F;
      sendOPC_xxx(OPC_SW_REQ, SLever_dcc & 0x7F, sw1);
      sendOPC_xxx(OPC_SW_REQ, SLever_dcc & 0x7F, sw2);
      break;
    case 2:
      // 2 -> FPL
      break;
    case 3:
      // 3 -> Signal
      break;
    case 4:
      // 4 -> Block signal
      break;
  }
  return;
}

// Object "Throttle"
class Throttle
{
  private:
    int SLOT;
    int ADR;
    int SPD;
    int DIRF;
    int SND;
  public:
    void Setup(int SADR);
    void Change_SPD(int SSPD);
    void Change_DIRF(int SDIRF);
    void Change_SND(int SSND);
}
;
void Throttle::Setup(int SADR)
{
  sendOPC_xxx(OPC_LOCO_ADR, 0, SADR);
  LnPacket = LocoNet.receive() ;
  while ((LnPacket->data[0] != 0xE7) | (LnPacket->data[4] != SADR))
  {
    sendOPC_xxx(OPC_LOCO_ADR, 0, SADR);
    LnPacket = LocoNet.receive();
  }
  Serial.print(LnPacket->data[0], HEX);
  Serial.print(" LocoNet Message Received -> DCC Adr ");
  Serial.print(LnPacket->data[4]);
  Serial.print(" was found in SLOT ");
  Serial.println(LnPacket->data[2]);
  SLOT = LnPacket->data[2];
  ADR = LnPacket->data[4];
  SPD = 0x00;
  DIRF = 0x00;
  SND = 0x00;
  sendOPC_xxx(OPC_MOVE_SLOTS, SLOT, SLOT);
  sendOPC_xxx(OPC_LOCO_DIRF, SLOT, DIRF);
  sendOPC_xxx(OPC_LOCO_SPD, SLOT, SPD);
  sendOPC_xxx(OPC_LOCO_SND, SLOT, SND);
  Serial.println("Communication initialized");
  int i = 0;
  while (used_SLOT[i] != 0)
  {
    i = i + 1;
  }
  used_SLOT[i] = SLOT;
  return;
}
void Throttle::Change_SPD(int SSPD)
{
  SPD = SSPD;
  Serial.print("SPD at ");
  Serial.print((SPD * 100) / 128);
  Serial.println("%");
  sendOPC_xxx(OPC_LOCO_SPD, SLOT, SPD);
}
void Throttle::Change_DIRF(int SDIRF)
{
  DIRF = DIRF + SDIRF;
  Serial.print("DIRF:");
  Serial.print(DIRF);
  Serial.print("\t\tDirection: ");
  Serial.print(((DIRF & 0x20) == 0) ? "<-" : "->");
  Serial.print("\tFunction(s): ");
  Serial.print(((DIRF & 0x10) == 0) ? "" : "F0 ");
  Serial.print(((DIRF & 0x01) == 0) ? "" : "F1 ");
  Serial.print(((DIRF & 0x02) == 0) ? "" : "F2 ");
  Serial.println(((DIRF & 0x04) == 0) ? "" : "F3");
  sendOPC_xxx(OPC_LOCO_DIRF, SLOT, DIRF);
}
void Throttle::Change_SND(int SSND)
{
  SND = SND + SSND;
  Serial.print("SND:");
  Serial.println(SND);
  sendOPC_xxx(OPC_LOCO_DIRF, SLOT, SND);
}
Throttle Loco_Throttle;


void setup()
{
  // Initialize Serial Port USB at 57600 baud
  Serial.begin(57600);
  Serial.println("Monitor ready");
  // LocoNet
  LocoNet.init(LN_TX_PIN);
  // DCC
  DCC_On();
  // ACR
  pinMode(ACR_On_Pin, INPUT);
  digitalWrite(ACR_On_Pin, HIGH);
  // DCC Sound
  pinMode(Sound_On_Pin, INPUT);
  digitalWrite(Sound_On_Pin, HIGH);
  // Speed Loco
  pinMode(Speed_Loco_Pin, INPUT);
  // ADR Loco
  pinMode(ADR_Loco_Pin, INPUT);
  // Initialize Detection Input
  pinMode(Detect_West1_PIN, INPUT);
  digitalWrite(Detect_West1_PIN, Not_Activated);
  pinMode(Detect_West2_PIN, INPUT);
  digitalWrite(Detect_West2_PIN, Not_Activated);
  pinMode(Detect_East1_PIN, INPUT);
  digitalWrite(Detect_East1_PIN, Not_Activated);
  pinMode(Detect_East2_PIN, INPUT);
  digitalWrite(Detect_East2_PIN, Not_Activated);
  // ACR Indicator
  pinMode(ACR_Indicator, OUTPUT);
  digitalWrite(ACR_Indicator, Off);
  // Initialize Loco Throttle
  // Loco_Throttle.Setup(ADR_Loco);
  // Initialize Random Stop_Time Time Variable
  randomSeed(1000);
  // System initialized
  Serial.println("System ACR initialized");
}

int ind_tab_read(int pin, int gap)
{
  int value;
  int k = gap;
  int i = 0;
  value = analogRead(pin);
  while (value > k)
  {
    k = k + gap;
    i++;
  }
  return (i);
}

void ACR_Detection_Indicated(int delay_time, int nb)
{
  for (int x = 0; x < nb; x++)
  {
    digitalWrite(ACR_Indicator, Off);
    delay(delay_time);
    digitalWrite(ACR_Indicator, On);
    delay(delay_time);
  }
  return;
}

void Stop_Time(int delay_time)
{
  Serial.print("Stop during ");
  Serial.print(delay_time);
  Serial.println(" ms");
  delay(delay_time);
  return;
}

void Whistle(int i)
{
  for (int x = 0; x < i; x++)
  {
    Loco_Throttle.Change_DIRF(0x02);
    Loco_Throttle.Change_DIRF(-0x02);
  }
  return;
}

void ACR_loop()
{
  while ((digitalRead(Detect_West1_PIN) == Not_Activated) && (digitalRead(Detect_West2_PIN) == Not_Activated))
  {
    delay(100);
  }
  Serial.println("Loco on West detector");
  ACR_Detection_Indicated(250, 2);
  delay(Detect_Time);
  Loco_Throttle.Change_SPD(0x00);
  Stop_Time(random(Min_Time, Max_Time));
  Loco_Throttle.Change_DIRF(-0x20);
  delay(1000);
  if (Sound_Activated)
  {
    Whistle(1);
    delay(2500);
  }
  Loco_Throttle.Change_SPD(Speed_Loco);
  while ((digitalRead(Detect_East1_PIN) == Not_Activated) && (digitalRead(Detect_East2_PIN) == Not_Activated))
  {
    delay(100);
  }
  Serial.println("Loco on East detector");
  ACR_Detection_Indicated(250, 2);
  delay(Detect_Time);
  Loco_Throttle.Change_SPD(0x00);
  Stop_Time(random(Min_Time, Max_Time));
  if (digitalRead(ACR_On_Pin) == Activated)
  {
    Loco_Throttle.Change_DIRF(0x20);
    delay(1000);
    if (Sound_Activated)
    {
      Whistle(2);
      delay(2500);
    }
    Loco_Throttle.Change_SPD(Speed_Loco);
    ACR_loop();
  }
  else
  {
    delay(2500);
    Loco_Throttle.Change_SPD(0x00);
    Serial.println("System ACR stopped");
  }
  return;
}

void loop()
{
  while (digitalRead(ACR_On_Pin) == Not_Activated)
  {
  }
  // Initialize Automatic Circuit Reverse
  // Initialize Loco Throttle with ADR Loco Selected
  ADR_Loco = ADR_Loco_Tab[ind_tab_read(ADR_Loco_Pin, 256)];
  Serial.print("ADR Loco ");
  Serial.print(ADR_Loco);
  Serial.println(" selected");
  Loco_Throttle.Setup(ADR_Loco);
  // Speed Loco selected
  Speed_Loco = Speed_Loco_Tab[ind_tab_read(Speed_Loco_Pin, 256)];
  Serial.print("Speed loco defined at ");
  Serial.print((Speed_Loco * 100) / 128);
  Serial.println("%");
  // Sound
  Serial.print("Sound ");
  if (digitalRead(Sound_On_Pin) == Activated)
  {
    Sound_Activated = HIGH;
  }
  else
  {
    Sound_Activated = LOW;
    Serial.print("not ");
  }
  Serial.println("activated");
  // Loco must have activated West 1 detector to initialize the system
  Serial.println("Waiting for System ACR activation");
  while (digitalRead (Detect_West1_PIN) == Not_Activated)
  {
    ACR_Detection_Indicated(100, 1);
  }
  // System initialized
  Serial.println("System ACR activited");
  digitalWrite(ACR_Indicator, On);
  Serial.print("Loco ADR ");
  Serial.print(ADR_Loco);
  Serial.println(" -> USED");
  delay(Detect_Time);
  Loco_Throttle.Change_SPD(0x00);
  delay(2500);
  Loco_Throttle.Change_DIRF(0x30);
  if (Sound_Activated)
  {
    delay(1000);
    Loco_Throttle.Change_DIRF(0x01);
    delay(5000);
  }
  ACR_loop();
  if (Sound_Activated)
  {
    delay(1000);
    Loco_Throttle.Change_DIRF(-0x01);
    delay(5000);
  }
  Loco_Throttle.Change_DIRF(-0x10);
  Serial.print("Loco ADR ");
  Serial.print(ADR_Loco);
  Serial.println(" -> NOT USED");
  digitalWrite(ACR_Indicator, Off);
}

void DCC_On()
// DCC Power ON
{
  sendOPC_x(OPC_GPOFF);
  delay(500);
  sendOPC_x(OPC_GPON);
  return;
}


A+
Fabrice Fayolle
Avatar de l’utilisateur
ffayolle
Causant
 
Messages: 234
Inscrit le: Mar 09 Mai 2006, 19:55
Localisation: Amiens, Somme, Picardie
Âge: 50


Retour vers Arduino

Qui est en ligne ?

Utilisateur(s) parcourant actuellement ce forum : Aucun utilisateur inscrit et 4 invité(s)