User Tools

Site Tools


nsl_cylon

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

nsl_cylon [2013/08/13 12:13] (current)
Line 1: Line 1:
 +The end product of the first [[Eagle Class]]
 +
 +  * [[http://storage.032.la/NSL_Cylon.rar|NSL_Cylon Code]]
 +  * Code is also available on the [[http://wiki.032.la/nsl/NSL_SVN_Server|NSL SVN]]  -  Under "/032/NSL_Cylon/"
 +  * [[http://batchpcb.com/index.php/Products/48332|Buy the PCB at BatchPCB]]
 +
 +{{:cylon.jpg?600|thumb|center|cylon !!!}}
 +
 +[[FILE:Cx_cylon_pov.jpg|600px|thumb|center|POV!]]
 +
 +http:<nowiki>//</nowiki>farm7.static.flickr.com/6020/5988398941_9df936c29c_z.jpg
 +br
 +<html>
 +
 +<a href="http:<nowiki>//</nowiki>www.flickr.com/photos/51925658@N08/5178009310/" title="IMG_4838 by charlie _x, on Flickr"><img src="http:<nowiki>//</nowiki>farm5.static.flickr.com/4103/5178009310_5460a434d9.jpg" width="500" height="333" alt="IMG_4838" /></a>
 +</html>
 +
 +<html>
 +<object type="application/x-shockwave-flash" width="400" height="267"   data="http:<nowiki>//</nowiki>www.flickr.com/apps/video/stewart.swf?v=71377" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"> <param name="flashvars" value="intl_lang=en-us&photo_secret=f0806a2b19&photo_id=5147364504"></param> <param name="movie" value="http:<nowiki>//</nowiki>www.flickr.com/apps/video/stewart.swf?v=71377"></param> <param name="bgcolor" value="#000000"></param> <param name="allowFullScreen" value="true"></param><embed type="application/x-shockwave-flash" src="http:<nowiki>//</nowiki>www.flickr.com/apps/video/stewart.swf?v=71377" bgcolor="#000000" allowfullscreen="true" flashvars="intl_lang=en-us&photo_secret=f0806a2b19&photo_id=5147364504" height="267" width="400" ></embed></object>
 +</html>
 +
 +<code>
 + 
 +  - if 1
 +
 +/*
 +larson.c
 +The Larson Scanner 
 +
 +Written by Windell Oskay, http:<nowiki>//</nowiki>www.evilmadscientist.com/
 +
 +<code>
 + Copyright 2009 Windell H. Oskay
 + Distributed under the terms of the GNU General Public License, please see below.</code>
 + 
 + 
 +
 +<code>
 + An avr-gcc program for the Atmel ATTiny2313  
 + Version 1.3   Last Modified:  2/8/2009. 
 + Written for Evil Mad Science Larson Scanner Kit, based on the "ix" circuit board. 
 + Improvements in v 1.3:
 + * EEPROM is used to *correctly* remember last speed & brightness mode.
 + Improvements in v 1.2:
 + * Skinny "eye" mode.  Hold button at turn-on to try this mode.  To make it default,
 + solder jumper "Opt 1."  (If skinny mode is default, holding button will disable it temporarily.)
 + * EEPROM is used to remember last speed & brightness mode.</code>
 + 
 + 
 +<code>
 + More information about this project is at 
 + http://www.evilmadscientist.com/article.php/larsonkit</code>
 + 
 + 
 + 
 +<code>
 + -------------------------------------------------
 + USAGE: How to compile and install</code>
 + 
 + 
 + 
 +<code>
 + A makefile is provided to compile and install this program using AVR-GCC and avrdude.
 + To use it, follow these steps:
 + 1. Update the header of the makefile as needed to reflect the type of AVR programmer that you use.
 + 2. Open a terminal window and move into the directory with this file and the makefile.  
 + 3. At the terminal enter
 + make clean   <return>
 + make all     <return>
 + make install <return>
 + 4. Make sure that avrdude does not report any errors.  If all goes well, the last few lines output by avrdude
 + should look something like this:
 + avrdude: verifying ...
 + avrdude: XXXX bytes of flash verified
 + avrdude: safemode: lfuse reads as 62
 + avrdude: safemode: hfuse reads as DF
 + avrdude: safemode: efuse reads as FF
 + avrdude: safemode: Fuses OK
 + avrdude done.  Thank you.</code>
 + 
 + 
 +<code>
 + If you a different programming environment, make sure that you copy over the fuse settings from the makefile.</code>
 + 
 + 
 +<code>
 + -------------------------------------------------
 + This code should be relatively straightforward, so not much documentation is provided.  If you'd like to ask 
 + questions, suggest improvements, or report success, please use the evilmadscientist forum:
 + http://www.evilmadscientist.com/forum/</code>
 + 
 + 
 +<code>
 + -------------------------------------------------</code>
 + 
 +  
 +  * /
 +
 +  - include <avr/io.h> 
 +  - include <avr/eeprom.h> 
 +  - include <avr/interrupt.h>
 +  - include <avr/pgmspace.h>
 +  - include <util/delay.h>
 +
 +  - define shortdelay(); \t\t\tasm("nop\
 +\\t" \\
 +"nop\
 +\\t");
 +
 +  - define TIMER1_PRESCALE_1 \t\t(1)
 +  - define TIMER1_PRESCALE_8 \t\t(2)
 +  - define TIMER1_PRESCALE_64 \t\t(3)
 +  - define TIMER1_PRESCALE_256\t\t(4)
 +  - define TIMER1_PRESCALE_1024\t(5)
 +
 +uint16_t eepromWord __attribute__((section(".eeprom")));
 +
 +int main (void)
 +{
 +\tuint8_t LEDs[[9]]; // Storage for current LED values
 +\t
 +\tint8_t eyeLoc[[5]]; // List of which LED has each role, leading edge through tail.
 +
 +\tuint8_t LEDBright[[4]] = {1u,4u,2u,1u};   // Relative brightness of scanning eye positions
 +\t
 +
 +
 +\tint8_t j, m;
 +\t
 +\tuint8_t position, loopcount, direction;
 +\tuint8_t ILED, RLED, MLED;
 +
 +\tuint8_t delaytime;
 +\t
 +\tuint8_t skinnyEye = 0;
 +\tuint8_t  pt, debounce, speedLevel;
 +\tuint8_t \tUpdateConfig;
 +\tuint8_t BrightMode;
 +\tuint8_t debounce2, modeswitched;
 +\t
 +\tuint8_t CycleCountLow;  
 +\tuint8_t LED0, LED1, LED2, LED3, LED4, LED5, LED6, LED7, LED8;
 +\t
 +\t//Initialization routine: Clear watchdog timer-- this can prevent several things from going wrong.\t\t
 +\tMCUSR &= 0xF7;\t\t//Clear WDRF Flag
 +\tWDTCSR\t= 0x18;\t\t//Set stupid bits so we can clear timer...
 +\tWDTCSR\t= 0x00;
 +
 +\t//Data direction register: DDR's
 +\t//Port A: 0, 1 are inputs.\t
 +\t//Port B: 0-3 are outputs, B4 is an input.
 +\t//Port D: 1-6 are outputs, D0 is an input.
 +\t
 +\tDDRA = 0U;
 +\tDDRB = 15U;\t
 +\tDDRD = 126U;
 +\t
 +\tPORTA = 3;\t// Pull-up resistors enabled, PA0, PA1
 +\tPORTB = 16;\t// Pull-up resistor enabled, PA
 +\tPORTD = 0;
 +\t\t
 +<code>
 +  TCCR1B = (1 << WGM12) | TIMER1_PRESCALE_1;
 +  OCR1A = (uint16_t)800;
 +  TIMSK |= 1 << OCIE1A;   // Output Compare Interrupt Enable (timer 1, OCR1A) </code>
 +
 +\t/* Visualize outputs:
 + 
 +\t L to R:
 + 
 +\t D2 D3 D4 D5 D6 B0 B1 B2 B3\t
 +  
 +\t*/
 +\t
 +\t//multiplexed = LowPower;\t
 + 
 +\tdebounce = 0; 
 +\tdebounce2 = 0;
 +\tloopcount = 254; 
 +\tdelaytime = 0;
 +\t
 +\tdirection = 0;
 +\tposition = 0;
 +\tspeedLevel = 0;  // Range: 1, 2, 3
 +\tBrightMode = 0;
 +\tCycleCountLow = 0;
 +\tUpdateConfig = 0;
 +\tmodeswitched = 0;
 +\t
 +\t
 +\tif ((PINA & 2) == 0)\t\t// Check if Jumper 1, at location PA1 is shorted
 +\t{  
 +\t\t// Optional place to do something.  :)
 +\t}
 +\t
 +\t
 +\t
 +\tif ((PINA & 1) == 0)\t\t// Check if Jumper 2, at location PA0 is shorted
 +\t{    
 +\t\tskinnyEye = 1; 
 +\t}\t
 +\t
 +\t
 +\tif ((PINB & 16) == 0)\t\t// Check if button pressed pressed down at turn-on
 +\t{\t\t
 +
 +\t//Toggle Skinnymode
 +\t\tif (skinnyEye)
 +\t\t\tskinnyEye = 0; 
 +\t\telse 
 +\t\t\tskinnyEye = 1;
 +\t}
 +\t
 +\t
 +\t
 +\tif (skinnyEye){
 +\t\tLEDBright[[0]] = 0;
 +\t\tLEDBright[[1]] = 4;\t
 +\t\tLEDBright[[2]] = 1;
 +\t\tLEDBright[[3]] = 0;  
 +\t}
 +\t
 +\t
 +\t//Check EEPROM values:
 +\t
 +\tpt = (uint8_t) (eeprom_read_word(&eepromWord)) ;
 +\tspeedLevel = pt >> 4;
 +\tBrightMode = pt & 1;
 +
 +\tif (pt == 0xFF)
 +\t{
 +\t\tBrightMode = 0;
 +\t}
 +\t
 +\t
 +\tif (speedLevel > 3)
 +\t\tspeedLevel = 1; 
 +\t
 +\tspeedLevel = 0;
 +
 +\tif ((speedLevel == 2) || (speedLevel == 3)) { 
 +\t\tdelaytime = 0;
 +\t} 
 +\telse 
 +\t{   speedlevel = 1; 
 +\t\tdelaytime = 1;
 +\t}\t
 +\t
 +\t 
 +\t
 +for (;;)  <nowiki>//</nowiki> main loop
 +{
 +
 +
 +\tloopcount++;
 +\t
 +\tif (loopcount > delaytime)
 +\t{
 +\t\tloopcount = 0;
 +\t\t
 +\t\tCycleCountLow++;
 +\t\tif (CycleCountLow > 250)  
 +\t\t\tCycleCountLow = 0;
 +\t\t
 +\t\t
 +\t\tif (UpdateConfig){\t\t// need to save configuration byte to eeprom 
 +\t\t\tif (CycleCountLow > 100) // Avoid burning EEPROM in event of flaky power connection resets
 +\t\t\t{
 +\t\t\t\t
 +\t\t\t\tUpdateConfig = 0;
 +\t\t\t\tpt = (speedLevel << 4) | (BrightMode & 1); 
 +\t\t\t\teeprom_write_word(&eepromWord, (uint8_t) pt);\t
 +\t\t\t\t// Note: this function causes a momentary brightness glitch while it writes the EEPROM.
 +\t\t\t\t// We separate out this section to minimize the effect. 
 +\t\t\t}
 +\t\t\t
 +\t\t}\t
 +
 +\t\t
 +\t\t
 +\tif ((PINB & 16) == 0)\t\t// Check for button press
 +\t{
 +\t\tdebounce2++;
 +\t\t
 +\t\tif (debounce2 > 100)  
 +\t\t{   
 +\t\t\tif (modeswitched == 0)
 +\t\t\t{  
 +\t\t\t\tdebounce2 = 0;
 +\t\t\t\tUpdateConfig = 1;
 +
 +\t\t\t\tswitch( BrightMode ) {
 +\t\t\t\t
 +\t\t\t\t\t\tcase 0:
 +\t\t\t\t\t\t\tBrightMode++;
 +\t\t\t\t\t\tcase 1: 
 +\t\t\t\t\t\t\tBrightMode++;
 +\t\t\t\t\t\t\tbreak;
 +\t\t\t\t\t\tcase 2:
 +\t\t\t\t\t\t// off
 +\t\t\t\t\t\t\t// switch on POV
 +\t\t\t\t\t\t\t// wrap
 +\t\t\t\t\t\t\tBrightMode++;
 +\t\t\t\t\t\t\tbreak;
 +
 +\t\t\t\t\t\tcase 3:
 +\t\t\t\t\t\t\t//sei();                 // Set Enable Interrupts
 +\t\t\t\t\t\t\t// runs POV
 +\t\t\t\t\t\t\tBrightMode++;
 +\t\t\t\t\t\t\tbreak;
 +
 +\t\t\t\t\t\tcase 4:
 +\t\t\t\t\t\t\tsei();                 // Set Enable Interrupts
 +\t\t\t\t\t\t\tBrightMode++;
 +\t\t\t\t\t\t\t// runs POV
 +\t\t\t\t\t\t\tbreak;
 +\t\t\t\t\t\tcase 5:
 +\t\t\t\t\t\t\tcli();                 // Set Enable Interrupts
 +\t\t\t\t\t\t\t// runs POV
 +\t\t\t\t\t\t\tBrightMode =  0 ;
 +\t\t\t\t\t\t\tbreak;
 +\t\t\t\t\t\t\t\t
 +\t\t\t\t\t\tdefault:
 +\t\t\t\t\t\t\t// interrupts off and wrap
 +\t\t\t\t\t\t\tBrightMode= 0;
 +\t\t\t\t\t\t\tbreak;
 +\t\t\t\t}
 +\t\t\t\t\t\t\t
 +\t\t\t\tmodeswitched = 1;
 +\t\t\t}
 +\t\t}
 +\t\telse {
 +\t\t\tdebounce = 1;\t\t// Flag that the button WAS pressed.
 +\t\t\tdebounce2++;\t
 +\t\t}
 + 
 +\t}\t
 +\telse{ 
 +\t\t
 +\t\tdebounce2 = 0;
 +\t\tmodeswitched = 0;
 +\t
 +\t\tif (debounce)
 +\t\t{ debounce = 0;
 +\t\t\tspeedLevel++;
 +\t\t\tUpdateConfig = 1;
 +\t\t\t
 +\t\t\tif ((speedLevel == 2) || (speedLevel == 3)) { 
 +\t\t\t\tdelaytime = 0;
 +\t\t\t} 
 +\t\t\telse 
 +\t\t\t{   speedlevel = 1; 
 +\t\t\t\tdelaytime = 1;
 +\t\t\t}
 +\t\t\t
 +\t\t\tdebounce = 0;
 +\t\t}
 +\t\t
 +\t\t\t}
 +\t    
 +\t\tposition++;
 +\t\t
 +\t\tif (speedLevel == 3)
 +\t\t\tposition++;
 +\t\t
 +\t if (position >= 128)\t//was  == 128
 +\t {
 +\t\t position = 0;
 +\t\t 
 +\t  if (direction == 0)
 +\t\t  direction = 1;
 +\t  else
 +\t\t  direction = 0; 
 +\t }
 +\t
 +\t\t \t\t
 +\tif (direction == 0)  // Moving to right, as viewed from front.
 +\t{   
 +\t\tILED = (15+position) >> 4; 
 +\t\tRLED = (15+position) - (ILED << 4);
 +\t\tMLED = 15 - RLED; \t\t
 +\t\t}
 +<code>
 +   else </code>
 +\t{   
 +\t\tILED = (127 - position) >> 4;  
 +\t\tMLED = (127 - position)  - (ILED << 4);
 +\t\tRLED =  15 - MLED;\t
 +\t}
 +\t\t 
 +\t\tj = 0;
 +\t\twhile (j < 9) {
 +\t\t\tLEDs[[j]] = 0; 
 +\t\t\tj++;
 +\t\t}  
 +\t\t 
 +\t\tj = 0;
 +\t\twhile (j < 5) {
 +\t\t\t
 +\t\t\tif (direction == 0) 
 +\t\t\t   m = ILED + (2 - j);\t// e.g., eyeLoc[[0]] = ILED + 2; 
 +\t\t\telse
 +\t\t\t   m = ILED + (j - 2);  // e.g., eyeLoc[[0]] = ILED - 2;
 +\t\t\t
 +\t\t\tif (m > 8)
 +\t\t\t\tm -= (2 * (m - 8));
 +\t\t\t
 +\t\t\tif (m < 0)
 +\t\t\t\tm *= -1;
 +\t\t\t
 +\t\t\teyeLoc[[j]] = m;
 +\t\t\t
 +\t\t\tj++;
 +\t\t} 
 +\t\t  
 +\t\tj = 0;\t\t// For each of the eye parts...
 +\t\twhile (j < 4) {
 +\t\t\t
 +\t\t\tLEDs[eyeLoc[j]]   += LEDBright[[j]]*RLED;\t\t\t
 +\t\t\tLEDs[eyeLoc[j+1]] += LEDBright[[j]]*MLED;\t\t\t
 +\t\t\t 
 +\t\t\tj++;
 +\t\t}  
 +\t
 +\t LED0 = LEDs[[0]];
 +<code>
 +     LED1 = LEDs[[1]];</code>
 +\t LED2 = LEDs[[2]];
 +\t LED3 = LEDs[[3]];
 +\t LED4 = LEDs[[4]];
 +\t LED5 = LEDs[[5]];
 +\t LED6 = LEDs[[6]];
 +\t LED7 = LEDs[[7]];
 +\t LED8 = LEDs[[8]];  
 +
 +\t}
 +
 +\tif ( BrightMode > 3 ) { 
 +\t\tcontinue;
 +\t}
 +\t 
 +\tif (BrightMode == 0)
 +\t{\t\t//multiplexing routine: each led is on (1/9) of the time. 
 +\t\t\t//  -> Use much less power.
 +\t\tj = 0;
 +\t\twhile (j < 60)\t\t// Truncate brightness at a max value (60) in the interest of speed.
 +\t\t{
 +\t\t  
 +\tif (LED0 > j) 
 +\t\tPORTD = 4; 
 +\t\t\telse\t
 +\t\t\tPORTD = 0;  
 +\t\t\t
 +\tif (LED1 > j) 
 +\t\tPORTD = 8;\t
 +\telse\t
 +\t\tPORTD = 0;\t 
 +\t\t\t
 +\tif (LED2 > j) 
 +\t\tPORTD = 16; 
 +\telse\t
 +\t\tPORTD = 0; 
 +\t\t\t
 +\tif (LED3 > j) 
 +\t\tPORTD = 32;\t
 +\telse\t
 +\t\tPORTD = 0;
 +\t\t\t
 +\tif (LED4 > j) 
 +\t\tPORTD = 64;
 +\telse\t
 +\t\tPORTD = 0;
 +\t\t  
 +\tif (LED5 > j) {
 +\t\tPORTB = 17;\t 
 +\t\tPORTD = 0;}
 +\t\t\telse\t{
 +\t\tPORTB = 16;
 +\tPORTD = 0;\t\t}
 +\t\t\t
 +\tif (LED6 > j) 
 +\t\tPORTB = 18;\t
 +\telse\t
 +\t\tPORTB = 16;
 +\t\t\t
 +\tif (LED7 > j) 
 +\t\tPORTB = 20;\t
 +\telse\t
 +\t\tPORTB = 16;
 +\t\t\t
 +\tif (LED8 > j) 
 +\t\tPORTB = 24;\t
 +\telse\t
 +\t\tPORTB = 16; 
 +\t\t 
 +\t\tj++;
 +<nowiki>//</nowiki>\t\tif (speedLevel == 3)
 +<nowiki>//</nowiki>\t\t\tj++;
 +\t\t PORTB = 16; 
 +\t} 
 +\t 
 +\t} 
 +\t else 
 +\t {\t\t// full power routine
 +\t\t 
 +\t  j = 0;
 +\t  while (j < 70)
 +\t  {
 +\t  
 +\t  pt = 0;\t
 +\t  if (LED0 > j) 
 +\t  pt = 4; 
 +\t  if (LED1 > j) 
 +\t  pt |= 8;\t
 +\t  if (LED2 > j) 
 +\t  pt |= 16; 
 +\t  if (LED3 > j) 
 +\t  pt |= 32;\t\t 
 +\t  if (LED4 > j) 
 +\t  pt |= 64;
 +\t  
 +\t  PORTD = pt;
 +\t  shortdelay(); 
 +\t  pt = 16;\t
 +\t  if (LED5 > j) 
 +\t  pt |= 1;\t
 +\t  if (LED6 > j) 
 +\t  pt |= 2;\t
 +\t  if (LED7 > j) 
 +\t  pt |= 4;\t
 +\t  if (LED8 > j) 
 +\t  pt |= 8;\t\t\t
 +\t  
 +\t  PORTB = pt;
 +\t  shortdelay(); 
 +\t\t  
 +\t  j++;
 +<nowiki>//</nowiki>\t  if (speedLevel == 3)
 +<nowiki>//</nowiki>\t  j++;
 +\t  }
 +\t\t   
 +\t }
 +\t
 +\t 
 +<nowiki>//</nowiki>Multiplexing routine: Each LED is on (1/9) of the time. 
 +<nowiki>//</nowiki>  -> Uses much less power.
 +   
 +\t}\t//End main loop
 +\treturn 0;
 +}
 +
 +
 +
 +  - define IS_BIT(a,p)    (a&(1<<p))    <nowiki>//</nowiki> test the a variable p bit
 +  - define SET_BIT(a,p) a |=  (1<<p)    <nowiki>//</nowiki> set in a the p bit
 +  - define CLR_BIT(a,p) a &= ~(1<<p)    <nowiki>//</nowiki> clear in a the p bit
 +
 +
 +  - define LED0 \t\t( 4 )//1
 +  - define LED1 \t\t( 3 )//2
 +  - define LED2 \t\t( 2 )//3
 +  - define LED3 \t\t( 1  )//4
 +  - define LED4 \t\t( 0 )//5
 +
 +<nowiki>//</nowiki> byte two
 +  - define LED5 \t\t( 3 )
 +  - define LED6 \t\t( 2 )
 +  - define LED7 \t\t( 1 )
 +  - define LED8 \t\t( 0 )
 +
 +void delay_ms( uint16_t milliseconds)
 +{
 +<code>
 +   for( ; milliseconds > 0; milliseconds--)
 +   {
 +      _delay_ms( 1);
 +   }</code>
 +
 +
 +
 +
 +<nowiki>//</nowiki> NSL Cylon
 +  - define B9__(x) ((x&0x0000000FLU)?LED0:0) \\
 +<code>
 +               +((x&0x000000F0LU)?LED1:0) \\
 +               +((x&0x00000F00LU)?LED2:0) \\
 +               +((x&0x0000F000LU)?LED3:0) \\
 +               +((x&0x000F0000LU)?LED4:0) \\
 +               +((x&0x00F00000LU)?LED5:0) \\
 +               +((x&0x0F000000LU)?LED6:0) \\
 +               +((x&0xF0000000LU)?LED7:0) \\
 +              +((x&0xF00000000LU)?LED8:0) </code>
 +
 +  - define _B9(d) ((uint16_t)B9__(HEX__(d)))
 +
 +  - define B9(d) 0b##d
 +
 +
 +const static uint16_t large_image[[]] PROGMEM  ======
 +
 +
 +  - if 1
 +
 +\tB9(000000000), 
 +\tB9(111111111), 
 +\tB9(100000001), 
 +\tB9(100000001), 
 +\tB9(000000000), 
 +\tB9(100000000), 
 +\tB9(100000000), 
 +\tB9(100000000), 
 +\tB9(111111111), 
 +\tB9(000000000), 
 +\tB9(111110001), 
 +\tB9(100010001), 
 +\tB9(100010001), 
 +\tB9(100011111), 
 +\tB9(000000000), 
 +\tB9(111111111), 
 +\tB9(001000000), 
 +\tB9(000111000), 
 +\tB9(000000100), 
 +\tB9(000000010), 
 +\tB9(111111111), 
 +\tB9(000000000), 
 +\tB9(100000001), 
 +\tB9(100000001), 
 +\tB9(111111111), 
 +\tB9(000000000), 
 +\tB9(000000000), 
 +\tB9(000000000), 
 +
 +
 +<nowiki>//</nowiki> nullspace (backwards)
 +
 +\tB9(100010001), 
 +\tB9(100010001), 
 +\tB9(100010001), 
 +\tB9(111111111), 
 +\tB9(000000000), 
 +\tB9(100000001), 
 +\tB9(100000001), 
 +\tB9(111111111), 
 +\tB9(000000000), 
 +\tB9(111111111), 
 +\tB9(000010001), 
 +
 +
 +\tB9(000010001), 
 +\tB9(111111111), 
 +\tB9(000000000), 
 +\tB9(000011111), 
 +\tB9(000010001), 
 +\tB9(000010001), 
 +\tB9(111111111), 
 +\tB9(000000000), 
 +\tB9(111110001), 
 +\tB9(100010001), 
 +\tB9(100010001), 
 +\tB9(100011111), 
 +\tB9(000000000), 
 +\tB9(100000000), 
 +\tB9(100000000), 
 +\tB9(111111111), 
 +\tB9(000000000), 
 +\tB9(100000000), 
 +\tB9(100000000), 
 +\tB9(111111111), 
 +\tB9(000000000), 
 +\tB9(111111111), 
 +\tB9(100000000), 
 +\tB9(100000000), 
 +\tB9(111111111), 
 +\tB9(000000000), 
 +\tB9(111111111), 
 +\tB9(010000000), 
 +\tB9(001110000), 
 +\tB9(000001100), 
 +\tB9(000000010), 
 +\tB9(111111111), 
 +
 +<nowiki>//</nowiki>\t0,0,0,0,
 +
 +  - else
 +
 +<nowiki>//</nowiki> flickr
 +B9(010101010), B9(000000000), 
 +B9(010101010), B9(000000000), B9(010101010), B9(101010101), B9(101010101), B9(101010101), B9(101010101), 
 +B9(101010101), B9(010101010), B9(010101010), B9(010101010), B9(010101010), B9(010101010), B9(101010101), B9(101010101), 
 +B9(101010101), B9(101010101), B9(101010101), 
 +
 +<nowiki>//</nowiki>
 +<code>
 + B9(000000000), 
 + B9(000000000), 
 + B9(101010101), B9(100000001), 
 + B9(100000001), B9(000000000), B9(000000000), B9(100000000), B9(100000000), B9(100000000), B9(101010101), B9(000000000), B9(000000000), B9(101010001), B9(100010001), B9(100010001), B9(100010101), B9(000000000), B9(000000000), B9(101010101), B9(000000000), B9(001000000), B9(000010000), B9(000000100), B9(000000000), B9(101010101), B9(000000000), B9(000000000), B9(100000001), B9(100000001), B9(101010101), 
 + B9(000000000), 
 + B9(000000000),
 + B9(000000000), B9(000000000), B9(000000000), B9(000000000), B9(000101010), B9(000100010), B9(000100010), B9(000100010), 
 + B9(010101010), B9(000000000), B9(000000000), B9(000000010), B9(000100010), B9(000100010), B9(000100010), B9(010101010), B9(000000000), B9(000000000), B9(010101010), B9(000000000), B9(000001000), B9(000000000), B9(000100000), B9(000000000), B9(000001000), B9(000000000), B9(010101010), </code>
 +  - endif
 +  
 +\t0,0,0,0,
 +\t65535
 +};
 +
 +
 +<nowiki>//</nowiki> special pointer for reading from ROM memory
 +PGM_P largeimage_p PROGMEM = (PGM_P)large_image;
 +
 +  - define NUM_ELEM(x) (sizeof (x) / sizeof (*(x)))
 +
 +<nowiki>//</nowiki> this function is called when timer1 compare matches OCR1A
 +
 +SIGNAL( SIG_TIMER1_COMPA ) {
 +
 +\tstatic uint8_t j = 0;
 +\tuint8_t tmpout;
 +
 +\tuint16_t tmp=0;
 +
 +<nowiki>//</nowiki>reset counter
 +\tif (pgm_read_word(largeimage_p + j ) == 65535 ) {
 +\t\tj = 0;
 +\t}
 +
 +\ttmp = pgm_read_word(largeimage_p + j);
 +
 +\ttmpout = 0;
 +
 +\tif( IS_BIT(tmp,0) ) SET_BIT(tmpout, LED0 ); 
 +\tif( IS_BIT(tmp,1) ) SET_BIT(tmpout, LED1 ); 
 +\tif( IS_BIT(tmp,2) ) SET_BIT(tmpout, LED2 ); 
 +\tif( IS_BIT(tmp,3) ) SET_BIT(tmpout, LED3 ); 
 +
 +\tPORTB =  (  tmpout  ) >>1;
 +
 +\ttmpout = 0;
 +
 +\tif( IS_BIT(tmp,4) ) SET_BIT(tmpout, LED0 ); 
 +\tif( IS_BIT(tmp,5) ) SET_BIT(tmpout, LED5 ); 
 +\tif( IS_BIT(tmp,6) ) SET_BIT(tmpout, LED6 ); 
 +\tif( IS_BIT(tmp,7) ) SET_BIT(tmpout, LED7 ); 
 +\tif( IS_BIT(tmp,8) ) SET_BIT(tmpout, LED8 ); 
 +
 +\tPORTD =  tmpout<<2; 
 +
 +<nowiki>//</nowiki> word
 +\tj+=2;
 +}
 +
 +  - else
 +/*
 +larsonextend.c
 +The Larson Scanner -- Alternative version to allow scanner to run off the edge of the board.
 + 
 +<code>
 + It simulates one LED at brightness 4, followed by one LED of brightness 1, that moves across
 + the nine pixels, disappearing off either end of the board, before returning to scan in the other direction.
 + There is no longer any overlap of these "LEDs" at either end, but up to three LEDs may be lit at a time as
 + the head fades in and the tail fades out.
 + Also, some of the input and output values and pull-up resistors have been changed from the original program 
 + in anticipation of future extensibility.
 + With the buttons linked between the units, it seems to be flakey, at best, to get an accurate button press
 + on multiple units at the same time, so that section is commented out below.  Change the speed in the variable
 + declarations as you see fit.  Also, since this program was originally written for a specific application
 + (a permanent installation in an enclosure), the unit was never really intended to change speeds.  I tried to
 + get it to work like the original, but couldn't.  Sorry, guys.</code>
 +
 +Original written by Windell Oskay, http:<nowiki>//</nowiki>www.evilmadscientist.com/
 +New alternative version written by John Breen III
 + 
 +<code>
 + Copyright 2009 Windell H. Oskay, 2010 John J. Breen III
 + Distributed under the terms of the GNU General Public License, please see below.</code>
 + 
 + 
 +
 +<code>
 + An avr-gcc program for the Atmel ATTiny2313  
 + Based on Version 1.1_alt1, written by Windell Oskay
 + Version 1.1   Last Modified:  26-Sep-2010. 
 + Written for Evil Mad Science Larson Scanner Kit, based on the "ix" circuit board. </code>
 + 
 + 
 +<code>
 + More information about this project is at 
 + http://www.evilmadscientist.com/article.php/larsonkit</code>
 + 
 + 
 + 
 +<code>
 + -------------------------------------------------
 + USAGE: How to compile and install</code>
 + 
 + 
 + 
 +<code>
 + A makefile is provided to compile and install this program using AVR-GCC and avrdude.
 + To use it, follow these steps:
 + 1. Update the header of the makefile as needed to reflect the type of AVR programmer that you use.
 + 2. Open a terminal window and move into the directory with this file and the makefile.  
 + 3. At the terminal enter
 + make clean   <return>
 + make all     <return>
 + make install <return>
 + 4. Make sure that avrdude does not report any errors.  If all goes well, the last few lines output by avrdude
 + should look something like this:
 + avrdude: verifying ...
 + avrdude: XXXX bytes of flash verified
 + avrdude: safemode: lfuse reads as 62
 + avrdude: safemode: hfuse reads as DF
 + avrdude: safemode: efuse reads as FF
 + avrdude: safemode: Fuses OK
 + avrdude done.  Thank you.</code>
 + 
 + 
 +<code>
 + If you a different programming environment, make sure that you copy over the fuse settings from the makefile.</code>
 + 
 + 
 +<code>
 + -------------------------------------------------
 + This code should be relatively straightforward, so not much documentation is provided.  If you'd like to ask 
 + questions, suggest improvements, or report success, please use the evilmadscientist forum:
 + http://www.evilmadscientist.com/forum/</code>
 + 
 + 
 +<code>
 + -------------------------------------------------</code>
 + 
 +  
 +  * /
 +
 +  - include <avr/io.h> 
 +
 +  - define shortdelay(); \t\t\tasm("nop\
 +\\t" \\
 +"nop\
 +\\t");
 +
 +  
 +int main (void)
 +{
 +uint8_t LEDs[[9]]; // Storage for current LED values
 +uint8_t rightLED[[6]], leftLED[[6]]; // Storage for initialization visualization LEDs
 +\t
 +int8_t eyeLoc[[5]]; // List of which LED has each role, leading edge through tail.
 +
 +uint8_t LEDBright[[4]] = {4u,2u,1u,1u};   // Relative brightness of scanning eye positions, head through tail
 +
 +void delay_ms(uint8_t ms) {
 +
 +return 0;
 +
 +<code>
 +   uint16_t delay_count = 100;
 +   volatile uint16_t i;
 +   while (ms != 0) 
 +   {
 +     for (i=0; i != delay_count; i++);
 +     ms--;
 +   }
 + }</code>
 +\t
 +int8_t j, k, m;
 +\t
 +uint8_t position, loopcount, direction, initloopcount, already_running, softbounce;
 +uint8_t runitout, d_base, a_base, d_mod, a_mod, far_left, far_right;
 +uint8_t ILED, RLED, MLED;\t// Eye position variables: Integer, Modulo, remainder
 +
 +uint8_t delaytime;
 +
 +uint8_t  pt, debounce, speedLevel;
 +unsigned int debounce2, BrightMode;
 +\t 
 +uint8_t LED0, LED1, LED2, LED3, LED4, LED5, LED6, LED7, LED8;
 +\t
 +<nowiki>//</nowiki>Initialization routine: Clear watchdog timer-- this can prevent several things from going wrong.\t\t
 +MCUSR &= 0xF7;\t\t//Clear WDRF Flag
 +WDTCSR\t= 0x18;\t\t//Set stupid bits so we can clear timer...
 +WDTCSR\t= 0x00;
 +
 +<nowiki>//</nowiki>Data direction register: DDR's
 +<nowiki>//</nowiki>Port A: 1 is an output, A0 is an input.\t
 +<nowiki>//</nowiki>Port B: 0-3 are outputs, B4 is an input.\t
 +<nowiki>//</nowiki>Port D: 1-6 are outputs, D0 is an input.
 +\t
 +\tDDRA = 2U;
 +\tDDRB = 15U;\t
 +\tDDRD = 126U;
 +\t
 +\ta_base = 3; // set a base value (resting value) for PA, to keep things easy to modify
 +\td_base = 3; // set a base value (resting value) for PD, to keep things easy to modify
 +\t
 +\tPORTA = a_base;\t// Pull-up resistor enabled, PA0, Port A1 High 
 +\tPORTB = 16;\t// Pull-up resistor enabled, PB4
 +\tPORTD = d_base;  // Pull-up resistor enabled, PD0, Port D1 High
 +\t
 +\td_mod = 0;
 +\ta_mod = 0;
 +\t
 +/* Visualize outputs:
 + 
 +<code>
 + L to R:
 + D2 D3 D4 D5 D6 B0 B1 B2 B3\t
 + <-- A1 (out to left)</code>
 + 
 +\t  (out to right) D1 -->
 +  
 +  * /
 +
 +<nowiki>//</nowiki> Clear out all of the LED values to blank out the display
 +
 +\tj = 0;
 +\twhile (j < 9) {
 +\t\tLEDs[[j]] = 0; 
 +\t\tj++;
 +\t} 
 +
 +\t LED0 = LEDs[[0]];
 +<code>
 +     LED1 = LEDs[[1]];</code>
 +\t LED2 = LEDs[[2]];
 +\t LED3 = LEDs[[3]];
 +\t LED4 = LEDs[[4]];
 +\t LED5 = LEDs[[5]];
 +\t LED6 = LEDs[[6]];
 +\t LED7 = LEDs[[7]];
 +\t LED8 = LEDs[[8]]; 
 +\t
 +<nowiki>//</nowiki>multiplexed = LowPower;\t
 + 
 +\tdebounce = 1; 
 +\tdebounce2 = 1;
 +\tloopcount = 254;
 +\tinitloopcount = 5; 
 +\tdelaytime = 0;
 +\t
 +\tdirection = 0;
 +\tposition = 0;
 +\trunitout = 0;
 +\talready_running = 0;
 +\tsoftbounce = 0;
 +\tfar_left = 0;
 +\tfar_right = 0;
 +\tspeedLevel = 3;  // Range: 1, 2, 3
 +\tBrightMode = 0;
 +
 +if ((PINB & 16) == 0)\t\t// Check if button held on startup; used to verify wiring configuration
 +\t{ initloopcount = 0; // if so, set the startup loop counter to 0 so that we can watch the startup lights
 +\t  softbounce = 1; // Also set the "soft-bounce" mode, which bounces back without leaving the edge, like the original
 +\t}\t
 +
 +delay_ms(200);
 +
 +PORTD = 1; <nowiki>//</nowiki>Pull D1 low, to trigger output on right side
 +
 +delay_ms(10); <nowiki>//</nowiki>Delay to allow output to latch
 +
 +if ((PIND & 1) == 0) <nowiki>//</nowiki>Check to see if D1 output has latched D0 input
 +\tfar_right = 1; //If D0 and D1 are connected, we're at the end of the chain; set far_right so we bounce back from this end
 +
 +PORTD = d_base; <nowiki>//</nowiki>Set D1 high
 +
 +PORTA = 1; <nowiki>//</nowiki>Pull A1 low, to trigger output on left side
 +
 +delay_ms(10); <nowiki>//</nowiki>Delay to allow output to latch
 +
 +if ((PINA & 1) == 0) <nowiki>//</nowiki>Check to see if A1 output has latched A0 input
 +\tfar_left = 1; //If A0 and A1 are connected, we're at the end of the chain; set far_left so we bounce back from this end
 +
 +PORTA = a_base; <nowiki>//</nowiki>Set A1 high
 +
 +
 +<nowiki>//</nowiki>A little bit if visual verification to the user as to which way each end of the scanner is set
 +<nowiki>//</nowiki> (flash outwards if it's open-ended to go to the next scanner in the chain, flash inwards if it's the end and will bounce back
 +
 +if (far_left) {
 +\tleftLED[[0]] = 7;
 +\tleftLED[[1]] = 11;
 +\tleftLED[[2]] = 19;
 +\tleftLED[[3]] = 19;
 +\tleftLED[[4]] = 19;
 +\tleftLED[[5]] = 19;
 +}
 +else {
 +\tleftLED[[0]] = 19;
 +\tleftLED[[1]] = 11;
 +\tleftLED[[2]] = 7;
 +\tleftLED[[3]] = 7;
 +\tleftLED[[4]] = 7;
 +\tleftLED[[5]] = 7;
 +}
 +
 +if (far_right) {
 +\trightLED[[0]] = 24;
 +\trightLED[[1]] = 20;
 +\trightLED[[2]] = 18;
 +\trightLED[[3]] = 18;
 +\trightLED[[4]] = 18;
 +\trightLED[[5]] = 18;
 +}
 +else {
 +\trightLED[[0]] = 18;
 +\trightLED[[1]] = 20;
 +\trightLED[[2]] = 24;
 +\trightLED[[3]] = 24;
 +\trightLED[[4]] = 24;
 +\trightLED[[5]] = 24;
 +}
 +
 +delay_ms(100);\t/* Allow all scanners to finish initializing before lighting any LEDs.
 +\t\t\t\t * This is necessary because the clock speeds on each chip only have a 10% tolerance, and initial
 +\t\t\t\t * testing showed that the tests to configure far_left and far_right were causing
 +\t\t\t\t * "faster" chips to get triggered by "slower" chips.
 +\t\t\t\t */
 +for (;;)  <nowiki>//</nowiki> main loop
 +{
 +\tloopcount++;
 +
 +\tif (loopcount > delaytime)
 +\t{
 +\t\tloopcount = 0;
 +\t\t
 +\tif ((PINB & 16) == 0) // Check for button press
 +\t{ 
 +\t\tif ((initloopcount >= 4) & (far_left == 1) & (already_running == 0))
 +\t\t{
 +\t\t\trunitout = 1;
 +\t\t\talready_running = 1;
 +\t\t\tdebounce = 0;  // Start running the program, but only on the left-most unit.
 +\t\t}
 +\t\t
 +/*\tThis is the section from the original program to let the button change the speeds and brightness.
 +\t\tdebounce2++;
 +\t\t
 +\t\tif (debounce2 > 100) 
 +\t\t{   debounce2 = 0;
 +\t\t\tdebounce = 0;
 +\t\t\t
 +\t\t if (BrightMode == 0) 
 +\t\t\tBrightMode = 1;
 +\t\t else
 +\t\t\tBrightMode = 0;
 +\t\t\t
 +\t\t}
 +\t\t
 +\t\tif (debounce)
 +\t\t{ 
 +\t\t\tspeedLevel++;
 +\t\t\t  
 +\t\t\tif ((speedLevel == 2) || (speedLevel == 3)) { 
 +\t\t\t\tdelaytime = 0;
 +\t\t\t} 
 +\t\t\telse 
 +\t\t\t{   speedlevel = 1; 
 +\t\t\t\tdelaytime = 1;
 +\t\t\t}
 +\t\t\t 
 +\t\tdebounce = 0;
 +\t\t}
 +\t}\t
 +\telse{ 
 +\tdebounce = 1;
 +\tdebounce2 = 1;
 +\t}
 +  * /\t
 +
 +\t}
 +\t
 +\tif ((PINA & 1) == 0)  // Check to see if display from the left has triggered to start
 +\t{
 +\t\tdirection = 0;
 +\t\trunitout = 1;
 +\t}
 +\t
 +\tif ((PIND & 1) == 0)  // Check to see if display from the right has triggered to start
 +\t{
 +\t\tdirection = 1;
 +\t\trunitout = 1;
 +\t}
 +
 +\t    
 +\tif (runitout)
 +\t{
 +\t\tposition++;
 +\t\t
 +\t\tif (speedLevel == 3)
 +\t\t\tposition++;
 +\t\t
 +\t\tif ((softbounce == 1) & (((direction == 0) & (far_right == 1)) || ((direction == 1) & (far_left == 1))) & (position >= 224))
 +\t\t{ // this allows us to "soft-bounce" off the ends, like in the original program, without running off the edge
 +\t\t\tposition = 15;
 +\t\t\tif (direction == 0)
 +\t\t\t\tdirection = 1;
 +\t\t\telse
 +\t\t\t\tdirection = 0;
 +\t\t}
 +\t\t
 +\t\tif (position >= 240)\t// To allow for runoff at the ends; was '== 128'
 +\t\t{
 +\t\t\tposition = 0;
 +\t\t 
 +\t\t\tif (direction == 0) {  
 +\t\t\t\tdirection = 1;  // we've reached the end, so go back in the other direction
 +\t\t\t\tif (far_right == 0) //  If this isn't the end of the chain, we want to stop, and wait for a signal to go again
 +\t\t\t\t\trunitout = 0;
 +\t\t\t}
 +\t\t\telse {
 +\t\t\t\tdirection = 0;
 +\t\t\t\tif (far_left == 0)  //  If this isn't the end of the chain, we want to stop, and wait for a signal to go again
 +\t\t\t\t\trunitout = 0;
 +\t\t\t}
 +\t\t}
 +\t\t \t\t
 +\tif (direction == 0)  // Moving to right, as viewed from front.
 +\t{   
 +\t\tILED = (15+position) >> 4; 
 +\t\tRLED = (15+position) - (ILED << 4);
 +\t\tMLED = 15 - RLED; \t\t
 +\t}
 +<code>
 +    else </code>
 +\t{   
 +\t\tILED = (127 - position) >> 4;  
 +\t\tMLED = (127 - position)  - (ILED << 4);
 +\t\tRLED =  15 - MLED;\t
 +\t}
 +\t
 +\tif ((ILED == 10) & (direction == 0) & (far_right == 0))
 +\t\td_mod = 2; // If we're heading to the right, and we're not at the end of the chain, we want to trigger D1 to start the next scanner
 +\t\t
 +\tj = 0;
 +\twhile (j < 9) {
 +\t\tLEDs[[j]] = 0; 
 +\t\tj++;
 +\t}  
 +\t\t 
 +\tj = 0;
 +\tif ((softbounce == 1) & (((direction == 0) & (far_right == 1)) || ((direction == 1) & (far_left == 1)))) { 
 +\t\twhile (j < 5) {
 +\t\t\t
 +\t\t\tif (direction == 0) 
 +\t\t\t   m = ILED - (j + 1);
 +\t\t\t   //m = ILED + (2 - j);\t// e.g., eyeLoc[[0]] = ILED + 2; 
 +\t\t\telse
 +\t\t\t   m = ILED + (j + 1);
 +\t\t\t   //m = ILED + (j - 2);  // e.g., eyeLoc[[0]] = ILED - 2;
 +\t\t\t
 +\t\t\tif ((direction == 0) & (m > 8))
 +\t\t\t\tm = 8;
 +\t\t\t
 +\t\t\tif ((direction == 1) & (m < 0))
 +\t\t\t\tm = 0;
 +\t\t\t
 +\t\t\teyeLoc[[j]] = m;
 +\t\t\t
 +\t\t\tj++;
 +\t\t}
 +\t}
 +\telse {
 +\t\twhile (j < 5)
 +\t\t{\t\t
 +\t\t\tif (direction == 0) 
 +\t\t\t\tm = ILED - (j + 1);\t// e.g., eyeLoc[[0]] = ILED - 1; 
 +\t\t\telse
 +\t\t\t\tm = ILED + (j + 1); // e.g., eyeLoc[[0]] = ILED + 1;
 +\t\t\t
 +\t\t\tif ((m == -1) & (direction == 1) & (far_left == 0))
 +\t\t\t\ta_mod = 2; // If we're heading to the left, and we're not at the end of the chain, we want to trigger A1 to start the next scanner
 +\t\t
 +\t\t\tif (m > 8)
 +\t\t\t\tm = -1;  // If eye position is past the end of the board, don't light it; set to -1
 +\t\t\t\t\t\t
 +\t\t\tif (m < 0)
 +\t\t\t\tm = -1;  // If eye position is past the end of the board, don't light it; set to -1
 +\t\t\t
 +\t\t\teyeLoc[[j]] = m;
 +\t\t\t
 +\t\t\tj++;
 +\t\t} 
 +\t}
 +\t\t  
 +\tj = 0;\t\t// For each of the eye parts...
 +\twhile (j < 4) 
 +\t{\t\t
 +\t\tif (eyeLoc[[j]] >= 0)
 +\t\t\tLEDs[eyeLoc[j]]   += LEDBright[[j]]*RLED;\t
 +\t\tif (eyeLoc[[j+1]] >= 0)
 +\t\t\tLEDs[eyeLoc[j+1]] += LEDBright[[j]]*MLED;
 +\t\tj++;
 +\t}  
 +\t
 +\t LED0 = LEDs[[0]];
 +<code>
 +     LED1 = LEDs[[1]];</code>
 +\t LED2 = LEDs[[2]];
 +\t LED3 = LEDs[[3]];
 +\t LED4 = LEDs[[4]];
 +\t LED5 = LEDs[[5]];
 +\t LED6 = LEDs[[6]];
 +\t LED7 = LEDs[[7]];
 +\t LED8 = LEDs[[8]];  
 +\t}
 +\telse if (initloopcount < 4 )
 +\t{
 +\t\tk = 0;
 +\t\twhile (k < 6) {
 +\t\t\tPORTD = leftLED[[k]];
 +\t\t\tPORTB = rightLED[[k]];
 +\t\t\tdelay_ms(1);
 +\t\t
 +\t\t\tPORTD = d_base;
 +\t\t\tPORTB = 16;
 +\t\t\tdelay_ms(29);
 +
 +\t\t\tk++;
 +\t\t}
 +\t\tdelay_ms(100);
 +\t\tinitloopcount++;
 +\t}
 +\t}
 +\tif (runitout) {
 +\tif (BrightMode == 0)
 +\t{\t\t//multiplexing routine: each led is on (1/9) of the time. 
 +\t\t\t//  -> Use much less power.
 +\t\tj = 0;
 +\t\tPORTA = a_base - a_mod; // we set a_mod to correspond to A1's bit in PORTA; this makes it easier to change the pin configs later
 +\t\twhile (j < 60)\t\t// Truncate brightness at a max value (60) in the interest of speed.
 +\t\t{
 +\t\t  
 +\tif (LED0 > j) 
 +\t\tPORTD = 7 - d_mod;  // we set d_mod to correspond to D1's bit in PORTD; this makes it easier to change the trigger pin configs later
 +\telse\t
 +\t\tPORTD = d_base - d_mod;  
 +\t\t\t
 +\tif (LED1 > j) 
 +\t\tPORTD = 11 - d_mod;\t
 +\telse\t
 +\t\tPORTD = d_base - d_mod;\t 
 +\t\t\t
 +\tif (LED2 > j) 
 +\t\tPORTD = 19 - d_mod; 
 +\telse\t
 +\t\tPORTD = d_base - d_mod; 
 +\t\t\t
 +\tif (LED3 > j) 
 +\t\tPORTD = 35 - d_mod;\t
 +\telse\t
 +\t\tPORTD = d_base - d_mod;
 +\t\t\t
 +\tif (LED4 > j) 
 +\t\tPORTD = 67 - d_mod;
 +\telse\t
 +\t\tPORTD = d_base - d_mod;
 +\t\t  
 +\tif (LED5 > j) {
 +\t\tPORTB = 17;\t 
 +\t\tPORTD = d_base - d_mod;}
 +\telse\t{
 +\t\tPORTB = 16;
 +\t\tPORTD = d_base - d_mod;}
 +\t\t\t
 +\tif (LED6 > j) 
 +\t\tPORTB = 18;\t
 +\telse\t
 +\t\tPORTB = 16;
 +\t\t\t
 +\tif (LED7 > j) 
 +\t\tPORTB = 20;\t
 +\telse\t
 +\t\tPORTB = 16;
 +\t\t\t
 +\tif (LED8 > j) 
 +\t\tPORTB = 24;\t
 +\telse\t
 +\t\tPORTB = 16; 
 +\t\t 
 +\t\tj++;
 +<nowiki>//</nowiki>\t\tif (speedLevel == 3)
 +<nowiki>//</nowiki>\t\t\tj++;
 +\t\t PORTB = 16; 
 +\t} 
 +\t 
 +\td_mod = 0;
 +\ta_mod = 0;
 +\t} 
 +\t else 
 +\t {\t\t// full power routine
 +\t 
 +\t  PORTA = a_base - a_mod;
 +
 +\t  j = 0;
 +\t  while (j < 70)
 +\t  {
 +\t  
 +\t  
 +\t  pt = d_base - d_mod;\t
 +\t  if (LED0 > j) 
 +\t  pt |= 4; 
 +\t  if (LED1 > j) 
 +\t  pt |= 8;\t
 +\t  if (LED2 > j) 
 +\t  pt |= 16; 
 +\t  if (LED3 > j) 
 +\t  pt |= 32;\t\t 
 +\t  if (LED4 > j) 
 +\t  pt |= 64;
 +\t  
 +\t  PORTD = pt;
 +\t  shortdelay(); 
 +\t  pt = 16;\t
 +\t  if (LED5 > j) 
 +\t  pt |= 1;\t
 +\t  if (LED6 > j) 
 +\t  pt |= 2;\t
 +\t  if (LED7 > j) 
 +\t  pt |= 4;\t
 +\t  if (LED8 > j) 
 +\t  pt |= 8;\t\t\t
 +\t  
 +\t  PORTB = pt;
 +\t  shortdelay(); 
 +\t\t  
 +\t  j++;
 +<nowiki>//</nowiki>\t  if (speedLevel == 3)
 +<nowiki>//</nowiki>\t  j++;
 +\t  }
 +\t
 +\t d_mod = 0; // we want to stop triggering D1, so set the modifier of PORTD back to 0
 +\t a_mod = 0; // we want to stop triggering A1, so set the modifier of PORTA back to 0
 +\t 
 +\t }
 +\t}
 +\t 
 +<nowiki>//</nowiki>Multiplexing routine: Each LED is on (1/9) of the time. 
 +<nowiki>//</nowiki>  -> Uses much less power.
 +<code>
 +   PORTA = a_base - a_mod;</code>
 +\t}\t//End main loop
 +\treturn 0;
 +}
 +
 +  - endif
 +\t
 +</code>
  
nsl_cylon.txt ยท Last modified: 2013/08/13 12:13 (external edit)