Bit Angle Modulation (BAM) in a PIC


Closed Thread
Results 1 to 40 of 151

Hybrid View

  1. #1
    Join Date
    Aug 2007
    Posts
    7

    Wink Bit Angle Modulation (BAM) in a PIC

    I have read a few posts about BAM on this website but I can't completely understand the difference between it and PWM. I have also read something on the Artistic website that says it is a better technique that PWM for dimming leds. Exactly what is the difference between BAM and PWM and how can it be implemented in a PIC?

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


    Did you find this post helpful? Yes | No

    Default BAM vs PWM.

    <table><tr><td>PWM (Pulse Width Modulation) has 2 periods per cycle.
    There's the period when the output is HIGH, and the period when it is LOW.

    There will always be only 2 periods, and together they add up to the time it takes for 1 complete cycle. The ratio of the "ON" time to the total Cycle time defines the DutyCycle. (Corrected by The Borg)

    BAM (Bit Angle Modulation) has as many periods as there are Bits in the Resolution. For instance, 8-bit resolution (0-255) would have 8 periods per cycle.

    Each Period has a duration that corresponds to the Bit number, with each period being half as long as the previous one.

    </td><td></td></tr><tr><td valign=top><hr>Assuming a 100hz refresh rate, each cycle will take 0.01 sec. (1/100)

    Bit 7 of the DutyCyle will last for half of that, or 0.005 sec.
    Bit 6 is half of that again, or 0.0025 sec.
    then, continuing to divide in half each time, you end up with the lowest bit taking 0.000039 sec, (39 uS).

    When you add up all the "ON" times for the example at DutyCycle=168, then you'll get 0.0065625 sec. which is the exact same amount of time that the PWM cycle would have been "ON" during it's Single "ON" Period.

    This works good for controlling anything that depends on the Average Output, like LED's. But, it's not good for driving motors, or anything with inductance. </td><td></td></tr></table>
    <hr>
    Why is it better than PWM?

    Well, the real savings come in when you have Multiple Outputs.

    With 8-bit PWM, you would have to Interrupt 256 times per cycle to accommodate multiple outputs switching at different times.
    And at 100 Hz refresh rate, it would need 25,600 interrupts per second.

    But with BAM, you only need 8 Interrupts per Cycle (1 for each bit of resolution), and @ 100Hz, that's only 800 Interrupts per Second or 3% of the processing power required for software PWM.

    So now that it has all this extra time on it's hands, the PIC can control the brightness of 16-32 or more LED's, and still have time left over to do the animations.

    More on BAM ...
    http://www.artisticlicence.com/app%20notes/appnote011.pdf<!-- BitAngleModulation.pdf -->
    Last edited by Darrel Taylor; - 30th October 2007 at 20:25. Reason: Paul found a mistake.
    DT

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


    Did you find this post helpful? Yes | No

    Default BAM theory problem

    I've been working with this on and off for quite some time now.
    I've also had it working for quite some time now ... (with 1 exception).

    It creates some of the smoothest fading effects I've seen so far, so I really want to figure out this one last problem with BAM theory.

    The problem happens when passing in either direction of 128 DutyCycle.
    Before that point, after that point, even continuously at that point, all works perfectly. But as it transitions from either above or below 128 there is a visble BLINK from the LEDs.

    It's taken me Waaaay too long to figure out why, but I'm now pretty sure this is the reason ...

    With anything below 128, the waveform looks something like this ...

    <img src="http://www.picbasic.co.uk/forum/attachment.php?attachmentid=3127" /> <!-- Name:  BAM127.GIF
Views: 21119
Size:  4.2 KB -->
    <br>
    And with anything equal or above 128, it looks like this ...
    <img src="http://www.picbasic.co.uk/forum/attachment.php?attachmentid=3125" /> <!-- Name:  BAM128.GIF
Views: 21062
Size:  4.2 KB -->

    A continuous stream of either of the above pulses works perfect.
    It's only in the transition from below to above 128 that 1 out of the 100 pulses that second looks like this ...

    <img src="http://www.picbasic.co.uk/forum/attachment.php?attachmentid=3126" /> <!-- Name:  BAM127-128.GIF
