PDA

View Full Version : Bit Angle Modulation (BAM) in a PIC



Bronx68
- 28th October 2007, 23:57
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?

Darrel Taylor
- 30th October 2007, 07:19
<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>http://www.pbpgroup.com/files/PWMvsBAM.GIF</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>http://www.pbpgroup.com/files/PWMvsBAM_BAM.GIF</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. :eek:

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 (http://www.picbasic.co.uk/forum/attachment.php?attachmentid=3123)<!-- 3123 -->

Darrel Taylor
- 16th January 2009, 02:29
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" /> <!-- 3127 -->
<br>
And with anything equal or above 128, it looks like this ...
<img src="http://www.picbasic.co.uk/forum/attachment.php?attachmentid=3125" /> <!-- 3125 -->

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" /> <!-- 3126 -->

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>

RadikalQ3
- 16th January 2009, 08:37
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 :?

Darrel Taylor
- 16th January 2009, 10:27
Hmmmm, such a Radikal idea.
Very interesting ... http://www.picbasic.co.uk/forum/images/icons/icon14.gif

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 ... :D

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

anonymouse
- 16th January 2009, 17:22
Hmmmm, such a Radikal idea.
Very interesting ... http://www.picbasic.co.uk/forum/images/icons/icon14.gif

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 ... :D

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.

anonymouse
- 17th January 2009, 12:04
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.
Thats as clear as mud, => 128 begin reverse read byte and vice versa

Darrel Taylor
- 17th January 2009, 23:33
RadikalQ3,

Thanks for the Mirror Image idea!
It has completely removed the blinking problem. http://www.picbasic.co.uk/forum/images/icons/icon14.gif

Unfortunately the higher frequency and extra code to reverse things has created some new ones, but I think I can work through them.

For your first post here, it was an awesome one. :)

Thanks again,

Also, thanks anonymouse,
But with multiple channels at different dutycycles all using the same timer, changing the interrupt sequence at 127 isn't possible.
I hadn't mentioned the multi-channel part yet ... oops.

RadikalQ3
- 18th January 2009, 07:46
RadikalQ3,
Thanks for the Mirror Image idea!
It has completely removed the blinking problem. http://www.picbasic.co.uk/forum/images/icons/icon14.gif

Oh, it's nothing... just was an idea.
I have spent the last days reading all I found in internet about PWM, BAM, Frecuency Modulation, etc.
I have a project to do and I am gathering all the information about this topic.
Simply... I found your topic (and this forum) and I thought that was a nice challenge solve your blinking problem O:)
I am waiting the recepcion of some hardware and in a few days I can do test with this for my own.

Later, I realized that this is a forum on basic! (and I just use assembler) :o

Darrel Taylor
- 19th January 2009, 00:45
Videos of oscilloscopes never seem to work very well.
But it's interesting to watch the way the mirror image works.

Let's call it BAM-BAM.

<object width="425" height="344"><param name="movie" value="http://www.youtube.com/v/4eZho2fN3r8&hl=en&fs=1"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/4eZho2fN3r8&hl=en&fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"></embed></object>

It's going through a ramp from 0-255 and back down.

Ioannis
- 19th January 2009, 07:52
Hi Darrel. It looks very good! Congratulations on that!

Very good job.

Ioannis

JEC
- 19th January 2009, 15:01
I'd run in to the exact same issues between 127 and 128. Never had time to investigate it further.

My implementation just used a state machine in the interrupt routine - 1 state for each bit.

Each state sets TMR1 to a different level, then sets / clears the appropriate pins.

I assume that you're implementing the 2xF 'mirror' method in a similar way? Very clever.

Darrel Taylor
- 19th January 2009, 22:40
Hi Ioannis :)

Hi John,
&nbsp; Just yesterday I was thinking about how this might be good for your Christmas Lights.
&nbsp; Apparently, the thought had not escaped you.


I assume that you're implementing the 2xF 'mirror' method in a similar way?
Well, the best method, is still to be determined. I'm trying every way I can think of ...

Currently, I'm rotating the DutyCycle out to the Pin, and when rotating it left, I shift the timer value Right to give 1/2 the period for the next bit, when rotating right, the timerval gets shifted left for 2x the period.

I'm also trying to incorporate the "Cylon Scanner (http://www.picbasic.co.uk/forum/showthread.php?p=47992#post47992)" that Bruce and I were playing with last year.
With the mirror image, the bit's are scanned back and forth much like a Cylon (or Kitt the car).

Never thought that optimization exercise would actually be useful some day. :D
<br>

JEC
- 19th January 2009, 23:06
&nbsp; Just yesterday I was thinking about how this might be good for your Christmas Lights.
&nbsp; Apparently, the thought had not escaped you.



Pity the 10F doesn't have a TMR1... :)

RadikalQ3
- 20th January 2009, 05:30
Let's call it BAM-BAM.


Better... BAM-MAB :)

Darrel Taylor
- 21st January 2009, 07:02
Better... BAM-MAB :)
I had thought of that ... but it was too hard to say (unless you're drunk).
Besides, I thought maybe Pebbles would show up to see what BamBam was doing. :D

Progress is cranking.
Should have an update soon.
<br>

mister_e
- 21st January 2009, 23:53
Should be BAMAB... unless your program stick too much on a side of the PWM cycle ;o)

bcd
- 24th January 2009, 10:31
I played with BAM some time ago, but always found this step in the middle of the range to be its big issue. Thank you for a workable solution !!!

Its interesting that Artistic License (the inventor, or populariser of BAM) make no mention of this issue.

Bill.

Darrel Taylor
- 24th January 2009, 21:28
Its interesting that Artistic License (the inventor, or populariser of BAM) make no mention of this issue.
I think Artistic License had given up on it, since all mention of BAM has been removed from their website. And when I was searching the web for answers, all I found was lots of threads with people complaining of blinking problems. :eek:

BAM-BAM to the rescue!
<img src="http://www.picbasic.co.uk/forum/attachment.php?attachmentid=3147&stc=1&d=1232834688" /> <!-- 3147 -->

I now have working code.
Anyone want to beta test it before I make it public?

It can run up to 48 LEDs simultaniously. (48mhz OSC)
Or 1 LED per mhz. 4mhz=4 LEDs, 20mhz=20 LEDs.
It has a self-contained Interrupt system. Instant Interrupts not required.
<br>

JEC
- 24th January 2009, 22:33
Would love a copy. Just emailed you. What's the processor utilization per MHz per LED?

Darrel Taylor
- 25th January 2009, 00:04
What's the processor utilization per MHz per LED?
Utilization is less than 6% of total.

The limiting factor is the Least Significant Bit in the dutycycle. It's so short that it doesn't give much time to do anything. The mirror image helped some, because I was able to combine the LSB of both halves of the mirror for a longer period, but it's still only 68 instructions (worst case).

It has to get into the interrupt handler, save context, reload the Timer, service all the LEDs dutycycles, keep track of the bit sequencing, restore context and exit the interrupt within those 68 instructions.

Each PIN uses 6 instructions, and the rest of the handler uses about 40.
So @ 4 mhz you can only get 4 LED's (40 + 24 = 64).
Refresh rate @ 4mhz = 80 hz with 4 LEDs.

With higher OSC freqs, refresh rates can be as high as 650hz, depends on how many LEDs there are.
The rate can be set lower with a DEFINE if needed.

Warnings from the assembler will indicate if your setup is out of range.
<br>

JEC
- 25th January 2009, 00:27
Utilization is less than 3% of total.

The limiting factor is the Least Significant Bit in the dutycycle. It's so short that it doesn't give much time to do anything. The mirror image helped some, because I was able to combine the LSB of both halves of the mirror, for a longer period, but it's still only 68 instructions (worst case).

It has to get into the interrupt handler, save context, reload the Timer, service all the LEDs dutycycles, keep track of the bit sequencing, restore context and exit the interrupt within those 68 instructions.

Each PIN uses 6 instructions, and the rest of the handler uses about 40.
So @ 4 mhz you can only get 4 LED's (40 + 24 = 64).
Refresh rate @ 4mhz = 80 hz with 4 LEDs.

With higher OSC freqs, refresh rates can be as high as 650hz, depends on how many LEDs there are.
The rate can be set lower with a DEFINE if needed.

Warnings from the assembler will indicate if your setup is out of range.
<br>


How flickery is 80 Hz x 4 @ 4 MHz?

Darrel Taylor
- 25th January 2009, 00:55
How flickery is 80 Hz x 4 @ 4 MHz?
Even though it's 80hz, the ducycycle is put out to the pin twice, so it's visually better than 80hz PWM would be.

I don't notice any flicker.
<br>

PicLearner
- 26th January 2009, 07:37
Bam sounds great. Does anybody have a sample code? Thank you in advance.

gmglickman
- 29th January 2009, 20:25
I played with a very simple form of BAM a while back, with at least 24 LEDs on a 20MHz 16F877A. This is the main loop:


BAM: 'each pass is one cycle, equiv to one PWM period
delay_index=%00000001
for i=0 to 7 'time slots, 0 shortest, 7 longest
PORTA.1=LED1>>i
PORTA.2=LED2>>i
PORTA.3=LED3>>i
.
.
.
PORTA.n=LEDn>>1
for j=1 to delay_index 'empty delay loop for each time slot, total 255
next j
delay_index=delay_index<<1
next i
GOTO BAM


where LED1, LED2 are intensity values that are updated when needed by interrupt. Refresh is totally dependent on clock speed and number of LEDs driven, but 100Hz is achievable.

I came across a scheme to reorder bits to avoid phase shift glitches but didn't get that far myself. See http://www.tenmilesquare.com/library

I'd love to see Darrel's code...

Gary

Darrel Taylor
- 30th January 2009, 03:21
<img src="http://www.picbasic.co.uk/forum/attachment.php?attachmentid=3157&stc=1&d=1233285538" />

Had that come up first, I woud have tried it. Looks interesting.

But the mirror image seems to work great, so no reason to change horses just yet.

There's 3 of our regular members looking at it now.
I like knowing they can set CONFIGs and disable A/D on their own.

Barring any problems, I'll post it soon.
<br>

Darrel Taylor
- 11th February 2009, 14:49
After realizing that Pebbles is probably 60-70 years old by now ...
I'm not so interested in BAMBAM anymore. :eek:

