Advertisement
grist

Untitled

Jan 9th, 2013
78
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 2.40 KB | None | 0 0
  1. /*
  2.  * MotionActivatedLightSwitch.c
  3.  *
  4.  * Created: 1/1/2013 3:57:11 PM
  5.  *  Author: grist.carrigafoyl
  6.  *  Target: ATtiny85
  7.  
  8.  Activate a pin when motion is detected via a PIR sensor on another pin. Checks
  9. ambient light level via a photoresistor on an analog input.
  10.  
  11. Didn't implement TIMER_POT in this version.
  12.  */
  13.  
  14. #define F_CPU           8000000UL  //  8Mhz
  15. #define ADMUX_BITS      0b0000     // All default (VCC ref, ADLAR unset)
  16. #define TIMER_POT       0b0001     // ADC1 PB2 (pin7)
  17. #define PHOTORESISTOR       0b0011     // ADC3 PB3 (pin2)
  18. #define PIR_PIN         PB0    // PCINT0 (pin5)
  19. #define SWITCH_PIN      PB1    // pin6
  20.  
  21. // The light level below which the switch will trigger.
  22. #define LOW_LIGHT_LEVEL     300 // Based on experimentation.
  23.  
  24. #include <avr/io.h>
  25. #include <util/delay.h>
  26.  
  27. // Prototypes
  28. int main(void);
  29. int read_adc(char pin);
  30.  
  31. int main(void)
  32. {
  33.     char pir_state;
  34.     int curr_light_level;
  35.  
  36.     // ADC settings. Check with data sheet that this is what you want
  37.     ADCSRA |= _BV(ADEN) | // Enable ADC
  38.         (_BV(ADPS1)) | // set pre-scaler to clock/128
  39.         (_BV(ADPS0)) | // 8MHz/128 = 62.5Khz (aiming for 50 - 200)
  40.         (_BV(ADPS2));  // so this is good.
  41.    
  42.     DDRB = _BV(SWITCH_PIN); // All input except the switch pin
  43.     PORTB = _BV(PIR_PIN);  // Internal pullup for the PIR pin
  44.    
  45.     // How long the light stays on for. Simple constant for now
  46.     int delay_time = 5000;
  47.     for (;;) {
  48.         pir_state = ~PINB & _BV(PIR_PIN);
  49.         if (pir_state != 0) {  // Movement detected
  50.             curr_light_level = read_adc(PHOTORESISTOR);
  51.             if (curr_light_level < LOW_LIGHT_LEVEL) {
  52.                 PORTB |= _BV(SWITCH_PIN);  // On
  53.                 _delay_ms(delay_time);
  54.             }
  55.         }
  56.         PORTB &= ~_BV(SWITCH_PIN); // Off
  57.     }
  58.     return 0; // Never going to happen
  59. }
  60.  
  61. int read_adc(char pin)
  62. { // Read the analog value from the ADC input pin.
  63.     // Code based on samples from http://avrbasiccode.wikispaces.com/
  64.     int ret_val;
  65.  
  66.     // Assumes ADCSRA enabled and prescalars are set already
  67.     // Set the input channel and other ADMUX bits
  68.     ADMUX = (ADMUX_BITS << 4) | pin;
  69.    
  70.     // Discard the first reading in case it had its settings changed mid-conversion
  71.     ADCSRA |= _BV(ADSC); // start a single conversion
  72.     while (ADCSRA & _BV(ADSC)); // wait until conversion is done
  73.  
  74.     ADCSRA |= _BV(ADSC); // start a single conversion
  75.     while (ADCSRA & _BV(ADSC)); // wait until conversion is done
  76.    
  77.     ret_val = ADCL; // Get ADCL first for 10bit and combine with ADCH
  78.     return((ADCH << 8) | ret_val);
  79. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement