Advertisement
Guest User

Stair-Light Prox/Motion Sensor - Draft

a guest
Jan 23rd, 2012
64
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.58 KB | None | 0 0
  1. /*
  2. Copyright 2011 Dustin L. Westaby
  3.  
  4. ----------------------------------------------------------------------
  5.     Stairway Light Controller for Attiny2313
  6. ----------------------------------------------------------------------
  7. Title:      stairway.c
  8. Author:     Dustin Westaby
  9. Date Created:   01/19/12
  10. Last Modified:  
  11. Purpose:  Monitor proximity and motion sensors and animate stairway
  12.           lighting.
  13.  
  14. Compiled with AVR-GCC WinAVR
  15.  
  16. Revisions List:
  17. 01/19/12 Initial draft
  18.  
  19. ----------------------------------------------------------------------
  20.     Fuses:
  21. ----------------------------------------------------------------------
  22.  BrownOut Disabled
  23.  CKDIV8
  24.  Int RC Osc 8Mhz + 64ms
  25.  
  26. ----------------------------------------------------------------------
  27.     Inputs:
  28. ----------------------------------------------------------------------
  29.  pin       port    function
  30. ----------------------------------------------------------------------
  31.   1        RST     Unused
  32.   2        PD0     Motion Sensor    (digital) (active low with pullup 10k)
  33.  23        PC0     Prox Sensor Low  (digital) 5 feet range
  34.  24        PC1     Prox Sensor High (digital)
  35.   4        PD2     Override button  (digital) External Interrupt 0
  36.  
  37. ----------------------------------------------------------------------
  38.     Ouputs:
  39. ----------------------------------------------------------------------
  40.  pin       port    function
  41. ----------------------------------------------------------------------
  42.  14        PB0      Lighting Channel
  43.  15        PB1      Lighting Channel
  44.  16        PB2      Lighting Channel
  45.  17        PB3      Lighting Channel
  46.  18        PB4      Lighting Channel
  47.  19        PB5      Lighting Channel
  48.   9        PB6      Lighting Channel
  49.  10        PB7      Lighting Channel
  50.  
  51.  
  52. The Prox sensors are analog, uses a comparator to convert to digital
  53. and a pot to select the cutoff range.
  54.  
  55. */
  56.  
  57. //--------------------------------------
  58. //          Global Variables           |
  59. //--------------------------------------
  60. // 8 MHz Internal Oscillator DIV8 (used for delay subroutines)
  61. // One CPU Cycle = 1us
  62. #define F_CPU 8000000UL/8
  63.  
  64. enum { up, down };
  65. enum { on, off };
  66. enum { low, high };
  67.  
  68. //--------------------------------------
  69. //              Includes               |
  70. //--------------------------------------
  71. #include <avr/io.h>
  72. #include <util/delay.h>
  73. //#include <avr/sleep.h>
  74. #include <inttypes.h>
  75.  
  76.  
  77. //--------------------------------------
  78. //          Global Constants           |
  79. //--------------------------------------
  80.  
  81. int START_CH = PB0; //lowest channel bit
  82. int NUM_OF_CH = 6;
  83. int ALL_ON  = 0xFF;
  84. int ALL_OFF = 0x00;
  85.  
  86. //--------------------------------------
  87. //          Delay Subroutines          |
  88. //--------------------------------------
  89. //These functions are from the delay.h include, the calls to delay functions
  90. //are re-written here to allow for longer waits.
  91. void delay_ms(uint16_t ms) {
  92.   while ( ms )
  93.   {
  94.     _delay_ms(1);
  95.     ms--;
  96.   }
  97. }
  98.  
  99. void delay_us(uint16_t us) {
  100.   while ( us )
  101.   {
  102.     _delay_us(1);
  103.     us--;
  104.   }
  105. }
  106.  
  107.  
  108. //--------------------------------------
  109. //          Other Functions            |
  110. //--------------------------------------
  111.  
  112. void standby_sequence(int count)
  113. {
  114.     int i;
  115.  
  116.     //determine if count is even or odd
  117.     PORTB = ALL_OFF;
  118.     if (count % 2 == 0)
  119.     {
  120.         //every other bit, even
  121.         for (i=START_CH; i <= NUM_OF_CH; i+=2)
  122.         {
  123.             PORTB |= (1 << i);
  124.         }
  125.     }
  126.     else
  127.     {
  128.         //every other bit, odd
  129.         for (i=(START_CH+1); i <= NUM_OF_CH; i+=2)
  130.         {
  131.             PORTB |= (1 << i);
  132.         }
  133.     }
  134.  
  135.  
  136. }
  137.  
  138. void animate_sequence(int direction, int onoff)
  139. {
  140.     int time = 100;
  141.     int i;
  142.  
  143.     if(direction == up)
  144.     {
  145.         if (onoff == on )
  146.         {
  147.             //rotates through.
  148.             PORTB = ALL_OFF;
  149.             for (i=START_CH; i < NUM_OF_CH; i++)
  150.             {
  151.                 PORTB |= (1 << i);
  152.                 delay_ms(time);
  153.             }
  154.  
  155.         }
  156.         else
  157.         {
  158.             //rotates through.
  159.             PORTB = ALL_ON;
  160.             for (i=START_CH; i < NUM_OF_CH; i++)
  161.             {
  162.                 PORTB &= ~(1 << i);
  163.                 delay_ms(time);
  164.             }
  165.  
  166.         }
  167.  
  168.     }
  169.     else
  170.     {
  171.         if (onoff == on )
  172.         {
  173.             //reverse rotates through.
  174.             PORTB = ALL_OFF;
  175.             for (i=( START_CH + NUM_OF_CH - 1); i >= 0; i--)
  176.             {
  177.                 PORTB |= (1 << i);
  178.                 delay_ms(time);
  179.             }
  180.         }
  181.         else
  182.         {
  183.             //reverse rotates through.
  184.             PORTB = ALL_ON;
  185.             for (i=( START_CH + NUM_OF_CH - 1); i >= 0; i--)
  186.             {
  187.                 PORTB &= ~(1 << i);
  188.                 delay_ms(time);
  189.             }
  190.         }
  191.     }
  192.  
  193. }
  194.  
  195.  
  196. int low_read()
  197. {
  198.  
  199.     if (bit_is_set(PIND, PD0))
  200.     {
  201.         delay_ms(1);
  202.         if (bit_is_set(PIND, PD0))
  203.         {
  204.             delay_ms(5);
  205.             return 1;
  206.         }
  207.     }
  208.  
  209.     return 0;
  210. }
  211.  
  212. int high_read()
  213. {
  214.  
  215.     if (bit_is_set(PIND, PD1))
  216.     {
  217.         delay_ms(1);
  218.         if (bit_is_set(PIND, PD1))
  219.         {
  220.             delay_ms(5);
  221.             return 1;
  222.         }
  223.     }
  224.  
  225.     return 0;
  226. }
  227.  
  228. int motion_read()
  229. {
  230.  
  231.     //[tbd] read motion sensor
  232.  
  233.     return 0;
  234. }
  235.  
  236.  
  237. void init_cpu()
  238. {
  239.     // Set direction registers
  240.     // sensors data direction
  241.     // lighting data direction
  242.  
  243.     DDRA =  0b11111111;
  244.     DDRB =  0b11111111;
  245.     DDRD =  0b00000000;
  246.  
  247.  
  248.     // Enable Wake Interrupts
  249.     //[TBD]
  250.    
  251.     // Set power down mode
  252.     //[tbd]
  253.  
  254. }
  255.  
  256.  
  257. //--------------------------------------
  258. //               Main                  |
  259. //--------------------------------------
  260. int main (void)
  261. {
  262.     int low_store = 0, high_store = 0;
  263.     int trigger_direction;
  264.     int counterA, counterB;
  265.     int motion_store = 0;
  266.     int TIMEOUT_MAX = 117; //~30 seconds
  267.  
  268.     init_cpu();  
  269.  
  270.     //turn off LEDs
  271.     PORTB = 0x00;
  272.  
  273.     while(1)
  274.     {
  275.         low_store = 0;
  276.         high_store = 0;
  277.         counterA = 0;
  278.         counterB = 0;
  279.         motion_store = 0;
  280.  
  281.         //wait for either ADC to match (ADC0 > ADC2) | (ADC1 > ADC3)
  282.         while((low_store != 1) && (high_store != 1) && (motion_store != 1))
  283.         {
  284.        
  285.             //read the sensor data and store local
  286.             low_store = low_read();
  287.             high_store = high_read();
  288.             motion_store = motion_read();
  289.  
  290.         }
  291.        
  292.  
  293.         //Determine which condition fired, so that the other may be watched later
  294.         if (low_store == 1)
  295.         {
  296.             //low sensor fired
  297.             trigger_direction = low;
  298.  
  299.             // play animations for low to high
  300.             animate_sequence(up, on);
  301.  
  302.             //turn on leds in low to high sequence
  303.  
  304.             //wait for high sensor
  305.             while((high_read() != 1) && (counterB <= TIMEOUT_MAX))
  306.             {
  307.                 counterA++;
  308.                 delay_ms(1);
  309.                 if (counterA >= 255)
  310.                 {
  311.                     counterA = 0;
  312.                     counterB++;
  313.                 }
  314.                
  315.                 if ((motion_read() == 1) || (low_read() == 1))
  316.                 {
  317.                     //motion detected, reset timer, turn lights on
  318.                     counterB = 0;
  319.                     PORTB = ALL_ON;
  320.                 }
  321.                
  322.                 if (counterB > (2*TIMEOUT_MAX/3))
  323.                 {
  324.                     //play standby animation (timeout is 2/3s complete)
  325.                     standby_sequence(counterB);
  326.                 }
  327.  
  328.             }
  329.  
  330.             //turn off LEDs
  331.             animate_sequence(up, off);
  332.  
  333.         }
  334.         else if (high_store == 1)
  335.         {
  336.             //high sensor fired
  337.             trigger_direction = high;
  338.  
  339.             //play animations for high to low
  340.             animate_sequence(down, on);
  341.  
  342.             //wait for low sensor
  343.             //also timeout
  344.             while((low_read() != 1) && (counterB <= TIMEOUT_MAX))
  345.             {
  346.                 counterA++;
  347.                 delay_ms(1);
  348.                 if (counterA >= 255)
  349.                 {
  350.                     counterA = 0;
  351.                     counterB++;
  352.                 }
  353.                
  354.                 if ((motion_read() == 1) || (high_read() == 1))
  355.                 {
  356.                     //motion detected, reset timer, turn lights on
  357.                     counterB = 0;
  358.                     PORTB = ALL_ON;
  359.                 }
  360.                
  361.                 if (counterB > (2*TIMEOUT_MAX/3))
  362.                 {
  363.                     //play standby animation (timeout is 2/3s complete)
  364.                     standby_sequence(counterB);
  365.                 }
  366.  
  367.                
  368.             }
  369.  
  370.             //turn off LEDs
  371.             animate_sequence(down, off);
  372.  
  373.         }
  374.         else
  375.         {
  376.             //[tbd] motion detected animation
  377.         }
  378.  
  379.         //small delay before lights are allowed to trigger again
  380.         delay_ms(2000);
  381.  
  382.        
  383.  
  384.  
  385.     }
  386.  
  387.  
  388.   while(1);                 // Ending infinite loop (just in case)
  389.  
  390. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement