Decoding DMX with picbasic pro


Closed Thread
Results 1 to 9 of 9
  1. #1
    Join Date
    Jan 2006
    Posts
    8

    Smile Decoding DMX with picbasic pro

    hello,

    I have studied the posts concerning dmx with picbasic, I want to dimming a led on portC.5 on a 18F452. I try this basic code but unfortunately it doesn't run.

    the dmx is converted by a driver SN75176 connected on pin 26 (RC.7/RX/DT). Please is someone can look my code for help me.

    sorry for my bad english i'm french.....
    greating

    Code:
    '****************************************************************
    '*  Name    : UNTITLED.BAS                                      *
    '*  Author  : [select VIEW...EDITOR OPTIONS]                    *
    '*  Notice  : Copyright (c) 2006 [select VIEW...EDITOR OPTIONS] *
    '*          : All Rights Reserved                               *
    '*  Date    : 26/01/2006                                        *
    '*  Version : 1.0                                               *
    '*  Notes   :                                                   *
    '*          :                                                   *
    '****************************************************************
    DEFINE OSC 16             ' for pic 18f452  
    DEFINE HSER_BAUD 250000    
    DEFINE HSER_CLROERR 1
    ASM
            ERRORLEVEL -306, -302
    ENDASM
    
    ' Variables diverves 
     
          counter        VAR word                ' Variable de travail WORD
          idleflag       VAR WORD          
          dummy          VAR WORD  
          RCIF           VAR byte
          startcode      VAR WORD
          aminus         VAR WORD
          adresse_grada  VAR WORD
          x              VAR WORD
          newlevel1     VAR WORD
       
    adresse_grada = 20
        
    'This next routine is called on a gosub from my main housekeeping loop:
    
    checkdmx:
    
    counter = 1 'just a dummy variable
    pulsin portc.7,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
    
    dummy = RCREG 'clear out any garbage which may be in the USART
    dummy = RCREG
    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 checkdmx 'do your own stuff here on a non-zero code
    
    aminus = adresse_grada - 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
    
    newlevel1 = RCREG 'This is your target channel data
    pwm portc.5, newlevel1 ,100  'i want dimming a LED on PORTC.5
    RCSTA.7 = 0 'turn off the USART
    
    goto checkdmx
    return
    Last edited by ScaleRobotics; - 6th August 2010 at 15:51. Reason: added code tags

  2. #2
    Join Date
    Apr 2005
    Posts
    32


    Did you find this post helpful? Yes | No

    Default

    http://www.melabs.com/resources/samples.htm

    here is a program for dimmer may be helpful for you?

    Code:
       ' Lamp dimmer
        ' ===========
        '
        ' File name : LampDim.bas
        ' Company : Mister E 
        ' Programmer : Steve Monfette
        ' Date : 23-12-2004
        ' Device : PIC12F675
        '
        '
        ' This program is use to dim intensity of an AC line load
        ' like lamp, motor and other.  Developped for 60 Hz line.
        '
        ' This allow to increase or decrease intensity.
        ' If the user doesn't held at least 0.5 sec:
        '    1. "Increase" : we will set the output for full brightness
        '    2. "Decrease" : we will turn off the output
        '
        '
        ' The software need :
        '     1. A full wave signal from the AC line on GP4
        '
        ' The software use :
        '     1. TIMER1 overflow to check if pushbutton are hold for
        '        more than 0.5 Sec
        '     2. Interrupt on GP4 (AcLine input) to synchronise Triac
        '
        '
        '        Device programming mode and hardware definition 
        '        ===============================================
                 ' Using Internal Clock, no clock out
                 ' Enable Watch dog timer
                 ' Disable MCLR pin   
                 ' Enable Power-up timer
                 ' Enable Brown-out detect
                 '
    @ __config _INTRC_OSC_NOCLKOUT & _WDT_ON & _MCLRE_OFF & _PWRTE_ON & _BODEN_ON
                 '
                 '
    TRISIO = %11111011
    OPTION_REG.7=0    ' Enable pull-ups
    WPU=%00000011    ' Enable pull-ups on GP0, GP1
    CMCON=7    ' Disable analog comparator
    ANSEL=0    ' Disable analog converter
    
    Pb_Inc    var    GPIO.0 ' Input for INCREMENT/ON push button
    Pb_Dec    var    GPIO.1 ' Input for DECREMENT/OFF push button
    Triac    var    GPIO.2 ' Output to TRIAC gate
    ACLine    var    GPIO.4 ' Input for the FullWave rectify AC line
        '
        '        Software definition
        '        ===================    
                 '
                 '
                 '
    MaxDelay                    var word
    TriacDelay                  var Word
    Debounce_AutoRepeatDelay    var    word
    FullBright                  var bit
        '
        '
        '        Interrupts definition
        '        =====================
                 '
                 '
                 '
    INTCON=%10001000 ' Enable interrupt on GPIO change
    IOCB.4=1         ' Enable interrupt on GP4 change
    PIE1.0=0          ' disable TMR1 overflow interrupt
    T1CON=%00110100  ' Set TIMER1 
                     ' prescaler 1:8
                     ' internal clock (Fosc/4) 1MHZ
                     ' synchro internal
                     ' we will use TIMER1 overflow
                     ' $ffff * 8* (1/(4MHZ / 4)) = 0.524 Sec
    ON INTERRUPT GOTO ACDetect
       '
       '          Hardware and variable initialisation
       '          ====================================
                  '
                  '
    Maxdelay=6000 ' Set Maximum delay (set to 8000 for 50Hz)
    FullBright=0  ' disable Full Brightness flag
    triac=0       ' disable Triac Gate
    triacdelay=0  ' Set delay to minimum
    gosub ResetTimer1 ' reset Timer1
       '
       '      Main
       '      ====
       ' Get entry from user to Increment of Decrement intensity
       '  
       '
    start: 
       '
       ' Test Increment push button
       ' --------------------------
       ' If hold more than .5 Sec, increment triac gate delay by 500 uSec
       ' case else Full brightness at output
       '
    while Pb_inc=0 
        gosub TestTimer1 ' test status of TIMER1
        while (Pb_inc==0) AND (PIR1.0==0) 'loop while holding push button 
                                          'and no TIMER1 overflow
    
        wend
        
        if PIR1.0==1 then ' If timer overflow (pushbutton hold for > 0.5 sec), 
            T1CON.0=0     ' disable TMR1
            gosub Debounce_AutoRepeat
            if (triacdelay<maxdelay) then="">
                triacdelay=triacdelay+500 'increment Triac gate delay
            else
                triacdelay=maxdelay ' if triacDelay>MaxDelay,
                fullbright=1        ' set the full brightness Flag
            endif
        else 
            triacdelay=maxdelay ' If pushButton was hold less than .5 sec
            Fullbright=1 ' Set the full brightness flag
        endif
    wend
    gosub ResetTimer1
       '
       ' Test Decrement push button
       ' --------------------------
       ' If hold more than .5 Sec, increment triac gate delay by 500 uSec
       ' Case else, turn off output
       '
    while Pb_dec=0 
        gosub TestTimer1 ' Test status of TIMER1
        while (Pb_dec==0) AND (PIR1.0==0) 'loop while holding push button 
                                          'and no TIMER1 overflow
    
        wend
        
        if PIR1.0==1 then ' If timer overflow (pushbutton hold for > 0.5 sec), 
            T1CON.0=0 ' disable TIMER1
            gosub Debounce_AutoRepeat
            if (triacdelay>0) then
                Fullbright=0 ' Reset TRIAC always ON flag
                triacdelay=triacdelay-500
            endif
        else
            Fullbright=0 ' Reset TRIAC always ON flag
            triacdelay=0
        endif
    wend
    gosub ResetTimer1
    goto start
        '
        '
        '     TestTimer1
        '     ----------
        '
        ' Enable TIMER1 if :
        '    not enable and not in overflow
        '
    TestTimer1:
        if (T1CON.0==0) AND (PIR1.0==0) then 'if TIMER1 not enable
                                             'and TIMER1 not overflow    
            T1CON.0=1 'enable TIMER1
        endif
        return
        '
        '
        '     ResetTimer1
        '     -----------
        '
        ' Subroutine to clear Timer1
        '    1. Overflow flag
        '    2. Disable Timer
        '    3. Clear counter
        '
    ResetTimer1:
    PIR1.0=0  'clear timer overflow
    T1CON.0=0 'disable timer
    TMR1L=$00 'clear counter
    TMR1H=$00 '
    return
        '
        '
        '     Debounce_AutoRepeat
        '     -------------------
        '
        ' Subroutine to debounce push button.
        ' Also provide kind of auto-repeat when push button
        ' are held down.
        '
        ' each delay = 20 mSec
        ' Use of PAUSEUS to be sure getting ACLine interrupt
        '
    Debounce_AutoRepeat:
    
    for Debounce_AutoRepeatDelay=1 to 2000
        pauseus 10
    next
    return
        '
        '
        '       ACDetect
        '       --------
        '
        ' Interrupt routine called by ACLine (GP4) pin state change
        '
    disable
    ACDetect:
    if ACline==1 then ' Check for rising edge of AC signal
        if triacdelay > 0 then
            Triac=1 ' Activate TRIAC
            if FullBright==0 then   ' In case Brightness flag is not set
                pauseus triacdelay  ' do the selected delay
                triac=0 ' Disable TRIAC
            endif
        else
            triac=0
        endif
    endif
    INTCON.0=0 ' Clear GPIF (interrupt on GP4 change)
    resume
    enable
    </maxdelay)>
    Last edited by ScaleRobotics; - 6th August 2010 at 15:50. Reason: added code tags

  3. #3
    Join Date
    Jan 2006
    Posts
    8


    Did you find this post helpful? Yes | No

    Smile thanks

    Thanks for your answer,

    My problem is more decoding DMX frame with picbasic , firstly I try to detect the break at the beginning of the dmx frame....

    Thanks too for the link.

    Greeting

  4. #4
    Join Date
    Jan 2006
    Posts
    8


    Did you find this post helpful? Yes | No

    Default Yes i find a break

    Hello,

    I find a break
    but i don't understand the RCIF fonction!!

    I think that RCIF is my problem because he is always at 0 thus RCREG he is already full !!

    How made for use the RCIF??


    Greeting

  5. #5
    Join Date
    Nov 2004
    Posts
    61


    Did you find this post helpful? Yes | No

    Default

    Have you read the chapter about the USART in the datasheet? It takes a few tries for it all to sink in, usually.

    If you're reading zeros, that means it's either empty, or it actually thinks a zero was received.

    Depending on how you've structured your code, you may consider turning OFF the USART while you look for the break.

    Once you've found the break signal, turn on the USART and clear it a few times, just to make sure it's ready for whatever data you're hoping to capture.

    JEC

  6. #6
    Join Date
    Jan 2006
    Posts
    8


    Did you find this post helpful? Yes | No

    Default the code

    Hello,
    Can you say to me if my code is good for the definition of the variables (rcif)and if there are not other errors.

    Thank you
    Code:
    '************************************************* ***************
    '* Name : UNTITLED.BAS *
    '* Author : [select VIEW...EDITOR OPTIONS] *
    '* Notice : Copyright (c) 2006 [select VIEW...EDITOR OPTIONS] *
    '* : All Rights Reserved *
    '* Date : 26/01/2006 *
    '* Version : 1.0 *
    '* Notes : *
    '* : *
    '************************************************* ***************
    DEFINE OSC 20 ' for pic 16f627 
    DEFINE HSER_BAUD 250000 
    DEFINE HSER_CLROERR 1
    
    ' Variables diverves 
    
    counter VAR word ' Variable de travail WORD
    idleflag VAR WORD 
    dummy VAR WORD 
    RCIF VAR byte
    startcode VAR WORD
    aminus VAR WORD
    adresse_grada VAR WORD
    x VAR WORD
    newlevel1 VAR WORD
    
    adresse_grada = 20   ' my adress for exemple 20
    
    'This next routine is called on a gosub from my main housekeeping loop:
    
    checkdmx:
    
    counter = 1 'just a dummy variable
    pulsin portB.1,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
    
    dummy = RCREG 'clear out any garbage which may be in the USART
    dummy = RCREG
    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 checkdmx 'do your own stuff here on a non-zero code
    
    aminus = adresse_grada - 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
    
    newlevel1 = RCREG 'This is your target channel data
    portA.2 = newlevel1  'i want dimming a LED on PORTA.2
    RCSTA.7 = 0 'turn off the USART
    
    goto checkdmx
    return
    Last edited by ScaleRobotics; - 6th August 2010 at 15:52. Reason: added code tags

  7. #7
    Join Date
    Nov 2004
    Posts
    61


    Did you find this post helpful? Yes | No

    Default

    Hi -

    From what I can tell, you've copied the code I posted a few months ago verbatim. And I know that the code is good.

    What I posted was a *subroutine* which checks for DMX at a particular address.

    But, if what you've posted is in fact your entire project, it seems that you haven't added anything to it all!

    RCIF needs to be defined as whichever bit of the PIR register it actually is. Without it being defined, you code may return strange results. PIR1.5? Check your datasheet.

    The PULSIN routine in my code looks for DMX on PORTB.1, which is the RX pin for the processor I used. Your first post from a few days ago mentions that you're hoping to receive on PORTC.7. But you haven't changed the PULSIN command to suit, so there's no chance it will work right out of the box.

    You're using a different oscillator than I did. Have you confirmed that SPBRG and BRGH have the same values?

    How do you know you're even finding the break signal? Have you added any flags or pin-twiddles which let you know where the program is at any given time?

    One thing I did when I started writing the code was to insert something like this:

    If break signal was received
    high PORTB.FOO
    pauseus 10
    low PORTB.FOO
    endif

    Then, I could monitor the incoming signal and the FOO pin at the same time on my 'scope. Once I saw the FOO pin pulsing at exactly the proper position, I moved on to decoding other parts of the DMX stream. But if you don't catch the break signal properly, you don't have a chance at getting the rest of the stream.

    There are so many inconsistencies here that it's hard to know where to start...

    John

  8. #8
    Join Date
    Jan 2006
    Posts
    8


    Did you find this post helpful? Yes | No

    Smile pic 16f627 20mhz

    Thank you JEC for your very detailed answer.
    Indeed I am only at the beginning of my project.

    My objective is to be able to decode DMX stream with a 16F627 or a 18Fxxx (what explains the differences of port RX between my different "post"), to use it for different functions not yet definite.


    All that in PICBASIC if possible.
    By the way I use an 20 MHz oscillator.
    I wish to proceed by small steps

    1) first, detect signal DMX, and light a LED if it is present on RX pin.

    For example, if the break is detected.

    2) Then, store DMX value on a preset address, (in my example address 20).


    3) View this value in a way or another


    4) using this value to dim a LED, if possible on a pin of the processor use.


    Thank you for all your examples, but I am almost a beginner in programming, so I require also the good DEFINE of the variables used.

    I will continue my experiments with these new councils.

    So long.
    Fred

  9. #9
    skatnimit's Avatar
    skatnimit Guest


    Did you find this post helpful? Yes | No

    Talking FIX dmx512 diming LED

    hi fd

    i tryed your code and i add like this .


    newlevel1 = RCREG 'This is your target channel data

    ================================================== =

    PWM portb.3 ,newlevel1 100 ' send pluse to led at
    ' portb.3 i use 16f628 xtal = 20 mhz

    serout portb.2, t9600 [#newlevel1 10,13 ] ' send data to monitor
    'on pc rs 232

    'portA.2 = newlevel1 ' i don't use
    ================================================== =

    RCSTA.7 = 0 'turn off the USART

    -------------
    and led is work diming from low to full bright when i add my volum from ch 1

    but i have another problem it read data not same as my dmx transmit
    like ch1 send data 200 but my code read out 100 and not sure it moveing
    even i don't move volume..

    ok if someone know how to fix please let me know..

    GOD bless you ok have a goo day.

Similar Threads

  1. ICD, ICSP and Picbasic Pro
    By mwhatley in forum mel PIC BASIC Pro
    Replies: 17
    Last Post: - 8th August 2024, 20:42
  2. How to configure SPI in PICBASIC PRO?
    By moogle in forum mel PIC BASIC Pro
    Replies: 13
    Last Post: - 15th April 2007, 18:31
  3. Question for all that use MELABS PICBASIC PRO
    By oskuro in forum Off Topic
    Replies: 2
    Last Post: - 24th March 2005, 17:15
  4. DMX & PicBasic coding problem
    By magicmarty in forum mel PIC BASIC Pro
    Replies: 2
    Last Post: - 20th September 2004, 15:35
  5. PicBasic Pro & PicBasic syntax different
    By Billyc in forum General
    Replies: 5
    Last Post: - 16th April 2004, 21:19

Members who have read this thread : 0

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