Dmx Solved !!!!!!!


Closed Thread
Results 1 to 19 of 19
  1. #1
    oscar's Avatar
    oscar Guest

    Talking Dmx Solved !!!!!!!

    hello again..
    after many many days lol of trying to get my dmx project going i have finally done it !!.. many thanks to all of you.... all done with pbp i may add and not a single asm in there lol. thank god !!.

    i have 1 remaining problem. im using a pic16f876a which has only 2 pwm on board. I need 3 !! anyone know of a pic chip with 3 comparators/pwm channels on it?

    thank you.

    oscar

  2. #2
    Join Date
    Jul 2003
    Posts
    2,405


    Did you find this post helpful? Yes | No

    Default

    The PIC16F7X7 series have 3 PWM channels.
    Regards,

    -Bruce
    tech at rentron.com
    http://www.rentron.com

  3. #3
    oscar's Avatar
    oscar Guest


    Did you find this post helpful? Yes | No

    Default im blind !

    hiya bruce thanx for the reply...
    i have been on the microchip site n secrched the 16f7 series. i cant seem to find a chip with more than 2 comparators/pwm channels...

    do you have a specific chip num please?
    thank's.

    oscar

  4. #4
    Join Date
    Jul 2003
    Posts
    2,405


    Did you find this post helpful? Yes | No

    Default

    I don't know of any 16F series with more than 2 comparators, but
    the 16F737, 747, 767 and 777 all have 3 PWM channels.
    Regards,

    -Bruce
    tech at rentron.com
    http://www.rentron.com

  5. #5
    oscar's Avatar
    oscar Guest


    Did you find this post helpful? Yes | No

    Thumbs up thanks bruce..

    thanx for the info bruce. ur a star !!!!!!!!

    found just what i wanted n seems as if the code should be compatible enough.

  6. #6
    Join Date
    Feb 2003
    Location
    Sydney, Australia
    Posts
    126


    Did you find this post helpful? Yes | No

    Smile DMX PIC Code

    Could you share your code - I'd be very interested !!

    Thanks,
    Bill

  7. #7
    Join Date
    Jun 2005
    Posts
    20


    Did you find this post helpful? Yes | No

    Default Re: DMX Solved!

    I would love to see your code on that-- that very problem (DMX in PICBasic only) has been plaguing me for years and I've never had the time on a project to sit down and figure it out. Seeing your code would be immensely helpful! Also, I have a subroutine implemented as inline assembler that you might find helpful-- it does 8 simultaneous channels of PWM. Let me know if you're interested!

    Thanks--

    --Alan

  8. #8
    Join Date
    Jun 2005
    Location
    Wisconsin
    Posts
    382


    Did you find this post helpful? Yes | No

    Default

    Yes, please post your code.

  9. #9
    Join Date
    Nov 2004
    Posts
    61


    Did you find this post helpful? Yes | No

    Default Dmx

    DMX isn't too bad if you spend a while in the datasheet. Depending on the chip you use, there are a few 'optimal' clock speeds which will allow you to send and receive zero error.

    It's just asynchronous serial @ 250 kbaud.

    I've used both '628s @ 20MHz and F88 chips @ 16Mhz, both transmitting and receiving.

    Just receive through an appropriate level shifting chip (MAX485, SN75176 or similar).

    The first thing I do is watch for the 'break' signal. PULSIN works remarkably well for this. I set a reasonable timeout duration and just keep watching for that 80 uS minimum break period.

    Then, I use a WHILE RCIF = 0 : WEND loop to sit there and wait for something else to come through the USART.

    Once I've found a valid break, the next byte is the start code. For dimmers, it should be zero.

    Then I just increment a counter each time a byte comes through and when I've received what I want, I exit the loop.

    I've not ever tried to implement a full interrupt based receiving system, as my other housekeeping code was fairly lightweight. However, it shouldn't be hard to do in theory.

    Transmitting is almost the same: just generate a 'break' signal (I like 120 uS), send out a zero byte and then however many bytes of channel data you need. With tight code, I can output 512 channels @ almost 40 Hz...

    John

  10. #10
    Join Date
    Jun 2005
    Posts
    20


    Did you find this post helpful? Yes | No

    Default DMX'ing

    John, thank you so much for pointing me in the right direction!

    I'm using a 16F877 at 20MHz, so the UART RX is pin 26, aka RC7. I'm using a 75176 also. I have no experience using the UART at all. Regarding your use of PULSIN, can I just do something like this?

    loop:
    PULSIN portC.7,1,pulse_word 'if portC.7 is set up at the UART input,
    'will PULSIN work? Is 1 the correct polarity?
    IF pulse_word<40 then loop '40 = 80uS with a 20MHz osc

    WHILE RCIF = 0
    HSERIN [dmx_val] 'throw away first value at it is the start code

    channel_loop:
    HSERIN [dmx_val] 'get channel 1 value
    count0 = count0 + 1
    if count0 = target_channel then exit
    goto channel_loop

    Since you've already done this, have you found any issues with UART overflow and needed to toggle that CREN bit? Also, I've read elsewhere that the data is in 8N2 value-- does that require any additional code to handle? I'm also wondering if having the UART enabled causes issues with then using PULSIN on the UART RX pin, PortC.7, and is the PULSIN polarity a 1 or a 0 for the break signal following the 75176?

    Thanks so much for your help so far!

    --Alan

  11. #11
    Join Date
    Nov 2004
    Posts
    61


    Did you find this post helpful? Yes | No

    Default Here there be Dragons

    >>overflow and needed to toggle that CREN bit? Also, I've read elsewhere that the data is in 8N2 value-- does that require any additional code to handle?

    Ooops. So what I usually do is check for my break signal with the USART turned completely off. Then, when the break is detected, I turn on the USART and read RCIF twice, just to make sure it's totally empty.

    Then, the next value that comes through is my start code.

    Don't just throw it away, though! The official spec (well worth the $30 paid to the USITT) talks about how dimmer data has a zero start code, but not everything needs to. It's totally OK for a manufacturer to send 'proprietary' data after a non-zero code. So if you're just blindly accepting everything after the first byte as valid, you may get burned down the road.

    Having said that, I've 'scoped the output of a GrandMA, a few different Hogs, a dozen or so ETC consoles, and some cheap throwaway DJ gear and never *not* found a zero start code...

    With one exception. It made me so mad I vowed never to buy or use that particular company's equipment again. I'd programmed *my* receiving equipment to flash an error LED if the data stream had a non-zero code for some reason.... Grrrrrrr.

    As an aside, if you tell your lighting controller to create a start code of, say, '10', only the 'proprietary' dimmers you've designed will work with that particular console. The marketing folks love that, because it fakes a case for using equipment only from one company.

    >>I'm also wondering if having the UART enabled causes issues with then using PULSIN on the UART RX pin, PortC.7, and is the PULSIN polarity a 1 or a 0 for the break signal following the 75176?

    After you've run the signal through the level shifter chip, you should see that the data line idles high. So you're watching for an active-low pulse of 80-120 uS.

    And the bit about 8N2 vs 8N1 doesn't really matter, because the stop bits are both high. So 8N2 is just a slightly 'slower' version of 8N1. It makes lots more sense if you can see it on a 'scope.

    So here's a loop in pseudocode:

    1. With the USART off
    2. Loop around until you find a decently long break

    3. If you've found a break, turn the USART on and clear RCREG twice (it's double-buffered, according to the datasheet. So it can receive two bytes without overflowing)
    4. When the RCIF flag is set, you've received a start code. Decide what you want to do with it.
    5. Then start counting and grab the rest of the data you're interested in.
    6. Turn off the USART

    Hope this helps some.

    Seriously, spend the $30 and get a copy of the DMX documentation. There's a lot of valuable design information included in what they'll send you.

    John

  12. #12
    Join Date
    Jun 2005
    Posts
    20


    Did you find this post helpful? Yes | No

    Default Dragons Ahoy!

    Hi John--

    Well, I bought the DMX spec... the current version is now $40. I feel that I understand what's going on there well enough to proceed with trying to translate that into PICBasic.

    Problem is, the PICBasic documentation on HSERIN just isn't very complete, and my brain hurts after about 15 minutes of trying to understand the Microchip datasheet... it looks like in PICBasic you enable the receiver by using defines, which don't allow me to turn the port on and off at runtime unless I know what specific register bit I want to change. It looks to me like I turn it on and off by toggling the SPEN bit (RCSTA.7) of the RCSTA register? I don't understand how to clear the RCREG, like you say to do twice... are you saying in your previous post that I don't need to do anything with the CREN bit?

    Using PULSIN I did successfully detect the start break, which I then used to generate a PULSOUT on another pin that I put back into my 'scope to use as a trigger. I can see the data as it should look (compared to the USITT data sheet), so at least that part is working. The code I used is:

    loop:
    pulsin porta.7,0,count0
    if count0 >40 then exit '(look for pulse longer than 80uS)
    goto loop

    exit:
    pulsout portb.0, 200
    goto loop

    Is this similar to what's working for you? (minus the pulsout, of course...)

    Also, it occurs to me that according to the spec, if I take more than 4-8 microsecs to determine the pulse length and turn on the USART, I'll miss the header byte... have you been able to implement your DMX receiver using only PICBasic, or do you have some assembly in there too? Do you set the USART to automatically clear its errors or toggle the RCSTA.4 bit?

    I'm still feeling kind of fried by all this register settings stuff, but I'm happy I can at least detect the break! (Hey, it's a start...)

    Thanks again for your help---

    ---Alan
    Last edited by alanmcf; - 29th June 2005 at 11:02.

  13. #13
    Join Date
    Nov 2004
    Posts
    61


    Did you find this post helpful? Yes | No

    Default DMX - There be Dragons...

    Let me try and find some code snippetts after breakfast & I'll post them.

    John

  14. #14
    Join Date
    Jun 2005
    Posts
    20


    Did you find this post helpful? Yes | No

    Default DMX Dragons

    Hi John--

    It would be great to see some actual code snippets-- that's the best way, I've found, for me to learn anything code-wise.


    By the way, I'm using an NSI Melange DMX board (circa 1993) to generate the DMX I'm viewing, and I also have a microTech hand-held DMX tester/analyzer that I'll use after I get the code working with output from the Melange. Both of these have zero for the start code, thank goodness.

    Thanks again--

    --Alan

  15. #15
    Join Date
    Nov 2004
    Posts
    61


    Did you find this post helpful? Yes | No

    Default DMX code snippets

    OK - Here are some bits and pieces from code which runs nicely on an 'F88 @ 16 MHz:

    * * * *

    DEFINE OSC 16
    DEFINE HSER_BAUD 250000
    DEFINE HSER_CLROERR 1

    * * * *
    This next routine is called on a gosub from my main housekeeping loop:
    * * * *

    checkdmx:

    counter = 1 'just a dummy variable
    pulsin target,0,counter 'here I'm looking for the break signal

    if counter = 0 then
    idleflag = 1 'either no dmx, or break was too long to count
    return
    endif


    if counter < 40 then checkdmx 'watching for 'break
    'if you get here, an active low pulse was detected, but it was too short.
    'probably just part of the datastream. So go back and look again.

    'otherwise, a valid break was found and it's time to read the start code

    RCREG = dummy 'clear out any garbage which may be in the USART
    RCREG = dummy
    SPBRG = 0
    TXSTA.2 = 0 'brgh = 0
    TXSTA.4 = 0
    RCSTA.7 = 1
    RCSTA.6 = 0 'setting 8 bit receive mode, no parity, etc
    RCSTA.4 = 0 'check the datasheet to see what all these bits do
    RCSTA.4 = 1 'now, the USART is on and ready to receive

    while RCIF = 0:wend 'hover here after break, before start code

    startcode = RCREG 'This is the first byte received after the break

    if startcode <> 0 then 'do your own stuff here on a non-zero code

    aminus = address1 - 1 'address1 is my target address

    for x = 1 to aminus 'set up a loop to count almost to the address
    while RCIF = 0:WEND 'sit here until a byte is received
    dummy = RCREG 'stash the byte somewhere unimportant
    next x

    hserin [newlevel1] 'This is your target channel data

    RCSTA.7 = 0 'turn off the USART

    return

  16. #16
    Join Date
    Jun 2005
    Posts
    20


    Did you find this post helpful? Yes | No

    Default Thanks!

    Thanks, John, for your help! I will be coding my gizmo in the next few days and those snippets will be very helpful in getting it up and running!

    I'll let you know how it goes...

    Thanks again--

    --Alan

  17. #17
    Join Date
    Jun 2005
    Posts
    20


    Did you find this post helpful? Yes | No

    Smile Success!! (mostly)

    Hi John--

    Well, I got it working, and its working fast, solid, stable and it is a really beautiful thing! Thank you so much for your help!

    I am having one problem... I used your code as-is, and I defined a starting address before starting the loop that calls checkdmx. The problem is there's a one channel offset-- if I program in channel 5 as my target address, the device actually reads the data coming in on channel 6. If I define channel 1, it reports what's coming in on channel 2. I can't get DMX channel 1. I can't set my starting address to 0 to compensate, or when we do the subtraction that sets aminus it would underflow and seek the wrong address. What do you think is causing this? I realize I could rewrite the code to trap out this error, but since you know your code works the way you wrote it I'm wondering what could be happening here.

    I also have a question-- you determine the start code by reading RCREG right after the bit is set indicating that something came into the USART following the start break with the statement startcode = rcreg. If that's all it takes to read the start code as a valid numerical byte, why do you need to use the hserin[newlevel1] statement at all? I realize my inexperience and lack of understanding about the USART is probably why I don't get it, but I am curious.

    Thanks again for all your help, it has truly been invaluable!

    --Alan

  18. #18
    Join Date
    Nov 2004
    Posts
    61


    Did you find this post helpful? Yes | No

    Default Dmx

    Two thoughts...

    First, I made a typo when I posted the original code:

    RCREG = dummy is bad. It should be
    dummy = RCREG to clear out the buffer.

    As far as catching the early data goes, it's probably more elegant to do something like

    while x < aminus
    'wait for a byte
    'discard it
    'increment x
    WEND

    This way, if aminus = 0 and your address = 1, the trashing routine is skipped altogether.

    ...

    And you're exactly right - there's no reason why you should need to use HSERIN at all to grab the last byte. I was experimenting back and forth reading the registers and using HSERIN. Once I got it stable, I didn't change everything to match.

    So you can leave it, or change it to say

    newlevel1 = RCREG

    Either way, it should work fine.

    Curious - what are you building?

    John

  19. #19
    Join Date
    Jun 2005
    Posts
    20


    Did you find this post helpful? Yes | No

    Default DMX Continued

    Hi John--

    I tried the While:wend loop you recommended to compensate for the adrress offset, but it didn't fix it... what DID fix it was getting rid of the HSERIN command-- when I changed that to newlevel1 = rcreg, it zeroed in on the correct address! I'm wondering if the HSERIN statement has some overhead that causes it to miss that first target byte?

    Regarding what I'm building, I replied to you offlist, so look for a message there.

    Thanks again--

    --Alan

    PS: Are there any gotchas if I want to use the USART to transmit DMX?

Similar Threads

  1. DMX receive issue
    By NoahLD in forum mel PIC BASIC Pro
    Replies: 5
    Last Post: - 27th August 2014, 14:51
  2. Simple 4 channel DMX controller
    By eggman in forum Code Examples
    Replies: 19
    Last Post: - 18th July 2012, 02:40
  3. Dmx
    By electronicsuk in forum mel PIC BASIC Pro
    Replies: 4
    Last Post: - 15th November 2008, 08:56
  4. Big Problem in PBP To receive DMX
    By programmer07 in forum mel PIC BASIC Pro
    Replies: 5
    Last Post: - 4th March 2007, 19:49
  5. DMX & PicBasic coding problem
    By magicmarty in forum mel PIC BASIC Pro
    Replies: 2
    Last Post: - 20th September 2004, 16:35

Members who have read this thread : 1

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts