Hello, welcome to our forum.

It looks like you have registered but you have not yet posted and messages. Our requirements are that you must post at least two messages, to allow the moderators to review your registration, before you will be allowed access to the full range of forum areas.

Please make a couple of posts, until then you may see a notice that says you are banned from certain forum areas.

Thank you.

Remove Text Formatting

Closed Thread
Results 1 to 3 of 3
  1. #1
    Join Date
    Jul 2003
    Colorado Springs

    Default MIBAM - (Mirror Imaged Bit Angle Modulation)

    MIBAM (pronounced "My BAM")
    Which stands for ... "Mirror Imaged Bit Angle Modulation"
    An include module for PicBasic Pro.

    After a year and a half of playing with this thing ... One statement from RadikalQ3 made all my problems go away.
    Thank you Radikal dude!

    Also many thanks to BCD for beta testing the module.

    I really liked the name "BAM-BAM", but MIBAM is probably a more descriptive acronym, so I've changed it. No matter what you call it ... I think you'll find that My "BAM" ... was the sound of hitting the nail on the head.

    This module is a modification of the BAM (Bit Angle Modulation) idea presented by Artistic License.
    For more information about BAM, it's blinking problem and how this program came to be, please see this thread ...

    Click image for larger Interactive version.

    Click image for larger Interactive version.

    What can it do?

    Well ... it can turn almost every pin on your PIC into an LED dimmer. (limitations apply)

    First, let's take a look at the basic MIBAM setup,
    For an RGB LED (3 outputs) it might look like this ....
    ;----[ MIBAM Setup ]--------------------------------------------------------
    BAM_COUNT CON 3                     ; How many BAM Pins are used?
    INCLUDE "MIBAM.pbp"                 ; Mirror Image BAM module
    BAM_LIST  macro                     ; Define PIN's to use for BAM
         BAM_PIN (PORTB,0, RED)         ;   and the associated Duty variables
         BAM_PIN (PORTB,1, GREEN)
         BAM_PIN (PORTB,2, BLUE)
      BAM_INIT  BAM_LIST                ; Initialize the Pins
    ;_________________________________________________  __________________________
    At this point, each BAM_PIN has been automatically set to OUTPUT, and the PINs will idle LOW until the Dutycycle variables are changed.

    The Dutycycle range is from 0-255, 0 = OFF, 255 = brightest.
    To change the brightness of an LED simply set the Dutycycle variable to the desired level.
    You don't need to call any subroutines.

    Here's an example of just fading the RGB LED's up and down.
    Speed       CON 20   ; Smaller=Faster
    Brightness  CON 200  ; Max DutyCycle
        FOR Red = 0 to Brightness -1          ; Ramp up 1 by 1
            PAUSE Speed
        NEXT RED
        FOR GREEN = 0 to Brightness -1
            PAUSE Speed
        NEXT GREEN
        FOR BLUE = 0 to Brightness -1
            PAUSE Speed
        NEXT BLUE
        FOR Red = Brightness to 1 STEP -1     ; Ramp down 1 by 1
            PAUSE Speed
        NEXT RED
        FOR GREEN = Brightness to 1 STEP -1
            PAUSE Speed
        NEXT GREEN
        FOR BLUE = Brightness to 1 STEP -1
            PAUSE Speed
        NEXT BLUE
    GOTO Main
    FOR loops always leave the variable 1 count further than the loop specifies.
    when using direct FOR loops, you must account for the difference.

    The module will work on most 16F's, ALL 18F's and some 12F's
    If you are using a 14-bit PIC. You'll need to add these variables to your program for the Interrupt Context.
    For 18F's you don't need to add these save locations. And they may cause errors if you do.
    ;____[ For 12F/16F only - Interrupt Context save locations]_________________
    wsave       var byte    $20     SYSTEM  ' location for W if in bank0
    ;wsave       var byte    $70     SYSTEM  ' Alternate save location for W 
                                            ' if using $70, comment out wsave1-3
    ' --- IF any of these next three lines cause an error ?? -------------------
    '       Comment them out to fix the problem ----
    ' -- The chip being used determines which variables are needed -------------
    wsave1      VAR BYTE    $A0     SYSTEM      ' location for W if in bank1
    wsave2      VAR BYTE    $120    SYSTEM      ' location for W if in bank2
    wsave3      VAR BYTE    $1A0    SYSTEM      ' location for W if in bank3
    '---DO NOT change these-----------------------------------------------------
    ssave       VAR BYTE    BANK0   SYSTEM      ' location for STATUS register
    psave       VAR BYTE    BANK0   SYSTEM      ' location for PCLATH register
    Limitations and Requirements
    • In order to use this module, you MUST be using MPASM for the assembler.
      PBP's default PM.exe assembler will not work.
    • This module takes over the Interrupts on the PIC because the timing of the waveforms must be exact.
      With 16F's, You can NOT use any other interrupts, this includes ON INTERRUPT.
      With 18F's, The module uses High Priority interrupts, and no other High Priority interrupts can be used.
      Low priority Interrupts are available, but you still can NOT use ON INTERRUPT.
    • The module uses Timer1, and it cannot be used for any other purposes.
      Consequently, the PIC being used must have a Timer1.
    • The number of LED's you can use is limited by the OSC frequency.
      It's not that the module uses so much processor time that it needs more speed.
      The limitation is the LSB (Least Significant Bit) of the DutyCycle, which is so short that it doesn't leave much time to do a whole lot of code.

      @ 4Mhz, you can only run 4 LEDs MAX. This can be useful for RGB LED's on small chips.
      @ 20Mhz, you can run 20 LEDs since there are more instructions available per period.
      @ 48Mhz, you can run 48 LEDs, and anywhere in-between you can have the equivelant number of LEDs to match the OSC frequency.
      If you attempt to use too many LEDs for a specific OSC frequency, the program will give a warning to indicate the results will be "Blinky".
    • DO NOT overload your PIC.
      A PIC can only source so much current. The specific amount is listed in the datasheet for the PIC you are using.
      If you are driving a lot of LED's, you may need to buffer them with transistors or various other drive mechanisms.
    Attached is the MIBAM.pbp module.
    Download and unzip it to your PBP folder. (The one with PBPW.exe, usually C:\PBP)
    Attached Files Attached Files
    Last edited by Darrel Taylor; - 7th June 2014 at 02:43.

  2. #2
    Join Date
    Jul 2003
    Colorado Springs

    Default MIBAM - More Info

    Option DEFINEs and Constants
    • BAM_COUNT CON xx
      This constant must match the number of BAM_PINS being used.
      If they do not match, an error will be displayed.
      By default, the module determines what the maximum refresh rate is for any given setup, and uses that rate. Depending on the conditions, it may be 700hz or more.
      If desired, you can set the frequency lower with this define.
      When using this define, MIBAM will display some information about the Refresh Rate (Frequency), Minimum Period, and number of pins used.
    • ScopeSync VAR PORTx.x
      If this alias is used, MIBAM will output a sync signal on the specified pin for use with an oscilloscope.
      This gives a nice stable view of the waveform.
      The Pin is automatically set to output.

    <hr>Error/Warning messages
    • Error: Symbol not previously defined (wsave)
      When using a 12F or 16F, you need to add the wsave block shown above to your program.
      This is not necessary for 18F's, so the vars have been omitted from the module.
    • ERROR: Variable wsaveX position request beyond RAM_END xx
      If the chip you are using doesn't have GP RAM in all 4 banks, then you have to comment out the wsave variables for any of the banks that don't have any. The ERROR message(s) tell you which ones need to be commented.
      If the chip has ACCESS RAM at address $70, then it's best to use that location, instead of wsave1-3.
    • Error: BAM_COUNT (x) is less than # of Pins used (x)
      The BAM_COUNT constant MUST match the number of BAM_PINs being used.
      Increase BAM_COUNT to fix the Error.
    • Error: Duplicate label ("BAM_PIN" or redefining symbol that cannot be redefined)
      The module requires case sensitivity in MPASM. But sensitivity has been turned off in MCS.
      In MicroCode Sudio, View | Compile and Program Options | Compiler Tab ...
      Check the "Case sensitive" box.
    • WARNING: Too many BAM pins for xx Mhz - Results will be BLINKY!
      The module can only run 1 LED per Mhz of the CPU's main Oscillator.
      Reducing the number of LED's or increasing the OSC frequency should eliminate the warning.
    • WARNING: BAM frequency (xxHz) is Less than Requested (xxHz)
      The module determines what the maximum refresh rate is for any given setup.
      If a BAM_FREQ has been defined that is higher than the maximum frequency, the module will warn you of the situation. This warning is not critical, and may still work in your application.
      Commenting the DEFINE BAM_FREQ line will squelch the warning.
    • MESSAGE: 'BAM_INFO' - MinPeriod= xx inst, Cycle= xxxx inst, Pins= xx, FREQ= xxx Hz
      This is an informational message that will be shown if you have set DEFINE BAM_INFO 1 or get a "BAM frequency WARNING".

  3. #3
    Join Date
    Jul 2003
    Colorado Springs


    Cylon Scanner

    Here's another quick example that simulates a Cylon or Kitt car scanner.

    It's running on a 16F887 with 8Mhz internal OSC. The PCB is the Microchip 44-pin Demo Board that comes with the PICkit2 Debug Express package.

    It's not too bad with 8 LEDs, but 16 would be better. The sequence will automatically use however many LEDs you define.

    By adjusting the constants, you can make it look like most of the different seasons of the shows. (Excluding the New "Knight Rider" 2009). 2009 can be done too, but it'll take a little modification.


    The main difference is in the way the Duytcycle variables are declared.
    By grouping them in an Array, they can be used with FOR loops to control all the LEDs, instead of having to access each one individually like the RGB's.

    ;----[ MIBAM Setup ]--------------------------------------------------------
    BAM_COUNT CON 8                     ; How many BAM Pins are used?
    INCLUDE &quot;MIBAM.pbp&quot;                 ; Mirror Image BAM module
      LED1    VAR BAM_DUTY[0]           ; group them in an 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] 
    BAM_LIST  macro                     ; Define PIN's to use for BAM
         BAM_PIN (PORTD,0, LED1)        ;   and the associated Duty variables
         BAM_PIN (PORTD,1, LED2)
         BAM_PIN (PORTD,2, LED3)
         BAM_PIN (PORTD,3, LED4)
         BAM_PIN (PORTD,4, LED5)
         BAM_PIN (PORTD,5, LED6)
         BAM_PIN (PORTD,6, LED7)
         BAM_PIN (PORTD,7, LED8)
      BAM_INIT  BAM_LIST                ; Initialize the Pins
    Then with all the dutycycles in the array, you can do something like this.

    Speed       CON 6         ; Smaller=Faster
    TracerSpeed CON 15        ; Smaller=Faster Left/Right
    Brightness  CON 200       ; Tracers DutyCycle
    DrainSpeed  CON 30        ; Smaller=Shorter Trail
    Idx         VAR BYTE
    LoopCount   VAR BYTE
    NextLED     VAR BYTE
    TraceDIR    VAR BIT
      TraceDIR  = 0
      LoopCount = 0
      NextLED   = 0
        if LoopCount = TracerSpeed then             ; __[ Cylon/Kitt Scanner ]__
          LoopCount = 0
          if TraceDIR then                          ; if scanning left
            NextLED = NextLED - 1
            if NextLED = 0 then TraceDIR = 0
          else                                      ; else scanning right
            NextLED = NextLED + 1
            if NextLED = BAM_COUNT-1 then TraceDIR = 1
        FOR Idx = 0 to BAM_COUNT - 1                ; Drain all dutycycles
           IF BAM_DUTY(Idx) > 0 then
        NEXT Idx
        pause Speed
        LoopCount = LoopCount + 1
    GOTO Main
    Attached is the full code and HEX file for the 887 on the Demo Board.
    Attached Files Attached Files
    Last edited by Darrel Taylor; - 5th June 2014 at 15:36. Reason: Trying to fix HTML

Similar Threads

  1. Bits, Bytes Words and Arrays
    By Melanie in forum FAQ - Frequently Asked Questions
    Replies: 24
    Last Post: - 14th June 2016, 07:55
  2. Bit Angle Modulation (BAM) in a PIC
    By Bronx68 in forum mel PIC BASIC Pro
    Replies: 150
    Last Post: - 24th February 2015, 13:41
  3. Bit Angle Modulation
    By BH_epuk in forum mel PIC BASIC Pro
    Replies: 1
    Last Post: - 18th November 2008, 07:01
  4. PICBasic newbie problem
    By ELCouz in forum mel PIC BASIC Pro
    Replies: 32
    Last Post: - 12th February 2008, 00:55
  5. USART interrupt not interrupting right
    By Morpheus in forum mel PIC BASIC Pro
    Replies: 12
    Last Post: - 6th March 2005, 01:07

Members who have read this thread : 7

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

Tags for this Thread

Posting Permissions

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