Advertisement
Guest User

Airwick Sensor with Timers

a guest
Jun 19th, 2014
1,350
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 3.19 KB | None | 0 0
  1. ///////////////////////////////////////////////////////
  2. //
  3. // AS-MLV_P VOC Sensor
  4. //
  5. // Test program
  6. //
  7. // (c) 2014 by Koepi
  8. //
  9. ///////////////////////////////////////////////////////
  10.  
  11. #include <stdio.h>
  12.  
  13. #define heater 0b00000100  // Heater VCC on D2 (PinD2)
  14. #define sensor 0b00000001  // Sensor VCC/Input on A0 (PinC0)
  15.  
  16. #define GREEN 0b00001000  // RGB LED green
  17. #define BLUE 0b00010000  // RGB LED blue
  18. #define RED 0b00100000  // RGB LED red
  19.  
  20. volatile uint16_t sensor_val = 0;
  21. uint32_t sensor_ovs = 0;
  22. volatile uint32_t timer = 0;
  23. volatile uint16_t milliseconds = 0;
  24. volatile bool sent = false;
  25. volatile uint8_t ms_old = 0;
  26.  
  27. ISR(TIMER0_COMPA_vect)
  28. {
  29.   milliseconds++;
  30.   if (milliseconds == 1001) {
  31.     milliseconds = 0;
  32.     timer++;
  33.   }
  34.  
  35.   if (milliseconds & 0x02) {  // PWM duty 25% for LED - switch on every 2nd uneven ms.
  36.       if (sensor_val<500) {
  37.         PORTD |= GREEN;
  38.       } else if (sensor_val<1000) {
  39.           PORTD |= BLUE;
  40.         } else if (sensor_val>=1000) {
  41.           PORTD |= RED;
  42.         }
  43.   } else PORTD&=~(RED|GREEN|BLUE);  // switch all LEDs off again. It's PWM! ;)
  44. }
  45.  
  46. void setup() {
  47.   // setup the sensor
  48.   DDRD |= heater;  // Heater is OUTPUT
  49.   PORTD &= ~(heater);  // Heater is OFF
  50.   DDRC &= ~(sensor);  // Sensor is INPUT
  51.   PORTC &= ~(sensor);  // Disable PullUp
  52.  
  53.   // ADC setup
  54.   ADCSRA |= ((1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0));  //Prescaler at 128 -> 125Khz ADC clock source
  55.   ADMUX |= (1<<REFS1);  // Avcc(+5v) as voltage reference
  56.   ADMUX |= 0;  // Pin A0 -> No change in MUX register...
  57.   ADCSRA |= (1<<ADEN);  //Power up the ADC
  58.   ADCSRA |= (1<<ADSC);  //Start converting
  59.  
  60.   // setup the LED
  61.   DDRD |= RED | GREEN | BLUE;  // RGB LED is OUTPUT
  62.  
  63.   // setup timer for LED PWM
  64.   cli();  // disable global interrupts
  65.   TCNT0 = 0;  // reset Timer2 counter value
  66.   TCCR0A = (1 << WGM01);   // CTC mode
  67.   TCCR0B = (1 << CS02) | (1 << CS00);  // Prescaler 1024
  68.   OCR0A = 15;  // 1000 Hz, Prescaler 1024 -> F_CPU / 1024 (Prescaler) /1000 (Hz) -1 -> 15,625Hz
  69.   TIMSK0 = (1<<OCIE0A);  // enable comapre-match OCR2A interrupt
  70.   sei();  // start global interrupts
  71.  
  72.   // for monitoring
  73.   Serial.begin(115200);
  74. }
  75.  
  76. void loop() {
  77.   char text[16];
  78.  
  79.   if ((milliseconds >= 100) && (milliseconds <=120)) {  // heat up the sensor
  80.     if (milliseconds & 0x01) PORTD |= heater; // turn on heating
  81.     else PORTD &= ~(heater); // turn off heating
  82.   }
  83.  
  84.   if (milliseconds == 121) PORTD &= ~(heater); // turn off heating
  85.  
  86.   if (milliseconds == 200) {  // measure the sensor
  87.     for (int i=0; i<64; i++) {  // Oversampling
  88.       ADCSRA |= (1<<ADSC);  // Start a new conversion
  89.       cli();  // disable interrupt
  90.       while(ADCSRA & (1<<ADSC));  // Wait for the conversion to finish
  91.       sensor_ovs += ADC << 1;
  92.       sei();  // enable interrupts
  93.     }
  94.     sensor_val = (sensor_ovs >> 5);
  95.     sensor_ovs=0;
  96.     sent = false;
  97.     milliseconds+=24;  // compensate for measuring time
  98.   }
  99.  
  100.   if (milliseconds == 250) {  // print out results via serial console
  101.     if (!sent) {
  102.       sprintf(text, "$1;1;%u;",timer);
  103.       Serial.print(text);
  104.       sprintf(text, "%u;0",sensor_val);
  105.       Serial.println(text);
  106.       sent = true;
  107.     }
  108.   }
  109. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement