On avance aujourd'hui.
La console que j'utilise pour envoyer du DMX :
et tant qu'à faire, je me dis "tiens, on va voir s'il y a quelque chose d'interressant dedans, genre la reprogrammer un jour?" Ben non, les circuits sont gommés, pas de port ISP... Tant pis. Je la remonte, et en la branchant, un poussoir coincé : la console ne voulait pas démarrer. je réouvre, et le fautif :
Il a été soudé de travers, c'est malin! alors je l'ai ressoudé. comment perdre 2 heures...
Puis j'ai rajouté dans mon code la réception DMX. Que de galère! j'avais mis un "espion" dans la routine de réception série (led 13 allumée au début de la trame DMX, éteinte lors de la réception des 12 canaux), mais voilà, pas de signal sur la pin 13! J'y ai passé une heure pour finir par trouver que la pin 13 était une sortie PWM, et qu'en initialisant mes timers, le timer prenait le pas sur la sortie, donc normal de ne pas avoir de signal...
Voilà, ça marche, à part que je dois m'intéresser aux canaux 5 à 17 de la trame DMX pour récupérer les voies 1 à 12 de la console. Comme la console n'est pas adressable et qu'elle envoie bien les canaux dans l'ordre, il faut que je vois pourquoi, je verrai ça avec celui qui a pondu le code de réception DMX (un certain marc Pierson).
Mon espace de travail a aussi évolué, j'avais plein de bouts de contreplaqué de même taille, donc chaque bout contient une fonction :
A3 : une prise 220 contenant un triac et son opto triac (on voit les deux fils qui permettent d'alimenter la led de l'opto)
B3 : a défaut d'avoir un MAX490, j'ai fait un ampli différentiel qui marche plutôt bien, le signal est super propre en sortie!
C3 : vous connaissez la mega2560...
BC2 : plaque d'essai
E2 : un opto et son triac pour commander le 12V de la lampe de bureau
C1 : deux potars pour les tests.
J'suis content, j'ai bien mérité l'apéro!
le code actuel :
/******************************* Variables d'adressage *****************************/
#define NUMBER_OF_CHANNELS 12 //Le nombre de canaux que l'on désire recevoir (12 par défaut).
volatile word dmxaddress = 5; // adresse de départ de réception
#define RX_PIN 17 // PIN RX2 - PH0
#define TX_PIN 16 // PIN TX2 - PH1
/******************************* Variables DMX ********************************/
volatile byte i = 0; // indexeurs pour dmxvalue[]
volatile byte dmxreceived = 0;
volatile word dmxcurrent = 0; //compteur incrémenté à chaque réception de donnée.
volatile byte dmxvalue[NUMBER_OF_CHANNELS]; // tableau des valeurs DMX reçues
volatile boolean dmxnewvalue = false; // indique la reception de nouvelles données DMX
volatile byte zerocounter = 0; // Pour compter le nombre de zeros consécutifs // reçus sur RX3. 22 zéros signifient un break (88µs).
/******************************* Variables phases ********************************/
volatile word PERIODE = 20000; // période du signal redressé, 20 000 par défaut.
volatile boolean ph1, ph2, ph3; // 1 = présence phase
volatile boolean ph_mesure; // flag temp
volatile word ph_retard; // flag temp
/******************************* Variables timers ********************************/
volatile word AVANCE_0 = 5; // Paramètre d'avance RAZ timer, (2.5µs par défaut)
volatile word ICR1_1, ICR3_1, ICR4_1; // valeurs de RAZ des timers.
void t134_setup(){ // initialisation des timers 1, 3 et 4
cli();
DDRB |= 0xE0; // T1 : voies 01, 04, 07
DDRE |= 0x38; // T3 : voies 02, 05, 08
DDRH |= 0x38; // T4 : voies 03, 06, 09
TCCR1A = 0xFE; // Utilisation des trois sorties du comparateurs du timer 1
TCCR3A = 0xFE; // Utilisation des trois sorties du comparateurs du timer 3
TCCR4A = 0xFE; // Utilisation des trois sorties du comparateurs du timer 4
TCCR1B = 0x18; // Préparation du timer 1, mise en attente
TCCR3B = 0x18; // Préparation du timer 3, mise en attente
TCCR4B = 0x18; // Préparation du timer 4, mise en attente
ICR1 = PERIODE + 500;
ICR3 = PERIODE + 500;
ICR4 = PERIODE + 500;
OCR1A = 0xFFFF; // initialisation de la sortie voie 01
OCR1B = 0xFFFF; // initialisation de la sortie voie 04
OCR1C = 0xFFFF; // initialisation de la sortie voie 07
OCR3A = 0xFFFF; // initialisation de la sortie voie 02
OCR3B = 0xFFFF; // initialisation de la sortie voie 05
OCR3C = 0xFFFF; // initialisation de la sortie voie 08
OCR4A = 0xFFFF; // initialisation de la sortie voie 03
OCR4B = 0xFFFF; // initialisation de la sortie voie 06
OCR4C = 0xFFFF; // initialisation de la sortie voie 09
ICR1_1 = ICR1 - AVANCE_0; // Valeur pour RAZ T1
ICR3_1 = ICR3 - AVANCE_0; // Valeur pour RAZ T3
ICR4_1 = ICR4 - AVANCE_0; // Valeur pour RAZ T4
}
void t134_start(){ // démarre les timers du dimmer
if (ph1) attachInterrupt(2, raz_ph1, RISING); // active l'interruption de passage à O secteur phase 1
TCCR1B |= 0x02; // démarre timer 1
}
void raz_ph1() { // phase de référence, mode 3 phases couplées
TCNT1 = ICR1_1; // RAZ T1
}
void dmx_setup() { // configuration entrée DMX
// Configuration du port série RX
pinMode(RX_PIN, INPUT); // RX_PIN en entrée
Serial2.begin(250000); //chaque bit DMX fait 4uS de long, soit 250Kbps
cli(); //Désactivation des interruptions
UCSR2B &= 0x7F; //Désactiver l'interruption de réception USART2
// Timer2 : configuration
TCCR2A = 0x02; // timer en mode 2, CTC. Le TOP sera OCRA.
TCCR2B = 0x01; // pas de prescaler, 16Mhz
OCR2A = 64; // Le timer 2 génèrera une interruption toutes les 4µs.
ASSR = 0x00;
TIMSK2 = 0x00; // pas d'interruption timer
sei(); // Réactiver les interruptions.
}
ISR(TIMER2_COMPA_vect) { // interruption appelée par timer2 toutes les 4µs
if (PINH & 0x01) { // Détection d'un 1 : ce n'est pas un break.
zerocounter = 0;
} else {
zerocounter++; // incrémentation du compteur de zéros
if (zerocounter == 20) { // si 20 zéros reçus consécutivement (80uS : break)
TIMSK2 &= 0xFD; // désactiver timer2, place au travail du USART2
UCSR2B |= 0x80; // activation de USART2
}
}
}
SIGNAL(USART2_RX_vect){ // interruption appelée par le port série.
dmxreceived = UDR2;
dmxcurrent++; //incrémentation du compteur d'adresse
if(dmxcurrent >= dmxaddress) { // vérification de l'adresse de démarrage
if (i == 0){
PORTG |= 0x02; // allumage led DMX : début de réception
} else {
PORTG &= 0xFD; // extinction led DMX : fin de réception
}
dmxvalue[i] = dmxreceived;
i++;
if(i == NUMBER_OF_CHANNELS) { // On a atteint le nombre de cannaux à recevoir, On s'arrête là.
UCSR2B &= 0x7F; // On désactive la réception DMX le temps d'exécuter
dmxnewvalue = HIGH; // le traitement des données reçues
dmxcurrent = 0;
zerocounter = 0;
i = 0;
}
}
}
void dmx_in_start() { // démarre la réception DMX
TIMSK2 |= 0x02; // relancer la recherche de trame DMX
}
void setup(){
pinMode(40, OUTPUT); // PG1
pinMode(A0, INPUT);
pinMode(21, INPUT);
t134_setup();
dmx_setup();
dmx_in_start();
t134_start();
}
void loop(){
if (dmxnewvalue) { // Réception d'un flot de données : traitement.
dimmer();
dmxnewvalue = LOW; // Réinitialiser les variables de réception DMX
TIMSK2 |= 0x02; // relancer la recherche de trame DMX
}
}
// j'avais oublié : cette fonction est dans un autre PDE pour mieux s'y retrouver...
void dimmer(){ // gères les données reçues
OCR1A = word(255-dmxvalue[0X00]) * 79; // dimmer voie 01
OCR3A = word(255-dmxvalue[0X01]) * 79; // dimmer voie 02
OCR4A = word(255-dmxvalue[0X02]) * 79; // dimmer voie 03
OCR1B = word(255-dmxvalue[0X03]) * 79; // dimmer voie 04
OCR3B = word(255-dmxvalue[0X04]) * 79; // dimmer voie 05
OCR4B = word(255-dmxvalue[0X05]) * 79; // dimmer voie 06
OCR1C = word(255-dmxvalue[0X06]) * 79; // dimmer voie 07
OCR3C = word(255-dmxvalue[0X07]) * 79; // dimmer voie 08
OCR4C = word(255-dmxvalue[0X08]) * 79; // dimmer voie 09
}
je n'ai activé que le timer1 et la phase 1, mais si j'ai le temps demain, je passe en triphasé (heureusement que j'en ai à la maison...)