Temperature

Thread Starter

FroceMaster

Joined Jan 28, 2012
708
Let us have a go at this tomorrow
Have u read back a couple of mess. Have got it to work. Just need to calculate
5000 mv divede by 1024 and 50 mv pr degree that should be possible to calc..
Or ???
Chip have 1024 steps. And 0-5 v ??
Or am i totally wrong ?
 

t06afre

Joined May 11, 2009
5,934
Have u read back a couple of mess. Have got it to work. Just need to calculate
5000 mv divede by 1024 and 50 mv pr degree that should be possible to calc..
Or ???
Chip have 1024 steps. And 0-5 v ??
Or am i totally wrong ?
That is fine! the ADC conversion result can take values from 0 to 1023. So it has 1024 steps. Each step is Vref/1024. In your case Vref is 5 volt. So each step is 5/1024. To be a nitpick the range is 0 to 5-(5/1024) volt. But well it is common to ignore the last term:)
 

t06afre

Joined May 11, 2009
5,934
Could be. Just somewhere in that statement
Not that familier with "for" statement in c code

Removed the "for" line. Then it works
now i need to get the right degree. But that should be simple
By the way, you must include what the endless for loop shall like this
Rich (BB code):
for(;;)
      {
           some code
       }
Else it will only loop in a do nothing loop
 

Thread Starter

FroceMaster

Joined Jan 28, 2012
708
Have a little calculate problem
if my input is 700 mv( measure by fluke).
Rich (BB code):
while(GO_DONE) continue;
degree = ADRESL; // Get the 8 bit LSB result
degree += (ADRESH << 8); // Get the 2 bit MSB result
and i calculate (5000/1024) * degree // IS THE degree in BIN ?
Thats should be the input in mv ?? right ?
but somehow it only calculate to arround 620 mv. ?
why ?
 

spinnaker

Joined Oct 29, 2009
7,830
You are talking about 80 mv difference. That is next to nothing. Who says your meter is right?

Unless you have an extremely stable voltage reference you are not going to get an exact match.

You could simply correct for the difference in software if the differences are consistent.
 

t06afre

Joined May 11, 2009
5,934
The ADC in your setting use the power supply voltage as reference. If the power supply voltage is not 5.0000 volt some error may be introduced
 

spinnaker

Joined Oct 29, 2009
7,830
Any way to get around that ?
or do i have to live with it.
only 8 degree wrong ;)
You can use an external voltage reference. It is a chip that will give a steady voltage at whatever you select.

Check your math again. Is 50mv really that much of a difference in temperature?


All of this is why I suggested something like the DS1820 in the first place. A little hard to get the one wire protocol to work but once you are past that, it is easy.
 

spinnaker

Joined Oct 29, 2009
7,830
Other nice things about the Dallas sensors is you can chain them together all on one pin. And you have the option of using parasitic power so only two wires need to go out to the sensors.
 

t06afre