The name has been changed to MIBAM. (Mirror Imaged Bit Angle Modulation)

And the code for PicBasic Pro is now available here ...
http://www.picbasic.co.uk/forum/showthread.php?t=10564

Cheers,

Ioannis
- 11th February 2009, 18:07
Hi Darrel.

I am testing your code on a 887 chip at 20MHz.

I am stuck on this error:

Error[115] c:\pbp\mibam-~1.asm 223 : Duplicate label ("BAM_PIN" or redefining symbol that cannot be redefined)
Error[115] c:\pbp\mibam-~1.asm 224 : Duplicate label ("BAM_PIN" or redefining symbol that cannot be redefined)
Error[115] c:\pbp\mibam-~1.asm 225 : Duplicate label ("BAM_PIN" or redefining symbol that cannot be redefined)
Error[115] c:\pbp\mibam-~1.asm 226 : Duplicate label ("BAM_PIN" or redefining symbol that cannot be redefined).

In fact, the code is a copy of the example. Nothing more or less. Of course the part about wsave is included too. Attached is the final test code.

Regards,
Ioannis

Darrel Taylor
- 11th February 2009, 18:11
Duplicate label ("BAM_PIN" or redefining symbol that cannot be redefined)
In MicroCode Sudio, View | Compile and Program Options | Compiler Tab ...

Check the "Case sensitive" box.
<br>

Ioannis
- 11th February 2009, 19:03
Yep, thats it.

One word describes this software.

A M A Z I N G !

Congratulations Darrel!

Only leds were more linear devices...

Thanks a lot.

Ioannis

P.S. About the case sensitivity, is this going to have any side effects on other programs that I develop? Why did that happen right now?

Darrel Taylor
- 11th February 2009, 20:35
One word describes this software.
<script language="JavaScript" src="http://www.pbpgroup.com/js/ColorText.js"></script>
<div id="DTtext"><b>A M A Z I N G !</b></div>
<script>ColorText("DTtext",['red','green','blue','magenta','cyan','black']);</script>
Thanks Ioannis, and I ... uh ... may have embellished your quote a little. (Shameless :rolleyes:)


P.S. About the case sensitivity, is this going to have any side effects on other programs that I develop?

I guess that depends on how much ASM code you've been writing.

The default for MPASM is "Case Sensitive".
The default for MicroCode Studio is "Case Sensitive".
So somewhere along the way, you've changed the setting in MCS, and it may or may not have solved your problem at the time. Sometimes you just try things ... grasping for answers.


Why did that happen right now?
Because I chose to use tricky things that require case sensitivity. :o

The sensitivity option has no effect on PBP statements, since PBP isn't case sensitive to begin with.
And there are some ASM problems that can come up when un-checking the "Case sensitive" box, so I'd recommend leaving it checked at all times.

Ioannis
- 11th February 2009, 22:24
OK. Thanks for the explanation. I will keep the option checked for case sensitivity. I really cannot recall un-checking it...

About the Light intensity control, at least for small 5mm Leds, at low levels there is a problem because of the nature of the diodes. Of course it has nothing to do with the code you have developed.

I suppose that there should be a non-linear function to increse the current at low levels, maybe an exponential or geometric function. Some experimentation will be necessary.

Anyway, having 20 devices to control with a kind of PWM is fantastic.

Once again, you are #1!

Ioannis

Bruce
- 12th February 2009, 22:14
Very smooth fading effect. Nice job DT.

Darrel Taylor
- 13th February 2009, 00:10
Thank you Bruce!

And thanks for the Cylon Scanner.

I mentioned it earlier, and I did end up using the Cylon program we were playing with a while back.

To get the Mirror Image, it scans back and forth just like we had it. Then it uses that to mask the current bit in the dutycycles. It really knocked the code size down.

I used your Cylon version, of course. :D
<br>

gmglickman
- 13th February 2009, 13:30
Ioannis:

You might want to remap the LED's brightness curve to compensate for the non-linearity in perceived brightness.

This are the values I use


data @$0, $00,$00,$01,$01,$01,$01,$02,$02,$02,$03,$03,$03,$0 4,$04,$04,$04,$05,$05,$05,$06,$06,$06,$07,$07,$07, $08,$08,$08,$09,$09,$0A,$0A
data $0A,$0B,$0B,$0B,$0C,$0C,$0C,$0D,$0D,$0E,$0E,$0E,$0 F,$0F,$10,$10,$10,$11,$11,$12,$12,$13,$13,$13,$14, $14,$15,$15,$16,$16,$16,$17
data $17,$18,$18,$19,$19,$1A,$1A,$1B,$1B,$1C,$1C,$1D,$1 D,$1E,$1E,$1F,$1F,$20,$20,$21,$21,$22,$23,$23,$24, $24,$25,$25,$26,$27,$27,$28
data $28,$29,$2A,$2A,$2B,$2B,$2C,$2D,$2D,$2E,$2F,$2F,$3 0,$31,$31,$32,$33,$33,$34,$35,$35,$36,$37,$37,$38, $39,$3A,$3A,$3B,$3C,$3D,$3D
data $3E,$3F,$40,$40,$41,$42,$43,$44,$44,$45,$46,$47,$4 8,$49,$49,$4A,$4B,$4C,$4D,$4E,$4F,$50,$51,$51,$52, $53,$54,$55,$56,$57,$58,$59
data $5A,$5B,$5C,$5D,$5E,$5F,$60,$61,$62,$63,$64,$65,$6 7,$68,$69,$6A,$6B,$6C,$6D,$6E,$6F,$71,$72,$73,$74, $75,$77,$78,$79,$7A,$7B,$7D
data $7E,$7F,$81,$82,$83,$84,$86,$87,$89,$8A,$8B,$8D,$8 E,$8F,$91,$92,$94,$95,$97,$98,$9A,$9B,$9D,$9E,$A0, $A1,$A3,$A4,$A6,$A7,$A9,$AB
data $AC,$AE,$B0,$B1,$B3,$B5,$B6,$B8,$BA,$BB,$BD,$BF,$C 1,$C3,$C4,$C6,$C8,$CA,$CC,$CE,$D0,$D1,$D3,$D5,$D7, $D9,$DB,$DD,$DF,$E1,$E3,$E6


Then just

READ LED, LED

Ioannis
- 16th February 2009, 07:27
Hi gmglickman,

Hmm, nice, thanks for the post. I was thinking more complicated on this!

Ioannis

Caius1
- 26th February 2009, 14:50
Hi,

I came across this topic when browsing for BAM.

Regarding the blink can you verify that the blink still occurs when:
1 The last value of the period = 2^nBits - 2 instead of 2^nBits-1
2 New value is only updated at the start of a pwm period.

It would seem strange to me if it does.
I think that a blink can only occur form value=0 to value=x

Thanks

Darrel Taylor
- 26th February 2009, 19:10
Regarding the blink can you verify that the blink still occurs when:
1 The last value of the period = 2^nBits - 2 instead of 2^nBits-1
2 New value is only updated at the start of a pwm period.

I assume you mean reversing the order of bits 6 and 7.

Yes, the blink still occurs. It just happens at different numbers.
No matter which way you order the bit's, if they are only scanned in one direction, there will always be a blink at some point.

I also found that at other points in the dutycycle, the original BAM has several more less obvious blinks as the phase shift does the exact same thing in the lower bits. You just can't see them as well because they are shorter periods. But if you stare right at the LED straight on, you can definitely see them.

However, the symmetrical nature of the Mirror Imaged waveform, completely eliminates ALL of the blinking. It's really amazing how well it fixed the problems.

You can see how it works from the animation in this thread ...

MIBAM - (Mirror Imaged Bit Angle Modulation)
http://www.picbasic.co.uk/forum/showthread.php?t=10564

vtt-info
- 27th March 2009, 18:41
Hi Darrel.

I am testing your Cylon Scanner
code on a 887 chip at 8MHz.

I am stuck on this error:

Error[118] c:\pbp\mibam-~1.asm 97:Overwriting previous address contents (2007)

In fact, the code is a copy of the example. Nothing more or less. Of course the part about wsave is included too. Attached is the final test code.

Regards,
Konrad
3284

Darrel Taylor
- 27th March 2009, 20:49
Try this thread ... post#5

Presetting Configuration Fuses (PIC Defines) into your Program
http://www.picbasic.co.uk/forum/showthread.php?t=543

Or, just delete the __config line, which will then use the PBP default configs.
<br>

lanyong
- 28th March 2009, 03:11
u will let it to 2.45kHz. the led will be not blink. i have test it.

last week, i send some thread. they r disappear, my god!

mbam will not solve the blink problem absolutely. from 127 to 128 change so much the same.

the best way is let more interrupt. and let the bit7 or bit6 or bit5 or bit4's time average in the period.

Darrel Taylor
- 28th March 2009, 03:40
last week, i send some thread. they r disappear, my god!
My fault. Your posts looked like SPAM.
Copied half the thread in a quote and added 1 sentance with a link. (4 times)

My bad. :o
<br>

lanyong
- 28th March 2009, 14:10
My fault. Your posts looked like SPAM.
Copied half the thread in a quote and added 1 sentance with a link. (4 times)

My bad. :o
<br>


it is seemd that my english is so poor.

the bam's question is that when the period is so long, from one to 2^n change so much.such as from 1 to 2, 3->4, 7->8, 15->16, 31->32,63->64, 127->128.

so u will watch the led blink.

Darrel Taylor
- 28th March 2009, 19:11
The blinking problem has been fixed.

