* DMX-2.0.sln: ajout code arduino
* UniversDMX.cs: bug... * DriverBoitierV1.cs: gestion par automate * dmx512_v2_ino.c:
This commit is contained in:
parent
94a463da33
commit
095ee07bd2
4 changed files with 336 additions and 44 deletions
|
|
@ -3,6 +3,11 @@ Microsoft Visual Studio Solution File, Format Version 11.00
|
|||
# Visual Studio 2010
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DMX-2.0", "DMX-2.0\DMX-2.0.csproj", "{2CB55300-0A5B-4DFA-8984-B7EC4C455962}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{EBEAADCF-456B-43AB-A1ED-E81459AD7DDF}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
dmx512_v2_ino.c = dmx512_v2_ino.c
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|x86 = Debug|x86
|
||||
|
|
@ -14,6 +19,8 @@ Global
|
|||
{2CB55300-0A5B-4DFA-8984-B7EC4C455962}.Release|x86.ActiveCfg = Release|x86
|
||||
{2CB55300-0A5B-4DFA-8984-B7EC4C455962}.Release|x86.Build.0 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(NestedProjects) = preSolution
|
||||
EndGlobalSection
|
||||
GlobalSection(MonoDevelopProperties) = preSolution
|
||||
StartupItem = DMX-2.0\DMX-2.0.csproj
|
||||
Policies = $0
|
||||
|
|
|
|||
|
|
@ -15,6 +15,15 @@ namespace DMX2
|
|||
public bool pressed;
|
||||
}
|
||||
|
||||
enum etatAutomate {
|
||||
Deconnecte,
|
||||
Transmission,
|
||||
Erreur,
|
||||
Reset,
|
||||
Parametrage,
|
||||
Fin
|
||||
}
|
||||
|
||||
bool[] buttons = new bool[8];
|
||||
bool[] watchButtons = new bool[8];
|
||||
|
||||
|
|
@ -25,7 +34,6 @@ namespace DMX2
|
|||
|
||||
//Thread de boucle
|
||||
Thread loopthread=null;
|
||||
volatile bool running=true;
|
||||
|
||||
UniversDMX patch=null;
|
||||
|
||||
|
|
@ -45,86 +53,117 @@ namespace DMX2
|
|||
|
||||
void Start ()
|
||||
{
|
||||
OpenPort();
|
||||
if (loopthread == null) {
|
||||
loopthread = new Thread(new ThreadStart(MainLoop));
|
||||
loopthread.Start();
|
||||
}
|
||||
}
|
||||
|
||||
void OpenPort ()
|
||||
void Connection ()
|
||||
{
|
||||
if (serial != null) {
|
||||
serial.Close();
|
||||
serial.Dispose();
|
||||
}
|
||||
serial = new SerialPort(portname, 460800,Parity.None,8,StopBits.One);
|
||||
serial.DtrEnable = false;
|
||||
serial.ReadTimeout = 15;
|
||||
serial.WriteTimeout = 200;
|
||||
serial.Open();
|
||||
etat = etatAutomate.Transmission;
|
||||
}
|
||||
|
||||
bool CheckPortStatus ()
|
||||
volatile etatAutomate etat = etatAutomate.Deconnecte;
|
||||
DateTime finAttente = DateTime.Now;
|
||||
|
||||
void MainLoop()
|
||||
{
|
||||
if(serial.IsOpen) return true;
|
||||
|
||||
OpenPort();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void MainLoop ()
|
||||
{
|
||||
DateTime prochainEnvoi= DateTime.Now;
|
||||
TimeSpan sleeptime;
|
||||
while (running) {
|
||||
lock(Conduite.Courante)
|
||||
{
|
||||
patch.CalculUnivers(outputbuffer,5,255);
|
||||
while(etat != etatAutomate.Fin)
|
||||
{
|
||||
switch (etat) {
|
||||
case etatAutomate.Deconnecte:
|
||||
Connection();
|
||||
Attente(DateTime.Now.AddMilliseconds(200));
|
||||
break;
|
||||
case etatAutomate.Transmission:
|
||||
finAttente = DateTime.Now.AddMilliseconds (22);
|
||||
EnvoiTrame();
|
||||
Reception();
|
||||
Attente(finAttente);
|
||||
break;
|
||||
case etatAutomate.Erreur:
|
||||
Deconnecte();
|
||||
Attente(DateTime.Now.AddSeconds(2));
|
||||
break;
|
||||
// case etatAutomate.Parametrage:
|
||||
// EnvoiParam();
|
||||
// break;
|
||||
// case etatAutomate.Reset:
|
||||
// EnvoiReset();
|
||||
// break;
|
||||
}
|
||||
|
||||
if(!CheckPortStatus())
|
||||
{
|
||||
Thread.Sleep(1000);
|
||||
continue;
|
||||
}
|
||||
|
||||
sleeptime = prochainEnvoi - DateTime.Now;
|
||||
if(sleeptime.TotalMilliseconds>1)
|
||||
Thread.Sleep(sleeptime);
|
||||
|
||||
prochainEnvoi = DateTime.Now.AddMilliseconds(22);
|
||||
Envoi();
|
||||
Reception();
|
||||
|
||||
}
|
||||
Deconnecte();
|
||||
}
|
||||
|
||||
void Envoi ()
|
||||
void Attente (DateTime date)
|
||||
{
|
||||
int sleeptime = (int) (date - DateTime.Now).TotalMilliseconds;
|
||||
if(sleeptime>2)
|
||||
Thread.Sleep(sleeptime);
|
||||
|
||||
while (DateTime.Now<date) Thread.Sleep(1);
|
||||
}
|
||||
|
||||
void Deconnecte ()
|
||||
{
|
||||
etat = etatAutomate.Deconnecte;
|
||||
if(serial == null) return;
|
||||
|
||||
serial.Close();
|
||||
serial.Dispose();
|
||||
}
|
||||
|
||||
void EnvoiTrame ()
|
||||
{
|
||||
try {
|
||||
if(!serial.IsOpen) {
|
||||
etat = etatAutomate.Erreur;
|
||||
}
|
||||
|
||||
if(patch!=null) patch.CalculUnivers(outputbuffer,5,255);
|
||||
|
||||
if(!serial.IsOpen) return;
|
||||
serial.Write(outputbuffer,0,outputbuffer.Length);
|
||||
|
||||
} catch (TimeoutException ex) {
|
||||
serial.Close();
|
||||
etat = etatAutomate.Erreur;
|
||||
}
|
||||
}
|
||||
|
||||
// void EnvoiParam ()
|
||||
// {
|
||||
// throw new NotImplementedException ();
|
||||
// }
|
||||
//
|
||||
// void EnvoiReset ()
|
||||
// {
|
||||
// throw new NotImplementedException ();
|
||||
// }
|
||||
|
||||
void Reception ()
|
||||
{
|
||||
try {
|
||||
|
||||
if(!serial.IsOpen) return;
|
||||
if(!serial.IsOpen || etat == etatAutomate.Erreur) {
|
||||
etat = etatAutomate.Erreur;
|
||||
return;
|
||||
}
|
||||
|
||||
serial.Read(inputbuffer,0,inputbuffer.Length);
|
||||
//Console.WriteLine(inputbuffer[0]);
|
||||
ProcessInput();
|
||||
|
||||
} catch (TimeoutException ex) {
|
||||
serial.Close();
|
||||
etat = etatAutomate.Erreur;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -147,14 +186,14 @@ namespace DMX2
|
|||
public override void Dispose ()
|
||||
{
|
||||
disposed = true;
|
||||
running = false;
|
||||
etat = etatAutomate.Fin;
|
||||
if (loopthread != null) {
|
||||
loopthread.Join ();
|
||||
loopthread = null;
|
||||
}
|
||||
//TODO : Close Port
|
||||
if(serial != null)
|
||||
serial.Close();
|
||||
serial.Dispose();
|
||||
|
||||
}
|
||||
#region implemented abstract members of DMX2.DriverDMX
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ namespace DMX2
|
|||
{
|
||||
if(allumageForce[i]) {
|
||||
valeurs[i+offset] = 255;
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
|
||||
g= _dimmers[i];
|
||||
|
|
|
|||
246
dmx512_v2_ino.c
Normal file
246
dmx512_v2_ino.c
Normal file
|
|
@ -0,0 +1,246 @@
|
|||
|
||||
|
||||
// definition des fonction cbi sbi idem assembleur
|
||||
#ifndef cbi
|
||||
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
|
||||
#endif
|
||||
#ifndef sbi
|
||||
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
|
||||
#endif
|
||||
|
||||
// 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
|
||||
// reception
|
||||
volatile int index_input_pc=0; // entrée serial 0
|
||||
volatile int index_output_pc=0; // sortie serial 0
|
||||
volatile int index_input_dmx=513; // entrée dmx
|
||||
volatile int index_output_dmx=0; //sortie dmx -2 en attente de fin de transmission; -1 break; 0 à 512 transmission
|
||||
volatile int etat_input_pc=0; // 0 raz ; 1 esc reçu ; 2 D reçu : pret à recevoir ; 3 prèt à emmetre
|
||||
volatile int start_code_rec=-1;
|
||||
char key; // caractère reçu serial 0
|
||||
int cpt_ana = 0;
|
||||
int ledPin = 13; // led interne
|
||||
int tx1pin = 18; // pin DMX serial 1
|
||||
|
||||
byte brk_timer_start=181; // def : 150us
|
||||
byte mab_timer_start=231; //def : 50us
|
||||
int nb_circuits=512;
|
||||
|
||||
// vecteur d'inéruption pour reception pc
|
||||
|
||||
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;
|
||||
|
||||
pe=tab_input_pc+514;
|
||||
for(pb=tab_input_pc;pb<pe;pb++) *pb=0;
|
||||
|
||||
pe=tab_input_dmx+533;
|
||||
for(pb=tab_input_dmx;pb<pe;pb++) *pb=0;
|
||||
|
||||
}
|
||||
// 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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
// vecteur d'intéruption pour reception dmx
|
||||
ISR(USART1_RX_vect)
|
||||
{
|
||||
char c,r;
|
||||
r = UCSR1A;
|
||||
c = UDR1;
|
||||
if (r & (1<<FE1)) {index_input_dmx=0;return;}
|
||||
if ( index_input_dmx==0 && c!=0 ) {index_input_dmx=513; }
|
||||
if ( index_input_dmx<=512 )
|
||||
{
|
||||
tab_input_dmx[index_input_dmx]=c;
|
||||
index_input_dmx++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// vecteur d'intéruption pour transmission DMX sur serial 1
|
||||
// vecteur : USART 1 transmission buffer vide
|
||||
ISR(USART1_TX_vect)
|
||||
{
|
||||
// si l'USART 1 est vide => break
|
||||
index_output_dmx=-1;
|
||||
}
|
||||
// vecteur : USART 1 transmission registre vide
|
||||
ISR(USART1_UDRE_vect)
|
||||
{
|
||||
if (index_output_dmx>=0) { //si index >=0 caratère suivant
|
||||
UDR1 = max(tab_input_pc[index_output_dmx],tab_input_dmx[index_output_dmx]);
|
||||
index_output_dmx++;
|
||||
}
|
||||
// si 512 transmits => mise en attente de fin de transmission
|
||||
// desactivation de l'intéruption sur le registre
|
||||
if (index_output_dmx>nb_circuits) {index_output_dmx=-2;cbi(UCSR1B, UDRIE1);}
|
||||
|
||||
}
|
||||
|
||||
// vecteur d'intéruption pour transmission vers le pc sur serial 0
|
||||
// vecteur registre de transmission
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void setup() {
|
||||
// initialisation du stat code à 0
|
||||
tab_input_pc[0]=0;
|
||||
|
||||
// initialisation de la liaison série pc à 1MB/s
|
||||
Serial.begin(460800);
|
||||
|
||||
// initialisation à 250k de serial 1
|
||||
// baudrate
|
||||
UCSR1A = 1 << U2X1;
|
||||
UBRR1H=0;
|
||||
UBRR1L = 7;
|
||||
|
||||
// 2 bit de stop; pas de parité; 8 bits de données
|
||||
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
|
||||
// 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
|
||||
sbi(ADCSRA, ADSC);
|
||||
|
||||
// init timer break
|
||||
TIMSK2 = 0;
|
||||
TCCR2B = 0;
|
||||
TCCR2A = 0; // 00000000
|
||||
ASSR &= ~(1<<AS2);
|
||||
TCNT2 = 0; // compteur
|
||||
OCR2A = 220 ; // 100µs
|
||||
OCR2B = 200 ; // 110µs
|
||||
|
||||
sei();
|
||||
// init pin led interne en sortie
|
||||
pinMode(ledPin, OUTPUT);
|
||||
digitalWrite(ledPin, LOW);
|
||||
|
||||
|
||||
// préparation du premier break
|
||||
index_output_dmx=-1;
|
||||
PORTA = 255;
|
||||
DDRA = 0;
|
||||
PORTC = 255;
|
||||
DDRC = 0;
|
||||
}
|
||||
|
||||
void loop() {
|
||||
|
||||
// génération du break en tache principale
|
||||
int cpt = 0;
|
||||
if (index_output_dmx==-1) {
|
||||
index_output_dmx=-2;
|
||||
pinMode(tx1pin, OUTPUT); // on met la broche 18 en mode sortie
|
||||
cbi(UCSR1B, TXEN1); //on stop la transmission
|
||||
digitalWrite(tx1pin, LOW); // on met la broche 18 à 0
|
||||
TCNT2 = brk_timer_start ;// RAZ compteur timer
|
||||
TIFR2 = 0 ; //Clear Flags timer
|
||||
TIMSK2 = 1 ; //activation intéruption A &B
|
||||
TCCR2B = 3; // 00000011 division par 32 de l'horloge base => 2µs
|
||||
} // fin du break
|
||||
|
||||
// suite du code
|
||||
tab_input_dmx[513]= PINA;
|
||||
tab_input_dmx[514]= PINC;
|
||||
tab_input_dmx[515]=0;
|
||||
tab_input_dmx[516]=0;
|
||||
if ( ! bit_is_set(ADCSRA, ADSC)) {
|
||||
//digitalWrite(ledPin, HIGH);
|
||||
tab_input_dmx[517+cpt_ana++]=ADCH;
|
||||
if (cpt_ana>15) cpt_ana=0;
|
||||
ADCSRB = (ADCSRB & ~(1 << MUX5)) | (((cpt_ana >> 3) & 0x01) << MUX5);
|
||||
ADMUX = 96 | (cpt_ana & 0x07);
|
||||
sbi(ADCSRA, ADSC);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in a new issue