/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Décodeur pour 5 aiguillages sur Arduino Nano
*
* Les aiguillages sont actionnés par des servomoteurs SG90
* Programme librement interprete par Babar sur la base de celui de Ruud Boer du 23 avril 2015
*
* Babar: septembre 2017
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include <DCC_Decoder.h>
#include <Servo.h>
#define kDCC_INTERRUPT 0
const byte maxservos = 5; // Nombre de servos pilotés par la carte
const byte servotimer = 10; // Vitesse du servo: plus le nombre est petit plus le servo va vite
unsigned long timetoupdatesetpoint = millis() + servotimer;
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* DEFINITION DES SERVOMOTEURS
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
struct servoItem {
int address; // Adresse DCC du servo
byte output; // Etat du servo: 1=on, 0=off
byte angle;
byte setpoint;
byte offangle; // Position aiguillage droit
byte onangle; // Position aiguillage devié
Servo servo;
};
servoItem servos[maxservos];
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* CONFIGUTATION DES SERVOMOTEURS
* L'adresse est a definir pour chaque décodeur
* offangle et onangle permettent d ajuster finemenmt les positions
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void ConfigureFunctionsAndServos()
{
servos[0].address = 501; // Adresse DCC du 1er servo attention enlever 4 pour les systèmes Roco
servos[0].servo.attach(3); // broche de commande du servo
servos[0].offangle = 45; // Angle du servo pour aiguillage droit à ajuster après montage
servos[0].onangle = 135; // Angle du servo pour aiguillage devié à ajuster après montage
servos[1].address = 502; // Adresse DCC du 2ème servo attention enlever 4 pour les systèmes Roco
servos[1].servo.attach(5); // broche de commande du servo
servos[1].offangle = 45; // Angle du servo pour aiguillage droit à ajuster après montage
servos[1].onangle = 90; // Angle du servo pour aiguillage devié à ajuster après montage
servos[2].address = 503; // Adresse DCC du 3ème servo attention enlever 4 pour les systèmes Roco
servos[2].servo.attach(7); // broche de commande du servo
servos[2].offangle = 45; // Angle du servo pour aiguillage droit à ajuster après montage
servos[2].onangle = 135; // Angle du servo pour aiguillage devié à ajuster après montage
servos[3].address = 504; // Adresse DCC du 4ème servo attention enlever 4 pour les systèmes Roco
servos[3].servo.attach(9); // broche de commande du servo
servos[3].offangle = 45; // Angle du servo pour aiguillage droit à ajuster après montage
servos[3].onangle = 135; // Angle du servo pour aiguillage devié à ajuster après montage
servos[4].address = 505; // Adresse DCC du 5ème servo attention enlever 4 pour les systèmes Roco
servos[4].servo.attach(11); // broche de commande du servo
servos[4].offangle = 45; // Angle du servo pour aiguillage droit à ajuster après montage
servos[4].onangle = 135; // Angle du servo pour aiguillage devié à ajuster après montage
} // Fin de la configuration des servomoteurs
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* DECODAGE DES COMMANDES DCC
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void BasicAccDecoderPacket_Handler(int address, boolean activate, byte data)
{
// Conversion des paquets NMRA en langage compréhensible!
address -= 1;
address *= 4;
address += 1;
address += (data & 0x06) >> 1;
boolean enable = (data & 0x01) ? 1 : 0;
for(int i=0; i<maxservos; i++)
{
if(address == servos[i].address)
{
if(enable) servos[i].output = 1;
else servos[i].output = 0;
}
}
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* SET UP
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void setup()
{
DCC.SetBasicAccessoryDecoderPacketHandler(BasicAccDecoderPacket_Handler, true);
ConfigureFunctionsAndServos();
for(int i=0; i<maxservos; i++)
{
servos[i].angle = servos[i].offangle; // Met les aiguillages en position "droit"
}
DCC.SetupDecoder( 0x00, 0x00, kDCC_INTERRUPT );
pinMode(2,INPUT_PULLUP);
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* BOUCLE PRINCIPALE
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void loop()
{
static int addr = 0;
DCC.loop(); // Librairie DCC
if(++addr >= maxservos) addr = 0;
// Chaque "servotimer" ms avance le servo d'un pas (si c'est necessaire)
if (millis() > timetoupdatesetpoint)
{
timetoupdatesetpoint = millis() + servotimer;
for (int n=0; n<maxservos; n++)
{
if (servos[n].output) servos[n].setpoint=servos[n].onangle;
else servos[n].setpoint=servos[n].offangle;
if (servos[n].angle < servos[n].setpoint) servos[n].angle++;
if (servos[n].angle > servos[n].setpoint) servos[n].angle--;
servos[n].servo.write(servos[n].angle);
}
}
} //FIN de la boucle principale |