There is NO blinking at all with MIBAM (http://www.picbasic.co.uk/forum/showthread.php?t=10564).
<br>

Bronx68
- 28th March 2009, 22:27
Darrel,
I started this link when I was working on an RGB backlight. I have been away from this task for quite some time but plan to get back into next month.
You mentioned that you are willing to let someone test out your code. I am using a 16F819. Will it run on this chip? Are you still looking for someone to do some testing?

Darrel Taylor
- 28th March 2009, 22:35
I started this link when I was working on an RGB backlight. I have been away from this task for quite some time but plan to get back into next month.
Welcome back!
We've been busy while you were away :D

I am using a 16F819. Will it run on this chip?
Absolutely! (and most others too)


Are you still looking for someone to do some testing?
Definitely ... Test away.

I've had good reports from others so far.
Always looking for any problems though.

Thanks!

lanyong
- 29th March 2009, 02:39
The blinking problem has been fixed.

There is NO blinking at all with MIBAM (http://www.picbasic.co.uk/forum/showthread.php?t=10564).
<br>


when i do the same bam as u. blink as u,haha.

i find ur post, it is very interesting.


in fact u let the bam is high, such as 2.4kHz, u will not watch the blink ,same.

Darrel Taylor
- 29th March 2009, 02:45
when i do the same bam as u. blink as u,haha.
Really? That's odd.

Which PIC are you using?
What OSC frequency, and how many LED's?

Are you assembling with MPASM or PM?

Did the program give you any warnings or errors?
<br>

lanyong
- 29th March 2009, 04:05
Really? That's odd.

Which PIC are you using?
What OSC frequency, and how many LED's?

Are you assembling with MPASM or PM?

Did the program give you any warnings or errors?
<br>

ten days ago. i try the bam, find from 127 to 128, the led blink.100Hz, 8bit.

i know it is change so much. so i find ur post:) and i send some post to urs.

last week, i let it to 2.4kHz, bam. the led will not blink.

i don't test ur mibam, i think it is good.

i use pic18, and 48 dmx512 channel. 2.4kHz bam 8 bit.

pmfa061
- 29th May 2009, 08:44
I'm not sure this is the right place to ask, but I was wondering if BAM is a patented technique (e.g. by Artistic License or any other company) and hence commercial use of BAM requires fees to be paid, or if it just like PWM a technique that can be freely implemented in any device.
10x in advance for any info

Darrel Taylor
- 29th May 2009, 11:15
Artistic License claims to have "Invented" BAM. But nowhere have I found a claim that they have received or even applied for a patent.
Although I have found a dozen or so patents that would probably keep A.L. from getting one if they tried.

Not that it would matter very much, because this is not BAM.
BAM is flawed, and MIBAM represents a "Significant Improvement".
<br>

tenaja
- 29th May 2009, 14:28
BAM has been in public domain for over one year. That alone means it is not patentable.

JEC
- 29th May 2009, 20:18
Artistic License claims to have "Invented" BAM. But nowhere have I found a claim that they have received or even applied for a patent.
Although I have found a dozen or so patents that would probably keep A.L. from getting one if they tried.

Not that it would matter very much, because this is not BAM.
BAM is flawed, and MIBAM represents a "Significant Improvement".
<br>

....... BAM was published by AL *specifically* to place the idea & implementation in the public domain and keep companies from patenting it.

Partly because there's been some ugliness in the professional lighting / theatre world by companies patenting (and then aggressively litigating) LED dimming and control techniques. These techniques have been obvious to those skilled in the trade since at least the 1970s, but the patents were granted nonetheless.

Darrel Taylor
- 29th May 2009, 22:49
....... BAM was published by AL *specifically* to place the idea & implementation in the public domain and keep companies from patenting it.

Excellent move by Artistic License.

Hopefully, by finding the Mirror Image improvement to BAM and releasing it to the public domain ...
RadikalQ3 and I have made it impossible for some squatter to patent a MIBAM equivalent too. ;)

MIBAM - (Mirror Imaged Bit Angle Modulation)
http://www.picbasic.co.uk/forum/showthread.php?t=10564
<br>

Mike, K8LH
- 26th July 2009, 13:59
Hi Darrel,

May I pass along my late congrats' on some brilliant work and share a couple ideas?

Instead of using six instructions (6 cycles) per LED during each update interval you might consider updating one port at a time using an exclusive-or instruction (2 cycles) and data from an eight byte "toggle" array that's refreshed during that long 64T end-of-period interval. This reduces overhead from 288 cycles for 48 LEDs to just 12 cycles during each update interval. Using "toggle" data and an exclusive-or instruction lets us update MIBAM output bits without changing non-MIBAM bits on each port.

Since the three '1T' intervals seem to be a major bottleneck we might consider combining the center |2T|1T|1T|1T|2T| intervals into a single '7T' interval and use small in-line isochronous delays to effect precise timing between updates. This would practically eliminate "overhead" effects on the center three '1T' intervals.

Here's a pseudo C code driver example (sorry, I don't have PBP). I'm sure you realize that the "switch" function should be replaced with assembly language to reduce overhead and eliminate jitter and that the LEDs and "data benders" should probably be setup as macros as you did in your driver.

An assembly language version I wrote supports 48 LEDs at decent refresh rates at almost any clock (4-MHz, 177 Hz, 1T = 22-usecs).

Food for thought. Kind regards, Mike, K8LH


unsigned char interval = 0; // ISR state machine var'

unsigned char red = 44;
unsigned char grn = 55;
unsigned char blu = 66;

volatile unsigned short ccpr1 @ 0xFBE;

/* *
* original intervals -> |64|32|16|8|4|2|1|1|1|2|4|8|16|32|64| *
* modified intervals -> |64|32|16|8|4|----7----|4|8|16|32|64| *
* */
void interrupt() // CCP1 "special event" interrupts
{ unsigned char Adat[8]; // porta "toggle" array
unsigned char Bdat[8]; // portb "toggle" array
pir1.CCP1IF = 0; // clear CCP1 interrupt flag
switch(interval++) //
{ case 0: // 64T
porta ^= Adat[7]; //
portb ^= Bdat[7]; //
ccpr1 = (64*tStep); // ccpr1 = half 2^7 (64T)
break; //
case 1: // 32T
porta ^= Adat[6]; //
portb ^= Bdat[6]; //
ccpr1 >>= 1; // ccpr1 = half 2^6 (32T)
break; //
case 2: // 16T
porta ^= Adat[5]; //
portb ^= Bdat[5]; //
ccpr1 >>= 1; // ccpr1 = half 2^5 (16T)
break; //
case 3: // 8T
porta ^= Adat[4]; //
portb ^= Bdat[4]; //
ccpr1 >>= 1; // ccpr1 = half 2^4 (8T)
break; //
case 4: // 4T
porta ^= Adat[3]; //
portb ^= Bdat[3]; //
ccpr1 >>= 1; // ccpr1 = half 2^3 (4T)
break; //
case 5: // 7T (2T+1T+1T+1T+2T)
porta ^= Adat[2]; //
portb ^= Bdat[2]; //
ccpr1 = (7*tStep); // ccpr1 = 7*tStep (7T)
delayCy(2*tStep-8); // 2T minus 8 cycles
porta ^= Adat[1]; //
portb ^= Bdat[1]; //
delayCy(1*tStep-4); // 1T minus 4 cycles
porta ^= Adat[0]; //
portb ^= Bdat[0]; //
delayCy(1*tStep-4); // 1T minus 4 cycles
porta ^= Adat[0]; //
portb ^= Bdat[0]; //
delayCy(1*tStep-4); // 1T minus 4 cycles
porta ^= Adat[1]; //
portb ^= Bdat[1]; //
break; //
case 6: // 4T
porta ^= Adat[2]; //
portb ^= Bdat[2]; //
ccpr1 = (4*tStep); // ccpr1 = half 2^3 (4T)
break; //
case 7: // 8T
porta ^= Adat[3]; //
portb ^= Bdat[3]; //
ccpr1 <<= 1; // ccpr1 = half 2^4 (8T)
break; //
case 8: // 16T
porta ^= Adat[4]; //
portb ^= Bdat[4]; //
ccpr1 <<= 1; // ccpr1 = half 2^5 (16T)
break; //
case 9: // 32T
porta ^= Adat[5]; //
portb ^= Bdat[5]; //
ccpr1 <<= 1; // ccpr1 = half 2^6 (32T)
break; //
case 10: // 64T (end-of-period)
porta ^= Adat[6]; //
portb ^= Bdat[6]; //
ccpr1 <<= 1; // ccpr1 = half 2^7 (64T)
interval = 0; // prep for new period
Adat[0] = 0; Adat[1] = 0; // clear Adat[] array
Adat[2] = 0; Adat[3] = 0; //
Adat[4] = 0; Adat[5] = 0; //
Adat[6] = 0; Adat[7] = 0; //
Bdat[0] = 0; Bdat[1] = 0; // clear Bdat[] array
Bdat[2] = 0; Bdat[3] = 0; //
Bdat[4] = 0; Bdat[5] = 0; //
Bdat[6] = 0; Bdat[7] = 0; //
/* *
* use one "data bender" for each LED (16 cycles each) *
* */
if(red.0) Bdat[0] |= 1; // 2^0 data RB0 pin
if(red.1) Bdat[1] |= 1; // 2^1 data RB0 pin
if(red.2) Bdat[2] |= 1; // 2^2 data RB0 pin
if(red.3) Bdat[3] |= 1; // 2^3 data RB0 pin
if(red.4) Bdat[4] |= 1; // 2^4 data RB0 pin
if(red.5) Bdat[5] |= 1; // 2^5 data RB0 pin
if(red.6) Bdat[6] |= 1; // 2^6 data RB0 pin
if(red.7) Bdat[7] |= 1; // 2^7 data RB0 pin

if(grn.0) Bdat[0] |= 2; // 2^0 data RB1 pin
if(grn.1) Bdat[1] |= 2; // 2^1 data RB1 pin
if(grn.2) Bdat[2] |= 2; // 2^2 data RB1 pin
if(grn.3) Bdat[3] |= 2; // 2^3 data RB1 pin
if(grn.4) Bdat[4] |= 2; // 2^4 data RB1 pin
if(grn.5) Bdat[5] |= 2; // 2^5 data RB1 pin
if(grn.6) Bdat[6] |= 2; // 2^6 data RB1 pin
if(grn.7) Bdat[7] |= 2; // 2^7 data RB1 pin

if(blu.0) Bdat[0] |= 4; // 2^0 data RB2 pin
if(blu.1) Bdat[1] |= 4; // 2^1 data RB2 pin
if(blu.2) Bdat[2] |= 4; // 2^2 data RB2 pin
if(blu.3) Bdat[3] |= 4; // 2^3 data RB2 pin
if(blu.4) Bdat[4] |= 4; // 2^4 data RB2 pin
if(blu.5) Bdat[5] |= 4; // 2^5 data RB2 pin
if(blu.6) Bdat[6] |= 4; // 2^6 data RB2 pin
if(blu.7) Bdat[7] |= 4; // 2^7 data RB2 pin
/* *
* convert Bdat[] and Adat[] array "output" data to "toggle" data *
* *
* red 0x2C 00101100 (on RB0) *
* grn 0x37 00110111 (on RB1) *
* blu 0x42 01000010 (on RB2) *
* *
* Bdat 'output data' Bdat 'toggle data' Bdat 'toggle data' *
* [0] 0x02 00000010 [0] 0x04 00000100 [0] 0x04 00000100 *
* [1] 0x06 00000110 [1] 0x05 00000101 [1] 0x05 00000101 *
* [2] 0x03 00000011 [2] 0x02 00000010 [2] 0x02 00000010 *
* [3] 0x01 00000001 [3] 0x03 00000011 [3] 0x03 00000011 *
* [4] 0x02 00000010 [4] 0x01 00000001 [4] 0x01 00000001 *
* [5] 0x03 00000011 [5] 0x07 00000111 [5] 0x07 00000111 *
* [6] 0x04 00000100 [6] 0x04 00000100 [6] 0x04 00000100 *
* [7] 0x00 00000000 [7] 0x00 00000000 [7] 0x01 00000001 *
* portb 0x00 00000000 portb 0x01 00000001 *
* */
asm {
movf _porta,W // get current PORTA bits
andlw 0 // keep only MIBAM output bits
xorwf _Adat+7,F // create 2^7 toggle bits
xorwf _Adat+7,W // W simulates cumulative PORTA
xorwf _Adat+6,F // create 2^6 toggle bits
xorwf _Adat+6,W //
xorwf _Adat+5,F // create 2^5 toggle bits
xorwf _Adat+5,W //
xorwf _Adat+4,F // create 2^4 toggle bits
xorwf _Adat+4,W //
xorwf _Adat+3,F // create 2^3 toggle bits
xorwf _Adat+3,W //
xorwf _Adat+2,F // create 2^2 toggle bits
xorwf _Adat+2,W //
xorwf _Adat+1,F // create 2^1 toggle bits
xorwf _Adat+1,W //
xorwf _Adat+0,F // create 2^0 toggle bits

movf _portb,W // get current PORTB bits
andlw 7 // keep only MIBAM output bits
xorwf _Bdat+7,F // create 2^7 toggle bits
xorwf _Bdat+7,W // W simulates cumulative PORTB
xorwf _Bdat+6,F // create 2^6 toggle bits
xorwf _Bdat+6,W //
xorwf _Bdat+5,F // create 2^5 toggle bits
xorwf _Bdat+5,W //
xorwf _Bdat+4,F // create 2^4 toggle bits
xorwf _Bdat+4,W //
xorwf _Bdat+3,F // create 2^3 toggle bits
xorwf _Bdat+3,W //
xorwf _Bdat+2,F // create 2^2 toggle bits
xorwf _Bdat+2,W //
xorwf _Bdat+1,F // create 2^1 toggle bits
xorwf _Bdat+1,W //
xorwf _Bdat+0,F // create 2^0 toggle bits
}
break; //
}
}