Joined May 11, 2009
5,934
Here is something I made last night. It should work. Please note this line
temprature=(float)ADC.res*478.1/1024;
It is nothing magical about it. It is just Vref*100/1024. And in this case VDD=Vref. So just measure VDD and put this value times 100. It should give you better temperature accuracy.
Rich (BB code):
///*// Config Register: CONFIG
//#define CONFIG               0x2007
//// Oscillator Selection bits
//// RC oscillator: CLKOUT function on RA4/OSC2/CLKOUT pin, RC on RA5/OSC1/CLKIN
//#define FOSC_EXTRCCLK        0xFFFF
//// RCIO oscillator: I/O function on RA4/OSC2/CLKOUT pin, RC on RA5/OSC1/CLKIN
//#define FOSC_EXTRCIO         0xFFFE
//// INTOSC oscillator: CLKOUT function on RA4/OSC2/CLKOUT pin, I/O function on RA5/OSC1/CLKIN
//#define FOSC_INTRCCLK        0xFFFD
//// INTOSCIO oscillator: I/O function on RA4/OSC2/CLKOUT pin, I/O function on RA5/OSC1/CLKIN
//#define FOSC_INTRCIO         0xFFFC
//// EC: I/O function on RA4/OSC2/CLKOUT pin, CLKIN on RA5/OSC1/CLKIN
//#define FOSC_EC              0xFFFB
//// HS oscillator: High-speed crystal/resonator on RA4/OSC2/CLKOUT and RA5/OSC1/CLKIN
//#define FOSC_HS              0xFFFA
//// XT oscillator: Crystal/resonator on RA4/OSC2/CLKOUT and RA5/OSC1/CLKIN
//#define FOSC_XT              0xFFF9
//// LP oscillator: Low-power crystal on RA4/OSC2/CLKOUT and RA5/OSC1/CLKIN
//#define FOSC_LP              0xFFF8
//// Watchdog Timer Enable bit
//// WDT enabled
//#define WDTE_ON              0xFFFF
//// WDT disabled and can be enabled by SWDTEN bit of the WDTCON register
//#define WDTE_OFF             0xFFF7
//// Power-up Timer Enable bit
//// PWRT disabled
//#define PWRTE_OFF            0xFFFF
//// PWRT enabled
//#define PWRTE_ON             0xFFEF
//// MCLR Pin Function Select bit
//// MCLR pin function is MCLR
//#define MCLRE_ON             0xFFFF
//// MCLR pin function is digital input, MCLR internally tied to VDD
//#define MCLRE_OFF            0xFFDF
//// Code Protection bit
//// Program memory code protection is disabled
//#define CP_OFF               0xFFFF
//// Program memory code protection is enabled
//#define CP_ON                0xFFBF
//// Data Code Protection bit
//// Data memory code protection is disabled
//#define CPD_OFF              0xFFFF
//// Data memory code protection is enabled
//#define CPD_ON               0xFF7F
//// Brown-out Reset Selection bits
//// BOR enabled
//#define BOREN_ON             0xFFFF
//// BOR enabled during operation and disabled in Sleep
//#define BOREN_NSLEEP         0xFEFF
//// BOR controlled by SBOREN bit of the PCON register
//#define BOREN_SBODEN         0xFDFF
//// BOR disabled
//#define BOREN_OFF            0xFCFF
//// Internal External Switchover bit
//// Internal External Switchover mode is enabled
//#define IESO_ON              0xFFFF
//// Internal External Switchover mode is disabled
//#define IESO_OFF             0xFBFF
//// Fail-Safe Clock Monitor Enabled bit
//// Fail-Safe Clock Monitor is enabled
//#define FCMEN_ON             0xFFFF
//// Fail-Safe Clock Monitor is disabled
//#define FCMEN_OFF            0xF7FF*/
#include <htc.h>
#include <stdio.h>
#include <stdlib.h>
#include "lcd.h"
__CONFIG (FCMEN_ON & IESO_OFF & BOREN_OFF & CPD_OFF & CP_OFF & MCLRE_OFF & PWRTE_ON & WDTE_OFF & FOSC_INTRCIO);
#define LED RC0
#define _XTAL_FREQ  4000000
//global defs
volatile bit timer_tick;
volatile bit blink;
union { 
unsigned int res;
  char bytes[2];
}ADC;
char ADC_num[6];
float temprature;
static void interrupt isr(void)   // Here is interrupt function - the name is
                                    // unimportant.
{
 if(TMR1IF) 
  {// Was this a timer overflow?
        TMR1IF=0;//Clear interrupt flag, ready for next
    TMR1H=0x80;
          //If we set TMR1 to start at 0x8000 (32768), the TMR1 will overflow every 1 second
       timer_tick=1;
             GO_DONE=1;
  }//we are done here
}
void setup(void)
 {   
  TRISA0=0;
      TRISC=0b01111000;//RC0-RC2 out,RC3-RC6 in,RC7 out
      TRISB=0; //All port B output
  GIE = 0;  // Global interrupt disable just in case
  ANSEL=0;
  ANSELH=0;//turn off all analog functions
//timer1 settings
  TMR1H=0x80;
  TMR1L=0;
  T1CON=0b00000110;//used during debug
      //T1CON=0b00001110;
// See datasheet REGISTER 6-1: T1CON: TIMER 1 CONTROL REGISTER
// bit order T1GINV TMR1GE T1CKPS1 T1CKPS0 T1OSCEN !T1SYNC TMR1CS TMR1ON
//Timer1 Interrupt prepare
  TMR1IE=1;// PIE1 register
  PEIE=1; //INTCON register
  PIR1=0; // Clear all bits PERIPHERAL INTERRUPT REQUEST REGISTER 1
    //todo now in order to generate interrupt GEI=1 and TMR1ON=1
//setup LCD
 lcd_init();
 lcd_goto(0); // select first line
//set the globals
//week_day=0;
     timer_tick=0;
     blink=0;
//setup ADC
 TRISA0 = 1;
 ANSEL = 0b00000001;  // Set PORT AN0 to analog input AN1 to AN7 digital I/O
 ANSELH = 0; 
 ADCON0=0b10000000;   // select right justify result. ADC port channel 0
 ADCON1=0b01010000;   // Select the FRC for 4 Mhz
 ADON=1;
//other misc settings
      timer_tick=0;//clear the tick
    }
