// // // desk.c // // Charlieplexed array activated by step response sensor // // Adapted from code by Neil Gershenfeld and Matt Blackshaw // 12/14/14 // #include #include #define output(directions,pin) (directions |= pin) // set port direction for output #define input(directions,pin) (directions &= (~pin)) // set port direction for input #define set(port,pin) (port |= pin) // set port pin #define clear(port,pin) (port &= (~pin)) // clear port pin #define pin_test(pins,pin) (pins & pin) // test for port pin #define bit_test(byte,bit) (byte & (1 << bit)) // test for bit set #define charge_delay() _delay_us(1) // charge delay 1 #define settle_delay() _delay_us(100) // settle delay #define char_delay() _delay_ms(10) // char delay //#define activate 436 //sense value with FabISP attached #define activate 515 // sense value without FabISP //#define remain 440 // sense value for desk to remain lit with FabISP #define remain 525 // sense value for desk to remain lit without FabISP #define on_delay 700 // cycles for desk to remain lit after activated //Step Response Pins #define charge_port PORTA // set port A for for charge pin (PA7) #define charge_direction DDRA // set data direction register for charge pin #define charge_pin (1 << PA7) // set charge pin (shield in step response circuit) #define sense_pin (1 << PA6) // set sense pin //Charlieplexing Pins #define led_delay() _delay_ms(1) // LED delay #define led_port PORTA // set port A for LED pins #define led_direction DDRA // set data direction register for LED pins #define A (1 << PA1) // row 1 #define B (1 << PA2) // row 2 #define C (1 << PA3) // row 3 #define D (1 << PA4) // row 4 void flash(uint8_t from, uint8_t to, uint8_t delay) { // // source from, sink to, flash // static uint8_t i; set(led_port,from); clear(led_port,to); output(led_direction,from); output(led_direction,to); for (i = 0; i < delay; ++i) led_delay(); input(led_direction,from); input(led_direction,to); } void flash_multi(uint8_t from1, uint8_t from2, uint8_t from3, uint8_t to, uint8_t delay) { // // achieve better brightness by turning multiple // LED's on at the same time // static uint8_t i; set(led_port,from1); set(led_port,from2); set(led_port,from3); clear(led_port,to); output(led_direction,from1); output(led_direction,from2); output(led_direction,from3); output(led_direction,to); for (i = 0; i < delay; ++i) led_delay(); input(led_direction,from1); input(led_direction,from2); input(led_direction,from3); input(led_direction,to); } void led_cycle(uint8_t number, uint8_t delay) { // // cycle through LEDs // uint8_t i; for (i = 0; i < number; ++i) { flash(A,B,delay); flash(A,C,delay); flash(A,D,delay); flash(B,A,delay); flash(B,C,delay); flash(B,D,delay); flash(C,A,delay); flash(C,B,delay); flash(C,D,delay); flash(D,A,delay); flash(D,B,delay); flash(D,C,delay); } } void led_on(uint8_t number, uint8_t delay) { // // cycle through multiplte LED's at a time // uint8_t i; for (i = 0; i < number; ++i) { flash_multi(B,C,D,A,delay); flash_multi(A,C,D,B,delay); flash_multi(A,B,D,C,delay); flash_multi(A,B,C,D,delay); } } int check_pin(unsigned char pin) { unsigned char up_lo,up_hi,down_lo,down_hi; int up_value, down_value, value; // // set the A/D pin // ADMUX = (0 << REFS1) | (0 << REFS0) //Vcc ref on t44 | (0 << ADLAR) // right adjust | (1 << MUX2) | (1 << MUX1) | (0 << MUX0); //PA6 on t44 // // settle, charge, and wait // settle_delay(); set(charge_port, charge_pin); charge_delay(); // // initiate conversion // ADCSRA |= (1 << ADSC); // // wait for completion // while (ADCSRA & (1 << ADSC)) ; // // save result // up_lo = ADCL; up_hi = ADCH; // // settle, discharge, and wait // settle_delay(); clear(charge_port, charge_pin); charge_delay(); // // initiate conversion // ADCSRA |= (1 << ADSC); // // wait for completion // while (ADCSRA & (1 << ADSC)) ; // // save result // down_lo = ADCL; down_hi = ADCH; // // process result // up_value = 256*up_hi + up_lo; down_value = 256*down_hi + down_lo; value = (up_value + (1023 - down_value))/2.0; return value; } int main (void) { // // set clock divider to /1 // CLKPR = (1 << CLKPCE); CLKPR = (0 << CLKPS3) | (0 << CLKPS2) | (0 << CLKPS1) | (0 << CLKPS0); // // initialize output pins // clear(charge_port, charge_pin); output(charge_direction, charge_pin); // // intialize A/D // ADMUX = (0 << REFS1) | (0 << REFS0) //Vcc ref t44 | (0 << ADLAR) // right adjust | (1 << MUX2) | (1 << MUX1) | (0 << MUX0); //PA6 t44 ADCSRA = (1 << ADEN) // enable | (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0); // prescaler /128 // //main loop // while(1) { int value = check_pin(sense_pin); int i=0; int bright = 0.8*on_delay; while (value < activate) { // threshold for sensing proximity i=i++; if (i==1){ led_cycle(1,40); // LED initialization sequence led_on(1,50); } int t=0; while(t < on_delay){ t=t++; if ( t < bright){ // // hold LED's on for specified time // led_on(1,1); value = check_pin(sense_pin); // checking for user activity if (value < remain) { t = 0; // restart timer if user is active } } else if ( t > bright){ // // dim lights to indicate imminent deactivation // led_cycle(1,1); value = check_pin(sense_pin); // checking for user activity if (value < remain) { t = 0; // restart timer if user is active } } } } } }