/* * Module S88 * */ #include // librairie S88 pour le MEGA /* * decodeur de 8 aiguillages sur Arduino UNO/NANO * Les aiguillages sont commandes par des sorties sur les broches a partir de la broche 3 par paire (aiguillage 1 = (3,4) etc...) * ces sorties peuvent etre utilisees directement pour commander des ULN2803 ou les inputs de relais ou L298N * */ /****************************************************************************************** * * LES PARAMETRES DE CONFIGURATION a definir par l'utilisateur * CONSOLE : pour avoir le deroulement du programme, si pas necessaire supprimer la ligne * FIRST_ID_DCC : premiere adresse DCC de depart, premier aiguillage (FIRST_ID_DCC sur broche 3), second aiguillage (FIRST_ID_DCC+1 sur broche 4, etc..) * NB_TURNOUT : le nombre d'aiguillages = 8 * *********************************************************************************************/ #define ROW_COUNT(array) (sizeof(array) / sizeof(*array)) #define CONSOLE // sortie console du deroulement #define DEBIT_CONSOLE 115200 // le debit de la console /*********************************************************************************************** * * LES PARAMETRES INTERNES * * ************************************************************************************************/ //////////////////// LE DCC ///////////////////////////////////////////////////////////////// #include // la bibliothèque de Minabay #define kDCC_INTERRUPT 3 // la pin 20 qui recoit les interruptions du signal DCC int adresse_precedente = 0; // evite les commandes multiples DCC int ancienne_position = 2; volatile boolean MAJ_activation; // si des MAJ a faire apres controle du DCC /////////////////// LES AIGUILLAGES /////////////////////////////////////////////////////// #define ETAT1 0 // adresse DCC/0 #define ETAT2 1 // adresse DCC/1 #define ACTIVATION_AIGUILLAGE 200 // duree d'activation des bobines en ms ( amodifier si necessaire) #define ACTIVATION_DETELEUR 1500 // duree d'activation des bobines en ms ( amodifier si necessaire) //#define ADRESSE_DCC_MIN 170 //#define ADRESSE_DCC_MAX 185 //// Tableau DCC //// int TableauDCC[][6]={ //Déclaration // Adresse, position actuelle, pin1, pin2, demande d'activation, fonction (0=Aiguillage, 1=Relais, 2=Signalisation, 3=Dételeur, 4=Detection, 5=Divers) {200, 0, 22, 23, 0,0}, //Aiguillage A10A {201, 0, 24, 25, 0,0}, //Aiguillage A10B {202, 0, 26, 27, 0,0}, //Aiguillage A20A {203, 0, 28, 29, 0,0}, //Aiguillage A20B //{174, 0, 11, 12, 0,0}, //Aiguillage 5 //{175, 0, 13, 14, 0,0}, //Aiguillage 6 //{176, 0, 15, 16, 0,0}, //Aiguillage 7 //{177, 0, 17, 18, 0,0}, //Aiguillage 8 //{178, 0, 19, 20, 0,0}, //Aiguillage 9 //{179, 0, 21, 22, 0,0}, //Aiguillage 10 //{180, 0, 23, 24, 0,0}, //Aiguillage 11 //{181, 0, 25, 26, 0,0}, //Aiguillage 12 //{182, 0, 27, 28, 0,3}, //Deteleur 1 //{183, 0, 29, 30, 0,3}, //Deteleur 2 //{184, 0, 31, 32, 0,3}, //Deteleur 3 //{185, 0, 33, 34, 0,3}, //Deteleur 4 //{186, 0, 35, 35, 0,1} //Relais 1 }; //Fin du tableau. /******************************************************************** * * METHODE APPELEE SI UNE DEMANDE DE MISE A JOUR PAR LE DCC * Determine periodiquemùent les bobines a activer * *******************************************************************/ void activation_dcc() { for (int i = 0; i < ROW_COUNT(TableauDCC); i++) // on balaie tous les aiguillages { if (TableauDCC[i][4] == true) // si l'aiguillage i est en attente d'activation { // Detection de fonction switch(TableauDCC[i][5]) // on regarde la position demandee { // Aiguillage case 0 :{ // Aiguillage - Verification de l'état switch(TableauDCC[i][1]) // on regarde la position demandee { case ETAT1 :{ // si bobine 1 digitalWrite(TableauDCC[i][2],HIGH); // activation delay(ACTIVATION_AIGUILLAGE); // duree de l'activation digitalWrite(TableauDCC[i][2],LOW); // arret de l'activation #ifdef CONSOLE Serial.print("activation -> Aiguillage DCC ");Serial.print(TableauDCC[i][0]);Serial.print(" - Bobine 1 - PIN ");Serial.println(TableauDCC[i][2]); #endif break;} case ETAT2 : { // si bobine 2 digitalWrite(TableauDCC[i][3],HIGH); // activation delay(ACTIVATION_AIGUILLAGE); // duree de l'activation digitalWrite(TableauDCC[i][3],LOW); // arret de l'activation #ifdef CONSOLE Serial.print("activation -> Aiguillage DCC ");Serial.print(TableauDCC[i][0]);Serial.print(" - Bobine 2 - PIN ");Serial.println(TableauDCC[i][3]); #endif break;} } break;} // Relais case 1 :{ switch(TableauDCC[i][1]) // on regarde la position demandee { case ETAT1 :{ // si bobine 1 digitalWrite(TableauDCC[i][2],LOW); // activation #ifdef CONSOLE Serial.print("activation -> Relais");Serial.print(i);Serial.println(" : Relay OFF"); #endif break;} case ETAT2 : { // si bobine 2 digitalWrite(TableauDCC[i][2],HIGH); // arret de l'activation #ifdef CONSOLE Serial.print("activation -> Relais");Serial.print(i);Serial.println(" : Relay ON"); #endif break;} } break;} // Signalisation case 2 :{Serial.print("Signalisation "); break;} // Deteleur case 3 :{ // si bobine 1 digitalWrite(TableauDCC[i][2],HIGH); // activation delay(ACTIVATION_DETELEUR); // duree de l'activation digitalWrite(TableauDCC[i][2],LOW); // arret de l'activation #ifdef CONSOLE Serial.print("activation -> Deteleur");Serial.print(i);Serial.println(" : bobine1"); #endif break;} // Detection case 4 :{Serial.print("Detection "); break;} // Divers case 5 :{Serial.print("Divers "); break;} } TableauDCC[i][4] = false; // l'aiguillage a etait traite } } MAJ_activation = false; // on a fait toutes les MAJ } /************************************************************************************* * * METHODE APPELEE A CHAQUE IT DU DCC * determine si un aiguillage est concerne par la commande DCC * ***********************************************************************************/ void BasicAccDecoderPacket_Handler(int adresse_DCC, boolean activate, byte data) { adresse_DCC -= 1; adresse_DCC *= 4; adresse_DCC += 1; adresse_DCC += (data & 0x06) >> 1; // decodage adresse DCC int ETAT = (data & 0x01) ? ETAT1 : ETAT2; // Etat de la demande DCC // si on change d'adresse ou de position if ((adresse_DCC != adresse_precedente) | ((ETAT != ancienne_position)&(adresse_DCC == adresse_precedente))) { //if ((adresse_DCC >= ADRESSE_DCC_MIN) && (adresse_DCC < ADRESSE_DCC_MAX)) // si une de nos adresses //{ // On parcourt le tableau for(int i=0; i