Le code :
// Lecture PPM6ch & pilotage LED RVB
// C'est le timer1 qui est utilisé la lecture du PPM
#define ledRouge 3 // Constante pour la broche 3
#define ledVert 5 // Constante pour la broche 5
#define ledBleu 6 // Constante pour la broche 6
#define ledPin 13 // Pin de la LED "locale" de l'Arduino
// Données de capture du Rx
boolean endTrame=0,failsafe=0,firstEdge=1;
volatile unsigned int vchUp[8];
volatile unsigned int vchPos[6];
unsigned int cha[6];
byte curEdge;
// Valeurs RVB
int R,V,B;
// Variables permettant de faire clignoter la led de l'Arduino
int ledState = LOW;
long previousMillis = 0;
long interval = 500;
void setup()
{
// Pin setup, parmetrage des PIN en sortie :
pinMode (ledVert,OUTPUT); // Broche ledVert configurée en sortie
pinMode (ledRouge,OUTPUT); // Broche ledRouge configurée en sortie
pinMode (ledBleu,OUTPUT); // Broche ledBleu configurée en sortie
pinMode(ledPin,OUTPUT); // Arduino LED
digitalWrite(ledPin,HIGH); // Allumage de la LED de l'Arduino
// Sortie DEBUG
Serial.begin(57600);
Serial.println("");
Serial.println("PPM read & Led RVB");
// Timer1 setup
TCCR1A=B00000000; // OCR2A/OCR2B : disconnected, Timer: normal mode
TCCR1B=B00000010; // Falling edge CAPTUREPIN detection, Timer:normal mode, Prescaler=clk/8
TIMSK1=B00100001; // Activate CAPTUREPIN interrupt & OVF interrupt
delay(1000); // pour etre certain que les interruptions aient tourné avant la main loop
}
ISR(TIMER1_CAPT_vect)
{
vchUp[curEdge]=ICR1; // Capture des timestamp 1 à 6
curEdge++;
if (curEdge>7) { // A partie du 7ème...
TCNT1=0; // RESET du counter pour éviter le FailSafe
if ((vchUp[7]-vchUp[1]) > 30000) { //Si la trame totale dépasse 15ms - Trame KO ou mauvaise synchro
curEdge=0; //Remise à 0 du compteur de fronts
}
else { //Sinon, une bonne trame est capturée, on calcule donc la valeur des canaux
curEdge=1;
for (int i=0;i<6;i++) {
vchPos[i]=(vchUp[i+2]-vchUp[i+1]); //Mesure des canaux (diviser par 2 pour obtenir des µs)
}
endTrame=1; // Pour dire à la MainLoop que de nouvelles valeurs sont disponibles
}
}
}
ISR(TIMER1_OVF_vect)
{
failsafe=1; // Le compteur a attends sa limite (32ms), on déclenche donc le FailSafe
}
void loop()
{
if (endTrame==1) {
cli();
for (int i=0;i<6;i++) {
cha[i]=vchPos[i]; // Recopie les valeurs des canaux
}
sei();
endTrame=0;
LedBlink(500);
if (failsafe){
failsafe=0;
Serial.println("End of FailSafe");
}
// La 1ere partie "intelligente" du code se trouve ICI
// Elle n'est jouée que si les canaux ont "bougé"
for (int i=0; i < 6; i++){ // Imprimer les valeurs des canaux sur le port série
Serial.print(cha[i]);
Serial.print(";");
}
// Mapper trois canaux vers les couleurs RVB
R=map(cha[1],1960,3960,0,255);
V=map(cha[2],1960,3960,0,255);
B=map(cha[3],1960,3960,0,255);
ledRVBpwm(R,V,B); // génère impulsion largeur voulue pour la couleur
// Imprimer les valauers de la LED
Serial.print(R);
Serial.print(";");
Serial.print(V);
Serial.print(";");
Serial.print(B);
Serial.println(";");
}
// La 2eme partie "intelligente" du code se trouve ICI
// Elle est jouée à chaque tour de boucle
if (failsafe){
if (R>255) R=0; // En mode FAILSAFE, on fait varier les 3 couleurs progressivement & simultanément
else R++;
if (V>255) V=0;
else V++;
if (B>255) B=0;
else B++;
ledRVBpwm(R,V,B); // génère impulsion largeur voulue pour la couleur
Serial.print("FAILSAFE");
LedBlink(50);
Serial.print(R);
Serial.print(";");
Serial.print(V);
Serial.print(";");
Serial.print(B);
Serial.println(";");
}
}
void ledRVBpwm(int pwmRouge, int pwmVert, int pwmBleu) { // reçoit valeur 0-255 par couleur
//--- attention - avec une LED RGB anode commune : la LED s'allume sur niveau BAS !
analogWrite(ledRouge, 255-pwmRouge); // impulsion largeur voulue sur la broche 0 = 0% et 255 = 100% haut
analogWrite(ledVert, 255-pwmVert); // impulsion largeur voulue sur la broche 0 = 0% et 255 = 100% haut
analogWrite(ledBleu, 255-pwmBleu); // impulsion largeur voulue sur la broche 0 = 0% et 255 = 100% haut
}
void LedBlink(long interval) { // reçoit délais de clignotement
unsigned long currentMillis = millis();
if(currentMillis - previousMillis > interval) {
// save the last time you blinked the LED
previousMillis = currentMillis;
// if the LED is off turn it on and vice-versa:
if (ledState == LOW)
ledState = HIGH;
else
ledState = LOW;
// set the LED with the ledState of the variable:
digitalWrite(ledPin, ledState);
}
}
EDIT : Le mode FAILSAFE indique que le signal PPM en entrée n'est plus fourni...