using System; using System.Threading; using System.IO.Ports; namespace DMX2 { public class DriverBoitierV2 : DriverDMX, IEventProvider { struct buttonState { public buttonState(byte _button, bool _pressed){ button=_button; pressed=_pressed; } public byte button; public bool pressed; } enum etatAutomate { Deconnecte, Transmission, Erreur, 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]; byte[] outputbuffer = new byte[514]; //Thread de boucle Thread loopthread=null; public UniversDMX patch1=null; public UniversDMX patch2=null; 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; outputbuffer[0]=27; outputbuffer[1]=68; Start(); } 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) { loopthread = new Thread(new ThreadStart(MainLoop)); loopthread.Start(); } } void Connection () { Console.WriteLine ("DriverV2.Connection()"); if (serial != null) { serial.Close (); serial.Dispose (); } serial = new SerialPort (portname, 460800, Parity.None, 8, StopBits.One); //serial.DtrEnable = false; serial.ReadTimeout = 200; serial.WriteTimeout = 200; try { serial.Open (); 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 () { 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(); } void Attente (DateTime date) { int sleeptime = (int) (date - DateTime.Now).TotalMilliseconds-1; if(sleeptime>2) Thread.Sleep(sleeptime); while (DateTime.Now timeout) return false; } return true; } // void EnvoiParam () // { // throw new NotImplementedException (); // } // // void EnvoiReset () // { // throw new NotImplementedException (); // } void Reception () { 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); if(serial.BytesToRead>0) serial.ReadExisting (); compteErreur= 0; } catch (Exception ex) { Console.WriteLine(serial.BytesToRead); Console.WriteLine("Exception Reception {0}",ex); etat = etatAutomate.Erreur; } } 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 () { byte b = 1; bool pressed; for (byte i = 0; i<8; i++) { if(!watchButtons[i]) continue; pressed = (inputbuffer[0] & b) != 0; if(buttons[i]^pressed) { eventsPending.Enqueue(new buttonState(i,pressed)); buttons[i] = pressed; } b <<= 1; } } public override void Dispose () { disposed = true; etat = etatAutomate.Fin; if (loopthread != null) { loopthread.Join (); loopthread = null; } //TODO : Close Port if(serial != null) serial.Dispose(); } #region implemented abstract members of DMX2.DriverDMX public override Gtk.Widget GetUI () { return new DriverBoitierV2UI(this); } #endregion #region IEventProvider implementation static System.Text.RegularExpressions.Regex regexEventID = new System.Text.RegularExpressions.Regex( @"BV2-B(?