Agreed. I could probably have made a movie of it in the time it would
take a PIC-er to just get started! Here it is:
http://www.terrypin.dial.pipex.com/Images/LED-Sequencer4MB.wmv
This took 5 minutes to code (adapted another project). 15 if you include
the setup, programming, testing, and bugfix (I inadvertently forgot to
call init(), and it didn't work the first time). Only one chip, a pot, 5
resistors, and 4 leds. Sadly, I don't have a movie camera, or I would
record it. This is compiled with the free 'hitech lite' C compiler, and is
downloaded to a pickit 1 using lawlor's usb_pickit for linux.
The PIC12F675 is an 8 pin uC, which supports ADC, timer interrupts, and
such. Pin 7 is used as the ADC input, so changing the voltage changes the
rate of change of the display, from once every 2 seconds to as fast as it
can go. The period is about Vin/Vcc * 2048 for Vin > 0.
Pin 6, 5, 3, and 2 are A, B, C, and D. Pin 4 is the reset, pin 1 is Vcc,
and pin 8 is GND. A-D can source up to 20mA, so a 1k resistor between it
and the LED limits current to about 3.5mA.
(for the curious, it uses a 1ms interrupt to do delays. The result of
the high byte of the AD is between 0 and 255. Thus 8 * AD is from 0 to
2040, and just delaying that number of ms interrupts provides the ability
to change the period from fast to slow)
BTW, I'm sure we all appreciate JF's and Terry's efforts to help people
out. I wish everybody's posted circuits were as well thought out, tested,
and nicely presented as the ones they post.
Regards
---------------------------------------------------------------------------
#include <pic.h>
__CONFIG(UNPROTECT & BORDIS & MCLREN & PWRTDIS & WDTDIS & INTIO);
unsigned int g_ticks; /* Ticks since startup */
#define TICKS_PER_SECOND 1000
#define LED_A GPIO1
#define LED_B GPIO2
#define LED_C GPIO4
#define LED_D GPIO5
void init_gpio(void)
{
GPIO = 0;
}
void init_tmr0(void)
{
/* prescaler is 1:4, GPIO pullups are disabled */
OPTION = 0x81;
}
void init_tmr1(void)
{
T1CON = 0; /* Disabled */
}
void init_comparator(void)
{
CMCON = 0x7; /* Turn off the comparator */
VRCON = 0x0;
}
void init_a2d(void)
{
ANSEL = 0x11; /* Fosc/8 and RA0 is analog */
ADCON0=0x00; // Left justify output
ADON=1; // turn on the A2D conversion module
}
void init_ee()
{
}
void init_interrupts(void)
{
INTCON = 0xA0;
}
void init(void)
{
OSCCAL = _READ_OSCCAL_DATA();
TRISIO = 0x01; /* RA0 is ad input, rest are outputs */
init_gpio();
init_tmr0();
init_tmr1();
init_comparator();
init_a2d();
init_interrupts();
}
unsigned int get_voltage (void)
{
GODONE=1; /* initiate conversion */
while(GODONE) /* wait for result */
{
continue;
}
return ADRESH;
}
void wait_ms(unsigned int x)
{
unsigned int temp = g_ticks + x;
while (temp != g_ticks);
}
void main(void)
{
int state = 0;
init();
LED_A = 1;
LED_B = 1;
LED_C = 0;
LED_D = 0;
for (;
{
unsigned int ms_to_wait = get_voltage() * 8;
wait_ms(ms_to_wait);
switch(state)
{
case 0:
LED_A = 0;
LED_C = 1;
state++;
break;
case 1:
LED_B = 0;
LED_D = 1;
state++;
break;
case 2:
LED_C = 0;
LED_A = 1;
state++;
break;
case 3:
LED_D = 0;
LED_B = 1;
state = 0;
break;
}
}
}
static void interrupt isr(void)
{
T0IF = 0;
TMR0 = 6;
g_ticks++;
}