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[1026]; //Thread de boucle Thread loopthread=null; public UniversDMX patch1=null; public UniversDMX patch2=null; string portname = ""; SerialPort serial = null; int brk = 150; int mab = 50; int nbc1 = 512; byte flag_merge1 = 1; byte flag_merge2 = 1; bool reinit=false ; public void ReInit () { reinit=true; } public int Break { get { return brk; } } public int Mab { get { return mab; } } public byte Flag_merge1 { get { return flag_merge1; } } public byte Flag_merge2 { get { return flag_merge2; } } public DriverBoitierV2 (string serialport, string id): base(id) { portname = serialport; outputbuffer[0]=27; outputbuffer[1]=68; Start(); } bool paramFlag = false; public void SetBreak( int _brk, int _mab, byte _merge1, byte _merge2) { brk = _brk; mab = _mab; flag_merge1 = _merge1; flag_merge2 = _merge2; 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 = null; } if (!System.IO.File.Exists (portname)) { Thread.Sleep (200); return; } 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 (Exception ex) { etat = etatAutomate.Deconnecte; Console.WriteLine("DriverV2:Connection : {0}",ex); Thread.Sleep (500); } } /// /// Synchronise le pilote et le boitier ... /// Après connexion ou erreur /// bool Synchronisation () { //return true; Console.WriteLine ("DriverV2.Synchronisation()"); if (serial == null) return false; if (!serial.IsOpen) return false; // Au cas ou le boitier attends une fin de commande : envoi 1030 octets a 0 (le boitier ignorera tout seul la suite) byte[] tmpBuffer = new byte[1030]; serial.Write (tmpBuffer, 0, 1030); // 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 () { DateTime t = DateTime.Now; while (etat != etatAutomate.Fin) { try { switch (etat) { case etatAutomate.Deconnecte: Connection (); compteErreur = 0; break; case etatAutomate.Transmission: finAttente = DateTime.Now.AddMilliseconds (22); Console.WriteLine(DateTime.Now-t); t = DateTime.Now; EnvoiTrame (); Reception (); Attente (finAttente); if (paramFlag) Parametrage (); if (reinit) EnvoieReInit(); break; case etatAutomate.Erreur: Console.WriteLine("DriverV2 : etatAutomate.Erreur"); compteErreur ++; Deconnecte (); Attente (DateTime.Now.AddSeconds (2)); 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 0) Thread.Sleep(1); serial.Write(outputbuffer,0,outputbuffer.Length); } catch (Exception ex) { Console.WriteLine("Exception Envoi {0}",ex); etat = etatAutomate.Erreur; } } 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 (); // } // // void EnvoiReset () // { // throw new NotImplementedException (); // } byte flag_input; void Reception () { try { if(!serial.IsOpen || etat == etatAutomate.Erreur) { etat = etatAutomate.Erreur; return; } if(!WaitForData (inputbuffer.Length)) { etat = etatAutomate.Erreur; Console.WriteLine("DriverV2.Reception : attente depassee"); return ; } serial.Read(inputbuffer,0,inputbuffer.Length); if (flag_input != inputbuffer[0]) { flag_input = inputbuffer[0]; Console.WriteLine(flag_input ); } 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[6]; tmpBuffer [0] = 27; // Esc tmpBuffer [1] = 66; // 'B' tmpBuffer [2] = // nb circuits (byte)(nbc1 / 2 - 1); tmpBuffer [3] = (byte)brk; tmpBuffer [4] = (byte)mab; tmpBuffer [5] = (byte) (flag_merge1 + flag_merge2 * 2); 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 EnvoieReInit() { reinit = false; if (!serial.IsOpen) { etat = etatAutomate.Erreur; return; } byte[] tmpBuffer = new byte[2]; tmpBuffer [0] = 27; // Esc tmpBuffer [1] = 67; // 'B' serial.Write (tmpBuffer, 0, tmpBuffer.Length); if(!WaitForData (1)) { etat = etatAutomate.Erreur; return ; } serial.Read(tmpBuffer,0,1); if(tmpBuffer[0] != 67) 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(?