|
|
View previous topic :: View next topic |
Author |
Message |
arunkish
Joined: 23 Dec 2008 Posts: 83
|
DMX Receiver Interrupt |
Posted: Tue Dec 13, 2011 8:53 pm |
|
|
Hello All
I am using the following code to Transmit DMX Data and it works. I do have a question now... Is it possible to Read / Receive the DMX data sent from one controller in another PIC controller using the interrupt ? If yes, can you please give some advice to get started?
Code: |
#include <16F73.h>
#fuses HS,NOWDT,PUT,NOBROWNOUT,PROTECT
#use delay(clock=8000000)
#byte PORTA=0x05
#byte TRISA=0x85
#bit DMXOUT=PORTA.0
#byte CHD=0
#bit CHD0=CHD.0
#bit CHD1=CHD.1
#bit CHD2=CHD.2
#bit CHD3=CHD.3
#bit CHD4=CHD.4
#bit CHD5=CHD.5
#bit CHD6=CHD.6
#bit CHD7=CHD.7
void sendchanneldata(void);
int j;
byte data_DMX[24]={255,6,45,0,0,
0,0,0,0,1,
0,0,0,0,0,
0,0,0,0,0,
0,0,0,0};
void main(void)
{
set_tris_a(0x00);PORTA=0x00;
DMXOUT=1;
sendchanneldata();
}
void sendchanneldata(void)
{
DMXOUT=1; // MTBP - Idle
delay_cycles(14); // MTBP - Idle
DMXOUT=1; // MTBP - Idle
delay_cycles(14); // MTBP - Idle
DMXOUT=0; // B
delay_cycles(100); //B
delay_cycles(79); //B
DMXOUT=1; // MAB
delay_cycles(7); //MAB
DMXOUT=1; // MAB
delay_cycles(7); //MAB
/*****************************************/
/* SC */
/*****************************************/
DMXOUT=0; delay_cycles(7); // 1 Start
delay_cycles(64);
DMXOUT=1;delay_cycles(7); DMXOUT=1; delay_cycles(7); // Stop
/*****************************************/
/* SC */
/*****************************************/
for(j=0;j<=23;j++)
{
CHD=data_DMX[j];
DMXOUT=0; delay_cycles(7); // 1 Start
DMXOUT=CHD0 ;delay_cycles(4);
DMXOUT=CHD1 ;delay_cycles(4);
DMXOUT=CHD2 ;delay_cycles(4);
DMXOUT=CHD3 ;delay_cycles(4);
DMXOUT=CHD4 ;delay_cycles(4);
DMXOUT=CHD5 ;delay_cycles(4);
DMXOUT=CHD6 ;delay_cycles(4);
DMXOUT=CHD7 ;delay_cycles(4);
DMXOUT=1;delay_cycles(7); DMXOUT=1; delay_cycles(7); //* Stop
}
} |
Thanks |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9225 Location: Greensville,Ontario
|
|
Posted: Wed Dec 14, 2011 9:06 am |
|
|
You've got some options...
1) spend a morning and use Google to locate 'DMX512 PIC C code' and decide which of the 1,000s of hits has what you want
2) do it 'old school' , since you know the datastream format and timing, setup a simple ISR that looks for the start of the DMX data, then decode the incoming bits based upon the pulse width and relative locations from the 'start bit'.
3) Use Google to locate PIC assembler code(tons out there) and convert to CCS C code
#1 is probably the easiest
#2 will teach you more
#3 is a compromise |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9225 Location: Greensville,Ontario
|
|
Posted: Wed Dec 14, 2011 5:05 pm |
|
|
Took another look ,seeing how it's raining again...., and found some nice CCS C code for 'ac dimmer' on the net.Simple,easy to under stand,even for an old guy like me.
Lots of code, mostly for PCM compiler,looks like a favorite 'final year project'.
Seems MIDI may be a close cousin to DMX512... |
|
|
arunkish
Joined: 23 Dec 2008 Posts: 83
|
|
Posted: Wed Dec 14, 2011 8:49 pm |
|
|
Thank you for your support. I would like to choose #2 so that I can learn out things as you have said. But I dont know how can I use the INT_EXT interrupt to look for the valid start BIT and decode bits based on the pulse width.
I have checked for 'ac dimmer' but I dont have the luck to get the right one. I can understand that I dont find them using the right keyword. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9225 Location: Greensville,Ontario
|
|
Posted: Thu Dec 15, 2011 6:32 am |
|
|
Simply put...
1) Draw on graphpaper a 'typical' datastream, with each square being one pulse width or bit.
2) the 'start bit' will be wider(longer) than the rest,or unique in some obvious way.
3) setup a 'capture pulse width ISR' to decode the width of this bit.When the PIC 'sees' this start bit, set a flag and then allow this flag to start a timer ISR that interrupts the PIC every 'bit width' in usecs.Test the pin for high or low and create a buffer of ones and zeros that shows the datastream.Do this until the line goes 'idle'( another unique condition),or just stop recording after xxx seconds.
4)Now that you have the 'datastream' in a buffer, decode into control bytes, command bytes, data bytes based upon location and value(0 or 1).
While not memory efficient,storing just one DMX bit in one byte makes it easier to decode and 'see' what is happening.
Program the PIC and test. To test, send the PIC the same identical DMX512 message every time !! Once you decode that message, change/add another piece of information,test, once that decodes correctly, try another.keep doing this until the PIC works correctly.
If you want to practice using this method, you can decode normal 'serial RS232' data this way and may be easier as you know what is being sent from say PC terminal program. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9225 Location: Greensville,Ontario
|
|
Posted: Thu Dec 15, 2011 7:38 am |
|
|
Take the time to download and read the MC appnote AN1076.
It has all the necessary info you need and should be fairly easy to convert to CCS C code. |
|
|
arunkish
Joined: 23 Dec 2008 Posts: 83
|
|
Posted: Mon Dec 19, 2011 3:07 am |
|
|
Hello.
I am unable to figure out who to read the time frame of the data sent from the master. This is the data I am sending as a test from the master
Code: |
DMXOUT=1; // MTBP - Idle
delay_cycles(50); // MTBP - Idle
DMXOUT=1; // MTBP - Idle
delay_cycles(100); // MTBP - Idle
dmxout=0;
delay_cycles(10); |
and this is the slave code to read the data. Please advice a little.
Code: |
#include <16F876A.h>
#fuses NOPROTECT,NODEBUG,NOWDT,HS,NOBROWNOUT
#use delay(clock=4000000)
#use rs232(baud=9600,xmit=PIN_C6,rcv=PIN_C7,ERRORS)
#use fast_io(b)
#include <string.h>
#include <stdio.h>
#byte PORTA=0x05
#byte TRISA=0x85
#byte PORTB=0x06
#byte TRISB=0x86
#bit RX_PIN= PORTB.0
int16 stcount=0;
byte i;
#INT_EXT
void extisr()
{
set_timer1(0);
while (RX_PIN==1)
{
stcount=get_timer1();
}
printf("VAL:%lu",stcount);
}
void main(void)
{
set_tris_a(0x00);
set_tris_b(0b00000001);
ext_int_edge(0,H_TO_L);
clear_interrupt(INT_EXT);
enable_interrupts(INT_EXT);
enable_interrupts(GLOBAL);
enable_interrupts(INT_RDA);
setup_timer_1(T1_INTERNAL|T1_DIV_BY_1);
stcount=0;
while(1);
}
|
|
|
|
|
|
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
|