
![]()
This is the source code for the blinkie thing. It is written in
Dynamic C for the Rabbit 2000 8 Bit Microcontroller.
I am sure it has changed since I posted this.
11.25.01 Slowed down the timing of the lights, it was causing surges on other circuits in the house.
11.23.01 Finally figured out how to preserve the formatting of the source code.
10.20.01 Dammit, I can't get an array of function pointers to work in this version of C.
10.01.01 What a binary day... Please know that I do properly indent my code. It just disappears when I convert it to HTML.
////////////////////////////////////////////////////////////////////////////////
//
// Blinkie.c
// Nick McCurdy 2001
//
// The ultimate blinkie thing. For the xmas lights 2001
//
//
////////////////////////////////////////////////////////////////////////////////
// Delay Constants
#define DELAYINC 25
#define INITDELAY 55
#define MINDELAY 50
#define MAXDELAY 250
// Misc Constants
#define ON 1
#define OFF 0
#define LIGHTON 0
#define LIGHTOFF 1
#define ALLOFF 0xFF
#define ALLON 0x00
// Pattern Constants
#define ALT0 0x55
#define ALT1 0xAA
#define BONG1 0x99
#define BONG2 0x66
#define ALT41 0xF0
#define ALT42 0x0F
// Pattern Names
#define ALTERNATE 0
#define WALKING1 1
#define WALKING0 2
#define BINARYU 3
#define RANDOM 4
#define ALLBITSON 5
#define BITS3ON 6
#define PAIRS 7
#define KNIGHT 8
#define SWEEP1BIT 9
#define PSEUDOSEQ 10
#define WIPEINOUT 11
#define BONGBONG 12
#define ALT4 13
#define OUTFROMCENTER 14
#define OUTFROMCENTER2 15
#define SCAN2OFF 16
#define BLINKIEWIPE 17
#define CATCHUP 18
#define COUNTUP255 19
#define ARRAYPATTERN 20
#define MAXPATTERN 20
#define INITPATTERN MAXPATTERN
// Time of Day Constants
#define MORNINGONTIMEH 6
#define MORNINGOFFTIMEH 7
#define EVENINGONTIMEH 17
#define EVENINGOFFTIMEH 20
#define SWITCHTIME 10
// Button 4 Constants
#define OFFOFF OFF
#define CYCLEON 1
#define OVERRIDEON 2
#define CYCLEONOVERON 3
//Serial port constants
#define BOUTBUFSIZE 31
#define BINBUFSIZE 31
// Function Forward Declarations
int CheckButton(char);
void WritePA(char);
int CheckTime(void);
cofunc void onoffdelay(int, int);
void DisplayResetMessage(void);
void InitGlobals(void);
void InitIO(void);
cofunc void Alt1(void);
cofunc void Walking1(void);
cofunc void Walking0(void);
cofunc void BinaryU(void);
cofunc void Random(void);
cofunc void AllBitsOn(void);
cofunc void Bits3On(void);
cofunc void Pairs(void);
cofunc void Knight(void);
cofunc void Sweep1Bit(void);
cofunc void Pseudoseq(void);
cofunc void WipeInOut(void);
cofunc void BongBong(void);
cofunc void Alt4(void);
cofunc void OutFromCenter(void);
cofunc void OutFromCenter2(void);
cofunc void Scan2Off(void);
cofunc void BlinkieWipe(void);
cofunc void CatchUp(void);
cofunc void CountUp(void);
cofunc void ArrayPattern(void);
// Globals
char portbyte, onswitch, offswitch;
char pattern, patswitch, cycle;
char overon, FunctionButton4;
char i, j, poweron, B4;
char bytea, byteb;
int ondelay, offdelay;
unsigned long timetoswitch;
struct tm rtc; // time struct
char dayname[7][4] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };char b[8] = {1,128,4,16,2,64,8,32};void (*FuncArray[MAXPATTERN+1])();
//void (*FuncArray[])(void)=
//{Alt1, Walking1, Walking0, BinaryU, Random, AllBitsOn, Bits3On, Pairs, Knight,//Sweep1Bit, Pseudoseq, WipeInOut, BongBong, Alt4, OutFromCenter, OutFromCenter2,
//Scan2Off,BlinkieWipe, CatchUp, CountUp, FastnSlow};
//**********************************************************************
//
// The main loop for the blinkie thing.
//
//**********************************************************************
main(){
InitGlobals();
InitIO();
DisplayResetMessage();
// Start of main loop
while (1) { BigLoopTop();
cycle = FunctionButton4 & CYCLEON;
overon = FunctionButton4 & OVERRIDEON;
poweron = (overon | CheckTime());
if (poweron == 0) WritePA(ALLOFF);
if (poweron > 0) { if (cycle > 0){ if( read_rtc() >= timetoswitch){timetoswitch = timetoswitch + SWITCHTIME;
pattern += 1;
if (pattern > MAXPATTERN) pattern = 0;
ondelay = (int)(MS_TIMER & 1000) / 8;
if (ondelay < 100) ondelay =100;
offdelay = ondelay;
}
}
costate{
//wfd *FuncArray[pattern]();
switch (pattern){case ALTERNATE: wfd Alt1(); break;
case WALKING1: wfd Walking1(); break;
case WALKING0: wfd Walking0(); break;
case BINARYU: wfd BinaryU(); break;
case RANDOM: wfd Random(); break;
case ALLBITSON: wfd AllBitsOn(); break;
case BITS3ON: wfd Bits3On(); break;
case PAIRS: wfd Pairs(); break;
case KNIGHT: wfd Knight(); break;
case SWEEP1BIT: wfd Sweep1Bit(); break;
case PSEUDOSEQ: wfd Pseudoseq(); break;
case WIPEINOUT: wfd WipeInOut(); break;
case BONGBONG: wfd BongBong(); break;
case ALT4: wfd Alt4(); break;
case OUTFROMCENTER: wfd OutFromCenter(); break;
case OUTFROMCENTER2: wfd OutFromCenter2(); break;
case SCAN2OFF: wfd Scan2Off(); break;
case BLINKIEWIPE: wfd BlinkieWipe(); break;
case CATCHUP: wfd CatchUp(); break;
case COUNTUP255: wfd CountUp(); break;
case ARRAYPATTERN: wfd ArrayPattern(); break;
} //end switch
} // end costate
} // end if poweron
costate{onswitch=CheckButton(1);
if (onswitch==1){ondelay+=DELAYINC;
if (ondelay > MAXDELAY) ondelay=MINDELAY;
onswitch=0;
}
}
costate{ offswitch = CheckButton(2);
if (offswitch==ON){offdelay+=DELAYINC;
if (offdelay > MAXDELAY) offdelay=MINDELAY;
offswitch=OFF;
}
}
costate{patswitch=CheckButton(3);
if (patswitch==ON){pattern+=1;
if (pattern > MAXPATTERN) pattern=0;
patswitch=OFF;
}
}
costate{ if (B4 = CheckButton(4)){ if (B4==ON){FunctionButton4+=1;
if (FunctionButton4 > CYCLEONOVERON) FunctionButton4=OFFOFF;
B4=OFF;
}
}
}
} // end of while loop
} // end of main
//**********************************************************************
//
// Check state of button 1 to 4 (debouncing)
//
//**********************************************************************
int CheckButton(char button){int buttonstate;
button+=1;
if (BitRdPortI(PBDR, button)) return 0;
costate{waitfor(DelayMs(50));} // wait 50 msif(BitRdPortI(PBDR,button)) return 0;
buttonstate = !buttonstate; // toggle virtual switch since button was down 50 ms
while (1) { costate{waitfor(BitRdPortI(PBDR, button));} // wait for button to go up costate{waitfor(DelayMs(50));} // wait additional 200 millisecondsif (BitRdPortI(PBDR,button)) break; // if button still up break out of while loop
}
return 1;
}
//**********************************************************************
//
// Write Byte to Port A
//
//**********************************************************************
void WritePA(char val)
{WrPortI(PADR, &PADRShadow,val);
}
//**********************************************************************
//
// Check the RTC return a 1 if the lights should be on.
//
//**********************************************************************
int CheckTime(void)
{struct tm rtc; // time struct
tm_rd(&rtc);
if (rtc.tm_hour >= MORNINGONTIMEH && rtc.tm_hour<= MORNINGOFFTIMEH) return ON;
if (rtc.tm_hour >= EVENINGONTIMEH && rtc.tm_hour<= EVENINGOFFTIMEH) return ON;
return OFF;
}
//**********************************************************************
//
// Do the onoff delay.
//
//**********************************************************************
cofunc void onoffdelay(int ond, int offd)
{waitfor(DelayMs(ond));
WritePA(ALLOFF);
waitfor(DelayMs(offd));
}
//**********************************************************************
//
// Output Reset Message to COMB.
//
//**********************************************************************
void DisplayResetMessage(void)
{char resetmessage[] = "Christmas Light Blinkie Thing\r\nŠ2001 Nick McCurdy\r\nNicktronicks\r\n";
serBopen(9600);
serBputs(resetmessage);
while (serBwrFree() != BOUTBUFSIZE) ;
serBclose();
}
//**********************************************************************
//
// Initialize Global Variables.
//
//**********************************************************************
void InitGlobals(void)
{ondelay = (int)(MS_TIMER & 1000) / 8;
if (ondelay < 50) ondelay =50;
offdelay = ondelay;
overon = OFF;
onswitch=OFF;
offswitch=OFF;
pattern=OFF;
patswitch=OFF;
tm_rd(&rtc);
timetoswitch = read_rtc();
poweron = OFF;
cycle = OFF;
FunctionButton4 = 0;
pattern = INITPATTERN;
FuncArray[0]=Alt1;
FuncArray[1]=Walking1;
FuncArray[2]=Walking0;
FuncArray[3]=BinaryU;
FuncArray[4]=Random;
FuncArray[5]=AllBitsOn;
FuncArray[6]=Bits3On;
FuncArray[7]=Pairs;
FuncArray[8]=Knight;
FuncArray[9]=Sweep1Bit;
FuncArray[10]=Pseudoseq;
FuncArray[11]=WipeInOut;
FuncArray[12]=BongBong;
FuncArray[13]=Alt4;
FuncArray[14]=OutFromCenter;
FuncArray[15]=OutFromCenter2;
FuncArray[16]=Scan2Off;
FuncArray[17]=BlinkieWipe;
FuncArray[18]=CatchUp;
FuncArray[19]=CountUp;
FuncArray[20]=ArrayPattern;
}
//**********************************************************************
//
// Initialize IO Control Registers.
//
//**********************************************************************
void InitIO(void)
{WrPortI(SPCR, &SPCRShadow, 0x84); // setup parallel port A as output
WritePA( 0xff); // turn off all LED's
}
//**********************************************************************
//
// Alternate Lights
//
//**********************************************************************
cofunc void Alt1(void)
{WritePA(ALT0);
waitfor(DelayMs(ondelay));
WritePA(ALT1);
waitfor(DelayMs(offdelay));
}
//**********************************************************************
//
// Walk a light on
//
//**********************************************************************
cofunc void Walking1(void)
{portbyte = 0x80;
for (i=0;i<8;i++){WritePA(~portbyte);
//wfd onoffdelay(ondelay, offdelay);
waitfor(DelayMs(ondelay));
waitfor(DelayMs(offdelay));
portbyte >>= 1;
}
}
//**********************************************************************
//
// Walk a light off
//
//**********************************************************************
cofunc void Walking0(void)
{ for (portbyte=0x80; portbyte > 0; portbyte>>=1){WritePA(portbyte);
waitfor(DelayMs(ondelay));
waitfor(DelayMs(offdelay));
//wfd onoffdelay(ondelay, offdelay);
}
}
//**********************************************************************
//
// Two four bit up counters
//
//**********************************************************************
cofunc void BinaryU(void)
{ for (portbyte=0; portbyte<16; portbyte++){WritePA( ~(portbyte | portbyte<<4));
//wfd onoffdelay(ondelay, offdelay);
waitfor(DelayMs(ondelay));
waitfor(DelayMs(offdelay));
}
}
//**********************************************************************
//
// Randomeness based on MS_TIMER
//
//**********************************************************************
cofunc void Random(void)
{WritePA((int) MS_TIMER);
//wfd onoffdelay(ondelay, offdelay);
waitfor(DelayMs(ondelay));
waitfor(DelayMs(offdelay));
}
//**********************************************************************
//
// Plain and Simple
//
//**********************************************************************
cofunc void AllBitsOn(void)
{WritePA(ALLON);
}
//**********************************************************************
//
// Walk 3 lights on
//
//**********************************************************************
cofunc void Bits3On(void)
{portbyte = 0x07;
for (i=0; i<8; i++){WritePA(~portbyte);
//wfd onoffdelay(ondelay, offdelay);
waitfor(DelayMs(ondelay));
waitfor(DelayMs(offdelay));
portbyte <<= 1;
}
}
//**********************************************************************
//
// Walk 2 lights on
//
//**********************************************************************
cofunc void Pairs(void)
{portbyte = 3;
for (i=0; i<4; i++){WritePA(~portbyte);
portbyte = portbyte << 2;
//wfd onoffdelay(ondelay, offdelay);
waitfor(DelayMs(ondelay));
waitfor(DelayMs(offdelay));
}
}
//**********************************************************************
//
// Knight Rider Lights
//
//**********************************************************************
cofunc void Knight(void)
{bytea=1;
byteb=128;
for (i=0; i<4; i++){portbyte = bytea | byteb;
WritePA(~portbyte);
//wfd onoffdelay(ondelay, offdelay);
waitfor(DelayMs(ondelay));
waitfor(DelayMs(offdelay));
bytea <<= 1;
byteb >>= 1;
}
}
//**********************************************************************
//
// Whats this do?
//
//**********************************************************************
cofunc void Sweep1Bit(void)
{portbyte = 128;
for (i=0; i<2; i++){ for (bytea=0; bytea<7; bytea++){WritePA(~portbyte);
//wfd onoffdelay(ondelay, offdelay);
waitfor(DelayMs(ondelay));
waitfor(DelayMs(offdelay));
if (i==1)
portbyte <<=1;
else
portbyte>>=1;
}
}
}
//**********************************************************************
//
// LFSR Random Sequence
//
//**********************************************************************
cofunc void Pseudoseq(void)
{portbyte = (int) read_rtc();
for (i=0; i<8; i++){bytea = (portbyte & 0x40) ^ (portbyte & 0x01);
bytea &= 0x01;
portbyte = portbyte | !bytea;
WritePA(~portbyte);
//wfd onoffdelay(ondelay, offdelay);
waitfor(DelayMs(ondelay));
waitfor(DelayMs(offdelay));
portbyte <<= 1;
}
}
//**********************************************************************
//
// Yeeehaaa
//
//**********************************************************************
cofunc void WipeInOut(void)
{portbyte = 0xFF;
for (bytea=0; bytea<2; bytea++){if (bytea==1) portbyte=0xFF;
for (i=0; i<8; i++){ WritePA(~portbyte);
waitfor(DelayMs(ondelay));
waitfor(DelayMs(offdelay));
if (bytea==1)
portbyte >>= 1;
else
portbyte <<= 1;
}
}
}
//**********************************************************************
//
// Looks like it should sound to me
//
//**********************************************************************
cofunc void BongBong(void)
{ for (bytea=0; bytea<8; bytea++){WritePA(BONG1);
waitfor(DelayMs(ondelay));
WritePA(BONG2);
waitfor(DelayMs(offdelay));
}
}
//**********************************************************************
//
// Bounce two constants
//
//**********************************************************************
cofunc void Alt4(void)
{WritePA(ALT41);
waitfor(DelayMs(ondelay));
WritePA(ALT42);
waitfor(DelayMs(offdelay));
}
//**********************************************************************
//
// Sweep two out from the center
//
//**********************************************************************
cofunc void OutFromCenter(void)
{bytea=0x08;
byteb=0x10;
for (i=0; i < 8; i++){WritePA(~(bytea | byteb));
waitfor(DelayMs(ondelay));
waitfor(DelayMs(offdelay));
bytea <<=1;
byteb >>=1;
}
}
//**********************************************************************
//
// Another version of the out from center idea
//
//**********************************************************************
cofunc void OutFromCenter2(void)
{portbyte = 0;
bytea=0x08;
byteb=0x10;
for (i=0; i < 4; i++){j = bytea | byteb;
portbyte = j | portbyte;
WritePA(~portbyte);
//wfd onoffdelay(ondelay, offdelay);
waitfor(DelayMs(ondelay));
waitfor(DelayMs(offdelay));
bytea >>=1;
byteb <<=1;
}
}
//**********************************************************************
//
// Scans two off
//
//**********************************************************************
cofunc void Scan2Off(void)
{portbyte = 0x3F;
for (i=0; i<2; i++){ for (bytea=0; bytea<7; bytea++){WritePA(~portbyte);
//wfd onoffdelay(ondelay, offdelay);
waitfor(DelayMs(ondelay));
waitfor(DelayMs(offdelay));
switch (i){case 0:
portbyte <<=1;
break;
case 1:
portbyte>>=1;
break;
}
}
}
}
//**********************************************************************
//
// Blinks and Wipes
//
//**********************************************************************
cofunc void BlinkieWipe(void)
{portbyte = 0x3F;
for (i=0; i<16; i++){WritePA(portbyte);
//wfd onoffdelay(ondelay, offdelay);
waitfor(DelayMs(ondelay));
waitfor(DelayMs(offdelay));
if (i < 7) bytea = 0; else bytea = 1;
if (i==7) portbyte = 0x3F;
switch (bytea){case 0:
portbyte>>=1;
break;
case 1:
portbyte<<=1;
break;
}
}
}
//**********************************************************************
//
// One behind the other
//
//**********************************************************************
cofunc void CatchUp(void)
{bytea = 0x80;
byteb = 0x40;
for (i=0; i<8; i++){portbyte = ~(bytea | byteb);
WritePA(portbyte);
//wfd onoffdelay(ondelay, offdelay);
waitfor(DelayMs(ondelay));
waitfor(DelayMs(offdelay));
bytea >>=2;
byteb >>=1;
}
}
//**********************************************************************
//
// 8 bit up counter.
//
//**********************************************************************
cofunc void CountUp(void)
{ for (i=0; i<8; i++){WritePA(~portbyte);
//wfd onoffdelay(ondelay, offdelay);
waitfor(DelayMs(ondelay));
waitfor(DelayMs(offdelay));
portbyte++;
}
}
//**********************************************************************
//
//
//
//**********************************************************************
cofunc void ArrayPattern(void)
{
portbyte = ALLOFF;
for (i=0; i<8; i++){WritePA(~b[i]);
waitfor(DelayMs(ondelay));
waitfor(DelayMs(offdelay));
}
}
![]()
Wednesday, July 11, 2007 07:00:01 PM