Darrel Taylor
- 26th July 2009, 16:41
WooHoo! Somebody's paying attention. :)

Hi Mike,

That's a VERY interesting idea!
Not sure at this point how I can let the user assign the pins at random, in any order, and any number of them, on any chip. But this sounds good enough to see if I can find a way.

For combining the smallest periods ... I already add the lsb from each side of the "mirror" into a single period to double the minimum interrupt time. Not sure where your 3rd one comes from. That would make the lsb worth 1.5.

I had also tried combining the 2 lsb's on both sides, but that reduced the resolution to 7-bit instead of 8, so the results weren't very good.

I'll see what I can do with the "Full PORT Press". :D

Thanks for the great idea.

Add: Hmmm, that would help minimze R-M-W issues too. http://www.picbasic.co.uk/forum/images/icons/icon14.gif
<br>

Mike, K8LH
- 26th July 2009, 17:55
For combining the smallest periods ... I already add the lsb from each side of the "mirror" into a single period to double the minimum interrupt time. Not sure where your 3rd one comes from. That would make the lsb worth 1.5.

I'm not sure I follow you here. The duty cycle b0 bit output is still 1T long smack in the middle and the b1 bit still generates two 1T outputs on either side of the b0 1T output so we're not losing any resolution. I've just combined those |2T|1T|1T|1T|2T| outputs into a single 7T interval so that our minimum ISR interval is now 4T instead of 1T which gives us more headroom and much higher refresh intervals (even with the overhead of full ISR context save/restore)


Not sure at this point how I can let the user assign the pins at random, in any order, and any number of them, on any chip. But this sounds good enough to see if I can find a way.

I'm not exactly sure how to do it either and then we would still need to dynamically come up with Amask, Bmask, Cmask constants or variables for each port output-to-toggle routine but like you, I'm excited enough to try and find a way.

With the new smaller 4T minimum ISR interval my assembly language test driver can achieve Kilohertz range refresh rates with some of the higher clock frequencies, though I'm not sure if that's really useful (grin).

Kind regards, Mike, K8LH

Darrel Taylor
- 26th July 2009, 19:52
I'm not sure I follow you here. The duty cycle b0 bit output is still 1T long smack in the middle and the b1 bit still generates two 1T outputs on either side of the b0 1T output so we're not losing any resolution. I've just combined those |2T|1T|1T|1T|2T| outputs into a single 7T interval so that our minimum ISR interval is now 4T instead of 1T which gives us more headroom and much higher refresh intervals (even with the overhead of full ISR context save/restore)
By combining those periods, you can't switch the LED for bit0, because it's combined in with bit1. That's what drops it down to 7-bit resolution. If it were a single output, you could combine them, but with multiple LED's, bit0 has to remain separate from bit1.

With MIBAM, it looks like this, with the red line being the "mirror".

Bit- 1 0 0 1
|2T|1T|1T|2T|

The 1T's on either side can be combined into a single period equal to 2T, but they can't be combined with the bit1 (2T's).


I'm excited enough to try and find a way.
I think I know how now, but welcome any more thoughts.
Just a matter of getting it done.

Thanks,

Mike, K8LH
- 28th July 2009, 02:01
Hi Darrel,

I think we may be confusing each other with terminology and perhaps a slight difference in our design. I was using "1T" as the PWM step size. For example, if we were to use a step size of 10-usecs and 256 steps or levels then we'd have a 2560-usec period (256*10-usecs). The b0 output is 10-usecs or 1T long. The b1 output is 20-usecs or 2T long but I split it in half with 10-usecs or 1T on either side of the b0 10-usec (1T) output. That's how I get |2T|1T|1T|1T|2T| == |20us|10us|10us|10us|20us| == |half b2|half b1|full b0|half b1|half b2|. I thought this was how you were doing it but now I suspect I didn't look closely enough at your code and I apologize.

It also seems you think I'm combining the b2, b1, and b0 outputs and reducing resolution but I'm not. I'm simply generating the b2, b1, and b0 outputs during a single interrupt interval.

More later... I'm trying to see if I can upgrade a very old 12F683 Charlieplexed 5-pin 20-LED project from 64 levels per LED to 256 levels per LED using MIBAM. Wish me luck...

Kind regards, Mike

<object width="425" height="344"><param name="movie" value="http://www.youtube.com/v/AgQTBKcg2D4&color1=0xb1b1b1&color2=0xcfcfcf&hl=en&feature=player_embedded&fs=1"></param><param name="allowFullScreen" value="true"></param><param name="allowScriptAccess" value="always"></param><embed src="http://www.youtube.com/v/AgQTBKcg2D4&color1=0xb1b1b1&color2=0xcfcfcf&hl=en&feature=player_embedded&fs=1" type="application/x-shockwave-flash" allowfullscreen="true" allowScriptAccess="always" width="425" height="344"></embed></object>

http://www.wowway.com/~mmclaren/PWM-64 (small).PNG

boroko
- 31st July 2009, 14:06
Is it possible to combine MIBAM and DT_INTS?

I am attempting to use MIBAM in a program where I have been using SPWM_INT. I understand that MIBAM need exclusive use of TMR1 and HI priority INTs. The thought was to see if I could still use DT_INTs to handle low priority ints for a pulse time capture and a HSER routine. I still have to play with it to decide if I can make them function with the probability of MIBAM cutting off the other two, but that is a separate problem.
The issue that I see is that DT_INTS has:
"DEFINE INTHAND INT_ENTRY_H"
"DEFINE INTLHAND INT_ENTRY_L"
and MIBAM has:
"DEFINE INTHAND doBAM"
Can the doBAM section be added to the INT_ENTRY_h section and eliminate the "DEFINE INTHAND doBAM"? If so how?

Until I understand this better, I'm going to continue with the SPWM_INT version of the code and work on finishing the rest of the code that way. I may not need the advantages of MIBAM, but it sure is a cool routine. Even with my limited coding ability, DT's routines have multiplied my capabilities tremendously. Thank you Darrel and all the others that have put in the effort and patience and have been willing to share your wisdom so freely.


Bo

Darrel Taylor
- 31st July 2009, 19:37
Since MIBAM uses a completely ASM interrupt handler, it would be much easier to make it compatible with DT_INTS instead of the other way around.

However, if you're just measuring pulse widths ... the use of Timer3 and a CCP module (Capture mode) might be more applicable. And you won't need Interrupts for that, although they can still be used with LOW Priority. It'll be more accurate with the CCP too.

The HIGH Priority interrupts will affect the "Timing" of LOW Priority ints.
The resolution of a Pulse measurement using LP ints (without CCP) will always suffer.
<br>

sanch0
- 5th August 2009, 23:12
The HIGH Priority interrupts will affect the "Timing" of LOW Priority ints.
The resolution of a Pulse measurement using LP ints (without CCP) will always suffer.
<br>

what means "LP ints"? Are u talking about jitter problem? U should update T0 then (for example) in every interrupt to avoid that. If u going to use CCP with prescalers/postscalers then will get jitter error too.

What refresh rates and bit resolutions have u achieved?

p.s. very nice aproach, congratulations. and sorry 4 poor english.(

Darrel Taylor
- 6th August 2009, 01:48
"LP ints" means Low Priority Interrupts on an 18F.

High Priority Interrupts can interrupt Low Priority Interrupts.
So trying to measure times exactly with Low Priority interrupts will not give very good results unless you are using hardware peripherals, like the CCP module.
<br>

Bill Legge
- 6th August 2009, 02:51
DT

I'm sorry to ask a basic question when this development/discussion is well under way.

I don't see why one PWM output needs 256 interrupts per cycle? I would have thought only one was needed - at the appropriate time in the cycle?

I'm missing something here - probably brains!

Regards Bill Legge

Bill Legge
- 6th August 2009, 03:00
DT

Sorry to ask a basic question when the discussion is well advanced.

I don't see why 256 interrupts are needed for one PWM signal? I would have thought that one interrupt - at the appropriate time - in the cycle would do the trick?

I'm missing something? Brains?

Regards Bill Legge

Darrel Taylor
- 6th August 2009, 08:04
I'm missing something? Brains?There are worse body parts to be missing. :D

You're correct.
For one PWM signal, all you need is 2 interrupts. One to turn it ON, and a second to turn it off.

It's when you have multiple PWM signals that you need to be able to turn any one of the channels OFF, at any one of the 255 time periods. So you need all thoses interrupts for every cycle. Even though nothing happens on 99% of them.

But again, blinky BAM only needs 8, and MIBAM uses 16 (doubled for the mirror image).
<br>

sanch0
- 6th August 2009, 11:51
What _maximum_ refresh rates and bit resolutions have u achieved? I have developed many devices with 18F working at 10 MIPS and giving 13 bit ~610Hz (14 bit is maximum at this speed IMHO). I use ASM.

Darrel Taylor
- 6th August 2009, 18:37
sanch0,

I'm not sure what you're talking about ... but I don't think it's BAM.

At 610hz with 13-bit resolution, the minimum bit period would be 0.2uS

Not even an 18F running at 40Mhz could do anything with 2 instructions.
<br>

Mike, K8LH
- 9th August 2009, 13:42
Actually, you could do it with just 2 instructions per update (using 18F and 40-MHz clock) but it would require a blanking interval of sorts at end-of-period or at some other point in time to update/refresh duty cycle values. In this particular case it would actually be easier to implement with BAM or MIBAM compared to the more traditional PWM methods.

As a side note. I think I have a method for using MIBAM modulation on that little 20-LED charlieplexed array. The refresh rate works out to a whopping 520-Hz per LED which would allow you to fade each individual LED from black to full to black (511 steps) in less than a second. The 520-Hz per LED (or per column) rate is achieved by using a 1.5-usec step or an overall refresh rate of 2600-Hz (with a 1920-usec frame rate). Man I'm good (LOL). Seriously though, this model or method suggests that we could achieve a very respectable refresh rate even with a standard mux'd 8x8 matrix.

Mike

Darrel Taylor
- 9th August 2009, 21:12
Charlieplexed MIBAM :eek: now you're scaring me Mike. :D

Still don't have the full-port version working yet.
<br>

Mike, K8LH
- 9th August 2009, 21:53
Charlieplexed MIBAM :eek: now you're scaring me Mike. :D

Still don't have the full-port version working yet.
<br>

What do you mean "full-port version", Sir?

Darrel Taylor
- 9th August 2009, 21:57
What do you mean "full-port version", Sir?

Your previous contribution starting at post#55.
<br>

Mike, K8LH
- 9th August 2009, 22:51
Sorry, I misunderstood.

I coded the full-port-at-a-time method driver in assembly language as part of a 16F886 project and will test it on a prototype board sometime soon.

I also coded the Charlieplexed 20-LED MIBAM driver in an assembly language project for a 16F886 host.

Both projects simply have variables and the ISR driver setup for simulation so they're far from complete demos'. When I get something up-n'-runnin' I'll post a video and the assembly code, if anyone asks for it.

Regards, Mike, K8LH

Darrel Taylor
- 9th August 2009, 23:01
When I get something up-n'-runnin' I'll post a video and the assembly code, if anyone asks for it.
OK, so let me go ahead and take care of that part ...

Hey Mike,

When you get it all working, could you post the code ... and maybe show a video of it in action?
It'll help me figure out how to do it in PicBasic Pro.

:D

sanch0
- 11th August 2009, 21:17
sanch0,

I'm not sure what you're talking about ... but I don't think it's BAM.

At 610hz with 13-bit resolution, the minimum bit period would be 0.2uS

Not even an 18F running at 40Mhz could do anything with 2 instructions.
<br>

Maximum gained speed of modulation (whatever way u make it) is only limited by speed You can change output. Normally it's 2 instruction. But U can make it in single instruction also, just clearing the output if previous port stage is known. Of course it's only could be done in ASM. Blanking period - the only problem exist here. It will limit maximum duty cycle for some value, depending number of ports needed. I have many devices working at 610hz with 13-bit resolution. Tryed several different ways to get this. Not used MIBAM yet)

lanyong
- 14th August 2009, 15:51
Maximum gained speed of modulation (whatever way u make it) is only limited by speed You can change output. Normally it's 2 instruction. But U can make it in single instruction also, just clearing the output if previous port stage is known. Of course it's only could be done in ASM. Blanking period - the only problem exist here. It will limit maximum duty cycle for some value, depending number of ports needed. I have many devices working at 610hz with 13-bit resolution. Tryed several different ways to get this. Not used MIBAM yet)

how to do it?

pls post the code.

bam is possible, we can change the H or L in two clocks in pic18. so 10M/(2^13)/2=1220.703125/2=610.3515625

lanyong
- 14th August 2009, 16:05
how to do it?

pls post the code.

bam is possible, we can change the H or L in two clocks in pic18. so 10M/(2^13)/2=1220.703125/2=610.3515625

i have 8 group i/o and get the 2450.98Hz 8 bit bam equl to 1 i/o:2450.98*8/(2^13/2^8)=610Hz.

the min time is 0.2us to change the i/o's voltage

sanch0
- 18th August 2009, 01:49
I have working code for 14bit 610hz BAM with 16 output PWM channels (code could be updated to get more channels with external logic if needed), but i didn't tried to resolve flicker problem with BAM yet. I think that simple signal mirroring doesn't help to fully avoid flicker(s), it just makes it significantly lower, but maybe also affects visual perception of signal "decreasing" actual refresh rate. And there are other ways to avoid flicker trouble, too. However, MIBAM is very good approach, thanx to it's simplicity in combination with reasonable effectivity. Thank You, Darrel Taylor & RadikalQ3 for giving good explanations and usefull thoughts. Btw, additional advantage of MIBAM method is that it might slightly reduce level of generated EMI.

Darrel Taylor
- 18th August 2009, 02:24
It's amazing how many people have come here to tell me that the Mirror Image won't fix BAM's blinking problem.

With the mirror image, there is absolutely NO blinking AT ALL. (Not even with a video camera).

Of course everyone admits that they've never even tried it.
But yet they still feel it's ok to tell the world that it won't work.

All I can do is return the favor ...
16 channel, 14-bit BAM, at 610hz, with a PIC, is IMPOSSIBLE.

It was bad enough when you said 13-bit. But now with 14-bits, the minimum period would be 0.1 µS. There's NO WAY you can set 16 outputs to the desired states with only one instruction, then set them all to new states on the very next instruction.

But then ... "I've never tried it".
<br>

Ioannis
- 18th August 2009, 06:51
And Christ did not ask for anything. He was crucified though...

Ioannis

sanch0
- 19th August 2009, 02:05
It's amazing how many people have come here to tell me that the Mirror Image won't fix BAM's blinking problem.

With the mirror image, there is absolutely NO blinking AT ALL. (Not even with a video camera).

Of course everyone admits that they've never even tried it.
But yet they still feel it's ok to tell the world that it won't work.

All I can do is return the favor ...
16 channel, 14-bit BAM, at 610hz, with a PIC, is IMPOSSIBLE.

It was bad enough when you said 13-bit. But now with 14-bits, the minimum period would be 0.1 µS. There's NO WAY you can set 16 outputs to the desired states with only one instruction, then set them all to new states on the very next instruction.

But then ... "I've never tried it".
<br>

Sorry for my poor english, maybe u hadn't understood me as it was supposed. I don't want to flame here... i feel a bit tired myself and i'm way too lazy now to start explanation again. I had thought to upload code here, but now i'm not sure of your reaction. Maybe even then u gonna blame me). Just read my previous posts again. But i don't want to disappoint u and u a free to think that i'm lousy liar))) Actually i started to code in ASM 17 years ago. And i don't have to prove nothing here. Yes, it works. Yes i didn't tried MIBAM yet with _MY_ 14 bit _BAM_ code (which was written about half year ago). I work periodically for local advertising companies and earn some $$$ from things i develop using my older 13 bit code for 18F, which actually isn't BAM nor "clear" PWM. (which, btw could also be upgraded to 14 bit 610Hz, but don't ask me how, as i had already described it). Sorry, do not have enough strength to continue that, i feel myself wasted a bit 8] best regards....

sanch0
- 19th August 2009, 02:08
example... sorry it's static...

Darrel Taylor
- 19th August 2009, 03:15
... Yes i didn't tried MIBAM yet with _MY_ 14 bit _BAM_ code (which was written about half year ago). ...
I'm sorry you're so tired, and I wouldn't want you to waist any more of your time.
I'm sure trying to explain something that's IMPOSSIBLE would really take a lot out of you.

But if it makes it any easier for you ... I don't need to see your whole code, or have a big explanation with pictures and billboards.

But I would like to know how you got past this one single problem.


... with 14-bits (BAM @ 610Hz), the minimum period would be 0.1 µS. There's NO WAY (a PIC) can set 16 outputs to the desired states with only one instruction, then set them all to new states on the very next instruction.

Since you do ASM, it's only 2 lines of code.

I would be apologizing profusely for weeks to come if you could.
<br>