Views: 20978
Size:  7.4 KB -->

    The change in pulse positions creates an ON period equal to 255, just for 1 period. Then it's fine again.
    But that 1 period, is extremely visible.

    Going from 127 to 128 it's a bright blink. From 128 to 127 it's a Dim blink, because they line up the other way (combined period = 0 dutycycle).

    The visual appeal and resulting reduction in processor requirements are too great to just give up on BAM.
    So I ask for your thoughts.
    <br>
    DT

  4. #4
    Join Date
    Jan 2009
    Posts
    3


    Did you find this post helpful? Yes | No

    Default

    You can invert the value of the bits in each cycle.

    In odd cycles, do first the normal order retard for each bit:
    1,2,4,8,16,32,64,128

    and, in the even cycles, reverse the value of each bit:
    128,64,32,16,8,4,2,1

    Edit:
    Oops this can generate the problem even without transtitions of the dutty cycle used... hummm... maybe rearranging the value of the bits, not just reversing them :?
    Last edited by RadikalQ3; - 16th January 2009 at 09:41.

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


    Did you find this post helpful? Yes | No

    Default

    Hmmmm, such a Radikal idea.
    Very interesting ...

    I had thought of putting the 7th bit in the middle, but it always came up lop-sided since it's Half of the period.

    But making a mirror image of the pulses (at twice the frequency) would put it smack dab in the middle of a nice symetrical waveform that might actually work.

    I must try this ...

    Oh, and Hi there Q3.
    Welcome to the forum!
    DT

  6. #6
    Join Date
    Nov 2008
    Posts
    19


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by Darrel Taylor View Post
    Hmmmm, such a Radikal idea.
    Very interesting ...

    I had thought of putting the 7th bit in the middle, but it always came up lop-sided since it's Half of the period.

    But making a mirror image of the pulses (at twice the frequency) would put it smack dab in the middle of a nice symetrical waveform that might actually work.

    I must try this ...

    Oh, and Hi there Q3.
    Welcome to the forum!
    Just my musings can you do a check if duty cycle = 127 + 1 then bit 7=0 (0.005s interrupt) then 128 duty cycle. I.e cause a timer interupt delay before starting on with the BAM again.

  7. #7
    Join Date
    Nov 2009
    Posts
    14


    Did you find this post helpful? Yes | No

    Default work MIBAM with hserin (16f628a)

    Hallo
    will work mibam with hserin on 16F828?

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


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by talatsahim View Post
    will work mibam with hserin on 16F828?
    Yes it will.
    DT

  9. #9
    Join Date
    Nov 2009
    Posts
    14


    Did you find this post helpful? Yes | No

    Question thanks

    Quote Originally Posted by Darrel Taylor View Post
    Yes it will.
    Sorry, my very poor english.
    Im new pbp user.
    can you help me why not work my code?
    Device 16F628





    Code:
    DEFINE OSC 20
    CLEAR
    
    ;_________________________Interrupt Context save locations]_________________
    
    wsave       var byte    $20     SYSTEM      ' location for W if in bank0
    wsave1      VAR BYTE    $A0     SYSTEM      ' location for W if in bank1
    wsave2      VAR BYTE    $120    SYSTEM      ' location for W if in bank2
    ssave       VAR BYTE    BANK0   SYSTEM      ' location for STATUS register
    psave       VAR BYTE    BANK0   SYSTEM      ' location for PCLATH register
    ;----[ MIBAM Setup ]--------------------------------------------------------
    BAM_COUNT CON 3                     ; How many BAM Pins are used?
    INCLUDE "MIBAM.pbp"                 ; Mirror Image BAM module
    
    BAM_FREQ    CON 100
    DEFINE BAM_INFO 1  
    DEFINE HSER_BAUD 250000
    DEFINE HSER_CLROERR 1
    DEFINE HSER_RCSTA 90h
    DEFINE HSER_TXSTA 20h 
    
    
    
    KANAL       CON 3   
    BREAKTIME   VAR BYTE
    DMXFLAG     VAR BIT
    STARTBYTE   VAR BYTE
    ADR         VAR BYTE
    RVAL        VAR BYTE
    GVAL        VAR BYTE
    BVAL        VAR BYTE
    YVAL        VAR BYTE
    X           VAR BYTE
    DUMMY       VAR BYTE
    i           VAR BYTE
    
    '*****************  MIBAM  ***************************************************
    RED         VAR BYTE
    GREEN       VAR BYTE
    BLUE        VAR BYTE
    
    ASM
    BAM_LIST  macro                     ; Define PIN's to use for BAM
         BAM_PIN (PORTB,5, RED)         ;   and the associated Duty variables
         BAM_PIN (PORTB,6, GREEN)
         BAM_PIN (PORTB,7, BLUE)
      endm
      BAM_INIT  BAM_LIST                ; Initialize the Pins
    ENDASM
    '*****************************************************************************
    TRISA=%00111001
    TRISB=%00000010 
    
    ScopeSync   VAR     PORTB.2   
    RXT         VAR     PORTB.1
    ERR         VAR     PORTB.4
    
    CMCON=7        
    VRCON=0 
    OPTION_REG.7 =0
    INTCON =%11000000  
    
    
    
    START:
    PAUSE 100
    DUMMY=0
    ADR = KANAL-1
    RED=50
    GREEN=100
    BLUE=180
    ERR=0
    GOTO LOOP
    '--------->>>>>>>>
    
    DMXBAK:
    i=i+1
    IF i> 200 THEN RETURN
    BREAKTIME =1:DMXFLAG = 0
    pulsin  RXT,0,BREAKTIME 
    
    if BREAKTIME = 0 then return  
    if BREAKTIME < 30 then DMXBAK 
    
    PIE1.5=1 
    RCREG = dummy 
    RCREG = dummy '
    SPBRG = 0 
    TXSTA.2 = 0 
    TXSTA.4 = 0 
    RCSTA.7 = 1 
    RCSTA.6 = 0  
    RCSTA.4 = 0 
    RCSTA.4 = 1 
    
    while RCIF = 0:wend 
    STARTBYTE = RCREG
    if STARTBYTE = 0 then 
         
        for x = 1 to ADR
        while RCIF = 0:WEND 
        dummy = RCREG 
        next x
        
        DATAAL:
        RVAL= RCREG 
        RCREG = 0 
        RCREG = 0 
        GVAL= RCREG 
        RCREG = 0 
        RCREG = 0 
        BVAL= RCREG 
    ENDIF
    RCSTA.7 = 0 
    DMXFLAG=1
    return
    
    
    LOOP:
        IF DMXFLAG=1 THEN
            RED= RVAL
            GREEN=GVAL
            BLUE=BVAL
        ENDIF
    GOSUB DMXBAK
        IF i>200 THEN 
            ERR=0
            ELSE
            ERR=1
        ENDIF
    i=0
    DUMMY=0
    
    GOTO LOOP
    
    END

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


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by talatsahim View Post
    can you help me why not work my code?
    Yes I can ...
    1. HSER defines only work with HSERIN/HSEROUT. If you are reading RCREG manually, the baud rate will not have been set by PBP and you will have to do that manually as well.<br><br>
    2. pulsin RXT,0,BREAKTIME, PULSIN does not work with interrupts. The timing will be wrong and you'll almost never see a Break pulse that way. Fortunately, the USART does it for you. Look for an FERR flag (framing error) which happens on every Break.<br><br>
    3. INTCON =%11000000, interrupts are controlled by the MIBAM routines. Don't change any interrupt registers.<br><br>
    4. PIE1.5=1, you've enabled the USART receive Interrupt ... don't do that.<br><br>
    5. RCREG = dummy, RCREG is a Read-Only register. Don't know what you were trying to do there.<br><br>
    6. SPBRG = 0, it's unlikely that you would want to put SPBRG (Baud Rate Generator Register) to 0 for any reason.<br><br>
    7. TXSTA.2 = 0, It's unlikely that you would want to put the USART in Low Speed mode when running at 250Kbaud.<br><br>
    8. TXSTA.4 = 0, OK, it's not synchronous mode .... but what is it?<br><br>
    9. I have no idea what you are trying to do here. RCREG is read-only, and you're reading 3-bytes from a maximum 2-byte buffer, without checking to see if anything is there.
      Code:
      DATAAL:
      RVAL= RCREG 
      RCREG = 0 
      RCREG = 0 
      GVAL= RCREG 
      RCREG = 0 
      RCREG = 0 
      BVAL= RCREG 
      ENDIF
      RCSTA.7 = 0 
      DMXFLAG=1
      return

    Back to the Drawing Board.
    DT

  11. #11
    Join Date
    Nov 2009
    Posts
    14


    Did you find this post helpful? Yes | No

    Red face thanks again

    "RCREG=DUMMY" was copy-paste from a sample code
    how can I set receive port with correct commands?
    and how sense break signal with FERR ?


    [QUOTE=Darrel Taylor;80570]Yes I can ...


    1. DEFINE OSC 20
      CLEAR
      ;_________________________Interrupt Context save locations]_________________

      wsave var byte $20 SYSTEM ' location for W if in bank0
      wsave1 VAR BYTE $A0 SYSTEM ' location for W if in bank1
      wsave2 VAR BYTE $120 SYSTEM ' location for W if in bank2
      ssave VAR BYTE BANK0 SYSTEM ' location for STATUS register
      psave VAR BYTE BANK0 SYSTEM ' location for PCLATH register
      ;----[ MIBAM Setup ]--------------------------------------------------------
      BAM_COUNT CON 3 ; How many BAM Pins are used?
      INCLUDE "MIBAM.pbp" ; Mirror Image BAM module

      BAM_FREQ CON 100
      DEFINE BAM_INFO 1
      ' MUST BE HERE DEFINE USART PARAMETER?

      KANAL CON 3 'my dmx adress, 3.byte red, 4. byte green, 5. byte blue
      BREAKTIME VAR BYTE
      DMXFLAG VAR BIT
      STARTBYTE VAR BYTE
      ADR VAR BYTE
      RVAL VAR BYTE
      GVAL VAR BYTE
      BVAL VAR BYTE
      YVAL VAR BYTE
      X VAR BYTE
      DUMMY VAR BYTE
      i VAR BYTE

      '***************** MIBAM ************************************************** *
      RED VAR BYTE
      GREEN VAR BYTE
      BLUE VAR BYTE

      ASM
      BAM_LIST macro ; Define PIN's to use for BAM
      BAM_PIN (PORTB,5, RED) ; and the associated Duty variables
      BAM_PIN (PORTB,6, GREEN)
      BAM_PIN (PORTB,7, BLUE)
      endm
      BAM_INIT BAM_LIST ; Initialize the Pins
      ENDASM
      '************************************************* ****************************
      TRISA=%00111001
      TRISB=%00000010

      ScopeSync VAR PORTB.2
      RXT VAR PORTB.1
      ERR VAR PORTB.4

      CMCON=7
      VRCON=0
      OPTION_REG.7 =0


      START:
      PAUSE 100
      DUMMY=0
      ADR = KANAL-1
      RED=50
      GREEN=100
      BLUE=180
      ERR=0
      GOTO LOOP
      '--------->>>>>>>>

      DMXBAK:
      i=i+1
      IF i> 200 THEN RETURN
      BREAKTIME =1MXFLAG = 0
      pulsin RXT,0,BREAKTIME ' I DONT KNOW HOW USE FERR THIS POINT

      if BREAKTIME = 0 then return
      if BREAKTIME < 30 then DMXBAK

      BRGH=1 ' 250000 BAUD ?
      SPBRG = 4 ' 250000 BAUD ?
      'AND HOW CAN I "DEFINE HSER_CLROERR 1" WITHOUT DEFINE?


      RCSTA.7 = 1
      RCSTA.6 = 0
      RCSTA.4 = 0
      RCSTA.4 = 1

      while RCIF = 0:wend
      STARTBYTE = RCREG
      if STARTBYTE = 0 then

      for x = 1 to ADR 'MY ADRESS 3, SKIP 2 BYTE
      while RCIF = 0:WEND
      dummy = RCREG
      next x

      DATAAL:
      RVAL= RCREG ' 3.BYTE, START OF MY DATA STREAM, RED VALUE
      GVAL= RCREG '4 BYTE.. GREEN VALUE
      BVAL= RCREG '5. BYTA BLUE VALUE
      ENDIF
      RCSTA.7 = 0
      DMXFLAG=1
      return

      LOOP:
      IF DMXFLAG=1 THEN
      RED= RVAL
      GREEN=GVAL
      BLUE=BVAL
      ENDIF
      GOSUB DMXBAK
      IF i>200 THEN
      ERR=0
      ELSE
      ERR=1
      ENDIF
      i=0
      GOTO LOOP

      END
    Last edited by talatsahim; - 9th November 2009 at 03:06. Reason: careless

  12. #12
    Join Date
    Feb 2015
    Posts
    1


    Did you find this post helpful? Yes | No

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

    Hi there !
    Can anybody mail me a code for charliplexing more than 20 or even 20 LEDs with 16F886 in a C listing file ?

  13. #13
    Join Date
    Sep 2010
    Location
    Las Vegas, NV
    Posts
    305


    Did you find this post helpful? Yes | No

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

    There are several posts encompassing a 20 LED charlie and at least one using only 4 PIC pins.

    I doubt though you'll find any of them in C and I guarantee you no one will do it for you.

Similar Threads

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