void main (void)         
 {
         signed int l;
            unsigned int rem;
          setup();
        // timer_tick=1;//just for debug
        GIE=1;
    TMR1ON=1;
          lcd_puts("hello");
         __delay_ms(1000);
         lcd_goto(0x40);
         lcd_puts("world :)");
         __delay_ms(2000);
         lcd_clear();
      GIE=1;
 TMR1ON=1;
         while (1)
          {
              if (timer_tick)
               {
                 lcd_clear();
                 while(GO_DONE);
                 ADC.bytes[0]=ADRESL;
                 ADC.bytes[1]=ADRESH;
                 utoa(ADC_num, ADC.res, 10);
                      lcd_puts("RAW ADC data ");                
                     lcd_puts(ADC_num);
                   temprature=(float)ADC.res*478.1/1024;
                    temprature=temprature-50;          
      l = (signed int)temprature;
      temprature -= (float)l;
            rem = (unsigned int)(temprature* 1e1);
      sprintf(&ADC_num, "%i.%u", l, rem);       
                    lcd_goto(0x40);
                     lcd_puts("Temp ");
                    lcd_puts(ADC_num);
                                  timer_tick=0; 
                   blink=!blink;
                LED=blink; 
            }  // end if (timer_tick) Memo to my self put all this in sub function
           }//end while endless loop
 }//End main
 

Thread Starter

FroceMaster