sanch0
- 19th August 2009, 19:25
What exactly do you mean saying "single problem"? u have just described 2 problems) IMHO. of course u can't operate 2 ports at the same time, but u can make somekind of "interleaving" and operate them separately. Here comes out one problem we had spoke about it above - blanking interval. If only 16 channels (actually even more) needed, this could be solved in two ways - design more complex code avoid it (but it's very hard and non-effective combined with time-excessive code for maximum refresh rates and resolutions (more than 8 bits of output per channel); u can just increase LED current accordingly or u can just forget it, as human eyes (actully because of brain's perception algo, which integrates all incoming signals))) do not see much difference between duty cycles of 100% and 90%, or even less.
More serious problem is to make 1Tcy output discretization. But i described this trick before - this could be done using state prediction in code - u can _change_ (set or clear 8 bit of file register and set, reset or toggle single bits) for example using CLRF [filereg] command (or SETF, ANDWF, IORWF, ADDWF and all other byte-oriented commands) in proper place of execution stream. Of course u can't copy value from other location or modify port value in single 1Tcy instruction). It works, i didn't lie.

I didn't sayd that MIBAM doesn't work!!!

i said:
"I think that simple signal mirroring doesn't help to fully avoid flicker(s), it just makes it significantly lower, but maybe also affects visual perception of signal "decreasing" actual refresh rate."
as u can see, i didn't said that i'm sure MIBAM doesn't work (?), it was "suggestion", of course.

[btw, how can u measure flicker power or detect flicker existance when it appear at lower bit transition. This "flicker" effect depends on individul perception's sensetivity and many "watching" conditions. There is such science called psychophysiology, if i'm right).]
I still suppose that MIBAM DO have some minor disadvantages!

First - lower "refresh rate" (it's very important for most of my designs, as i like to get _PERFECT_ fadings, color slides or animations, as i'm very expirienced in this stuff, believe me. Most people accept much lower visual quality and even do not see any differences at all, where i see it) Maybe it could be also avoided forcing some blanking between two MIBAM parts? it should help...

Second - - floating period phase and frequency of signal. it's advantage too, as it decreases EMI amount generating in wider spectrum range without spikes on certain frequencies))). actually it's not realy important for most simple projects. situation changes when u work with huge led amounts, huge currents, long wires, when u must take into account effects of parasitic capasitances, inductivities, switching delays with specific LED drivers etc.

It's important to me to find compromises between time/memory-excessive code, it's complexity, resolution and speed, as i want to use LP INTs to
communicate at higher bitrates. Unfortunately, low-end PIC MCUs do not have larger FIFO buffers. With my present 13/610 PWM code only about 150 kbps speed could be achieved. And code itself uses significantly more RAM than my "flickering" 14/610 BAM, so i search for best suitable desicion for my designs and my aesthetic requirements (visual influence))).

Btw, if u didn't noticed, I thanked You for good work. And now I especially thank RadicalQ3, as his post helped me to select directions of my "engine" development. Somewhen later (got much other things to do, too) i could share some of my achievements with you, if you interested. But i'm not interested in disputes too much)))

lanyong
- 20th August 2009, 07:12
sanch0

i can understand u.

u r right.

u can do 14bit for 16 channel.

as some limlit precondition.

1:ur video don't be too high, such as 60Hz

2:ur 16 channels are not at the same phase position.

u r relly a genius.

lanyong
- 20th August 2009, 07:32
pls give us a code for generateing

the 14bit 610Hz such as 10 1010 1010 1010 a channel.

output_low(pin_a0);
output_toggle(pin_a0);
delay_cycles(2);
output_toggle(pin_a0);
delay_cycles(4);
output_toggle(pin_a0);
delay_cycles(8);
output_toggle(pin_a0);

.....

hahaha.

lanyong
- 20th August 2009, 07:42
pls give us a code for generateing

the 14bit 610Hz such as 10 1010 1010 1010 a channel.

output_low(pin_a0);
output_toggle(pin_a0);
delay_cycles(2);
output_toggle(pin_a0);
delay_cycles(4);
output_toggle(pin_a0);
delay_cycles(8);
output_toggle(pin_a0);

.....

hahaha.

movff two cycles.

so 13bit 610Hz is easy.
14bit 610Hz is hard:)

lanyong
- 20th August 2009, 07:57
sanch0

u r a very valuable programmer.

ur boss is so fortunate.

Darrel Taylor
- 20th August 2009, 20:45
movff two cycles.

so 13bit 610Hz is easy.
14bit 610Hz is hard:)
I agree, movff could set 8-outputs, using 2 cycles.
The other 8-outputs would take another 2 cycles, for a total of 4.

With a PICrunning at 40Mhz, that would take 0.4 µS.
At 14-bit resolution there are 16384 divisions of the period, so 0.4µS * 16384 = 0.0065536 Sec. for the entire BAM cycle.

Which means that the MAXIMUM refresh rate for 16 channels of 14-bit BAM is 152.5 HZ (1 / 0.0065536).
At 13-bit resolution, the MAX refresh is 305.1 Hz (1 / 0.0032768).

So I reiterate ....

16 channels of 14-bit BAM, at 610Hz ... IS IMPOSSIBLE.
<br>

sanch0
- 21st August 2009, 01:39
I agree, movff could set 8-outputs, using 2 cycles.
The other 8-outputs would take another 2 cycles, for a total of 4.

With a PICrunning at 40Mhz, that would take 0.4 µS.
At 14-bit resolution there are 16384 divisions of the period, so 0.4µS * 16384 = 0.0065536 Sec. for the entire BAM cycle.

Which means that the MAXIMUM refresh rate for 16 channels of 14-bit BAM is 152.5 HZ (1 / 0.0065536).
At 13-bit resolution, the MAX refresh is 305.1 Hz (1 / 0.0032768).

So I reiterate ....

16 channels of 14-bit BAM, at 610Hz ... IS IMPOSSIBLE.
<br>

Are u blind? What u just wanna prove iterating yer silly cycles, just try to return from yer subroutine, or generate some interrupt for yer brains. Try to think. I have these devices perfectly working and even more - they work pretty much time ago. I took much time to develop first working 13/610. 14bit isn't finished a bit, but i only need to delete flickers or improve BAM engine code + speed up comm bitrates + add more channels.


What do u see so impossible in my devices? Perhabs u think that if u can't do something, or u do not understand how it works, nobody could make it in whole Universe? U are such amazyng man, dude.... Stop smoking or eating much fastfood stuff) Just look for some "state-of-the-ART" code wroten for demoscene... U'll be surprised by the level of optimization and execution speed of some algos, just compare it with most of MS code - sometimes it very hard to understand way it works.

Ok, i would to share my secret ONLY WITH U!!! Actually 3 little green men from other galaxy just gave me much power to heal people, kill them also or make any Microchip MCU's work several times faster and presented me their magic LED-driver engines working far beyond the limits of physics laws (in your opinion))))

lanyong
- 21st August 2009, 02:08
haha, don't bicker.

16 channels of 14-bit BAM, at 610Hz ... IS POSSIBLE

i know the secret,haha.

in fact u have many time to handle the datas.

u only want to how to find a way to change the H/L in one cycles.

sanch0, u r right! where r u?

I am in Shanghai, China. Nice to meet u.


Darrel Taylor, everything is possible:)

the world is really magical:)

lanyong
- 21st August 2009, 02:21
which book?

i will read them.

Darrel Taylor
- 21st August 2009, 02:30
Whatever ....

My case has been made.
Anyone who knows anything will know the difference.

And apparently we will never see eye to eye.

Onward ... Through the fog ...
<br>

lanyong
- 21st August 2009, 02:35
Whatever ....

My case has been made.
Anyone who knows anything will know the difference.

And apparently we will never see eye to eye.

Onward ... Through the fog ...
<br>

we will learn from sanch0.

he is a program expert.

sanch0
- 21st August 2009, 02:38
haha, don't bicker.

16 channels of 14-bit BAM, at 610Hz ... IS POSSIBLE

i know the secret,haha.

in fact u have many time to handle the datas.

u only want to how to find a way to change the H/L in one cycles.

sanch0, u r right! where r u?

I am in Shanghai, China. Nice to meet u.


Darrel Taylor, everything is possible:)

the world is really magical:)


Hi there! I'm from Tallinn / ESTONIA / EU
Very nice to meet u too.

I'll show u how to increase resolution to 1Tcy later, just do not have time now. I don't like to upload or post something unfinished. I don't use much comments in code and some of them are in russian. So when i finish my work on development, i should make code look better and more clear for anybody and for myself too)).

Darrel Taylor
- 21st August 2009, 02:43
I wait with baited breath for your code.

Just be aware ...
I'm going to tell you why it doesn't do what you think it does.
<br>

sanch0
- 21st August 2009, 02:47
And I use only pure ASM code for such relatively slow MCUs, of course...

p.s. please don't expect me to do it very soon, as i have to finish some other projects too. Firstly I must repair of girlfriend's apartment and after that I planned to develop some mechanics for other project. It could take 2 weeks, i hope. Sorry. Hope u'll be patient.
Darrel Taylor: )))))))))))))))))))))))))))))))))))))))))))))
It do what it supposed to do, not less not more.)) I've got enough measurement tools and other stuff to be 100% sure what i'm saying. And even i hadn't any of them... I don't just put MCU instructions into text file randomly. I know what i'm doing _exactly_, Darrel. I started studying electronics and ASM (for Z80 - first programming language i studied and used, M68K, PIC, AVR, x86 etc.) from my childrenhood, so i know what about i'm talking. U just have not any chanse, Darrel))))

lanyong
- 21st August 2009, 02:54
And I use only pure ASM code for such relatively slow MCUs, of course...


because u can share ur code.

so i say the secret,haha.

we can get A[0],A[1],,,A[13].

then

move A[1] to W.

then

movff A[0], PORTA
movwf PORTA

then we changer the H/L in a cycle.

have a good time.

haha.

lanyong
- 21st August 2009, 04:20
from ur childrenhood.

my god.

too young,haha.

i learn mcu in Unversity only.

sanch0
- 21st August 2009, 18:59
because u can share ur code.

so i say the secret,haha.

we can get A[0],A[1],,,A[13].

then

move A[1] to W.

then

movff A[0], PORTA
movwf PORTA

then we changer the H/L in a cycle.

have a good time.

haha.

Yep=)))
It's something like that.


btw, i had got my first shocks from electronics when i tryed to understand how my photoflash works. There was ~1000V on capacitor after trafo, but it didn't scare me) i was 5 years old then)

lanyong
- 22nd August 2009, 02:02
Yep=)))
It's something like that.


btw, i had got my first shocks from electronics mosquitowhen i tryed to understand how my photoflash works. There was ~1000V on capacitor after trafo, but it didn't scare me) i was 5 years old then)


but it is a secret for me.

we can use the 1000v to electronic mosquito,

Mike, K8LH
- 22nd August 2009, 15:43
Darrel,

I think these Gentlemen may be having a little fun at your expense as they try to get a rise out of you (LOL). That's the only reason I can think of for avoiding a simple question and for becoming a bit offensive when challenged.

