Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

BoostC Charlieplexed PWM 32

Status
Not open for further replies.
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
 
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.
This was fun. :D 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
	}
}
 
Last edited:
Looks very nice here but with some artifacts that I see with my photos too.

Thanks for a very nice example to study.

Mike
 
Replace this part of main() with this new version. Should work better on side by side displays:
Code:
	reset();
	trail[0]=10;trail[1]=8;trail[2]=5;trail[3]=2;trail[4]=1;
	while(1){
		for(x=0;x<10;x++){
			reset();
			led[x]=31;
			led[(x-9)+19]=31;
			for(y=0;y<5;y++){
				if((x-(y+1))>-1)
					led[x-(y+1)]=trail[y];
				if(((x-9)+19)-(y+1)>9)
					led[((x-9)+19)-(y+1)]=trail[y];
			}
			delay_ms(30);
		}
		for(x=9;x>0;x--){
			reset();
			led[x]=31;
			led[(x-9)+19]=31;
			for(y=0;y<5;y++){
				if((x+(y+1))<10)
					led[x+(y+1)]=trail[y];
				if(((x-9)+19)+(y+1)<20)
					led[((x-9)+19)+(y+1)]=trail[y];
			}
			delay_ms(30);
		}
	}
 
Here's my version of the schematic. If you want to use GP3 as an input and still be able to use ICSP then you'll have to add a third switch (or some other means of isolation) to switch between VPP use and input use.
12f683_leds.png
 
Whether the connections to R6 and R7 be changed to after the programming switch? It would help in-situ programming, not to have load on the chip pins. The schematic after suggested mod is attached.
By the way I saw another youtube video . i felt it excellent. and link is here

YouTube - 12F683 Bluebox
 

Attachments

  • 12f683_leds mod.PNG
    12f683_leds mod.PNG
    45.4 KB · Views: 262
Last edited:
Whether the connections to R6 and R7 be changed to after the programming switch? It would help in-situ programming, not to have load on the chip pins. The schematic after suggested mod is attached.
Yes, I thought of that. Already had it wired the other way though, and didn't feel like changing it. Anyway, it works perfect as is, without that change. I'm lazily soldering one together. Guess I'll make that change on the soldered one.


By the way I saw another u-tube video . i felt it excellent. and link is here

YouTube - 12F683 Bluebox
Ya, I watched that. Nice project.
 
Last edited:
Here it is, Mr. Sarma. :D Added the third switch as well, so that one last input pin can be used.
View attachment 20072
Nice Futz, ultimate as all pins are now free for use. Great job.

On the trailing lamps project, please imagine the lamps physically mounted in a curve shape and let the trail display . , hope it would simulate a snake motion. ofcourse we may have to mask the board by say a green foil or perspex.
 
Replace this part of main() with this new version. Should work better on side by side displays:
Code:
    reset();
    trail[0]=10;trail[1]=8;trail[2]=5;trail[3]=2;trail[4]=1;
    while(1){
        for(x=0;x<10;x++){
            reset();
            led[x]=31;
            led[(x-9)+19]=31;
            for(y=0;y<5;y++){
                if((x-(y+1))>-1)
                    led[x-(y+1)]=trail[y];
                if(((x-9)+19)-(y+1)>9)
                    led[((x-9)+19)-(y+1)]=trail[y];
            }
            delay_ms(30);
        }
        for(x=9;x>0;x--){
            reset();
            led[x]=31;
            led[(x-9)+19]=31;
            for(y=0;y<5;y++){
                if((x+(y+1))<10)
                    led[x+(y+1)]=trail[y];
                if(((x-9)+19)+(y+1)<20)
                    led[((x-9)+19)+(y+1)]=trail[y];
            }
            delay_ms(30);
        }
    }

Futz,

You've come up with a couple extremely nice "Cylon Eye" examples. Thank you.

I tried to come up with my own version late last night and I'm still stuck. It's much harder than I thought it would be when I casually suggested someone "throw something together" (grin).

Mike
 
Mike. I have one little question. How are your LEDs laid out?
00-19
01-18
02-17
03-16
04-15
05-14
06-13
07-12
08-11
09-10

or

00-10
01-11
02-12
03-13
04-14
05-15
06-16
07-17
08-18
09-19

I lean toward the first layout.
 
That board was originally a Serial LED Bar/Dot Controller so led 00 is bottom left, 09 is top left, 10 is bottom right, and 19 is top right.

BTW, I completely understand both of your Cylon Eye examples. I was just trying to see if I could come up with something as good or better. Talk about a humbling experience (grin)...
 
Last edited:
Hi Gayan,

I'm not sure what you mean by "hack my design".

Attached is picture of bottom of board. It contains one surface mount PNP row driver transistor on GP0 (an experiment to increase peak current from 20 ma to around 50 ma).

Mike

Thanks for that Mike.Because I like to know what methods other guys use when they are soldering..........

ahhhhhhhhhhh
This guy has made a UV meter from PIC16F628.Unfortunately I couldn't find any schematic from it.

It also has a fade trail.

YouTube - PIC16F628 64 led bar
 
Last edited:
I finished my permanent Mike-K8LH blinky thing. Works fine and now I can have my breadboard back. :D Here's a couple pics:

**broken link removed**

**broken link removed**
 
I finished my permanent Mike-K8LH blinky thing. Works fine and now I can have my breadboard back. :D Here's a couple pics:
Oh! what an wiring effort Futz... looks Good and thanks for the photos.
 
Last edited:
Futz,

Your board looks excellent...

Those PCB mounted slide switches look great. May I ask about Manufacturer, Part Number, Source, please?

You probably could have done away with the switch on GP3. I just added a push button "mode" switch onto my board at GP3 with a pull-up resistor. You can also potentially use GP3 for bit-banged serial receive.

Mike
 
Last edited:
Those PCB mounted slide switches look great. May I ask about Manufacturer, Part Number, Source, please?
They are Digikey part# EG1903-ND. That's a Canadian link. For US link, click here.

Those switches work great on breadboards too.

You probably could have done away with the switch on GP3. I just added a push button "mode" switch onto my board at GP3 with a pull-up resistor. You can also potentially use GP3 for bit-banged serial receive.
True. Could rig a single tact switch to control all three lines. Just hold down to program.
 
Last edited:
Could rig a single tact switch to control all three lines. Just hold down to program.
I don't understand.

You wouldn't need a slide switch at all for GP3 because that would be connected to a normally open push button switch.

How would you connect a single push button switch to disconnect GP0/ICSPDAT and GP1/ICSPCLK from the LED circuitry when you push it and hold it down?
 
Status
Not open for further replies.

Latest threads

Back
Top