Bit Angle Modulation (BAM) in a PIC


Closed Thread
Results 1 to 40 of 151

Hybrid View

  1. #1
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default

    Thanks for the Backup Mike.
    It's nice to see somebody else gets the same numbers.

    I'm making some progress with the "full-port" modification to MIBAM.

    Actually doing the outputs is easy, just like you showed previously.
    But I'm still having problems letting the user assign pins at random.

    It's getting there, although a bit slower than anticipated.
    <br>
    DT

  2. #2
    Join Date
    Aug 2009
    Posts
    16


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by Darrel Taylor View Post
    Thanks for the Backup Mike.
    It's nice to see somebody else gets the same numbers.

    I'm making some progress with the "full-port" modification to MIBAM.

    Actually doing the outputs is easy, just like you showed previously.
    But I'm still having problems letting the user assign pins at random.

    It's getting there, although a bit slower than anticipated.
    <br>
    that's nice, but not so effective at all. interleaving could be used to get more channels at the same freq. and something else to get 100ns discretization.)))

  3. #3
    Join Date
    Feb 2008
    Location
    Michigan, USA
    Posts
    231


    Did you find this post helpful? Yes | No

    Default LP INTS with MIBAM

    Hi all,
    I had a question that seems to have gotten lost in the fray....

    I'm trying to use other interrupts in hardware functions while using MIBAM.
    Specifically, a CCP HI/LO capture or USUART. the stand alone MIBAM examples work wonderfully, but when I try and incorporate a lo priority pulse capture or do comm, I run into problems. Is there a way to use incorporate the other ints and still use MIBAM? I have resorted to using a second PIC, but that isn't very elegant.

    Thanks for thinking about it.
    Bo

  4. #4
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default

    Hi Bo,

    If you're using an 18F, then sure ... you can have Low Priority interrupts running too. But I don't think you need interrupts for that stuff.

    With MIBAM ... <strike>99.4%</strike> 94% of the processor time is un-used. It's just sitting around twiddling it's thumbs. (if it has any)

    And since "capture's" retain the captured value for a while, they can easily be handled in the main loop by polling the CCPIF flag.

    I've also run the USART at 250kbaud for DMX reception, again strictly polled in the main loop, while MIBAM runs in the background.

    So much time ... so few things to do ... if only life were like that.
    <br>
    DT

  5. #5
    Join Date
    Feb 2008
    Location
    Michigan, USA
    Posts
    231


    Did you find this post helpful? Yes | No

    Default

    Thanks Darrel for the timely reply.

    Yes, I'm using an 18F1320.
    I guess that I was still thinking in terms of SPWM_INT where your available processor time was limited. I didn't realize that MIBAM left so much to play with.

    I have been trying to get them combined and I have it to the point that the only errors that I get are 3x "Symbol not previously defined (_doBam)". I haven't gotten it to compile, so I may be way off anyway. Don't know.

    I might try to better understand the magic static later, but for now,with your enlightenment, I'm going to change directions and just poll the flag.

    "Not as smart as tomorrow, but smarter than yesterday!"

    Thanks
    Bo

  6. #6
    Join Date
    Aug 2009
    Posts
    16


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by Darrel Taylor View Post
    Hi Bo,

    If you're using an 18F, then sure ... you can have Low Priority interrupts running too. But I don't think you need interrupts for that stuff.

    With MIBAM ... <strike>99.4%</strike> 94% of the processor time is un-used. It's just sitting around twiddling it's thumbs. (if it has any)

    And since "capture's" retain the captured value for a while, they can easily be handled in the main loop by polling the CCPIF flag.

    I've also run the USART at 250kbaud for DMX reception, again strictly polled in the main loop, while MIBAM runs in the background.

    So much time ... so few things to do ... if only life were like that.
    <br>

    This stuff would work for low-current balanced circuits or if don't need much accuracy and precision in result. Background? hmm.... If want get better results u should use HP Interrupts to minimize jitter and other timing errors. For 18F U should T2 Ints (or check and update timers everytime in HP ISR to avoid jitter). In more complicated designs parameters of switching element (or specialised driver) should be taken in to account. Sorrry for repeating what i've said earlier. P.S. Hope u wount blame be again, as the truth is far outhere) Best REGARDzzz.

  7. #7
    Join Date
    Feb 2008
    Location
    Michigan, USA
    Posts
    231


    Did you find this post helpful? Yes | No

    Default Trying to duck the mortar fire......

    Thanks Darrel for the advise.... sadly, I'm still having problems....

    To all that care to give me some advise:
    I have tried cleaning up my code so that I can check flags often enough to avoid missing the comm coming in through the USART. The PWM is fairly dynamic and seems to blow up the comm (OERR) if I enable more than one of the LED subroutines. I have tried to use low priority INTS, and didn't get it sorted out, I have tried to use a pattern similar to Darrel's in http://www.picbasic.co.uk/forum/showthread.php?t=4972 #16, but I haven't managed that yet either. Any advise would be appreciated.
    Code:
    '*  Notes   : derived from Darrel Taylor & Mister E's work     
    '*          : 18F1320a @ 8 mHz, PWM Freq = 95 Hz
    clear
    DEFINE OSC 8
    OSCCON  = %01110001         ' INTOSC primary, 8MHz 
    INCLUDE "AllDigital.pbp" 
    include "EE_Vars.PBP"       ' manipulation of EEPROM
    BAM_COUNT CON 8             ; BAM Pins are used?
    INCLUDE "MIBAM.pbp"         ; 
    
    ;----[ MIBAM Setup ]-------------
    BAM_DUTY  VAR BYTE[BAM_COUNT]
      LED1    VAR BAM_DUTY[0]           ; array for easy access
      LED2    VAR BAM_DUTY[1]           ; with FOR loops etc.
      LED3    VAR BAM_DUTY[2] 
      LED4    VAR BAM_DUTY[3] 
      LED5    VAR BAM_DUTY[4] 
      LED6    VAR BAM_DUTY[5] 
      LED7    VAR BAM_DUTY[6] 
      LED8    VAR BAM_DUTY[7] 
    
    ASM
    BAM_LIST  macro                     ; Define PIN's for BAM
         BAM_PIN (PORTB,5, LED1)        ;   and Duty variables
         BAM_PIN (PORTB,0, LED2)
         BAM_PIN (PORTA,3, LED3)
         BAM_PIN (PORTA,2, LED4)
         BAM_PIN (PORTA,1, LED5)
         BAM_PIN (PORTA,0, LED6)
         BAM_PIN (PORTA,7, LED7)
         BAM_PIN (PORTB,2, LED8)
      endm
      BAM_INIT  BAM_LIST                ; Init Pins
    ENDASM
    
    DEFINE HSER_RCSTA 90h ' En serial port & cont rx
    DEFINE HSER_TXSTA 24h ' En transmit, BRGH = 1
    DEFINE HSER_CLROERR 1 ' Clear overflow automatically
    DEFINE HSER_SPBRG 160 ' 4800 Baud @ 8MHz, -0.08%
    SPBRGH = 1
    BAUDCTL.3 = 1         ' 
    
    address      var byte
    command      var byte        
    charcnt      var byte        '
    Cnt          var byte        ' counter for ramping the display brighter
    Counter      var byte
    CyLoop       var word        ' MAY be able to combine this later
    Dly          var byte        ' used on delay loop sub
    holdoff      var word
    i            var byte
    IDloop       var byte        ' loop cntr in ID Loop
    Idx          VAR BYTE
    loop         var byte
    LoopCount    VAR WORD: LoopCount = 0        ' from Random Sub
    ModeCnt      var byte: @ EE_var _ModeCnt, BYTE, 8 ' count flashes of 1&8 LEDs when Switch
    NextLED      VAR BYTE: NextLED   = 1
    PowerOn      VAR WORD: @ EE_var _PowerOn,  WORD, 0     '
    RandVar      var word: RandVar  = 12345
    RandVar8     var byte            '
    SerialString var byte[40]         '
    Speed        VAR BYTE: @ EE_var _Speed, BYTE, 50 ' delay length /control speed
    state        var byte         ' condition bits
    state2       var byte         ' condition bits
    time         var WORD         ' delay loop sub
    temp         var byte
    value        var byte
    Sync         VAR state.0        ' Sync byte rcvd
    ForMe        VAR state.1        ' Packet is for this device
    CmdRcvd      VAR state.2        ' flag for Command  rcvd
    CntState     var state2.0       ' flag for counting pulse
    ERROR        VAR state.3        ' Sync rcvd out of order
    header       var state2.2
    tlate        VAR state.4        ' command rcvd before last one done
    ValRcvd      var state.5        ' flag: Value data rcvd 
    Success      var state.6
    idle         var state.7        ' flag: idle polarity  
    TraceDIR     VAR state2.1       ' cyclon
    CREN         var RCSTA.4        ' RX enable bit
    OERR         var RCSTA.1        ' Overrun  error
    RCIF         VAR PIR1.5         ' Receive  int flag (1=full , 0=empty)
    TXIF         VAR PIR1.4         ' Transmit int flag (1=empty, 0=full 
    Brightness   CON 100            ; Tracers DutyCycle
    ID           CON 123            ' ID. unique to each, 255=all
    SyncByte     CON 85             ' "U" for SYNC. constant on all 
    TracerSpeed  CON 15             ; Smaller = Faster L-R
    DrainSpeed   CON 30             ; Smaller = Shorter Trail       
    
    '*************************
    Main:
    ' once comm is figured out, Command will be used for selecting ModeCnt or speed 
    ' and value will be the rate that it flashes the LEDs  
         
    'ManMod: 
    '    branch ModeCnt,[fadem,smoothm,rampm,twinklem,cyclonm,dimm,RanMainm,IDm,autom]' 
    '.....
          
    'autom:
            gosub FadeUp
            gosub SmoothUp        ' as soon as I enable more than one-
    '        gosub Fillup         ' comm starts to get erratic
    '        gosub StrobeUp
    '        gosub cyclon
    '        gosub drvdim                
    '        gosub RanSub
    '        gosub shoid        
    goto Main:
    '**********Sub for polled comm *********
    RX:
       IF OERR then
    hserout ["OERR", 13,10]
          CREN=0
          CREN=1
          endif
    getcomm:      
          i=RCREG                  ' take it        
          if header then
              if i ="#" then Discard  ' is it the end? "#" = yes   
            Serialstring[Counter]=i ' Store into the array
            Counter=Counter+1
            endif 
           if RCIF then getcomm     'try again of still data
          if i ="!" then header=1 ' header character? "!" = yes         
          Discard:
              while RCIF
                    temp=RCREG
              wend
        
              if i="#" then       ' End of String character
                 Success=1        ' Yeah i got a valid string
                 header=0
              endif
      
       if Success then
          CREN=0                  ' Disable Receiver 
          address =  Serialstring[0]   'do deciphering here
          command =  Serialstring[1]
          value   =  Serialstring[2]
          
          hserout ["Str rx : ",str Serialstring\Counter," Ch : ", dec Counter,13,10]
          CREN=1                  ' Enable receiver
          Counter = 0
          Success = 0
          endif
    return   
    
    '***** Timing Sub:   *****
    DlyTime3:                    ' longest delay loop
         for time = 0 to speed   
         next time
    DlyTime2:                    ' mid delay loop
         for time = 0 to speed   
         PAUSE 2
         next time               
    DlyTime1:                    ' smallest delay loop
         for Dly = speed to 0 step -1
         if RCIF then             ' check here for a comm flag r
            gosub RX              ' and get the character
            goto short            ' reduce delay, avoid blinking 
         endif
         PAUSEUS 180              ' times need to be refined
    Short:
          'pauseus 5              ' times need to be refined
         next Dly
    return 
    
    '**********************      
    ' Subs for patterns
    '
    '***** Fade Sub: MODE 0  ******
    FadeUp:
           hserout ["fadeUp",13,10]
       for  cnt = 0 to Brightness      ' fade up 
        gosub DlyTime1
        LED1 = Cnt: LED2 = Cnt: LED3 = Cnt: LED4 = Cnt
        LED5 = Cnt: LED6 = Cnt: LED7 = Cnt: LED8 = Cnt           '
       next Cnt                    ' 
    hserout ["fadeDown",13,10]
    FadeDown:        
       for  Cnt = Brightness to 0  step -1 ' fade down
        gosub DlyTime1
        LED1 = Cnt: LED2 = Cnt: LED3 = Cnt: LED4 = Cnt
        LED5 = Cnt: LED6 = Cnt: LED7 = Cnt: LED8 = Cnt           '
       next Cnt                     '
    return                           'stay in fade loop 
    '**** Smooth Sub: MODE 1 ******
    SmoothUp: 
              hserout ["SmoothUp",13,10]  
       for loop = 0 to 7
       BAM_DUTY(loop) = Brightness           ' smooth up
       gosub DlyTime2
       BAM_DUTY(loop) = 0
       next loop
      
    SmoothDown:
               hserout ["SmoothDown",13,10]
       for loop = 6 to 0 step -1
       BAM_DUTY(loop) = Brightness           ' smooth up
       gosub DlyTime2
       BAM_DUTY(loop) = 0
       next loop
       RETURN
    '*****  Ramp Sub: MODE 2 ******
    ' .......
    '
    end
    Thanks
    Bo

  8. #8
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default

    Hi Bo,

    At 4800 baud, each byte takes about 2.1 mS.
    The USART has a 2.8 byte buffer, so at around 6 mS the USART buffer will overflow.

    In the DlyTime2 section, it will loop 50 times with a 2mS delay without checking the USART.
    By the time it's finished, the buffer is very likely to have overflowed.

    I think if you do the same thing you did in DlyTime1, and check the RCIF bit inside the loop, it will have a better chance.

    And as you work on the rest of the program, look for any of those Evil PAUSE statements.
    Anything more than 4ms will have to be broken in smaller loops with RCIF checks in the middle.

    Added:
    Another method might be to use ON DEBUG, with only the Delay routines ENABLEd.
    Then it would be able to check RCIF in-between each and every statement in the delay routine without actually having to write the checks into the routine.

    hth,
    Last edited by Darrel Taylor; - 20th September 2009 at 20:04. Reason: Added
    DT

  9. #9
    Join Date
    Feb 2012
    Posts
    64


    Did you find this post helpful? Yes | No

    Default Re: Bit Angle Modulation (BAM) in a PIC

    I notice this is an old thread (Starting in 2009 with the last post in 2011). I downloaded Darrel Taylor's BIBAM ver 1.1 and had it working great with a 16f690.
    I am now trying it on a 18f14k22 and I can't get it working at all. From what I am reading it should work with the 18F's. I am trying to control 9 outputs (3 RGB LEDs). The 16f690 is too slow @8MHz

    Does anyone know if there are any issues using this with the 18f14k22 or if there is an updated BIBAM available?
    I am getting assembly errors when I try to compile: Symbol not previously defines (_VarIn), Missing arguments.

    Jim

  10. #10
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default Re: Bit Angle Modulation (BAM) in a PIC

    Hi Jim,

    It should work with the 14K22.

    That error can only be generated by a BAM_PIN statement.

    Make sure it looks something like this ...

    BAM_PIN (PORTB,0, Duty1)

    Note the comma between PORTB and 0.
    Duty1 should be a BYTE var.

    Make sure the designated pins are available.
    The 14K22 only has RA0-RA5, RB4-RB7 and RC0-RC7
    DT

  11. #11
    Join Date
    Feb 2012
    Posts
    64


    Did you find this post helpful? Yes | No

    Default Re: Bit Angle Modulation (BAM) in a PIC

    Darrel,
    I don't know what I did, but I got it to work. The code was working on the 16f690. The ports are the same on the 18f14k22 so that error should not have been there.

    Anyway, I swiched to the 18f14k22 because I am trying to control 9 ports (3 RGB LEDs) and the Ramps up/down were not smooth at all on the 16f690. I was hoping the speed from 8MHz to 16MHz would fix the problem, but it didn't.

    I just made a copy of the program and removed all the BIBAM code and replaced it with PWM statements (One for each of the 9 ports with a cycle of 1 and no pause). It works smooth and looks good, except the LED's are not quite as bright since they are actally taking turns being on, but they show no visible flicker.

    If I could just get the BIBAM to work as smoothly. I must be doing something wrong. I am controling all 9 LED ports directly from the micro. I did try using transistors, but it made no difference.

    I will keep trying, but I am running out of ideas.

    Jim

  12. #12
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default Re: Bit Angle Modulation (BAM) in a PIC

    What does the BAM_INFO report?

    Are you using the Cylon example, or something you wrote?
    DT

  13. #13
    Join Date
    Aug 2005
    Location
    Michigan, USA
    Posts
    224


    Did you find this post helpful? Yes | No

    Default Re: Bit Angle Modulation (BAM) in a PIC

    Unfortunately varying duty cycle incrementally does not produce linear changes in brightness.

    I use brightness level correction in the form of a "gamma" array which contains a smaller set of duty cycle values, which produce linear changes in brightness, spanning the larger PWM duty cycle range. For example, the C program below for a 12F1822 uses the PWM module for a very smooth fading output with 64 brightness corrected levels using duty cycle values in the 64 element "gamma" array which span the 256 step PWM duty cycle range. Unfortunately, I'm not sure how you would implement something like this in PBP.

    Good luck on your project... Cheerful regards, Mike

    Code:
       #include <system.h>
    
       #pragma DATA _CONFIG1, _FOSC_INTOSC & _WDTE_OFF & _MCLRE_ON
       #pragma DATA _CONFIG2, _LVP_OFF & _PLLEN_OFF
    
       #pragma CLOCK_FREQ 8000000   // 8-MHz INTOSC
    
       #define r08 const rom unsigned char
    
    
       r08 gamma[] = {  0,  1,  2,  2,  2,  2,  3,  3,  3,  4,
                        4,  5,  5,  6,  6,  7,  8,  8,  9, 10,
                       11, 12, 13, 14, 15, 17, 18, 20, 21, 23,
                       25, 27, 29, 31, 34, 36, 39, 42, 45, 49,
                       53, 57, 61, 65, 70, 75, 81, 87, 93,100,
                      107,114,123,131,140,150,161,172,183,196,
                      209,224,239,255 };
    
       void main()
       { ansela = 0;                // make pins digital
         trisa = 0b00000000;        // porta all outputs
         porta = 0;                 // all output latches low
         osccon = 0b01110010;       // initialize 8-MHz INTOSC
         while(!oscstat.HFIOFS);    // wait until OSC stable
    
         ccp1con = 0b00001100;      // pwm mode, p1a active hi
         ccpr1l = 0;                // 0% duty cycle initially
         pr2 = 255;                 //
         t2con = 1<<TMR2ON;         // pre 1, post 1, 7812.5 Hz
    
         while(1)                   //
         { static char duty = 32;   // start at ~50% brightness
           while(duty < 63)         // fade up to 100%
           { ccpr1l = gamma[duty++];
             delay_ms(30);          // over period of ~1 sec
           }                        //
    
           while(duty > 32)         // fade down to ~50%
           { ccpr1l = gamma[duty--];
             delay_ms(30);          // over period of ~1 sec
           }                        //
           delay_ms(100);           // pause at 50% brightness
         }                          //
       }


    Here's another example using 64 brightness level steps on a 20 LED Charlieplexed matrix with 8-bit (256 level) BAM modulation. While only one LED is being faded in the video, all twenty LEDs could be faded at the same time.

    Last edited by Mike, K8LH; - 26th July 2012 at 23:53.

  14. #14
    Join Date
    Feb 2012
    Posts
    64


    Did you find this post helpful? Yes | No

    Default Re: Bit Angle Modulation (BAM) in a PIC

    It is something I am writing. I was assuming that the duty in the BIBAM routine was directly related to the brightness level so that a loop from 0 to 255 should be a smooth increase in brightness. All I am doing right now is fading colors up and down to smoothly blend colors together. I will play with it a bit more next week.
    Thanks,
    Jim

Similar Threads

  1. decoding quadrature encoders
    By ice in forum mel PIC BASIC Pro
    Replies: 93
    Last Post: - 28th February 2017, 09:02
  2. Cordic trig assembly code for PIC18f
    By ScaleRobotics in forum mel PIC BASIC Pro
    Replies: 54
    Last Post: - 8th September 2015, 05:36
  3. AT/PS2 Keybord - PIC Interface?
    By Kamikaze47 in forum Code Examples
    Replies: 73
    Last Post: - 9th August 2009, 16:10
  4. MIBAM - (Mirror Imaged Bit Angle Modulation)
    By Darrel Taylor in forum Code Examples
    Replies: 2
    Last Post: - 15th February 2009, 16:02
  5. Bit Angle Modulation
    By BH_epuk in forum mel PIC BASIC Pro
    Replies: 1
    Last Post: - 18th November 2008, 07:01

Members who have read this thread : 2

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