My precalculated "output table" or "toggle table" MIBAM method should work fine with 13 or 14 bit duty cycle values but as you've already determined I can only get refresh rates of 610-Hz (8-chan, 13-bit, 200-nsec step) or 305-Hz (16-chan, 13-bit, 400-nsec step), etc., when using an 18F' device and 40-MHz clock (Tcy = 100-nsec). ISR "overhead" would be about 77% for the example below but could be improved with some structural changes.

Take care. Kind regards, Mike



;
; 8-chan (port b), 13-bit, 200-nsec (1638.4-usec period), 610-Hz
;
v_isr_h
movff bdat+12,LATB ; b12 data (2048T)
inDlyCy(2048*tStep-2) ; half 2^12
movff bdat+11,LATB ; b11 data (1024T)
inDlyCy(1024*tStep-2) ; half 2^11
movff bdat+10,LATB ; b10 data (512T)
inDlyCy(512*tStep-2) ; half 2^10
movff bdat+09,LATB ; b9 data (256T)
inDlyCy(256*tStep-2) ; half 2^9
movff bdat+08,LATB ; b8 data (128T)
inDlyCy(128*tStep-2) ; half 2^8
movff bdat+07,LATB ; b7 data (64T)
inDlyCy(64*tStep-2) ; half 2^7
movff bdat+06,LATB ; b6 data (32T)
inDlyCy(32*tStep-2) ; half 2^6
movff bdat+05,LATB ; b5 data (16T)
inDlyCy(16*tStep-2) ; half 2^5
movff bdat+04,LATB ; b4 data (8T)
inDlyCy(8*tStep-2) ; half 2^4
movff bdat+03,LATB ; b3 data (4T)
inDlyCy(4*tStep-2) ; half 2^3
movff bdat+02,LATB ; b2 data (2T)
inDlyCy(2*tStep-2) ; half 2^2
movff bdat+01,LATB ; b1 data (1T)
inDlyCy(1*tStep-2) ; half 2^1 (0 delay)
movff bdat+00,LATB ; b0 data (1T)
inDlyCy(1*tStep-2) ; full 2^0 (0 delay)
movff bdat+01,LATB ; b1 data (1T)
inDlyCy(1*tStep-2) ; half 2^1 (0 delay)
movff bdat+02,LATB ; b2 data (2T)
inDlyCy(2*tStep-2) ; half 2^2
movff bdat+03,LATB ; b3 data (4T)
inDlyCy(4*tStep-2) ; half 2^3
movff bdat+04,LATB ; b4 data (8T)
inDlyCy(8*tStep-2) ; half 2^4
movff bdat+05,LATB ; b5 data (16T)
inDlyCy(16*tStep-2) ; half 2^5
movff bdat+06,LATB ; b6 data (32T)
inDlyCy(32*tStep-2) ; half 2^6
movff bdat+07,LATB ; b7 data (64T)
inDlyCy(64*tStep-2) ; half 2^7
movff bdat+08,LATB ; b8 data (128T)
inDlyCy(128*tStep-2) ; half 2^8
movff bdat+09,LATB ; b9 data (256T)
inDlyCy(256*tStep-2) ; half 2^9
movff bdat+10,LATB ; b10 data (512T)
inDlyCy(512*tStep-2) ; half 2^10
movff bdat+11,LATB ; b11 data (1024T)
inDlyCy(1024*tStep-802) ; half 2^11
rcall prep ; rebuild bdat array
movff btmp,LATB ; b12 data (2048T)
retfie FAST ;
;

Darrel Taylor
- 22nd August 2009, 18:56
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. :o
<br>

sanch0
- 25th August 2009, 21:38
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. :o
<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.)))

boroko
- 14th September 2009, 05:15
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

Darrel Taylor
- 14th September 2009, 06:03
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>

boroko
- 14th September 2009, 08:24
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

sanch0
- 16th September 2009, 00:38
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.

boroko
- 20th September 2009, 11:44
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.


'* 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

Darrel Taylor
- 20th September 2009, 19:56
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,

sayzer
- 25th September 2009, 10:40
It would be very handy if we could use a shift register with MIBAM to multiplex the outputs.

In that case, we could use a small PIC like 12F629 or 675, then use 74HC595 type of shift registers and get as many outputs as we want, with the possible limitations of course.

BTW; I am getting flickering at 4Mhz even with RGB routine only.

-------------

ShortBus
- 27th September 2009, 17:15
I'm having problems compiling the sample code. Would you have any suggestions?


;----[ MIBAM Setup ]--------------------------------------------------------
BAM_COUNT CON 3 ; How many BAM Pins are used?
INCLUDE "MIBAM.pbp" ; Mirror Image BAM module

RED VAR BYTE
GREEN VAR BYTE
BLUE VAR BYTE

ASM
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)
endm
BAM_INIT BAM_LIST ; Initialize the Pins
ENDASM
;_________________________________________________ __________________________



Assembler output:


project.asm 257: Symbol not previously defined (wsave)
project.asm 260: Symbol not previously defined (ssave)
project.asm 262: Symbol not previously defined (psave)
project.asm 388: Symbol not previously defined (psave)
project.asm 390: Symbol not previously defined (ssave)
project.asm 392: Symbol not previously defined (wsave)
project.asm 393: Symbol not previously defined (wsave)

Darrel Taylor
- 27th September 2009, 19:41
In the MIBAM thread (http://www.picbasic.co.uk/forum/showthread.php?t=10564). The second post lists the typical Error/Warning messages you might encounter.

In your case, you need to add the wsave block shown in Post#1.
<br>

boroko
- 29th September 2009, 10:16
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.

Sorry I didn't get back. Thank you, that was where I missed it.

Bit of a lull as I wait for a new meLabs serial programmer. For some reason the 18F2550 decided to become a heating element instead of a processor. Alas, it lived a good life.... Couldn't be EOC, could it? (Excessive Operator Carelessness). Had to dig out an old laptop that still had a parallel port to run the EPIC programmer.

Bo

talatsahim
- 8th November 2009, 20:34
Hallo
will work mibam with hserin on 16F828?
:confused:

Darrel Taylor
- 8th November 2009, 20:59
will work mibam with hserin on 16F828? :confused:
Yes it will.

talatsahim
- 8th November 2009, 23:34
Yes it will.

Sorry, my very poor english.
Im new pbp user.
can you help me why not work my code?
Device 16F628







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

Darrel Taylor
- 9th November 2009, 00:28
can you help me why not work my code?
Yes I can ...


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>
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>
INTCON =%11000000, interrupts are controlled by the MIBAM routines. Don't change any interrupt registers.<br><br>
PIE1.5=1, you've enabled the USART receive Interrupt ... don't do that.<br><br>
RCREG = dummy, RCREG is a Read-Only register. Don't know what you were trying to do there.<br><br>
SPBRG = 0, it's unlikely that you would want to put SPBRG (Baud Rate Generator Register) to 0 for any reason.<br><br>
TXSTA.2 = 0, It's unlikely that you would want to put the USART in Low Speed mode when running at 250Kbaud.<br><br>
TXSTA.4 = 0, OK, it's not synchronous mode .... but what is it?<br><br>
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.
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. :)

talatsahim
- 9th November 2009, 01:48
"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 ...





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 =1:DMXFLAG = 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

Darrel Taylor
- 9th November 2009, 02:27
Sorry talatsahim,

This little bit of code I made, has already turned into several commercial products.
I have no problem with that, and everyone is free to do so if they wish.

But, some things you just have to do on your own.
If you can come up with the rest, that's great.

Best regards,

talatsahim
- 9th November 2009, 03:37
thanks all




Sorry talatsahim,

This little bit of code I made, has already turned into several commercial products.
I have no problem with that, and everyone is free to do so if they wish.

But, some things you just have to do on your own.
If you can come up with the rest, that's great.

Best regards,

Darrel Taylor
- 12th November 2009, 19:00
Mike,

Did you get anywhere with this ...
I can not figure out a way to Charlieplex MIBAM. :o

I need to finish this thing, and think I'm going to have to toss Charlie out the window (from a very tall building).

DT


...
More later... I'm trying to see if I can upgrade a very old 12F683 Charlieplexed 5-pin 20-LED project from 64 levels per LED to 256 levels per LED using MIBAM. Wish me luck...

Kind regards, Mike

<object width="425" height="344"><param name="movie" value="http://www.youtube.com/v/AgQTBKcg2D4&color1=0xb1b1b1&color2=0xcfcfcf&hl=en&feature=player_embedded&fs=1"></param><param name="allowFullScreen" value="true"></param><param name="allowScriptAccess" value="always"></param><embed src="http://www.youtube.com/v/AgQTBKcg2D4&color1=0xb1b1b1&color2=0xcfcfcf&hl=en&feature=player_embedded&fs=1" type="application/x-shockwave-flash" allowfullscreen="true" allowScriptAccess="always" width="425" height="344"></embed></object>

http://www.wowway.com/~mmclaren/PWM-64 (small).PNG

Mike, K8LH
- 13th November 2009, 00:14
What "thing" are you talking about tossing Darrel?

I wrote and simulated the ISR driver for a 5-pin 20-LED demo' but that's as far as I got. You want to see that part Sir?

<added>

Tell me what chip you want it for and I'll give you a simple 5-pin (rb0..rb4) 20-LED sample Saturday that you can breadboard and play with.

Mike

Darrel Taylor
- 13th November 2009, 01:56
What "thing" are you talking about tossing Darrel?At this point, I'd like to toss Charlie Allen himself. :)


I wrote and simulated the ISR driver for a 5-pin 20-LED demo' ...Is that with MIBAM? I'd love too.
For whatever chip, in whatever language.

Even if it's not MIBAM, it might give me an idea that could save Charlie's life. :D

Thanks again Master,

Mike, K8LH
- 13th November 2009, 22:41
Yes, it's a sample ISR engine for MIBAM within an assembly language 'skeleton' program for 16F886 with 20 Charlieplexed LEDs on 5 pins (RB0..RB4). Just needs config lines, an init section, and short main section to manipulate the led[] array. I was interested in seeing if MIBAM could be implemented on a Charlieplexed matrix and after I wrote and simulated the MIBAM ISR 'engine' I got distracted by other projects.

I will send you the Charlie-MIBAM skeleton in a PM and work on those missing pieces so that you can actually try something on some hardware, if you like.

