/* TEMP1 Temperature monitor and data logging One to four temperature sensors can be used Each are measured every second The highest value for each is stored during a 5 second cycle and then written to memory The LED is illuminated if any sensor exceeds 50'C (visual indication of high heat) Memory is cleared every time the device is powered up Data must start being downloaded before LED's stop flashing (within 6 seconds of applying power) Memory can hold 32 iterations of 4 sensors Measuring temperatures in 5 second 'cycles' yields 5 minutes recording time Sensors can be calibrated by setting values in the 'offset' array To get identical measurements: 1. Comment out the 'Convert to degrees' section in measure_temp() (to get raw ADC values) 2. Zero the values in the offset[] array 3. Suspend sensors in still air and allow to settle 4. Capture test data and adjust the offset[] array to give no differences 5. Restore the commented out code Written for PIC12F683 (8 pin) / BoostC compiler and MCP9701 temperature sensors Assuming a 5v reference voltage, an ADC value of 82 represents 0'C Each degree above or below this increments ADC value by 4 (eg: 282 is 50'C: 282-82 =200 /4 =50') Personal and non-commercial use encouraged Copyright 2007 - David Theunissen - See www.flyelectric.ukgateway.net */ //PREPROCESSOR section ======================================================== #include //Generic device 'include'; actual device set in compiler (Settings/Target) #pragma DATA _CONFIG, _FCMEN_OFF & _IESO_OFF & _BOD_ON & _CPD_OFF & _CP_OFF & _MCLRE_OFF & _PWRTE_ON & _WDT_OFF & _INTOSCIO //Core configuration options //VARIABLES section =========================================================== #define led gpio.5 //GP5 (Pin2) is LED typedef unsigned char u8; //Defines u8 as an unsigned char (8bits) typedef unsigned short u16; //Defines u16 as an unsigned short (16bits) u8 offset[5] = {0,11,0,0,0}; //Mechanism for calibrating sensors (ignore 1st) u16 temp[5]; //Individual temperature sensor values u16 high_t[5]; //Highest accummulated temperatures in each cycle u16 highest_t; //Highest overall temperature seen (for LED) u16 t_value; //Used to run ADC module u8 channel[5]; //ADC channel config u16 m_count; //Memory counter - prevents over-writes //FUNCTIONS section =========================================================== void write_data () //Function to write to EEPROM flash memory { intcon.7 = 0; //Disable all interrupts if not done elsewhere pir1.7 = 0; //EEIF: Clear this bit which gets set after each write eecon2 = 0x55; //Required before writing to memory eecon2 = 0xAA; //Required before writing to memory eecon1.1 = 1; //WR: Writes data eedata to address eeadr while(eecon1.1==1); //Wait for write to complete (becomes 0 when complete) eeadr++; //Increment the address by 1 for next write (8 bit 0-255) //intcon.7 = 1; //Enable interrupts if appropriate } //----------------------------------------------------------------------------- void run_adc () //Function to run ADC conversions { u8 p; //Run ADC for(p=0; p<1; p++); //Delay for acquisition capacitor to charge (1 = ~14uS) pir1.6 = 0; //Clear the ADC Complete flag adcon0.1 = 1; //GO: Start ADC acquisition while(pir1.6==0); //Wait for conversion to complete (become 1) //Store ADC value in ADCVALUE MAKESHORT(t_value, adresl, adresh); } //----------------------------------------------------------------------------- void measure_temp () //Function to trigger ADC conversions and measure temperatures { u8 i; //adcon0 structure... //1 Right justify ADC values //0 Use Vdd as reference //00 Not used //10 Input channel (CHS0) is AN2 (THIS PART CHANGES BELOW) //0 ADC capture (GO) not started //1 ADC enabled //Run ADC for(i=1; i<5; i++) { adcon0 = channel[i]; //Makes AN0 channel active run_adc(); //Run ADC conversion temp[i] = t_value; //Copy result into appropriate register } //Convert to degrees for(i=1; i<5; i++) { temp[i] -= offset[i]; //Deduct calibration value temp[i] -= 82; //Deduct 0' offset temp[i] /= 4; //Convert to degrees C } } //=========================================================================== void main() //main program { //Main port settings gpio = 0; //Initialise port trisio.0 = 1; //Sets GP0/AN0 (pin7) to Input (sensor1) trisio.1 = 1; //Sets GP1/AN1 (pin6) to Input (sensor2) trisio.2 = 1; //sets GP2/AN2 (pin5) to Input (sensor3) trisio.4 = 1; //sets GP4/AN3 (pin3) to INput (sensor4) trisio.5 = 0; //Sets GP5 (pin2) to Output (LED) ansel.0 = 1; //Sets AN0 (pin7) to analogue ansel.1 = 1; //Sets AN1 (pin6) to analogue ansel.2 = 1; //Sets AN2 (pin5) to analogue ansel.3 = 1; //Sets AN3 (pin3) to analogue cmcon0 = 0b111; //Switches all 3 comparator ports off //Static ADC settings ansel.4 = 1; //ADCS: Set AD Conversion Clock to Fosc/16 ansel.5 = 0; //part of above ansel.6 = 1; //part of above pie1.6 = 0; //ADC interrupts disabled //ADC channel config channel[1] = 0b10000001; channel[2] = 0b10000101; channel[3] = 0b10001001; channel[4] = 0b10001101; //Initialise u8 i; u8 k; highest_t = 0; m_count = 0; //Static EEPROM data logging settings eecon1.3 = 0; //WRERR: clear on startup in case previously set eecon1.2 = 1; //WREN: enable writing to memory eeadr = 0; //Address to be used for first write //Flash LED three times on startup //Download of data must start in this 3sec window to avoid being over-written for (i=0; i<3; i++) { led=1; delay_s(1); led=0; delay_s(1); } //Initialise EEPROM //This overwrites memory so start download before LEDs stop flashing!!! u16 e; for (e=0; e<256; e++) { eedata = 0; write_data(); } eeadr = 0; //Address to be used for first write in rest of program //----------------------------------------------------------------------------- while(1) { //Initialise for(i=1; i<5; i++) high_t[i]=0; //Establish timing of cycles and writes to memory ('k' represents seconds) for (k=0; k<10; k++) //Measure sensors k times in each cycle { measure_temp(); //Measure all sensors for(i=1; i<5; i++) { if(temp[i]>high_t[i]) high_t[i]=temp[i];//Store highest temperatures } delay_s(1); //Wait 1 second } //Write highest temperatures in each cycle to memory if (m_count<252) //Check if space remains (to prevent memory being over-written) { for(i=1; i<5; i++) { eedata = high_t[i]; //Select high 8bits to record write_data(); //Write to memory m_count ++; //Increment counter } } //Determine highest temperature seen for(i=1; i<5; i++) { if (high_t[i]>highest_t) highest_t=high_t[i]; //Increment if higher } //Illuminate LED if chosen threshold exceeded (simple visual indication) if (highest_t>50) led=1; //One-off; does not reset } //end while } //end main