#include #include "lcd.h" #include "delay.h" #include // Updated April 2007, MAE // Updated March 2007, wlg // This is the sensor.c file int datapoints = 0; float CDEG, FDEG, XIN,Y, DKEL; float XIN6 = 0, XIN5 = 0, XIN4 = 0, XIN3 = 0, XIN2 = 0, XIN1 = 0; float A,B,A1; bool AD590 = 1; // Which sensor, AD590 or AD22103 void main(void) { // clock config WDTCTL = WDTPW + WDTHOLD; // Stop WDT // set up Basic Timer IE2 |= BTIE; // Enable BT interrupt BTCTL = BT_ADLY_2000 | BT_fLCD_DIV256; // 128 Hz LCD, 2s Interrupt // set up ADC ADC12IE |= 0x0040; // Enable ADC6 ADC12CTL0 = ADC12ON + REF2_5V + REFON; // Aref = 2.5V, Aref on ADC12CTL1 = CSTARTADD_6 + ADC12SSEL_1 + SHP; // ADCCLK = ACLK, pulse mode; ADC12MCTL6 = SREF_1 + INCH_6; // Select sixth reg, Aref on, Aref = Vref+,Avss ADC12CTL0 |= ENC ; //set port pins //set P6.6/A6 as input P6SEL |= BIT6; //select adc function //call lcd func setupLCD(); // Enable interrupts and go to sleep forever _EINT(); // Enable interrupts // _BIS_SR(LPM3_bits); // Enter LPM4 while(1); // NOP } // Basic Timer interrupt service routine interrupt[BASICTIMER_VECTOR] void basic_timer(void) { ADC12CTL0 |= ADC12SC; // start conversion } // ADC interrupt service routine interrupt[ADC_VECTOR] void adc(void) { // ****************************************** // ****************************************** // The following code combines code writen by // Matt Mahin of UNF to get display output for the // AD590 Analog Device temperature sensor. // Prepared by W. L. Green ECE Department, University // of Tennessee; April, 2006 if(AD590){ A = 0.613; B = 0.2; XIN = abs( A*B*ADC12MEM6 ); // Absoulte value of input, Kelvin is an absolute scale }else{ A = 0.0613; A1 = 21.5909; B = 2.41818; XIN = ((ADC12MEM6*A) - A1)/B; } // The external sensor signal is brought in on the A to D // converter at ADC12MEM6; // A is a scale factor (0.163) that takes the input from the A/D // and produces a number on the display that corresponds to the // input to the A/D. // B is a scale factor the is the recipal of the gain of the op amp // used to raise the sensor output voltage. In my case an op amp gain // of 5 was used. Therefore, B = 0.2. // Check to see if we have a real value // I noticed values up to 150 can be just noise, but I set it to 75 to be safe // This means this program will only work down to -123.2 degrees celcius // Keep up to 6 of the last values for averaging/smooting purposes if(XIN > 75){ if(datapoints < 6){datapoints++;} XIN6 = XIN5; XIN5 = XIN4; XIN4 = XIN3; XIN3 = XIN2; XIN2 = XIN1; XIN1 = XIN; }else{ // Note that if a case statement does not have a break, // all the statements after it will ALSO happen switch(datapoints){ case 0: case 1: XIN1 = 0; case 2: XIN2 = 0; case 3: XIN3 = 0; case 4: XIN4 = 0; case 5: XIN5 = 0; case 6: XIN6 = 0; break; } if(datapoints > 0){ datapoints--;} } // Require at least 2 datapoints to have a "valid" reading if(datapoints < 2){ lcd_all(0); lcd_scroll("Reading Sensor"); return; } // If we made it to this point, we have enough values to show something // Filter the signal with a 6th order variable FIFO queue moving average filter. DKEL = ( XIN1 + XIN2 + XIN3 + XIN4 + XIN5 + XIN6 ) / (float)datapoints; // DKEL is deg Kelvin if(!AD590){CDEG = DKEL;} // The AD22103 gives values in C already else{CDEG = (DKEL - 273.2);} // Converting from Kelvin to deg C // In this case DKEL is the sensor reading // in deg K. FDEG = 1.8*CDEG + 32.0; // converting from deg C to deg F if(CDEG<200){ lcd_word(100*CDEG, 2); // the l00 causes the first 3 digits of CDEG }else{ // to be displayed. The 2 causes a decimal lcd_word(10*CDEG,1); // to be placed to the left of the second display } // slot. lcd_char(0,'C'); // The 0 corresponds to the first position on the // right side of the display. The 'C' causes a C // to be displayed in this position wait_ms(2000); // Waits 2000 milliseconds then displays deg F if(FDEG<200){ lcd_word(100*FDEG, 2); // The l00 causes the first 3 digits of FDEG to be displayed. }else{ // The 2 moves the decimal to the left of the 2nd position. lcd_word(10*FDEG,1); } lcd_char(0, 'F'); // See the above statement wait_ms(2000); // Wait 2000 milliseconds. The program then moves // back to lcd_word(100*CDEG, 0) and continues as a loop }