Joined Jan 28, 2012
708
Here is something I made last night. It should work. Please note this line
It is nothing magical about it. It is just Vref*100/1024. And in this case VDD=Vref. So just measure VDD and put this value times 100. It should give you better temperature accuracy.
Rich (BB code):
///*// Config Register: CONFIG
//#define CONFIG               0x2007
//// Oscillator Selection bits
//// RC oscillator: CLKOUT function on RA4/OSC2/CLKOUT pin, RC on RA5/OSC1/CLKIN
//#define FOSC_EXTRCCLK        0xFFFF
//// RCIO oscillator: I/O function on RA4/OSC2/CLKOUT pin, RC on RA5/OSC1/CLKIN
//#define FOSC_EXTRCIO         0xFFFE
//// INTOSC oscillator: CLKOUT function on RA4/OSC2/CLKOUT pin, I/O function on RA5/OSC1/CLKIN
//#define FOSC_INTRCCLK        0xFFFD
//// INTOSCIO oscillator: I/O function on RA4/OSC2/CLKOUT pin, I/O function on RA5/OSC1/CLKIN
//#define FOSC_INTRCIO         0xFFFC
//// EC: I/O function on RA4/OSC2/CLKOUT pin, CLKIN on RA5/OSC1/CLKIN
//#define FOSC_EC              0xFFFB
//// HS oscillator: High-speed crystal/resonator on RA4/OSC2/CLKOUT and RA5/OSC1/CLKIN
//#define FOSC_HS              0xFFFA
//// XT oscillator: Crystal/resonator on RA4/OSC2/CLKOUT and RA5/OSC1/CLKIN
//#define FOSC_XT              0xFFF9
//// LP oscillator: Low-power crystal on RA4/OSC2/CLKOUT and RA5/OSC1/CLKIN
//#define FOSC_LP              0xFFF8
//// Watchdog Timer Enable bit
//// WDT enabled
//#define WDTE_ON              0xFFFF
//// WDT disabled and can be enabled by SWDTEN bit of the WDTCON register
//#define WDTE_OFF             0xFFF7
//// Power-up Timer Enable bit
//// PWRT disabled
//#define PWRTE_OFF            0xFFFF
//// PWRT enabled
//#define PWRTE_ON             0xFFEF
//// MCLR Pin Function Select bit
//// MCLR pin function is MCLR
//#define MCLRE_ON             0xFFFF
//// MCLR pin function is digital input, MCLR internally tied to VDD
//#define MCLRE_OFF            0xFFDF
//// Code Protection bit
//// Program memory code protection is disabled
//#define CP_OFF               0xFFFF
//// Program memory code protection is enabled
//#define CP_ON                0xFFBF
//// Data Code Protection bit
//// Data memory code protection is disabled
//#define CPD_OFF              0xFFFF
//// Data memory code protection is enabled
//#define CPD_ON               0xFF7F
//// Brown-out Reset Selection bits
//// BOR enabled
//#define BOREN_ON             0xFFFF
//// BOR enabled during operation and disabled in Sleep
//#define BOREN_NSLEEP         0xFEFF
//// BOR controlled by SBOREN bit of the PCON register
//#define BOREN_SBODEN         0xFDFF
//// BOR disabled
//#define BOREN_OFF            0xFCFF
//// Internal External Switchover bit
//// Internal External Switchover mode is enabled
//#define IESO_ON              0xFFFF
//// Internal External Switchover mode is disabled
//#define IESO_OFF             0xFBFF
//// Fail-Safe Clock Monitor Enabled bit
//// Fail-Safe Clock Monitor is enabled
//#define FCMEN_ON             0xFFFF
//// Fail-Safe Clock Monitor is disabled
//#define FCMEN_OFF            0xF7FF*/
#include <htc.h>
#include <stdio.h>
#include <stdlib.h>
#include "lcd.h"
__CONFIG (FCMEN_ON & IESO_OFF & BOREN_OFF & CPD_OFF & CP_OFF & MCLRE_OFF & PWRTE_ON & WDTE_OFF & FOSC_INTRCIO);
#define LED RC0
#define _XTAL_FREQ  4000000
//global defs
volatile bit timer_tick;
volatile bit blink;
union { 
unsigned int res;
  char bytes[2];
}ADC;
char ADC_num[6];
float temprature;
static void interrupt isr(void)   // Here is interrupt function - the name is
                                    // unimportant.
{
 if(TMR1IF) 
  {// Was this a timer overflow?
        TMR1IF=0;//Clear interrupt flag, ready for next
    TMR1H=0x80;
          //If we set TMR1 to start at 0x8000 (32768), the TMR1 will overflow every 1 second
       timer_tick=1;
             GO_DONE=1;
  }//we are done here
}
void setup(void)
 {   
  TRISA0=0;
      TRISC=0b01111000;//RC0-RC2 out,RC3-RC6 in,RC7 out
      TRISB=0; //All port B output
  GIE = 0;  // Global interrupt disable just in case
  ANSEL=0;
  ANSELH=0;//turn off all analog functions
//timer1 settings
  TMR1H=0x80;
  TMR1L=0;
  T1CON=0b00000110;//used during debug
      //T1CON=0b00001110;
// See datasheet REGISTER 6-1: T1CON: TIMER 1 CONTROL REGISTER
// bit order T1GINV TMR1GE T1CKPS1 T1CKPS0 T1OSCEN !T1SYNC TMR1CS TMR1ON
//Timer1 Interrupt prepare
  TMR1IE=1;// PIE1 register
  PEIE=1; //INTCON register
  PIR1=0; // Clear all bits PERIPHERAL INTERRUPT REQUEST REGISTER 1
    //todo now in order to generate interrupt GEI=1 and TMR1ON=1
//setup LCD
 lcd_init();
 lcd_goto(0); // select first line
//set the globals
//week_day=0;
     timer_tick=0;
     blink=0;
//setup ADC
 TRISA0 = 1;
 ANSEL = 0b00000001;  // Set PORT AN0 to analog input AN1 to AN7 digital I/O
 ANSELH = 0; 
 ADCON0=0b10000000;   // select right justify result. ADC port channel 0
 ADCON1=0b01010000;   // Select the FRC for 4 Mhz
 ADON=1;
//other misc settings
      timer_tick=0;//clear the tick
    }
