![]() | ![]() | ![]() |
| | #31 |
| No it doesn't. I slowed the clock down to a crawl and still get the same LEDs lit, but flickering now, as the update rate is too slow. Some of them are brighter than others and some aren't on at all. Is it supposed to animate (move)? I haven't really deciphered that ISR yet. Anyway, nothing moves. Maybe what I'll do is draw up a schematic of what I've done and let you have a look. Maybe I did something different than you. Your schematic seemed just a tiny bit unclear to me. What program is that?
__________________ ========================= Futz's Microcontrollers & Robotics ========================= Last edited by futz; 27th June 2008 at 03:45 PM. | |
| |
| | #32 |
|
Hi Eric, No practical plans. This board was originally the prototype for a Serial Addressable Bar/Dot Display Controller which I used in a power management system to display Battery Capacity and Battery Load conditions. Now the board is just a test bed, though it's been programmed a couple times to display staggered night rider patterns for a visiting niece or nephew (grin). Regards, Mike | |
| |
| | #33 | |
| Quote:
I probably should have left my original smooth fade duty cycle values in there (also not animated), which were; Code: led[0] = led[19] = 31; // 100% brightness
led[1] = led[18] = 23; // 90% brightness
led[2] = led[17] = 18; // 80% brightness
led[3] = led[16] = 14; // 70% brightness
led[4] = led[15] = 11; // 60% brightness
led[5] = led[14] = 9; // 50% brightness
led[6] = led[13] = 7; // 40% brightness
led[7] = led[12] = 5; // 30% brightness
led[8] = led[11] = 3; // 20% brightness
led[9] = led[10] = 2; // 10% brightness
Let me see if I can work up an explanation for that ISR which is doin' all the work. Mike Last edited by Mike, K8LH; 27th June 2008 at 05:26 PM. | ||
| |
| | #34 |
|
Can someone help me come up with a Cylon night-rider routine for that demo program? Something like a night rider but with trailing LEDs that fade? I would try to throw something together quickly but Helen's sister's wedding is tomorrow and we have to do rehersal and dinner and stuff so I'm a little short of time today. Regards, Mike | |
| |
| | #35 | ||
| Quote:
Code: led[0] = led[19] = 1; // led[1] = led[18] = 1; // led[2] = led[17] = 4; // led[3] = led[16] = 0; // led[4] = led[15] = 0; // led[5] = led[14] = 1; // led[6] = led[13] = 1; // led[7] = led[12] = 0; // led[8] = led[11] = 1; // led[9] = led[10] = 1; // I replaced the numbers just now with your: Code: led[0] = led[19] = 31; // 100% brightness
led[1] = led[18] = 23; // 90% brightness
led[2] = led[17] = 18; // 80% brightness
led[3] = led[16] = 14; // 70% brightness
led[4] = led[15] = 11; // 60% brightness
led[5] = led[14] = 9; // 50% brightness
led[6] = led[13] = 7; // 40% brightness
led[7] = led[12] = 5; // 30% brightness
led[8] = led[11] = 3; // 20% brightness
led[9] = led[10] = 2; // 10% brightness
Quote:
![]() I still need to grind through that ISR till I understand exactly what's going on in there. I have most of the day off, so I think I'll grind today.
__________________ ========================= Futz's Microcontrollers & Robotics ========================= Last edited by futz; 27th June 2008 at 05:53 PM. | |||
| |
| | #36 | |
| Quote:
__________________ ========================= Futz's Microcontrollers & Robotics ========================= | ||
| |
| | #37 | |
| Quote:
The things we have to do for our kids. I appreciate the test bed method of proving a concept, its so much easier than trying to develop an idea in the middle of an actual application. It looks a useful feature which could be used for a number of practical projects.
__________________ Eric " Good enough is Perfect " I will NOT answer PM's requesting technical help, please use the Forum PIC tutorials: Nigel's www.winpicprog.co.uk/ Bill's: www.blueroomelectronics.com/ | ||
| |
| | #38 |
|
Hey Mike! If you're still reading, I'm having a strange problem. I put stuff in the while() loop to alter the led[] array's contents on the fly, but nothing happens. I can't seem to use debug on this dinky little chip, and there's no spare pins to put a debugging blinky LED on, so I'm not sure what's happening. Any ideas?
__________________ ========================= Futz's Microcontrollers & Robotics ========================= | |
| |
| | #39 |
|
Send me your code so I can double check you? Looks like you've got mclr enabled (your photo'). I'll just turn it back off for my board... k8lh(at)arrl.net Last edited by Mike, K8LH; 27th June 2008 at 08:17 PM. | |
| |
| | #40 | |
| Quote:
Boostc.h has been included for the delays.Code: #include <system.h>
#include <boostc.h>
#pragma DATA _CONFIG, _MCLRE_ON&_WDT_OFF&_INTOSCIO
#pragma CLOCK_FREQ 8000000
unsigned char led[20]; // led matrix, pwm values 0..31
unsigned char shadow = 0; // isr, trisio shadow register
unsigned char colpos = 1; // isr, gpio column ring counter bit
unsigned char dcy = 15; // isr, duty cycle counter, 0..31
unsigned char dc0 = 0; // isr, row 0 (gp0) pwm value, 0..31
unsigned char dc1 = 0; // isr, row 1 (gp1) pwm value, 0..31
unsigned char dc2 = 0; // isr, row 2 (gp2) pwm value, 0..31
unsigned char dc3 = 0; // isr, row 3 (gp4) pwm value, 0..31
unsigned char addr = (unsigned char) &led;
#define end_of_period dcy.5 // isr, end of 32 pwm steps
#define end_of_cycle colpos.6 // isr, end of 5 column update cycle
void main()
{
unsigned char x,temp;
osccon = 0b01110001; // set 8 MHz INTOSC
cmcon0 = 7; // comparator off, digital I/O
ansel = 0; // a2d module off, digital I/O
trisio = 0b00111111; // set all pins to inputs
gpio = 0; // set all output latches to '0'
// setup 100 usec Timer 2 interrupts (8 MHz clock)
pir1 = 0; // clear peripheral interrupt flags
pie1 = 0; // clear peripheral interrupt enables
pie1.TMR2IE = 1; // set Timer 2 interrupt enable bit
tmr2 = 0; // clear Timer 2 register
t2con = 0b00000100; // '0-------' unimplemented bit
// '-0000---' TOUTPS<3:0>, postscale 1
// '-----1--' TMR2ON, turn Timer 2 on
// '------00' T2CKPS<1:0>, prescale 1
pr2 = 200-1; // 200 x 500-nsec 'ticks' = 100 usecs
intcon = 0b11000000; // '1-------' GIE, enable global ints
// '-1------' PEIE, enable peripheral ints
// '--0-----' T0IE, TMR0 ints disabled
// '---0----' INTE, off
// '----0---' GPIE, IOC disabled
// '-----000' T0IF/INTF/GPIF flags
// simple led interface to pwm driver, duty cycle values of 0..31
led[0] = led[19] = 0;
led[1] = led[18] = 0;
led[2] = led[17] = 0;
led[3] = led[16] = 0;
led[4] = led[15] = 0;
led[5] = led[14] = 0;
led[6] = led[13] = 0;
led[7] = led[12] = 0;
led[8] = led[11] = 0;
led[9] = led[10] = 0;
while(1){
led[0] = 2;
led[1] = 3;
led[2] = 5;
led[3] = 7;
led[4] = 9;
led[5] = 11;
led[6] = 14;
led[7] = 18;
led[8] = 23;
led[9] = 31;
delay_ms(200);
led[0] = 1;
led[1] = 1;
led[2] = 1;
led[3] = 1;
led[4] = 1;
led[5] = 1;
led[6] = 1;
led[7] = 1;
led[8] = 1;
led[9] = 1;
delay_ms(200);
}
}
/********************************************************************/
/* interrupt service routine */
/********************************************************************/
/* */
/* 100 usec Timer2 interrupts, 32 interrupts/column (3.2 msecs) */
/* for 32 pwm brightness levels. 160 interrupts (16 msecs) for a */
/* complete 5 column update cycle (62.5 Hz refresh rate). */
/* */
/* led array duty cycle parameter values of 0..31 produce actual */
/* duty cycles of 0% to 20% per LED in 0.625% (100 usec) steps. */
/* */
/* 57 to 84 cycles or approximately 42% "overhead" (8 MHz clock) */
/* */
/********************************************************************/
void interrupt()
{
if(dc0 == dcy) // if row 0 duty cycle match
shadow.0 = 0; // clear shadow bit (gp0)
if(dc1 == dcy) // if row 1 duty cycle match
shadow.1 = 0; // clear shadow bit (gp1)
if(dc2 == dcy) // if row 2 duty cycle match
shadow.2 = 0; // clear shadow bit (gp2)
if(dc3 == dcy) // if row 3 duty cycle match
shadow.4 = 0; // clear shadow bit (gp4)
dcy++; // increment duty cycle counter
asm{
movf _colpos,W
andwf _shadow,W // is the float bit required?
btfss _status,Z // no, skip, else
iorlw 0b00100000 // set the 'float' bit
iorwf _shadow,W // pick up led bits
iorwf _colpos,W // pick up column bit
xorlw 0b00111111 // invert all
movwf _trisio // update the column LEDs
}
if(end_of_period){ // if all 32 pwm steps complete
dcy = 0; // reset duty cycle counter
asm{
bcf _status,C // shift column bit mask
rlf _colpos,F
btfsc _colpos,3 // if gp3 bit position
rlf _colpos,F // shift to gp4 bit position
}
if(end_of_cycle){ // if all 5 columns have been updated
colpos = 1; // reset colpos bit to column 0
asm{ // reset led[] array address pointer
movlw _led
movwf _addr // addr = (unsigned char) &led
}
}
shadow = 0b00010111; // setup shadow (all row bits "on")
gpio = colpos; // setup output latch, only 1 bit high
fsr = addr; // setup new column pwm work variables
dc0 = indf; // row 0 (gp0) pwm value, 0..31
fsr++;
dc1 = indf; // row 1 (gp1) pwm value, 0..31
fsr++;
dc2 = indf; // row 2 (gp2) pwm value, 0..31
fsr++;
dc3 = indf; // row 3 (gp4) pwm value, 0..31
addr = fsr + 1; // save array address
}
}
__________________ ========================= Futz's Microcontrollers & Robotics ========================= | ||
| |
| | #41 |
|
No, it's not you. I'm the one who's embarrassed. Please add the following line at the top of the ISR; Code: void interrupt()
{ pir1.TMR2IF = 0; // clear timer 2 interrupt flag
| |
| |
| | #42 | |
| Quote:
Excellent!
__________________ ========================= Futz's Microcontrollers & Robotics ========================= | ||
| |
| | #43 | |
| Quote:
My displays are end to end, so it looks best that way. I don't know what it'll look like on side by side displays. You may have to rewrite it to suit.Code: #include <system.h>
#include <boostc.h>
#pragma DATA _CONFIG, _MCLRE_OFF&_WDT_OFF&_INTOSCIO
#pragma CLOCK_FREQ 8000000
void reset(void);
unsigned char trail[5];
unsigned char led[20]; // led matrix, pwm values 0..31
unsigned char shadow = 0; // isr, trisio shadow register
unsigned char colpos = 1; // isr, gpio column ring counter bit
unsigned char dcy = 15; // isr, duty cycle counter, 0..31
unsigned char dc0 = 0; // isr, row 0 (gp0) pwm value, 0..31
unsigned char dc1 = 0; // isr, row 1 (gp1) pwm value, 0..31
unsigned char dc2 = 0; // isr, row 2 (gp2) pwm value, 0..31
unsigned char dc3 = 0; // isr, row 3 (gp4) pwm value, 0..31
unsigned char addr = (unsigned char) &led;
#define end_of_period dcy.5 // isr, end of 32 pwm steps
#define end_of_cycle colpos.6 // isr, end of 5 column update cycle
void main()
{
unsigned char x,y,z,temp;
osccon = 0b01110001; // set 8 MHz INTOSC
cmcon0 = 7; // comparator off, digital I/O
ansel = 0; // a2d module off, digital I/O
trisio = 0b00111111; // set all pins to inputs
gpio = 0; // set all output latches to '0'
// setup 100 usec Timer 2 interrupts (8 MHz clock)
pir1 = 0; // clear peripheral interrupt flags
pie1 = 0; // clear peripheral interrupt enables
pie1.TMR2IE = 1; // set Timer 2 interrupt enable bit
tmr2 = 0; // clear Timer 2 register
t2con = 0b00000100; // '0-------' unimplemented bit
// '-0000---' TOUTPS<3:0>, postscale 1
// '-----1--' TMR2ON, turn Timer 2 on
// '------00' T2CKPS<1:0>, prescale 1
pr2 = 200-1; // 200 x 500-nsec 'ticks' = 100 usecs
intcon = 0b11000000; // '1-------' GIE, enable global ints
// '-1------' PEIE, enable peripheral ints
// '--0-----' T0IE, TMR0 ints disabled
// '---0----' INTE, off
// '----0---' GPIE, IOC disabled
// '-----000' T0IF/INTF/GPIF flags
// simple led interface to pwm driver, duty cycle values of 0..31
reset();
trail[0]=12;trail[1]=9;trail[2]=6;trail[3]=2;trail[4]=1;
while(1){
for(x=0;x<19;x++){
reset();
led[x]=31;
for(y=0;y<5;y++){
if((x-(y+1))>-1)
led[x-(y+1)]=trail[y];
}
delay_ms(30);
}
for(x=19;x>0;x--){
reset();
led[x]=31;
for(y=0;y<5;y++){
if((x+(y+1))<20)
led[x+(y+1)]=trail[y];
}
delay_ms(30);
}
}
}
void reset(){
led[0] = led[19] = 0;
led[1] = led[18] = 0;
led[2] = led[17] = 0;
led[3] = led[16] = 0;
led[4] = led[15] = 0;
led[5] = led[14] = 0;
led[6] = led[13] = 0;
led[7] = led[12] = 0;
led[8] = led[11] = 0;
led[9] = led[10] = 0;
}
/********************************************************************/
/* interrupt service routine */
/********************************************************************/
/* */
/* 100 usec Timer2 interrupts, 32 interrupts/column (3.2 msecs) */
/* for 32 pwm brightness levels. 160 interrupts (16 msecs) for a */
/* complete 5 column update cycle (62.5 Hz refresh rate). */
/* */
/* led array duty cycle parameter values of 0..31 produce actual */
/* duty cycles of 0% to 20% per LED in 0.625% (100 usec) steps. */
/* */
/* 57 to 84 cycles or approximately 42% "overhead" (8 MHz clock) */
/* */
/********************************************************************/
void interrupt()
{
pir1.TMR2IF = 0; // clear timer 2 interrupt flag
if(dc0 == dcy) // if row 0 duty cycle match
shadow.0 = 0; // clear shadow bit (gp0)
if(dc1 == dcy) // if row 1 duty cycle match
shadow.1 = 0; // clear shadow bit (gp1)
if(dc2 == dcy) // if row 2 duty cycle match
shadow.2 = 0; // clear shadow bit (gp2)
if(dc3 == dcy) // if row 3 duty cycle match
shadow.4 = 0; // clear shadow bit (gp4)
dcy++; // increment duty cycle counter
asm{
movf _colpos,W
andwf _shadow,W // is the float bit required?
btfss _status,Z // no, skip, else
iorlw 0b00100000 // set the 'float' bit
iorwf _shadow,W // pick up led bits
iorwf _colpos,W // pick up column bit
xorlw 0b00111111 // invert all
movwf _trisio // update the column LEDs
}
if(end_of_period){ // if all 32 pwm steps complete
dcy = 0; // reset duty cycle counter
asm{
bcf _status,C // shift column bit mask
rlf _colpos,F
btfsc _colpos,3 // if gp3 bit position
rlf _colpos,F // shift to gp4 bit position
}
if(end_of_cycle){ // if all 5 columns have been updated
colpos = 1; // reset colpos bit to column 0
asm{ // reset led[] array address pointer
movlw _led
movwf _addr // addr = (unsigned char) &led
}
}
shadow = 0b00010111; // setup shadow (all row bits "on")
gpio = colpos; // setup output latch, only 1 bit high
fsr = addr; // setup new column pwm work variables
dc0 = indf; // row 0 (gp0) pwm value, 0..31
fsr++;
dc1 = indf; // row 1 (gp1) pwm value, 0..31
fsr++;
dc2 = indf; // row 2 (gp2) pwm value, 0..31
fsr++;
dc3 = indf; // row 3 (gp4) pwm value, 0..31
addr = fsr + 1; // save array address
}
}
__________________ ========================= Futz's Microcontrollers & Robotics ========================= Last edited by futz; 27th June 2008 at 11:37 PM. | ||
| |
| | #44 |
|
And here's a YouTube video of that last code. My camera does a terrible job on LEDs in general. You can't really see very well that the trailing LEDs are fading, but they are. In the vid they all look the same brightness.
__________________ ========================= Futz's Microcontrollers & Robotics ========================= | |
| |
| | #45 |
|
Looks very nice here but with some artifacts that I see with my photos too. Thanks for a very nice example to study. Mike | |
| |
|
| Tags |
| boostc, charlieplexed, pwm |
| Thread Tools | |
| Display Modes | |
| |
Similar | ||||
| Title | Starter | Forum | Replies | Latest |
| BoostC question.. AddressOf | Mike, K8LH | Micro Controllers | 8 | 25th June 2008 12:20 AM |
| LCD degree symbol with sprintf (BoostC) | futz | Micro Controllers | 29 | 5th June 2008 05:19 AM |
| math.h and lib for BoostC? | futz | Micro Controllers | 3 | 31st March 2008 06:29 AM |
| Charlieplexed code segment for the Cricket Thermostat | William At MyBlueRoom | Micro Controllers | 2 | 14th March 2006 05:12 PM |
| My PIC Projects Site NEW (includes 2 Charlieplexed Display) | William At MyBlueRoom | Electronic Projects Design/Ideas/Reviews | 0 | 28th February 2006 02:31 PM |