Mike

Mike, K8LH
- 15th November 2009, 14:59
Someone asked about the diagonal line on my Charlieplexed display sketch. It's what I refer to as the "float" pin and it's connected to the LEDs that occupy positions in the matrix that would otherwise share a common column and row (RB0/RB0, RB1/RB1, etc.).

I apologize if the diagonal line has thrown you off. It's a remnant from some of my sketches of Charlieplexed 7-segment displays.

Both drawings below are electrically the same but the second drawing below may make more sense. Basically I just slid those LEDs in the bottom row up into the empty spaces in the matrix.

Kind regards, Mike

http://www.picbasic.co.uk/forum/attachment.php?attachmentid=3790&d=1258296964

Mike, K8LH
- 22nd November 2009, 12:29
Darrel,

I was just wondering -- is MIBAM even necessary on a multiplexed display due to the long pauses between LED activation. You know, column one LEDs would be BAM'ed then turned off while we sequencially BAM column two LEDs, then BAM column three LEDs, etc.?

Darrel Taylor
- 22nd November 2009, 17:11
Hi Mike,

I wholeheartedly agree.
MIBAM with multiplexed display doesn't seem like it's worth it, because you loose so much of the available dutycycle.

Thanks for the explanation of the diagonal line.
I did get your example working, with only 8 leds (2 columns).
I made enough changes to not know if it's actually the way yours works or not. :o

But I don't see a way to incorporate it into the MIBAM routines (because of the duty cycle losses), so I'm officially tossing Charlie out the window.
Good thing I live at ground level. :)

I'll complete the modifications for your previous idea (full port updates) and get this thing done.

Thanks for all your assistance Mike, much appreciated.

Mike, K8LH
- 18th February 2010, 22:11
Yes, LED duty cycle is decreased with any multiplexed display and while we normally pump up the "peak" current to get better "average" current (and brightness) we can't do that with a Charlieplexed display (or any other multiplexed display that uses "direct drive" for matrix columns or rows).

Anyway, I thought you might enjoy taking a peek at a multiplexed 8-channel RGB display demo' (24 discrete LEDs) with 256-level BAM driver and a pretty amazing 868-Hz refresh rate. The display is fashioned as a 3x8 matrix (33% duty cycle) so biasing the LED "peak" current to approximately 3x desired "average" current will be necessary. This assembly language program just contains the driver. No animation or anything like that, yet.

Regards, Mike

http://www.picbasic.co.uk/forum/attachment.php?attachmentid=4013&d=1266530741

Mike, K8LH
- 19th February 2010, 13:24
Is there any way I can get temporary access to locked post above to update the program listing? I posted incorrect version which has some bugs. Sorry!

Mike, K8LH
- 5th March 2010, 18:25
Darrel (and gang),

A long overdue assembly language Charlieplexed BAM example for 20 LEDs on a 12F683. Example uses 8-bit 256 step BAM driver with a 1-usec step size. Refresh rate is 781-Hz with a 1280-usec frame rate. LED "0" is animated. That is, it ramps from duty cycle value of 0 up to 127 and then back down to 0. LED "10" through LED "19" are lighted with duty cycle values of 1 through 10 so you can check out "low end" illumination.

You might just hook up a single LED for LED "0" to check out the program. Just connect the LED cathode to GP5 and the LED anode to GP0.

Kind regards, Mike

Mike, K8LH
- 8th March 2010, 11:24
Has anyone tried "gamma" correction to smooth out LED brightness level changes? I just added a 64 level rom "gamma" array to the program in the previous post and it made an amazing difference in the smoothness of the fade.

Ioannis
- 8th March 2010, 12:07
I supose this depends on the type of LED. Each type of LED may need its own gamma curve.

Ioannis

Mike, K8LH
- 8th March 2010, 12:51
Bummer! I was afraid of that...

Sneaky-geek
- 9th March 2010, 01:15
Hi Mike,
Fantastic work!

Could you please post:
LED Part number,
Gamma correction routine?

Please, Please, Pretty Please?

I've learned a lot from this thread and want to say Thank You, to ALL who have contributed.

73,
Terry K9HA

Mike, K8LH
- 9th March 2010, 15:53
Hi Terry, K9HA,

Attached is assembler source with "gamma" table. I also slowed down LED "0" fade loop time considerably to look for "stair stepping" effect since I was only using 64 "gamma" steps but the fading is remarkably smooth.

I'm using Fairchild MV57164 Bar/Dot displays but almost any LED should work fine.

A couple observations;

(1) I'm very surprised at the light produced from LED "10" which is set to a duty cycle of 1 (1-usec -> 1/1280th or 0.078125% duty cycle).
(2) Mirrored BAM doesn't seem to be necessary to correct the 127-128 duty cycle transition visual artifact when using a multiplexed display (with gaps between LED updates).

Regards and "very 73", Mike, K8LH

Sneaky-geek
- 10th March 2010, 15:02
Mike,
Thank you for the part data AND the assembly code.
It will be fun experimenting with this!

73
Terry
K9HA

Mike, K8LH
- 10th March 2010, 16:38
I'm geeked!

Just added a 256-step BAM driver to an old project which had a 4-digit 7-segment display (direct I/O drive) and using it for brightness control works great (488-Hz refresh rate @ 4-MHz INTOSC).

I've got a few of these old three or four digit 'pnp' (practically no parts) type projects around and I had always wanted to implement a form of PWM brightness control on them but nothing worked as well or was as 'clean' as this K8LH BAM driver method.

Only "down side" so far is that I haven't figured out a way to implement "cycle accurate" delays in BoostC which means I'm stuck writing in assembler which no one can understand (lol).

Regards, Mike, K8LH

sanch0
- 24th March 2010, 16:12
Has anyone tried "gamma" correction to smooth out LED brightness level changes? I just added a 64 level rom "gamma" array to the program in the previous post and it made an amazing difference in the smoothness of the fade.

yep... tryed it in 3 ways:
1. Simple ISR-based software PWM with floating (table-generated) pulse widths.
2. Strobing /OE of external latches (54 PWM channels/PIC16f877a) with HW PWM output (table-generated) + SW PWM (i had to slightly increase LED current to get more brightness, as the full duty cycle hadn't been achievable, almost like with 1.5x charlieplexing)
3. Increased bit depth to 13(14) bit and PWM speed (refresh rate) to 610Hz on 18F for better perfomance.

sanch0
- 1st April 2010, 00:32
2 ALL...
There is one small problem with high speed BAM/MIBAM. Problem exists if u use simpler MOSFET driving scheme (or if u use slower bipolar schemes like darlinghton's transistor pairs and if actual switches are controlled by MCU's outputs directly) or if u need higher current per channel, especially if currents on some channels are significantly different. This happens because switching delays differ too. Check out datasheets for gate driving characteristics for higher current applications and compare it with needed signal discretization. PWM methods don't solve the problem but it need less signal transitions per cycle and work slightly better for lower bit depths without additional gate drivers (for reasonable currents, of course). Actually this problem just increase duty_cycle/brightness relation's non-linearity, but combined with longer wires, bad PCB layouts etc. it may cause unpredictable results for visual perception. So don't be surprised). sorry, can't describe problem in detail because of my poor english (lack of practics) and lazyness. Anyway, best solution is to check your application's requirements in advance))).

lanyong
- 18th July 2010, 13:15
hi,sanch0.

how r u?

i am waiting for ur codes for 16 channels of 14-bit BAM, at 610Hz.

where are them?

thank u.

sanch0
- 30th July 2010, 13:54
hi,sanch0.

how r u?

i am waiting for ur codes for 16 channels of 14-bit BAM, at 610Hz.

where are them?

thank u.

done and working already... for now my code gives 16 bit (E)BAM at 610hz (actually 14bit at 610 hz (1 Tcy discretisation) + 2 bits at 610/2 and 610/4 Hz and channel values are updated at 610/4Hz) my code gives real 610hz refresh rate because i don't use MIBAM, which would steal additional frame giving in result twice lower framerate (for visual perception). for now 16 channel code is working (with same 28-pin PIC18xxxx PCB, i've posted it's photo before), more channels may be easily added if needed (it's possible to make up to 64 channels with external latches upto my calculations, more with internal latches). Actually my algo has some more improvements compared to MIBAM. but i'm slightly drunk for now to describe it)))...
Sorry guyz, i got no access to internet from home, checking mail very rarely. have no normal job for long time to pay for all stuff i need... Stupid country, stupid government, stupid myself)
best regardzzz

lanyong
- 2nd August 2010, 07:03
done and working already... for now my code gives 16 bit (E)BAM at 610hz (actually 14bit at 610 hz (1 Tcy discretisation) + 2 bits at 610/2 and 610/4 Hz and channel values are updated at 610/4Hz) my code gives real 610hz refresh rate because i don't use MIBAM, which would steal additional frame giving in result twice lower framerate (for visual perception). for now 16 channel code is working (with same 28-pin PIC18xxxx PCB, i've posted it's photo before), more channels may be easily added if needed (it's possible to make up to 64 channels with external latches upto my calculations, more with internal latches). Actually my algo has some more improvements compared to MIBAM. but i'm slightly drunk for now to describe it)))...
Sorry guyz, i got no access to internet from home, checking mail very rarely. have no normal job for long time to pay for all stuff i need... Stupid country, stupid government, stupid myself)
best regardzzz

hi,i want to watch ur codes.

thanks.

i advise u read some works of liening's(Влади́мир Ильи́ч Ле́нин). u will find the hope.

JimAvanti
- 24th July 2012, 21:39
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

Darrel Taylor
- 24th July 2012, 22:28
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

JimAvanti
- 26th July 2012, 16:38
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

Darrel Taylor
- 26th July 2012, 17:35
What does the BAM_INFO report?

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

Mike, K8LH
- 26th July 2012, 23:35
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


#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
} //
}



http://www.youtube.com/watch?v=J0abEwfFe7Q&feature=plcp

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.


http://www.youtube.com/watch?v=9PNHyJdpUVs&feature=relmfu

JimAvanti
- 27th July 2012, 21:47
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

bjdriver
- 22nd February 2015, 20:16
Hi there !
Can anybody mail me a code for charliplexing more than 20 or even 20 LEDs with 16F886 in a C listing file ?

AvionicsMaster1
- 24th February 2015, 13:41
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.