playground:playground
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revision | |||
playground:playground [2013/08/13 14:56] – bmbr | playground:playground [2019/01/06 01:29] (current) – external edit 127.0.0.1 | ||
---|---|---|---|
Line 1: | Line 1: | ||
====== PlayGround ====== | ====== PlayGround ====== | ||
- | |||
- | The end product of the first [[Eagle Class]] | ||
- | |||
- | * [[http:// | ||
- | * Code is also available on the [[http:// | ||
- | * [[http:// | ||
- | |||
- | {{: | ||
- | |||
- | [[FILE: | ||
- | |||
- | http:// | ||
- | br | ||
- | < | ||
- | |||
- | <a href=" | ||
- | </ | ||
- | |||
- | < | ||
- | <object type=" | ||
- | </ | ||
- | |||
- | <code c> | ||
- | |||
- | - if 1 | ||
- | |||
- | /* | ||
- | larson.c | ||
- | The Larson Scanner | ||
- | |||
- | Written by Windell Oskay, http:// | ||
- | |||
- | | ||
- | | ||
- | |||
- | |||
- | An avr-gcc program for the Atmel ATTiny2313 | ||
- | | ||
- | | ||
- | | ||
- | * EEPROM is used to *correctly* remember last speed & brightness mode. | ||
- | | ||
- | * Skinny " | ||
- | | ||
- | * EEPROM is used to remember last speed & brightness mode. | ||
- | |||
- | |||
- | More information about this project is at | ||
- | | ||
- | |||
- | |||
- | |||
- | | ||
- | | ||
- | |||
- | |||
- | |||
- | |||
- | 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 < | ||
- | make all < | ||
- | make install < | ||
- | 4. Make sure that avrdude does not report any errors. | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | |||
- | |||
- | |||
- | If you a different programming environment, | ||
- | |||
- | |||
- | |||
- | | ||
- | This code should be relatively straightforward, | ||
- | | ||
- | | ||
- | |||
- | |||
- | |||
- | | ||
- | |||
- | | ||
- | * / | ||
- | |||
- | - include < | ||
- | - include < | ||
- | - include < | ||
- | - include < | ||
- | - include < | ||
- | |||
- | - define shortdelay(); | ||
- | \ " \\ | ||
- | "nop\ | ||
- | \ "); | ||
- | |||
- | - define TIMER1_PRESCALE_1 | ||
- | - define TIMER1_PRESCALE_8 | ||
- | - define TIMER1_PRESCALE_64 | ||
- | - define TIMER1_PRESCALE_256 | ||
- | - define TIMER1_PRESCALE_1024 | ||
- | |||
- | uint16_t eepromWord __attribute__((section(" | ||
- | |||
- | int main (void) | ||
- | { | ||
- | uint8_t LEDs[[9]]; // Storage for current LED values | ||
- | | ||
- | int8_t eyeLoc[[5]]; | ||
- | |||
- | uint8_t LEDBright[[4]] = {1u, | ||
- | | ||
- | |||
- | |||
- | int8_t j, m; | ||
- | | ||
- | uint8_t position, loopcount, direction; | ||
- | uint8_t ILED, RLED, MLED; | ||
- | |||
- | uint8_t delaytime; | ||
- | | ||
- | uint8_t skinnyEye = 0; | ||
- | uint8_t | ||
- | uint8_t | ||
- | uint8_t BrightMode; | ||
- | uint8_t debounce2, modeswitched; | ||
- | | ||
- | uint8_t CycleCountLow; | ||
- | uint8_t LED0, LED1, LED2, LED3, LED4, LED5, LED6, LED7, LED8; | ||
- | | ||
- | // | ||
- | MCUSR &= 0xF7; //Clear WDRF Flag | ||
- | WDTCSR | ||
- | WDTCSR | ||
- | |||
- | //Data direction register: DDR's | ||
- | //Port A: 0, 1 are inputs. | ||
- | //Port B: 0-3 are outputs, B4 is an input. | ||
- | //Port D: 1-6 are outputs, D0 is an input. | ||
- | | ||
- | DDRA = 0U; | ||
- | DDRB = 15U; | ||
- | DDRD = 126U; | ||
- | | ||
- | PORTA = 3; // Pull-up resistors enabled, PA0, PA1 | ||
- | PORTB = 16; // Pull-up resistor enabled, PA | ||
- | PORTD = 0; | ||
- | | ||
- | |||
- | TCCR1B = (1 << WGM12) | TIMER1_PRESCALE_1; | ||
- | OCR1A = (uint16_t)800; | ||
- | TIMSK |= 1 << OCIE1A; | ||
- | |||
- | /* Visualize outputs: | ||
- | |||
- | L to R: | ||
- | |||
- | D2 D3 D4 D5 D6 B0 B1 B2 B3 | ||
- | | ||
- | */ | ||
- | | ||
- | // | ||
- | |||
- | debounce = 0; | ||
- | debounce2 = 0; | ||
- | loopcount = 254; | ||
- | delaytime = 0; | ||
- | | ||
- | direction = 0; | ||
- | position = 0; | ||
- | speedLevel = 0; // Range: 1, 2, 3 | ||
- | BrightMode = 0; | ||
- | CycleCountLow = 0; | ||
- | UpdateConfig = 0; | ||
- | modeswitched = 0; | ||
- | | ||
- | | ||
- | if ((PINA & 2) == 0) // Check if Jumper 1, at location PA1 is shorted | ||
- | { | ||
- | // Optional place to do something. | ||
- | } | ||
- | | ||
- | | ||
- | | ||
- | if ((PINA & 1) == 0) // Check if Jumper 2, at location PA0 is shorted | ||
- | { | ||
- | skinnyEye = 1; | ||
- | } | ||
- | | ||
- | | ||
- | if ((PINB & 16) == 0) // Check if button pressed pressed down at turn-on | ||
- | { | ||
- | |||
- | //Toggle Skinnymode | ||
- | if (skinnyEye) | ||
- | skinnyEye = 0; | ||
- | else | ||
- | skinnyEye = 1; | ||
- | } | ||
- | | ||
- | | ||
- | | ||
- | if (skinnyEye){ | ||
- | LEDBright[[0]] = 0; | ||
- | LEDBright[[1]] = 4; | ||
- | LEDBright[[2]] = 1; | ||
- | LEDBright[[3]] = 0; | ||
- | } | ||
- | | ||
- | | ||
- | //Check EEPROM values: | ||
- | | ||
- | pt = (uint8_t) (eeprom_read_word(& | ||
- | speedLevel = pt >> 4; | ||
- | BrightMode = pt & 1; | ||
- | |||
- | if (pt == 0xFF) | ||
- | { | ||
- | BrightMode = 0; | ||
- | } | ||
- | | ||
- | | ||
- | if (speedLevel > 3) | ||
- | speedLevel = 1; | ||
- | | ||
- | speedLevel = 0; | ||
- | |||
- | if ((speedLevel == 2) || (speedLevel == 3)) { | ||
- | delaytime = 0; | ||
- | } | ||
- | else | ||
- | { | ||
- | delaytime = 1; | ||
- | } | ||
- | | ||
- | |||
- | | ||
- | for (;;) // main loop | ||
- | { | ||
- | |||
- | |||
- | loopcount++; | ||
- | | ||
- | if (loopcount > delaytime) | ||
- | { | ||
- | loopcount = 0; | ||
- | | ||
- | CycleCountLow++; | ||
- | if (CycleCountLow > 250) | ||
- | CycleCountLow = 0; | ||
- | | ||
- | | ||
- | if (UpdateConfig){ | ||
- | if (CycleCountLow > 100) // Avoid burning EEPROM in event of flaky power connection resets | ||
- | { | ||
- | | ||
- | UpdateConfig = 0; | ||
- | pt = (speedLevel << 4) | (BrightMode & 1); | ||
- | eeprom_write_word(& | ||
- | // Note: this function causes a momentary brightness glitch while it writes the EEPROM. | ||
- | // We separate out this section to minimize the effect. | ||
- | } | ||
- | | ||
- | } | ||
- | |||
- | | ||
- | | ||
- | if ((PINB & 16) == 0) // Check for button press | ||
- | { | ||
- | debounce2++; | ||
- | | ||
- | if (debounce2 > 100) | ||
- | { | ||
- | if (modeswitched == 0) | ||
- | { | ||
- | debounce2 = 0; | ||
- | UpdateConfig = 1; | ||
- | |||
- | switch( BrightMode ) { | ||
- | | ||
- | case 0: | ||
- | BrightMode++; | ||
- | case 1: | ||
- | BrightMode++; | ||
- | break; | ||
- | case 2: | ||
- | // off | ||
- | // switch on POV | ||
- | // wrap | ||
- | BrightMode++; | ||
- | break; | ||
- | |||
- | case 3: | ||
- | // | ||
- | // runs POV | ||
- | BrightMode++; | ||
- | break; | ||
- | |||
- | case 4: | ||
- | sei(); | ||
- | BrightMode++; | ||
- | // runs POV | ||
- | break; | ||
- | case 5: | ||
- | cli(); | ||
- | // runs POV | ||
- | BrightMode = 0 ; | ||
- | break; | ||
- | | ||
- | default: | ||
- | // interrupts off and wrap | ||
- | BrightMode= 0; | ||
- | break; | ||
- | } | ||
- | | ||
- | modeswitched = 1; | ||
- | } | ||
- | } | ||
- | else { | ||
- | debounce = 1; // Flag that the button WAS pressed. | ||
- | debounce2++; | ||
- | } | ||
- | |||
- | } | ||
- | else{ | ||
- | | ||
- | debounce2 = 0; | ||
- | modeswitched = 0; | ||
- | | ||
- | if (debounce) | ||
- | { debounce = 0; | ||
- | speedLevel++; | ||
- | UpdateConfig = 1; | ||
- | | ||
- | if ((speedLevel == 2) || (speedLevel == 3)) { | ||
- | delaytime = 0; | ||
- | } | ||
- | else | ||
- | { | ||
- | delaytime = 1; | ||
- | } | ||
- | | ||
- | debounce = 0; | ||
- | } | ||
- | | ||
- | } | ||
- | | ||
- | position++; | ||
- | | ||
- | if (speedLevel == 3) | ||
- | position++; | ||
- | | ||
- | if (position >= 128) //was == 128 | ||
- | { | ||
- | | ||
- | |||
- | if (direction == 0) | ||
- | direction = 1; | ||
- | else | ||
- | direction = 0; | ||
- | } | ||
- | | ||
- | |||
- | if (direction == 0) // Moving to right, as viewed from front. | ||
- | { | ||
- | ILED = (15+position) >> 4; | ||
- | RLED = (15+position) - (ILED << 4); | ||
- | MLED = 15 - RLED; | ||
- | } | ||
- | |||
- | | ||
- | { | ||
- | ILED = (127 - position) >> 4; | ||
- | MLED = (127 - position) | ||
- | RLED = 15 - MLED; | ||
- | } | ||
- | |||
- | j = 0; | ||
- | while (j < 9) { | ||
- | LEDs[[j]] = 0; | ||
- | j++; | ||
- | } | ||
- | |||
- | j = 0; | ||
- | while (j < 5) { | ||
- | | ||
- | if (direction == 0) | ||
- | m = ILED + (2 - j); // e.g., eyeLoc[[0]] = ILED + 2; | ||
- | else | ||
- | m = ILED + (j - 2); // e.g., eyeLoc[[0]] = ILED - 2; | ||
- | | ||
- | if (m > 8) | ||
- | m -= (2 * (m - 8)); | ||
- | | ||
- | if (m < 0) | ||
- | m *= -1; | ||
- | | ||
- | eyeLoc[[j]] = m; | ||
- | | ||
- | j++; | ||
- | } | ||
- | | ||
- | j = 0; // For each of the eye parts... | ||
- | while (j < 4) { | ||
- | | ||
- | LEDs[eyeLoc[j]] | ||
- | LEDs[eyeLoc[j+1]] += LEDBright[[j]]*MLED; | ||
- | |||
- | j++; | ||
- | } | ||
- | | ||
- | LED0 = LEDs[[0]]; | ||
- | |||
- | LED1 = LEDs[[1]]; | ||
- | LED2 = LEDs[[2]]; | ||
- | LED3 = LEDs[[3]]; | ||
- | LED4 = LEDs[[4]]; | ||
- | LED5 = LEDs[[5]]; | ||
- | LED6 = LEDs[[6]]; | ||
- | LED7 = LEDs[[7]]; | ||
- | LED8 = LEDs[[8]]; | ||
- | |||
- | } | ||
- | |||
- | if ( BrightMode > 3 ) { | ||
- | continue; | ||
- | } | ||
- | |||
- | if (BrightMode == 0) | ||
- | { // | ||
- | // -> Use much less power. | ||
- | j = 0; | ||
- | while (j < 60) // Truncate brightness at a max value (60) in the interest of speed. | ||
- | { | ||
- | | ||
- | if (LED0 > j) | ||
- | PORTD = 4; | ||
- | else | ||
- | PORTD = 0; | ||
- | | ||
- | if (LED1 > j) | ||
- | PORTD = 8; | ||
- | else | ||
- | PORTD = 0; | ||
- | | ||
- | if (LED2 > j) | ||
- | PORTD = 16; | ||
- | else | ||
- | PORTD = 0; | ||
- | | ||
- | if (LED3 > j) | ||
- | PORTD = 32; | ||
- | else | ||
- | PORTD = 0; | ||
- | | ||
- | if (LED4 > j) | ||
- | PORTD = 64; | ||
- | else | ||
- | PORTD = 0; | ||
- | | ||
- | if (LED5 > j) { | ||
- | PORTB = 17; | ||
- | PORTD = 0;} | ||
- | else { | ||
- | PORTB = 16; | ||
- | PORTD = 0; } | ||
- | | ||
- | if (LED6 > j) | ||
- | PORTB = 18; | ||
- | else | ||
- | PORTB = 16; | ||
- | | ||
- | if (LED7 > j) | ||
- | PORTB = 20; | ||
- | else | ||
- | PORTB = 16; | ||
- | | ||
- | if (LED8 > j) | ||
- | PORTB = 24; | ||
- | else | ||
- | PORTB = 16; | ||
- | |||
- | j++; | ||
- | // if (speedLevel == 3) | ||
- | // j++; | ||
- | PORTB = 16; | ||
- | } | ||
- | |||
- | } | ||
- | | ||
- | | ||
- | |||
- | j = 0; | ||
- | while (j < 70) | ||
- | { | ||
- | | ||
- | pt = 0; | ||
- | if (LED0 > j) | ||
- | pt = 4; | ||
- | if (LED1 > j) | ||
- | pt |= 8; | ||
- | if (LED2 > j) | ||
- | pt |= 16; | ||
- | if (LED3 > j) | ||
- | pt |= 32; | ||
- | if (LED4 > j) | ||
- | pt |= 64; | ||
- | | ||
- | PORTD = pt; | ||
- | shortdelay(); | ||
- | pt = 16; | ||
- | if (LED5 > j) | ||
- | pt |= 1; | ||
- | if (LED6 > j) | ||
- | pt |= 2; | ||
- | if (LED7 > j) | ||
- | pt |= 4; | ||
- | if (LED8 > j) | ||
- | pt |= 8; | ||
- | | ||
- | PORTB = pt; | ||
- | shortdelay(); | ||
- | | ||
- | j++; | ||
- | // if (speedLevel == 3) | ||
- | // j++; | ||
- | } | ||
- | |||
- | } | ||
- | | ||
- | |||
- | // | ||
- | // -> Uses much less power. | ||
- | |||
- | } //End main loop | ||
- | return 0; | ||
- | } | ||
- | |||
- | |||
- | |||
- | - define IS_BIT(a, | ||
- | - define SET_BIT(a, | ||
- | - define CLR_BIT(a, | ||
- | |||
- | |||
- | - define LED0 ( 4 )//1 | ||
- | - define LED1 ( 3 )//2 | ||
- | - define LED2 ( 2 )//3 | ||
- | - define LED3 ( 1 )//4 | ||
- | - define LED4 ( 0 )//5 | ||
- | |||
- | // byte two | ||
- | - define LED5 ( 3 ) | ||
- | - define LED6 ( 2 ) | ||
- | - define LED7 ( 1 ) | ||
- | - define LED8 ( 0 ) | ||
- | |||
- | void delay_ms( uint16_t milliseconds) | ||
- | { | ||
- | |||
- | for( ; milliseconds > 0; milliseconds--) | ||
- | { | ||
- | _delay_ms( 1); | ||
- | } | ||
- | } | ||
- | |||
- | |||
- | |||
- | // NSL Cylon | ||
- | - define B9__(x) ((x& | ||
- | |||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | +((x& | ||
- | |||
- | - define _B9(d) ((uint16_t)B9__(HEX__(d))) | ||
- | |||
- | - define B9(d) 0b##d | ||
- | |||
- | |||
- | const static uint16_t large_image[[]] PROGMEM | ||
- | { | ||
- | |||
- | - if 1 | ||
- | |||
- | B9(000000000), | ||
- | B9(111111111), | ||
- | B9(100000001), | ||
- | B9(100000001), | ||
- | B9(000000000), | ||
- | B9(100000000), | ||
- | B9(100000000), | ||
- | B9(100000000), | ||
- | B9(111111111), | ||
- | B9(000000000), | ||
- | B9(111110001), | ||
- | B9(100010001), | ||
- | B9(100010001), | ||
- | B9(100011111), | ||
- | B9(000000000), | ||
- | B9(111111111), | ||
- | B9(001000000), | ||
- | B9(000111000), | ||
- | B9(000000100), | ||
- | B9(000000010), | ||
- | B9(111111111), | ||
- | B9(000000000), | ||
- | B9(100000001), | ||
- | B9(100000001), | ||
- | B9(111111111), | ||
- | B9(000000000), | ||
- | B9(000000000), | ||
- | B9(000000000), | ||
- | |||
- | |||
- | // nullspace (backwards) | ||
- | |||
- | B9(100010001), | ||
- | B9(100010001), | ||
- | B9(100010001), | ||
- | B9(111111111), | ||
- | B9(000000000), | ||
- | B9(100000001), | ||
- | B9(100000001), | ||
- | B9(111111111), | ||
- | B9(000000000), | ||
- | B9(111111111), | ||
- | B9(000010001), | ||
- | |||
- | |||
- | B9(000010001), | ||
- | B9(111111111), | ||
- | B9(000000000), | ||
- | B9(000011111), | ||
- | B9(000010001), | ||
- | B9(000010001), | ||
- | B9(111111111), | ||
- | B9(000000000), | ||
- | B9(111110001), | ||
- | B9(100010001), | ||
- | B9(100010001), | ||
- | B9(100011111), | ||
- | B9(000000000), | ||
- | B9(100000000), | ||
- | B9(100000000), | ||
- | B9(111111111), | ||
- | B9(000000000), | ||
- | B9(100000000), | ||
- | B9(100000000), | ||
- | B9(111111111), | ||
- | B9(000000000), | ||
- | B9(111111111), | ||
- | B9(100000000), | ||
- | B9(100000000), | ||
- | B9(111111111), | ||
- | B9(000000000), | ||
- | B9(111111111), | ||
- | B9(010000000), | ||
- | B9(001110000), | ||
- | B9(000001100), | ||
- | B9(000000010), | ||
- | B9(111111111), | ||
- | |||
- | // 0,0,0,0, | ||
- | |||
- | - else | ||
- | |||
- | // flickr | ||
- | B9(010101010), | ||
- | B9(010101010), | ||
- | B9(101010101), | ||
- | B9(101010101), | ||
- | |||
- | // | ||
- | |||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | - endif | ||
- | | ||
- | 0,0,0,0, | ||
- | 65535 | ||
- | }; | ||
- | |||
- | |||
- | // special pointer for reading from ROM memory | ||
- | PGM_P largeimage_p PROGMEM = (PGM_P)large_image; | ||
- | |||
- | - define NUM_ELEM(x) (sizeof (x) / sizeof (*(x))) | ||
- | |||
- | // this function is called when timer1 compare matches OCR1A | ||
- | |||
- | SIGNAL( SIG_TIMER1_COMPA ) { | ||
- | |||
- | static uint8_t j = 0; | ||
- | uint8_t tmpout; | ||
- | |||
- | uint16_t tmp=0; | ||
- | |||
- | //reset counter | ||
- | if (pgm_read_word(largeimage_p + j ) == 65535 ) { | ||
- | j = 0; | ||
- | } | ||
- | |||
- | tmp = pgm_read_word(largeimage_p + j); | ||
- | |||
- | tmpout = 0; | ||
- | |||
- | if( IS_BIT(tmp, | ||
- | if( IS_BIT(tmp, | ||
- | if( IS_BIT(tmp, | ||
- | if( IS_BIT(tmp, | ||
- | |||
- | PORTB = ( tmpout | ||
- | |||
- | tmpout = 0; | ||
- | |||
- | if( IS_BIT(tmp, | ||
- | if( IS_BIT(tmp, | ||
- | if( IS_BIT(tmp, | ||
- | if( IS_BIT(tmp, | ||
- | if( IS_BIT(tmp, | ||
- | |||
- | PORTD = tmpout<< | ||
- | |||
- | // word | ||
- | j+=2; | ||
- | } | ||
- | |||
- | - else | ||
- | /* | ||
- | larsonextend.c | ||
- | The Larson Scanner -- Alternative version to allow scanner to run off the edge of the board. | ||
- | |||
- | |||
- | 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 " | ||
- | 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. | ||
- | | ||
- | (a permanent installation in an enclosure), the unit was never really intended to change speeds. | ||
- | get it to work like the original, but couldn' | ||
- | |||
- | Original written by Windell Oskay, http:// | ||
- | New alternative version written by John Breen III | ||
- | |||
- | |||
- | | ||
- | | ||
- | |||
- | |||
- | |||
- | |||
- | An avr-gcc program for the Atmel ATTiny2313 | ||
- | Based on Version 1.1_alt1, written by Windell Oskay | ||
- | | ||
- | | ||
- | |||
- | |||
- | |||
- | More information about this project is at | ||
- | | ||
- | |||
- | |||
- | |||
- | |||
- | | ||
- | | ||
- | |||
- | |||
- | |||
- | |||
- | 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 < | ||
- | make all < | ||
- | make install < | ||
- | 4. Make sure that avrdude does not report any errors. | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | |||
- | |||
- | |||
- | If you a different programming environment, | ||
- | |||
- | |||
- | |||
- | | ||
- | This code should be relatively straightforward, | ||
- | | ||
- | | ||
- | |||
- | |||
- | | ||
- | |||
- | | ||
- | * / | ||
- | |||
- | - include < | ||
- | |||
- | - define shortdelay(); | ||
- | \ " \\ | ||
- | "nop\ | ||
- | \ "); | ||
- | |||
- | | ||
- | int main (void) | ||
- | { | ||
- | uint8_t LEDs[[9]]; // Storage for current LED values | ||
- | uint8_t rightLED[[6]], | ||
- | | ||
- | int8_t eyeLoc[[5]]; | ||
- | |||
- | uint8_t LEDBright[[4]] = {4u, | ||
- | |||
- | void delay_ms(uint8_t ms) { | ||
- | |||
- | return 0; | ||
- | |||
- | |||
- | | ||
- | | ||
- | while (ms != 0) | ||
- | { | ||
- | for (i=0; i != delay_count; | ||
- | ms--; | ||
- | } | ||
- | } | ||
- | | ||
- | int8_t j, k, m; | ||
- | | ||
- | uint8_t position, loopcount, direction, initloopcount, | ||
- | uint8_t runitout, d_base, a_base, d_mod, a_mod, far_left, far_right; | ||
- | uint8_t ILED, RLED, MLED; // Eye position variables: Integer, Modulo, remainder | ||
- | |||
- | uint8_t delaytime; | ||
- | |||
- | uint8_t | ||
- | unsigned int debounce2, BrightMode; | ||
- | |||
- | uint8_t LED0, LED1, LED2, LED3, LED4, LED5, LED6, LED7, LED8; | ||
- | | ||
- | // | ||
- | MCUSR &= 0xF7; //Clear WDRF Flag | ||
- | WDTCSR | ||
- | WDTCSR | ||
- | |||
- | //Data direction register: DDR's | ||
- | //Port A: 1 is an output, A0 is an input. | ||
- | //Port B: 0-3 are outputs, B4 is an input. | ||
- | //Port D: 1-6 are outputs, D0 is an input. | ||
- | | ||
- | DDRA = 2U; | ||
- | DDRB = 15U; | ||
- | DDRD = 126U; | ||
- | | ||
- | a_base = 3; // set a base value (resting value) for PA, to keep things easy to modify | ||
- | d_base = 3; // set a base value (resting value) for PD, to keep things easy to modify | ||
- | | ||
- | PORTA = a_base; | ||
- | PORTB = 16; // Pull-up resistor enabled, PB4 | ||
- | PORTD = d_base; | ||
- | | ||
- | d_mod = 0; | ||
- | a_mod = 0; | ||
- | | ||
- | /* Visualize outputs: | ||
- | |||
- | |||
- | L to R: | ||
- | D2 D3 D4 D5 D6 B0 B1 B2 B3 | ||
- | < | ||
- | |||
- | (out to right) D1 --> | ||
- | | ||
- | * / | ||
- | |||
- | // Clear out all of the LED values to blank out the display | ||
- | |||
- | j = 0; | ||
- | while (j < 9) { | ||
- | LEDs[[j]] = 0; | ||
- | j++; | ||
- | } | ||
- | |||
- | LED0 = LEDs[[0]]; | ||
- | |||
- | LED1 = LEDs[[1]]; | ||
- | LED2 = LEDs[[2]]; | ||
- | LED3 = LEDs[[3]]; | ||
- | LED4 = LEDs[[4]]; | ||
- | LED5 = LEDs[[5]]; | ||
- | LED6 = LEDs[[6]]; | ||
- | LED7 = LEDs[[7]]; | ||
- | LED8 = LEDs[[8]]; | ||
- | | ||
- | // | ||
- | |||
- | debounce = 1; | ||
- | debounce2 = 1; | ||
- | loopcount = 254; | ||
- | initloopcount = 5; | ||
- | delaytime = 0; | ||
- | | ||
- | direction = 0; | ||
- | position = 0; | ||
- | runitout = 0; | ||
- | already_running = 0; | ||
- | softbounce = 0; | ||
- | far_left = 0; | ||
- | far_right = 0; | ||
- | speedLevel = 3; // Range: 1, 2, 3 | ||
- | BrightMode = 0; | ||
- | |||
- | if ((PINB & 16) == 0) // Check if button held on startup; used to verify wiring configuration | ||
- | { initloopcount = 0; // if so, set the startup loop counter to 0 so that we can watch the startup lights | ||
- | softbounce = 1; // Also set the " | ||
- | } | ||
- | |||
- | delay_ms(200); | ||
- | |||
- | PORTD = 1; //Pull D1 low, to trigger output on right side | ||
- | |||
- | delay_ms(10); | ||
- | |||
- | if ((PIND & 1) == 0) //Check to see if D1 output has latched D0 input | ||
- | far_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; //Set D1 high | ||
- | |||
- | PORTA = 1; //Pull A1 low, to trigger output on left side | ||
- | |||
- | delay_ms(10); | ||
- | |||
- | if ((PINA & 1) == 0) //Check to see if A1 output has latched A0 input | ||
- | far_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; //Set A1 high | ||
- | |||
- | |||
- | //A little bit if visual verification to the user as to which way each end of the scanner is set | ||
- | // (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) { | ||
- | leftLED[[0]] = 7; | ||
- | leftLED[[1]] = 11; | ||
- | leftLED[[2]] = 19; | ||
- | leftLED[[3]] = 19; | ||
- | leftLED[[4]] = 19; | ||
- | leftLED[[5]] = 19; | ||
- | } | ||
- | else { | ||
- | leftLED[[0]] = 19; | ||
- | leftLED[[1]] = 11; | ||
- | leftLED[[2]] = 7; | ||
- | leftLED[[3]] = 7; | ||
- | leftLED[[4]] = 7; | ||
- | leftLED[[5]] = 7; | ||
- | } | ||
- | |||
- | if (far_right) { | ||
- | rightLED[[0]] = 24; | ||
- | rightLED[[1]] = 20; | ||
- | rightLED[[2]] = 18; | ||
- | rightLED[[3]] = 18; | ||
- | rightLED[[4]] = 18; | ||
- | rightLED[[5]] = 18; | ||
- | } | ||
- | else { | ||
- | rightLED[[0]] = 18; | ||
- | rightLED[[1]] = 20; | ||
- | rightLED[[2]] = 24; | ||
- | rightLED[[3]] = 24; | ||
- | rightLED[[4]] = 24; | ||
- | rightLED[[5]] = 24; | ||
- | } | ||
- | |||
- | delay_ms(100); | ||
- | * This is necessary because the clock speeds on each chip only have a 10% tolerance, and initial | ||
- | * testing showed that the tests to configure far_left and far_right were causing | ||
- | * " | ||
- | */ | ||
- | for (;;) // main loop | ||
- | { | ||
- | loopcount++; | ||
- | |||
- | if (loopcount > delaytime) | ||
- | { | ||
- | loopcount = 0; | ||
- | | ||
- | if ((PINB & 16) == 0) // Check for button press | ||
- | { | ||
- | if ((initloopcount >= 4) & (far_left == 1) & (already_running == 0)) | ||
- | { | ||
- | runitout = 1; | ||
- | already_running = 1; | ||
- | debounce = 0; // Start running the program, but only on the left-most unit. | ||
- | } | ||
- | | ||
- | /* This is the section from the original program to let the button change the speeds and brightness. | ||
- | debounce2++; | ||
- | | ||
- | if (debounce2 > 100) | ||
- | { | ||
- | debounce = 0; | ||
- | | ||
- | if (BrightMode == 0) | ||
- | BrightMode = 1; | ||
- | else | ||
- | BrightMode = 0; | ||
- | | ||
- | } | ||
- | | ||
- | if (debounce) | ||
- | { | ||
- | speedLevel++; | ||
- | | ||
- | if ((speedLevel == 2) || (speedLevel == 3)) { | ||
- | delaytime = 0; | ||
- | } | ||
- | else | ||
- | { | ||
- | delaytime = 1; | ||
- | } | ||
- | |||
- | debounce = 0; | ||
- | } | ||
- | } | ||
- | else{ | ||
- | debounce = 1; | ||
- | debounce2 = 1; | ||
- | } | ||
- | * / | ||
- | |||
- | } | ||
- | | ||
- | if ((PINA & 1) == 0) // Check to see if display from the left has triggered to start | ||
- | { | ||
- | direction = 0; | ||
- | runitout = 1; | ||
- | } | ||
- | | ||
- | if ((PIND & 1) == 0) // Check to see if display from the right has triggered to start | ||
- | { | ||
- | direction = 1; | ||
- | runitout = 1; | ||
- | } | ||
- | |||
- | | ||
- | if (runitout) | ||
- | { | ||
- | position++; | ||
- | | ||
- | if (speedLevel == 3) | ||
- | position++; | ||
- | | ||
- | if ((softbounce == 1) & (((direction == 0) & (far_right == 1)) || ((direction == 1) & (far_left == 1))) & (position >= 224)) | ||
- | { // this allows us to " | ||
- | position = 15; | ||
- | if (direction == 0) | ||
- | direction = 1; | ||
- | else | ||
- | direction = 0; | ||
- | } | ||
- | | ||
- | if (position >= 240) // To allow for runoff at the ends; was '== 128' | ||
- | { | ||
- | position = 0; | ||
- | |||
- | if (direction == 0) { | ||
- | direction = 1; // we've reached the end, so go back in the other direction | ||
- | if (far_right == 0) // If this isn't the end of the chain, we want to stop, and wait for a signal to go again | ||
- | runitout = 0; | ||
- | } | ||
- | else { | ||
- | direction = 0; | ||
- | if (far_left == 0) // If this isn't the end of the chain, we want to stop, and wait for a signal to go again | ||
- | runitout = 0; | ||
- | } | ||
- | } | ||
- | |||
- | if (direction == 0) // Moving to right, as viewed from front. | ||
- | { | ||
- | ILED = (15+position) >> 4; | ||
- | RLED = (15+position) - (ILED << 4); | ||
- | MLED = 15 - RLED; | ||
- | } | ||
- | |||
- | else | ||
- | { | ||
- | ILED = (127 - position) >> 4; | ||
- | MLED = (127 - position) | ||
- | RLED = 15 - MLED; | ||
- | } | ||
- | | ||
- | if ((ILED == 10) & (direction == 0) & (far_right == 0)) | ||
- | d_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 | ||
- | | ||
- | j = 0; | ||
- | while (j < 9) { | ||
- | LEDs[[j]] = 0; | ||
- | j++; | ||
- | } | ||
- | |||
- | j = 0; | ||
- | if ((softbounce == 1) & (((direction == 0) & (far_right == 1)) || ((direction == 1) & (far_left == 1)))) { | ||
- | while (j < 5) { | ||
- | | ||
- | if (direction == 0) | ||
- | m = ILED - (j + 1); | ||
- | //m = ILED + (2 - j); // e.g., eyeLoc[[0]] = ILED + 2; | ||
- | else | ||
- | m = ILED + (j + 1); | ||
- | //m = ILED + (j - 2); // e.g., eyeLoc[[0]] = ILED - 2; | ||
- | | ||
- | if ((direction == 0) & (m > 8)) | ||
- | m = 8; | ||
- | | ||
- | if ((direction == 1) & (m < 0)) | ||
- | m = 0; | ||
- | | ||
- | eyeLoc[[j]] = m; | ||
- | | ||
- | j++; | ||
- | } | ||
- | } | ||
- | else { | ||
- | while (j < 5) | ||
- | { | ||
- | if (direction == 0) | ||
- | m = ILED - (j + 1); // e.g., eyeLoc[[0]] = ILED - 1; | ||
- | else | ||
- | m = ILED + (j + 1); // e.g., eyeLoc[[0]] = ILED + 1; | ||
- | | ||
- | if ((m == -1) & (direction == 1) & (far_left == 0)) | ||
- | a_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 | ||
- | | ||
- | if (m > 8) | ||
- | m = -1; // If eye position is past the end of the board, don't light it; set to -1 | ||
- | | ||
- | if (m < 0) | ||
- | m = -1; // If eye position is past the end of the board, don't light it; set to -1 | ||
- | | ||
- | eyeLoc[[j]] = m; | ||
- | | ||
- | j++; | ||
- | } | ||
- | } | ||
- | | ||
- | j = 0; // For each of the eye parts... | ||
- | while (j < 4) | ||
- | { | ||
- | if (eyeLoc[[j]] >= 0) | ||
- | LEDs[eyeLoc[j]] | ||
- | if (eyeLoc[[j+1]] >= 0) | ||
- | LEDs[eyeLoc[j+1]] += LEDBright[[j]]*MLED; | ||
- | j++; | ||
- | } | ||
- | | ||
- | LED0 = LEDs[[0]]; | ||
- | |||
- | LED1 = LEDs[[1]]; | ||
- | LED2 = LEDs[[2]]; | ||
- | LED3 = LEDs[[3]]; | ||
- | LED4 = LEDs[[4]]; | ||
- | LED5 = LEDs[[5]]; | ||
- | LED6 = LEDs[[6]]; | ||
- | LED7 = LEDs[[7]]; | ||
- | LED8 = LEDs[[8]]; | ||
- | } | ||
- | else if (initloopcount < 4 ) | ||
- | { | ||
- | k = 0; | ||
- | while (k < 6) { | ||
- | PORTD = leftLED[[k]]; | ||
- | PORTB = rightLED[[k]]; | ||
- | delay_ms(1); | ||
- | | ||
- | PORTD = d_base; | ||
- | PORTB = 16; | ||
- | delay_ms(29); | ||
- | |||
- | k++; | ||
- | } | ||
- | delay_ms(100); | ||
- | initloopcount++; | ||
- | } | ||
- | } | ||
- | if (runitout) { | ||
- | if (BrightMode == 0) | ||
- | { // | ||
- | // -> Use much less power. | ||
- | j = 0; | ||
- | PORTA = 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 | ||
- | while (j < 60) // Truncate brightness at a max value (60) in the interest of speed. | ||
- | { | ||
- | | ||
- | if (LED0 > j) | ||
- | PORTD = 7 - d_mod; | ||
- | else | ||
- | PORTD = d_base - d_mod; | ||
- | | ||
- | if (LED1 > j) | ||
- | PORTD = 11 - d_mod; | ||
- | else | ||
- | PORTD = d_base - d_mod; | ||
- | | ||
- | if (LED2 > j) | ||
- | PORTD = 19 - d_mod; | ||
- | else | ||
- | PORTD = d_base - d_mod; | ||
- | | ||
- | if (LED3 > j) | ||
- | PORTD = 35 - d_mod; | ||
- | else | ||
- | PORTD = d_base - d_mod; | ||
- | | ||
- | if (LED4 > j) | ||
- | PORTD = 67 - d_mod; | ||
- | else | ||
- | PORTD = d_base - d_mod; | ||
- | | ||
- | if (LED5 > j) { | ||
- | PORTB = 17; | ||
- | PORTD = d_base - d_mod;} | ||
- | else { | ||
- | PORTB = 16; | ||
- | PORTD = d_base - d_mod;} | ||
- | | ||
- | if (LED6 > j) | ||
- | PORTB = 18; | ||
- | else | ||
- | PORTB = 16; | ||
- | | ||
- | if (LED7 > j) | ||
- | PORTB = 20; | ||
- | else | ||
- | PORTB = 16; | ||
- | | ||
- | if (LED8 > j) | ||
- | PORTB = 24; | ||
- | else | ||
- | PORTB = 16; | ||
- | |||
- | j++; | ||
- | // if (speedLevel == 3) | ||
- | // j++; | ||
- | PORTB = 16; | ||
- | } | ||
- | |||
- | d_mod = 0; | ||
- | a_mod = 0; | ||
- | } | ||
- | | ||
- | | ||
- | |||
- | PORTA = a_base - a_mod; | ||
- | |||
- | j = 0; | ||
- | while (j < 70) | ||
- | { | ||
- | | ||
- | | ||
- | pt = d_base - d_mod; | ||
- | if (LED0 > j) | ||
- | pt |= 4; | ||
- | if (LED1 > j) | ||
- | pt |= 8; | ||
- | if (LED2 > j) | ||
- | pt |= 16; | ||
- | if (LED3 > j) | ||
- | pt |= 32; | ||
- | if (LED4 > j) | ||
- | pt |= 64; | ||
- | | ||
- | PORTD = pt; | ||
- | shortdelay(); | ||
- | pt = 16; | ||
- | if (LED5 > j) | ||
- | pt |= 1; | ||
- | if (LED6 > j) | ||
- | pt |= 2; | ||
- | if (LED7 > j) | ||
- | pt |= 4; | ||
- | if (LED8 > j) | ||
- | pt |= 8; | ||
- | | ||
- | PORTB = pt; | ||
- | shortdelay(); | ||
- | | ||
- | j++; | ||
- | // if (speedLevel == 3) | ||
- | // j++; | ||
- | } | ||
- | | ||
- | d_mod = 0; // we want to stop triggering D1, so set the modifier of PORTD back to 0 | ||
- | a_mod = 0; // we want to stop triggering A1, so set the modifier of PORTA back to 0 | ||
- | |||
- | } | ||
- | } | ||
- | |||
- | // | ||
- | // -> Uses much less power. | ||
- | |||
- | PORTA = a_base - a_mod; | ||
- | } //End main loop | ||
- | return 0; | ||
- | } | ||
- | |||
- | - endif | ||
- | </ | ||
- | |||
playground/playground.1376431017.txt.gz · Last modified: 2013/08/13 14:56 by bmbr