diff --git a/DMX-2.0/DriverBoitierV1.cs b/DMX-2.0/DriverBoitierV1.cs index b66f05d..5a48b4c 100644 --- a/DMX-2.0/DriverBoitierV1.cs +++ b/DMX-2.0/DriverBoitierV1.cs @@ -136,7 +136,7 @@ namespace DMX2 serial.Write(outputbuffer,0,outputbuffer.Length); - } catch (TimeoutException ex) { + } catch { etat = etatAutomate.Erreur; } } @@ -163,7 +163,7 @@ namespace DMX2 serial.Read(inputbuffer,0,inputbuffer.Length); ProcessInput(); - } catch (TimeoutException ex) { + } catch { etat = etatAutomate.Erreur; } } diff --git a/DMX-2.0/DriverBoitierV2.cs b/DMX-2.0/DriverBoitierV2.cs index eb718b9..ab7a1b7 100644 --- a/DMX-2.0/DriverBoitierV2.cs +++ b/DMX-2.0/DriverBoitierV2.cs @@ -19,14 +19,13 @@ namespace DMX2 Deconnecte, Transmission, Erreur, - Reset, - Parametrage, Fin } bool[] buttons = new bool[8]; bool[] watchButtons = new bool[8]; + const int timeout = 200; // tampons Entrée/Sortie public byte[] inputbuffer = new byte[532]; @@ -41,6 +40,16 @@ namespace DMX2 string portname = ""; SerialPort serial = null; + + int break1 = 150; + int break2 = 150; + + int mab1 = 50; + int mab2 = 50; + + int nbc1 = 512; + int nbc2 = 512; + public DriverBoitierV2 (string serialport, string id): base(id) { portname = serialport; @@ -50,6 +59,22 @@ namespace DMX2 } + bool paramFlag = false; + + public void SetBreak1( int brk, int mab) + { + break1 = brk; + mab1 = mab; + paramFlag = true; + } + + public void SetBreak2( int brk, int mab) + { + break2 = brk; + mab2 = mab; + paramFlag = true; + } + void Start () { if (loopthread == null) { @@ -71,50 +96,107 @@ namespace DMX2 serial.WriteTimeout = 200; try { serial.Open (); - etat = etatAutomate.Transmission; + Attente(DateTime.Now.AddMilliseconds(1000)); + + if(Synchronisation()) + etat = etatAutomate.Transmission; + else { + serial.Close(); + etat = etatAutomate.Deconnecte; + } + } catch { etat = etatAutomate.Deconnecte; } } + /// + /// Synchronise le pilote et le boitier ... + /// Après connexion ou erreur + /// + bool Synchronisation () + { + return true; + + + if (serial == null) + return false; + if (!serial.IsOpen) + return false; + + // Au cas ou le boitier attends une fin de commande : envoi 520 octets a 0 (le boitier ignorera tout seul la suite) + byte[] tmpBuffer = new byte[520]; + serial.Write (tmpBuffer, 0, 520); + + // On attends un peu + Thread.Sleep (300); + + // Vide le buffer d'entree + if (serial.BytesToRead > 0) + serial.ReadExisting (); + + if(serial.BytesToWrite > 0) + Console.WriteLine("Les infos partent pas ..."); + + // on envoie Esc 'A' + tmpBuffer [0] = 27; + tmpBuffer [1] = 65; + serial.Write (tmpBuffer, 0, 2); + + // On attends un peu + if(!WaitForData (1)) { + return false; + } + + serial.Read(tmpBuffer,0,1); + if(tmpBuffer[0] == 65) return true; + return false; + } + volatile etatAutomate etat = etatAutomate.Deconnecte; DateTime finAttente = DateTime.Now; int compteErreur = 0; - void MainLoop() + void MainLoop () { - while(etat != etatAutomate.Fin) - { - switch (etat) { - case etatAutomate.Deconnecte: - Connection(); - compteErreur= 0; - Attente(DateTime.Now.AddMilliseconds(1000)); - serial.DiscardInBuffer(); - break; - case etatAutomate.Transmission: - finAttente = DateTime.Now.AddMilliseconds (22); - EnvoiTrame(); - Reception(); - Attente(finAttente); - break; - case etatAutomate.Erreur: - compteErreur ++; - if(compteErreur>3){ - Deconnecte(); - Attente(DateTime.Now.AddSeconds(2)); - } - else { - Attente(DateTime.Now.AddSeconds(1)); - etat = etatAutomate.Transmission; - } - break; + while (etat != etatAutomate.Fin) { + try { + switch (etat) { + case etatAutomate.Deconnecte: + Connection (); + compteErreur = 0; + break; + case etatAutomate.Transmission: + finAttente = DateTime.Now.AddMilliseconds (22); + EnvoiTrame (); + Reception (); + Attente (finAttente); + if (paramFlag) + Parametrage (); + break; + case etatAutomate.Erreur: + compteErreur ++; + if (compteErreur > 3) { + Deconnecte (); + Attente (DateTime.Now.AddSeconds (2)); + } else { + Attente (DateTime.Now.AddMilliseconds (250)); + if (Synchronisation ()) + etat = etatAutomate.Transmission; + else + compteErreur++; + } + break; // case etatAutomate.Parametrage: // EnvoiParam(); // break; // case etatAutomate.Reset: // EnvoiReset(); // break; + } + } catch (Exception ex) { + Console.WriteLine("Exception dans DriverV2 : {0}",ex); + if(etat != etatAutomate.Fin) etat = etatAutomate.Erreur; } } Deconnecte(); @@ -122,7 +204,7 @@ namespace DMX2 void Attente (DateTime date) { - int sleeptime = (int) (date - DateTime.Now).TotalMilliseconds; + int sleeptime = (int) (date - DateTime.Now).TotalMilliseconds-1; if(sleeptime>2) Thread.Sleep(sleeptime); @@ -156,6 +238,16 @@ namespace DMX2 } } + bool WaitForData (int len) + { + int wcnt =0 ; + + while (serial.BytesToRead < len) { + Thread.Sleep (1); + if (++wcnt > timeout) return false; + } + return true; + } // void EnvoiParam () // { // throw new NotImplementedException (); @@ -170,14 +262,22 @@ namespace DMX2 { try { + if(!serial.IsOpen || etat == etatAutomate.Erreur) { etat = etatAutomate.Erreur; return; } + if(!WaitForData (inputbuffer.Length)) { + etat = etatAutomate.Erreur; + return ; + } + serial.Read(inputbuffer,0,inputbuffer.Length); - //ProcessInput(); - //Console.WriteLine(inputbuffer[0]); + + if(serial.BytesToRead>0) + serial.ReadExisting (); + compteErreur= 0; } catch (Exception ex) { Console.WriteLine(serial.BytesToRead); @@ -186,6 +286,38 @@ namespace DMX2 } } + void Parametrage () + { + paramFlag = false; + + if (!serial.IsOpen) { + etat = etatAutomate.Erreur; + return; + } + + byte[] tmpBuffer = new byte[5]; + + tmpBuffer [0] = 27; // Esc + tmpBuffer [1] = 66; // 'B' + + tmpBuffer [2] = // nb circuits + (byte)(nbc1 / 2 - 1); + + tmpBuffer [3] = (byte)break1; + tmpBuffer [4] = (byte)mab1; + + serial.Write (tmpBuffer, 0, tmpBuffer.Length); + + if(!WaitForData (1)) { + etat = etatAutomate.Erreur; + return ; + } + + serial.Read(tmpBuffer,0,1); + if(tmpBuffer[0] != 66) + etat = etatAutomate.Erreur; + + } void ProcessInput () { diff --git a/dmx512_v2_ino.c b/dmx512_v2_ino.c index a385be2..888b6ac 100644 --- a/dmx512_v2_ino.c +++ b/dmx512_v2_ino.c @@ -10,7 +10,7 @@ // déclaration des tableaux de données byte tab_input_pc[514]; // venant du pc -byte tab_input_dmx[533]; // données venant de l'extérieur : les 512 premiers DMX; les 20 suivant 4x8 bp + 16 analogique 8bits +byte tab_input_dmx[534]; // données venant de l'extérieur : les 512 premiers DMX; les 20 suivant 4x8 bp + 16 analogique 8bits ; 1 octet d'etat // reception volatile int index_input_pc=0; // entrée serial 0 volatile int index_output_pc=0; // sortie serial 0 @@ -31,65 +31,94 @@ int nb_circuits=512; ISR(USART0_RX_vect) { - char c,r; - byte *pb, *pe; - r = UCSR0A; - c = UDR0; - switch (etat_input_pc) { - case 0: - // on attend un 'esc' pour commencer - if (c==27) { etat_input_pc=1; digitalWrite(ledPin, LOW);break;} - - break; - case 1: - // on attend 'D' pour recevoir - if (c==68) {etat_input_pc=2;index_input_pc=1; - index_output_pc=1; // on init l'index d'emmission vers le pc ( le 0 n'est pas emit => start code) - sbi(UCSR0B, UDRIE0); // activation de l'intéruption registre emmission - - } - // Esc 'C' réinit - if (c==67) {etat_input_pc=0;index_input_pc=0; + char c,r; + byte *pb, *pe; + r = UCSR0A; + c = UDR0; + switch (etat_input_pc) { + + case 0: + // on attend un 'esc' pour commencer + if (c==27) { etat_input_pc=1; digitalWrite(ledPin, LOW);break;} - pe=tab_input_pc+514; - for(pb=tab_input_pc;pb start code) + sbi(UCSR0B, UDRIE0); // activation de l'intéruption registre emmission + } + // Esc 'C' réinit + if (c==67) { + etat_input_pc=0; - pe=tab_input_dmx+533; - for(pb=tab_input_dmx;pb 512) {// on se prépare à emmetre vers le pc + etat_input_pc=0; + digitalWrite(ledPin, HIGH); + + } + break; + + case 10: // 1er parametre : nb de circuits / 2 - 1 ( de 2 a 512 ) + etat_input_pc++; nb_circuits= ((int)c)*2 + 2; + break; + + case 11: // 2nd parametre : duree du break en us + etat_input_pc++; + brk_timer_start = 255 - (c/2) +1; + break; + + case 12: // 3eme parametre : duree du mab en us + etat_input_pc=0; + mab_timer_start = 255 - (c/2) +1; + + // on a tout recu, on reponds + tab_input_dmx[533]=66; + index_output_pc=533; // on init l'index d'emmission vers le pc ( uniquement etat : 66 'B' ) + sbi(UCSR0B, UDRIE0); + + break; + + default: + // on fait rien + break; } - // Esc 'B' parametrage - if (c==66) {etat_input_pc=0;index_input_pc=10; } - // si aucune commande n'est trouvée (toujours à 1) on repart à 0 - if (etat_input_pc==1) {etat_input_pc=0;} - break; - case 2: // reception trame pc - // on rempli le tableau - tab_input_pc[index_input_pc]=c; - index_input_pc++; - // si on arrive à 512 - if (index_input_pc > 512) {// on se prépare à emmetre vers le pc - etat_input_pc=0; - digitalWrite(ledPin, HIGH); - } - break; - case 10: // 1er parametre : nb de circuits / 2 - 1 ( de 2 a 512 ) - etat_input_pc=11; nb_circuits= ((int)c)*2 + 2; - break; - case 11: // 2nd parametre : duree du break - etat_input_pc=12; - brk_timer_start = 255 - (c/2) +1; - break; - case 12: // 3eme parametre : duree du mab - etat_input_pc=0; - mab_timer_start = 255 - (c/2) +1; - break; - default: - // on fait rien - break; - } - } @@ -137,27 +166,27 @@ ISR(USART0_UDRE_vect) //caratère suivant UDR0 = tab_input_dmx[index_output_pc]; index_output_pc++; - if (index_output_pc>532) {cbi(UCSR0B, UDRIE0); -} + if (index_output_pc>532 { + cbi(UCSR0B, UDRIE0); + } } ISR(TIMER2_OVF_vect) { -if (index_output_dmx==-2) { - digitalWrite(tx1pin, HIGH); // on met la broche 18 à 1 pendant 10 µs - //digitalWrite(ledPin, HIGH); - index_output_dmx=-3; - TCNT2 = mab_timer_start ;// RAZ compteur timer - TIFR2 = 0 ; //Clear Flags timer - return; -} -if (index_output_dmx==-3) { - sbi(UCSR1B, TXEN1); // on redémarre la transmission - index_output_dmx=0; // on se prépare à émmettre à partir du stat code ( 513 octets ) - sbi(UCSR1B, UDRIE1); // on réactive l'intéruption du registre - TIMSK2 = 0 ; //desactivation intéruption A &B - TCCR2B = 0; - -} + if (index_output_dmx==-2) { + digitalWrite(tx1pin, HIGH); // on met la broche 18 à 1 pendant 10 µs + //digitalWrite(ledPin, HIGH); + index_output_dmx=-3; + TCNT2 = mab_timer_start ;// RAZ compteur timer + TIFR2 = 0 ; //Clear Flags timer + return; + } + if (index_output_dmx==-3) { + sbi(UCSR1B, TXEN1); // on redémarre la transmission + index_output_dmx=0; // on se prépare à émmettre à partir du stat code ( 513 octets ) + sbi(UCSR1B, UDRIE1); // on réactive l'intéruption du registre + TIMSK2 = 0 ; //desactivation intéruption A &B + TCCR2B = 0; + } } @@ -178,13 +207,16 @@ void setup() { UCSR1C = 14; // activation transmission et intéruption serial 1 - sbi(UCSR1B, RXEN1); //Reception - sbi(UCSR1B, TXEN1); //Transmission - sbi(UCSR1B, RXCIE1); //Interruption sur reception - sbi(UCSR1B, TXCIE1); //Interruption pour fin de transmission -sbi(UCSR0B, RXEN0); //Reception -sbi(UCSR0B, RXCIE0); //Interruption sur reception -sbi(UCSR0B, TXEN0); //Transmission + sbi(UCSR1B, RXEN1); //Reception + sbi(UCSR1B, TXEN1); //Transmission + sbi(UCSR1B, RXCIE1); //Interruption sur reception + sbi(UCSR1B, TXCIE1); //Interruption pour fin de transmission + + sbi(UCSR0B, RXEN0); //Reception + sbi(UCSR0B, RXCIE0); //Interruption sur reception + sbi(UCSR0B, TXEN0); //Transmission + + // Init convertion analogique pour le premier canal pin0 ADCSRB = (ADCSRB & ~(1 << MUX5)); ADMUX = 96; //01100000 reférence sur le 5v et alignement pour lecture sur 8 bits @@ -211,6 +243,7 @@ sbi(UCSR0B, TXEN0); //Transmission DDRA = 0; PORTC = 255; DDRC = 0; + tab_input_dmx[533]=0; } void loop() {