void main (void)         
 {
         signed int l;
            unsigned int rem;
          setup();
        // timer_tick=1;//just for debug
        GIE=1;
    TMR1ON=1;
          lcd_puts("hello");
         __delay_ms(1000);
         lcd_goto(0x40);
         lcd_puts("world :)");
         __delay_ms(2000);
         lcd_clear();
      GIE=1;
 TMR1ON=1;
         while (1)
          {
              if (timer_tick)
               {
                 lcd_clear();
                 while(GO_DONE);
                 ADC.bytes[0]=ADRESL;
                 ADC.bytes[1]=ADRESH;
                 utoa(ADC_num, ADC.res, 10);
                      lcd_puts("RAW ADC data ");                
                     lcd_puts(ADC_num);
                   temprature=(float)ADC.res*478.1/1024;
                    temprature=temprature-50;          
      l = (signed int)temprature;
      temprature -= (float)l;
            rem = (unsigned int)(temprature* 1e1);
      sprintf(&ADC_num, "%i.%u", l, rem);       
                    lcd_goto(0x40);
                     lcd_puts("Temp ");
                    lcd_puts(ADC_num);
                                  timer_tick=0; 
                   blink=!blink;
                LED=blink; 
            }  // end if (timer_tick) Memo to my self put all this in sub function
           }//end while endless loop
 }//End main
Will try to implement it,
wondering why you put an interrupt go_done=1,
meaning it will calculate every second, ?
i have done it only every 3 seconds, no need to calculate while it doesnt show the temperature. or ?
need to check it out, when i got the time to it,
 

t06afre

Joined May 11, 2009
5,934
Will try to implement it,
wondering why you put an interrupt go_d
meaning it will calculate every second, ?
i have done it only every 3 seconds, no need to calculate while it doesnt show the temperature. or ?
need to check it out, when i got the time to it,
Just pick and mix as you want. I just wrote the program as an example for you that was tested. But it dos not harm to measure temperature say every second and then display an average value based on several measurements. However it nice to have and need to have. Focus on the simplest solution first. And then this work you can go for something more advanced.
I am a little concern that you will run out of program space using the compiler in lite mode(free). I will then suggest using the PIC16f1509. It should fit into your board. And is supported by PICKIT 2. You will be able to keep the core of your program. But some minor rewriting in the setup function will be required
 

Thread Starter

FroceMaster

Joined Jan 28, 2012
708
Just pick and mix as you want. I just wrote the program as an example for you that was tested. But it dos not harm to measure temperature say every second and then display an average value based on several measurements. However it nice to have and need to have. Focus on the simplest solution first. And then this work you can go for something more advanced.
I am a little concern that you will run out of program space using the compiler in lite mode(free). I will then suggest using the PIC16f1509. It should fit into your board. And is supported by PICKIT 2. You will be able to keep the core of your program. But some minor rewriting in the setup function will be required

Havent checked for space yet, but lets see.
as it is now, before the changes you suggested, there was lots of space.
maybee tomorrow i will work on it again.
 

Thread Starter

FroceMaster

Joined Jan 28, 2012
708
Havent checked for space yet, but lets see.
as it is now, before the changes you suggested, there was lots of space.
maybee tomorrow i will work on it again.
Havent not enough space, if i use that. 99,9 % used,
and still need to implent some thing.
Nevermind the accarusy, i use a stabel powersupply, and then i can program my way out of it.

Have a couple of questions.
Can i set another temp-sensor to ex AN1(RA1 ) ?
and then i have both inside and outside temperature.

This calculations works, but how can i make it ex 20.5 degree and not just 20 and 21 ect.
Rich (BB code):
celcius=(((5000/1024)*degree)-500)/10;
i know if i dont divede by 10 in the end, i will get ex 205 and need to add a .(dot) in that. ?
 

spinnaker

Joined Oct 29, 2009
7,830
Havent not enough space, if i use that. 99,9 % used,
and still need to implent some thing.
Nevermind the accarusy, i use a stabel powersupply, and then i can program my way out of it.
Your not going to find one. You need an external voltage reference.

Look at your code again. There are always places where you can optimize the code.

Have a couple of questions.
Can i set another temp-sensor to ex AN1(RA1 ) ?
and then i have both inside and outside temperature.
Not easily.Especially since you are already low on code memory. Again why I recommend the dallas sensors in the first place.
 
Top