|
|
View previous topic :: View next topic |
Author |
Message |
stefanomalizia
Joined: 21 Jul 2011 Posts: 1
|
Problem with dimmer DMX and PIC18F26K22 |
Posted: Fri Sep 30, 2011 5:15 pm |
|
|
Hi guys, I'm a new user on this forum and I apologize for my bad English.
I explain my problem
my code works fine but sometimes I have errors in reception, occasionally I get the next channel of the channel set.
for example:
The board address is 120, sometimes I get the value of address 121.
Why????
I use Mark code receiver routine copied from this forum and pic work at 16MHz ( Cristal)
this is the full code:
Code: |
//Compilatore PCWHD 4.122
/************************************************************************
* DEFINIZIONE I/O *
************************************************************************/
#define b0 PIN_A0 //PIN address
#define b1 PIN_B1
#define b2 PIN_B2
#define b3 PIN_B3
#define b4 PIN_B4 //PIN address
#define b5 PIN_B5
#define b6 PIN_B6
#define b7 PIN_B7
#define b8 PIN_A1
#define config PIN_A2
#define dim_1 PIN_C0
#define data_led PIN_A5
/************************************************************************
* DEFINIZIONE REGISTRI *
************************************************************************/
#byte SPBRGH1 = 0xFB0
#byte SPBRG1 = 0xFAF
#byte TXSTA1 = 0xFAC
#bit SYNC = TXSTA1.4
#bit BRGH = TXSTA1.2
#byte TRISC = 0xF94
#bit TRISC7 = TRISC.7
#bit TRISC6 = TRISC.6
#byte RCSTA1 = 0xFAB
#bit SPEN = RCSTA1.7
#bit RX9 = RCSTA1.6
#bit CREN = RCSTA1.4
#bit ADDEN = RCSTA1.3
#bit FERR = RCSTA1.2
#bit OERR = RCSTA1.1
#bit RX9D = RCSTA1.0
#byte RCREG1 = 0xFAE
#byte BAUDCON1 = 0xFB8
#bit DTRXP = BAUDCON1.5
#bit BRG16 = BAUDCON1.3
#byte INTCON = 0xFF2
#bit GIE = INTCON.3 // GIE/GIEH
#bit PEIE = INTCON.6 // PEIE/GIEL
#byte PIE1 = 0xF9D
#bit RC1IE = PIE1.5
#byte PIR1 = 0xF9E
#bit RC1IF = PIR1.5
/************************************************************************
* DEFINIZIONE VARIABILI GLOBALI *
************************************************************************/
//#define DMX_512_Offset 12 //Indirizzo Principale dispositivo DMX
int16 DMX_512_Offset=1;
#define MAX_BUFFER 1 //antes 24
int8 Rx_Buffer[MAX_BUFFER];
int8 Val_1 = 0;
/************************************************************************
* INIZIALIZZAZIONE RS485 *
************************************************************************/
void rs485_init(void)
{
TRISC6=1;
TRISC7=1;
SPBRGH1=0; //Baud Rate Generator
SPBRG1=3; //Baud Rate Generator
BRGH=1; // High Baud Rate Select bit
BRG16=0; // 16-bit Baud Rate Generator bi
SYNC=0; // EUSART Mode Select bit
SPEN=1; // Serial Port Enable bit
RC1IE=1;
GIE=1;
PEIE=1;
RX9=1; //9-bit Receive Enable bit
ADDEN=0; // Enables address detection, enable interrupt and load the receive buffer when RSR<8> is set
//DTRXP=0; // Data/Receive Polarity Select bit
CREN=1; //Continuous Receive Enable bit
return;
}
/************************************************************************
* Dimming MAP *
************************************************************************/
const int16 Map[256] = { 27536, 27536, 27536, 27536, 27536, 27536, 27691, 27846, 28001, 28156,
28311, 28467, 28622, 28777, 28932, 29087, 29242, 29397, 29552, 29707,
29862, 30018, 30173, 30328, 30483, 30638, 30793, 30948, 31103, 31258,
31413, 31569, 31724, 31879, 32034, 32189, 32344, 32499, 32654, 32809,
32964, 33120, 33275, 33430, 33585, 33740, 33895, 34050, 34205, 34360,
34515, 34671, 34826, 34981, 35136, 35291, 35446, 35601, 35756, 35911,
36066, 36221, 36377, 36532, 36687, 36842, 36997, 37152, 37307, 37462,
37617, 37772, 37928, 38083, 38238, 38393, 38548, 38703, 38858, 39013,
39168, 39323, 39479, 39634, 39789, 39944, 40099, 40254, 40409, 40564,
40719, 40874, 41030, 41185, 41340, 41495, 41650, 41805, 41960, 42115,
42270, 42425, 42581, 42736, 42891, 43046, 43201, 43356, 43511, 43666,
43821, 43976, 44131, 44287, 44442, 44597, 44752, 44907, 45062, 45217,
45372, 45527, 45682, 45838, 45993, 46148, 46303, 46458, 46613, 46768,
46923, 47078, 47233, 47389, 47544, 47699, 47854, 48009, 48164, 48319,
48474, 48629, 48784, 48940, 49095, 49250, 49405, 49560, 49715, 49870,
50025, 50180, 50335, 50490, 50646, 50801, 50956, 51111, 51266, 51421,
51576, 51731, 51886, 52041, 52197, 52352, 52507, 52662, 52817, 52972,
53127, 53282, 53437, 53592, 53748, 53903, 54058, 54213, 54368, 54523,
54678, 54833, 54988, 55143, 55299, 55454, 55609, 55764, 55919, 56074,
56229, 56384, 56539, 56694, 56850, 57005, 57160, 57315, 57470, 57625,
57780, 57935, 58090, 58245, 58400, 58556, 58711, 58866, 59021, 59176,
59331, 59486, 59641, 59796, 59951, 60107, 60262, 60417, 60572, 60727,
60882, 61037, 61192, 61347, 61502, 61658, 61813, 61968, 62123, 62278,
62433, 62588, 62743, 62898, 63053, 63209, 63364, 63519, 63674, 63829,
63984, 64139, 64294, 64449, 64604, 64760, 64915, 65070, 65225, 65380,
65535, 65535, 65535, 65535, 65535, 65535 };
/************************************************************************
* Pulse *
************************************************************************/
void trig(void)
{
output_high(dim_1);
delay_us(100);
output_low(dim_1);
return;
}
/************************************************************************
* RS485 *
************************************************************************/
#INT_RDA
void DMX_Rx_isr()
{
#define WAIT_FOR_NEXT_BYTE 0
#define WAIT_FOR_BREAK 1
#define WAIT_FOR_START 2
#define WAIT_FOR_DATA 3
#define RECEIVE_DATA 4
char data;
static char Rx_State = WAIT_FOR_BREAK;
union {
unsigned char fullbyte;
struct {
unsigned char RX9D:1;
unsigned char OERR:1;
unsigned char FERR:1;
unsigned char ADDEN:1;
unsigned char CREN:1;
unsigned char SREN:1;
unsigned char RX9:1;
unsigned char SPEN:1;
} bits ;
}rcsta;
static unsigned int16 DMX_512_Count=0;
static char Rx_Index = 0;
while (RC1IF)
{
output_high(data_led);
rcsta.fullbyte = RCSTA1;
data = RCREG1;
if (rcsta.bits.OERR)
{
CREN=0;
CREN=1;
Rx_State = WAIT_FOR_NEXT_BYTE;
return;
}
switch (Rx_State)
{
case WAIT_FOR_NEXT_BYTE:
if (!rcsta.bits.FERR)
Rx_State = WAIT_FOR_BREAK;
break;
case WAIT_FOR_BREAK:
/* Check for a framing error */
if (rcsta.bits.FERR)
{
if (!data)
Rx_State = WAIT_FOR_START;
}
break;
case WAIT_FOR_START:
if (rcsta.bits.FERR)
Rx_State = WAIT_FOR_NEXT_BYTE;
else
{
if (!data)
{
Rx_Index = 0;
if (DMX_512_Offset == 1)
Rx_State = RECEIVE_DATA;
else
{
Rx_State = WAIT_FOR_DATA;
DMX_512_Count = 1;
}
}
else
{
Rx_State = WAIT_FOR_BREAK;
}
}
break;
case WAIT_FOR_DATA:
if (rcsta.bits.FERR)
if (!data)
Rx_State = WAIT_FOR_START;
else
Rx_State = WAIT_FOR_NEXT_BYTE;
else
{
DMX_512_Count++;
if (DMX_512_Count == DMX_512_Offset)
Rx_State = RECEIVE_DATA;
}
break;
case RECEIVE_DATA:
if (rcsta.bits.FERR)
{
if (!data)
Rx_State = WAIT_FOR_START;
else
Rx_State = WAIT_FOR_NEXT_BYTE;
}
else
{
/* Store the data received in the Rx buffer */
//if (Rx_Buffer[Rx_Index] != data)
// levels[Rx_Index] |= 0x80;
Rx_Buffer[Rx_Index] = data;
/* Point to the next byte */
++Rx_Index;
/* Check to see if we have received all of our data */
if (Rx_Index >= MAX_BUFFER)
Rx_State = WAIT_FOR_BREAK;
}
break;
// default:
/* Unknown start code */
}
}
output_low(data_led);
return;
}
/************************************************************************
* ZERO CROSSING AND DIMMING INTERRUPT *
************************************************************************/
#int_EXT
void EXT_isr(void)
{
clear_interrupt(int_timer1);
clear_interrupt(int_timer3);
if(Val_1 < 5 ) //Lampada OFF
{
output_low(dim_1);
}else if(Val_1 > 250) //Lampada ON
{
output_high(dim_1);
}else
{
set_timer1(Map[Val_1]);
enable_interrupts(INT_TIMER1);
set_timer3(27000);
enable_interrupts(INT_TIMER3);
}
return;
}
#INT_TIMER1
void TIMER1_isr(void)
{
trig();
disable_interrupts(INT_TIMER1);
clear_interrupt(int_timer1);
return;
}
#INT_TIMER3
void TIMER3_isr(void)
{
set_timer1(Map[Val_1]);
enable_interrupts(INT_TIMER1);
disable_interrupts(INT_TIMER3);
clear_interrupt(int_timer3);
return;
}
/************************************************************************
* GET ADDRESS *
************************************************************************/
int16 get_address(void)
{
int16 address=0;
if(!input(b0))
{
address += 1;
}
if(!input(b1))
{
address += 2;
}
if(!input(b2))
{
address += 4;
}
if(!input(b3))
{
address += 8;
}
if(!input(b4))
{
address += 16;
}
if(!input(b5))
{
address += 32;
}
if(!input(b6))
{
address += 64;
}
if(!input(b7))
{
address += 128;
}
if(!input(b8))
{
address += 256;
}
return address;
}
/************************************************************************
* Programma Principale *
************************************************************************/
void main()
{
setup_timer_1(T1_INTERNAL|T1_DIV_BY_1);
setup_timer_3(T3_INTERNAL|T3_DIV_BY_1);
setup_timer_4(T4_DISABLED,0,1);
setup_comparator(NC_NC_NC_NC);// This device COMP currently not supported by the PICWizard
//pulisco le uscite
output_low(data_led);
output_low(dim_1);
Rx_Buffer[0]=0; // Inizializzo buffer
port_b_pullups(TRUE);
//INIZIO ROUTINE DMX512
DMX_512_Offset = get_address(); //Acquisizione indirizzo scheda
ext_int_edge( H_TO_L ); //Interrupt sul fronte di discesa
enable_interrupts(INT_RDA); //abilito interrupt porta seriale
enable_interrupts(GLOBAL); //Abilito interrupt globali
rs485_init(); //Inizializzo comunicazione seriale rs485
if(input(config)) //Controllo Modalita DipSW-10
{
enable_interrupts(INT_EXT);
while(true)
{
Val_1 = Rx_Buffer[0];
/*
if((Rx_Buffer[0] < 5) && (Rx_Buffer[0]> 250))
{
Val_1 = Rx_Buffer[0];
}else
{
if(Val_1 < Rx_Buffer[0])
{
Val_1++;
}
if(Val_1 > Rx_Buffer[0])
{
Val_1--;
}
}
*/
}
} else //Modalità ON/OFF
{
disable_interrupts(INT_EXT); //Disabilito lo zero crossing
while(true) //ON/OFF routine
{
if(Rx_Buffer[0]>128) // 0-128 --> OFF / 129-255 --> ON
{
output_high(dim_1);
}else
{
output_low(dim_1);
}
}
}
}
|
I hope in your help to solve this little problem...
thank you |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9246 Location: Greensville,Ontario
|
|
Posted: Fri Sep 30, 2011 6:38 pm |
|
|
Without cut/paste/compiling your copied code I'd say that the difference in the addresses may be due to a timing problem(slewing or stretching). DMX512 is 250KHz I believe and is doable with a 16MHz xtal.
I used PicBaud.exe to figure out your setup may not be right, though PicBaud gives 2 perfect answers, the 3rd, like your program gives an error.
Any error in timing will cause problems,especially if using long lines, unshielded wire, EMI, etc. |
|
|
freesat
Joined: 08 Feb 2011 Posts: 32
|
|
Posted: Wed Oct 05, 2011 2:11 am |
|
|
I have done some dmx devices using long lines, poor cables and works fine! 100% success, but!!! I have problem like your only using AC Dimmer, in this case, delay routines caused the problem.
Now I'm trying dimmer based only in timer0, without delay_?s().
Check if your code have free cycles to handle dmx at 16Mhz. |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|