Advertisement
Guest User

26.06.2014 VOC-Sensor @ ATmega328

a guest
Jun 25th, 2014
563
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.96 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 0b00000010  // Heater VCC on A1 (PinC1)
  14. #define sensor 0b00000001  // Sensor VCC/Input on A0 (PinC0)
  15.  
  16. #define GREEN 0b00001000  // RGB LED green
  17. #define BLUE 0b00100000  // RGB LED blue
  18. #define RED 0b00010000  // 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 bool measured = false;
  26. volatile int temperature=0;
  27. volatile uint8_t ms_old = 0;
  28.  
  29. ISR(TIMER0_COMPA_vect)
  30. {
  31.   milliseconds++;
  32.   if (milliseconds == 1001) {
  33.     milliseconds = 0;
  34.     timer++;
  35.   }
  36.  
  37.   if (milliseconds & 0x04) {  // PWM duty 12,5% for LED - switch on every 4th uneven ms.
  38.       if (sensor_val<200) {
  39.         PORTD |= GREEN;
  40.       } else if (sensor_val<500) {
  41.           PORTD |= BLUE;
  42.         } else if (sensor_val>=500) {
  43.           PORTD |= RED;
  44.         }
  45.   } else PORTD&=~(RED|GREEN|BLUE);  // switch all LEDs off again. It's PWM! ;)
  46. }
  47.  
  48. void setup() {
  49.   // setup the sensor
  50.   DDRC |= heater;  // Heater is OUTPUT
  51.   PORTC &= ~(heater);  // Heater is OFF
  52.   DDRC &= ~(sensor);  // Sensor is INPUT
  53.   PORTC &= ~(sensor);  // Disable PullUp
  54.  
  55.   // ADC setup
  56.   ADCSRA |= ((1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0));  //Prescaler at 128 -> 125Khz ADC clock source
  57.   ADMUX |= (1<<REFS1);  // Avcc(+5v) as voltage reference
  58.   ADMUX |= 0;  // Pin A0 -> No change in MUX register...
  59.   ADCSRA |= (1<<ADEN);  //Power up the ADC
  60.   ADCSRA |= (1<<ADSC);  //Start converting
  61.  
  62.   DIDR0 = (1 << ADC0D) | (1 << ADC1D);  // Disable Digital Input Buffer on Pin C0/C1
  63.  
  64.   // setup the LED
  65.   DDRD |= RED | GREEN | BLUE;  // RGB LED is OUTPUT
  66.  
  67.   // setup timer for LED PWM
  68.   cli();  // disable global interrupts
  69.   TCNT0 = 0;  // reset Timer2 counter value
  70.   TCCR0A = (1 << WGM01);   // CTC mode
  71.   TCCR0B = (1 << CS02) | (1 << CS00);  // Prescaler 1024
  72.   OCR0A = 15;  // 1000 Hz, Prescaler 1024 -> F_CPU / 1024 (Prescaler) /1000 (Hz) -1 -> 15,625Hz
  73.   TIMSK0 = (1<<OCIE0A);  // enable comapre-match OCR2A interrupt
  74.   sei();  // start global interrupts
  75.  
  76.   // for monitoring
  77.   Serial.begin(57600);
  78. }
  79.  
  80. void loop() {
  81.   char text[16];
  82.  
  83.   if ((milliseconds >= 100) && (milliseconds <=(127 - (temperature/4)))) {  // heat up the sensor / temperature compensated
  84.     if (milliseconds & 0x01) PORTC |= heater; // turn on heating
  85.     else PORTC &= ~(heater); // turn off heating
  86.   }
  87.  
  88.   if (milliseconds == 130) PORTC &= ~(heater); // turn off heating for sure
  89.  
  90.   if (milliseconds == 200) {  // measure the sensor
  91.     for (int i=0; i<4; i++) {  // averaging
  92.       ADCSRA |= (1<<ADSC);  // Start a new conversion
  93.       while(ADCSRA & (1<<ADSC));  // Wait for the conversion to finish
  94.       sensor_ovs += ADC ;
  95.     }
  96.     sensor_val = (sensor_ovs >> 2);
  97.     sensor_ovs=0;
  98.     sent = false;
  99.   }
  100.  
  101.   if (milliseconds == 250) {  // print out results via serial console
  102.     if (!sent) {
  103.       sprintf(text, "$1;1;");
  104.       Serial.print(text);
  105.       sprintf(text, "%u;",timer);
  106.       Serial.print(text);
  107.       sprintf(text, "%u;",sensor_val);
  108.       Serial.print(text);
  109.       sprintf(text, "%u;",temperature);
  110.       Serial.print(text);
  111.       sprintf(text, "0");
  112.       Serial.println(text);
  113.       sent = true;
  114.     }
  115.   }
  116.  
  117.   if (milliseconds == 690) {  // switch ADC Mux to Pin A1 & Heater -> INPUT; stabelizing for some ms
  118.     if (!measured) {  // only run once per second ;)
  119.       measured=true;
  120.  
  121.       // make heater INPUT
  122.       DDRC &= ~(heater);  // Heater is INPUT
  123.       PORTC |= (heater);  // Heater uses PullUp for measurement
  124.  
  125.       // switch ADC Mux to Pin A1 and measure
  126.       ADMUX |= (1 << MUX0);  // Pin A1
  127.       ADCSRA |= (1<<ADSC);  //Start converting
  128.     }  // of if measured
  129.   }
  130.  
  131.   if (milliseconds==699) measured=false;
  132.  
  133.   if (milliseconds == 700) {  // measure resistance of heater
  134.     if (!measured) {  // only run once per second ;)
  135.       measured=true;
  136.    
  137.       for (int i=0; i<4; i++) {  // averaging
  138.         ADCSRA |= (1<<ADSC);  //Start converting
  139.         while(ADCSRA & (1<<ADSC));  // Wait for the conversion to finish
  140.         temperature+=(ADC-62);
  141.       }
  142.       temperature >>= 2;
  143.     }  // of if measured
  144.   }  
  145.  
  146.   if (milliseconds==702) measured=false;
  147.  
  148.   if (milliseconds==703) {  // switch back to Heater mode and Pin C0 measurement
  149.     if (!measured) {  // only run once per second ;)
  150.       measured=true;
  151.       // switch ADC Mux back to Pin A0
  152.       ADMUX &= ~(1 << MUX0);  // Disable Pin C1, return to Pin C0
  153.       ADCSRA |= (1<<ADSC);  //Start converting
  154.       // restore heater as OUTPUT
  155.       PORTC &= ~(heater);  // Heater disable PullUp
  156.       DDRC |= heater;  // Heater is OUTPUT
  157.       PORTC &= ~(heater);  // Heater is OFF
  158.     }  // of if measured
  159.   }
  160.  
  161.   if (milliseconds==705) measured=false;
  162. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement