Temperature wrong ds18b20

Discussion in 'Embedded Systems and Microcontrollers' started by FroceMaster, Jan 17, 2016.

  1. FroceMaster

    Thread Starter Member

    Jan 28, 2012
    402
    4
    Hi
    When i read out the temperature i get a wrong output.
    -1.7500
    -1,8125
    -1,8750
    -1,9375
    -1,0000
    -2,0625
    -2,1250
    -2,1875
    -2,2500
    -2,3125

    See my point ?
    all code i got in here from one of you.
    here is the part that "convert" to text.

    Code (Text):
    1.  
    2. printf("sign %d\n", sign_flag);
    3.  
    4.                 buffer[1] = ((lsb / 100)%10) + 48;
    5.                 buffer[2] = (((lsb / 10)%10) + 48);
    6.                 buffer[3] = (((lsb)%10))+ 48 + sign_flag;
    7.                 buffer[4] = '.';
    8.                 buffer[5] = ((places[0]%10)+48);
    9.                 buffer[6] = ((places[1]%10)+48);
    10.                 buffer[7] = ((places[2]%10)+48);
    11.                 buffer[8] = ((places[3]%10)+48);
    12.                 buffer[9] = ' ' ;
    13.                 buffer[10]= 'C';
    14.                
    And here you have all the code.
    PIC 16F1509
    Code (Text):
    1. #include <htc.h>
    2. #include <stdio.h>
    3. #include <stdlib.h>
    4. #include "lcd.h"
    5. #include <string.h>
    6.  
    7. #pragma config FOSC = LP//INTOSC      // Oscillator Selection Bits (XT Oscillator, Crystal/resonator connected between OSC1 and OSC2 pins)
    8. #pragma config WDTE = OFF       // Watchdog Timer Enable (WDT disabled)
    9. #pragma config PWRTE = ON       // Power-up Timer Enable (PWRT disabled)
    10. #pragma config MCLRE = OFF      // MCLR Pin Function Select (MCLR/VPP pin function is digital input)
    11. #pragma config CP = OFF         // Flash Program Memory Code Protection (Program memory code protection is disabled)
    12. #pragma config BOREN = OFF      // Brown-out Reset Enable (Brown-out Reset enabled)
    13. #pragma config CLKOUTEN = OFF   // Clock Out Enable (CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin)
    14. #pragma config IESO = OFF       // Internal/External Switchover Mode (Internal/External Switchover Mode is enabled)
    15. #pragma config FCMEN = ON       // Fail-Safe Clock Monitor Enable (Fail-Safe Clock Monitor is enabled)
    16.  
    17. // CONFIG2
    18. #pragma config WRT = OFF        // Flash Memory Self-Write Protection (Write protection off)
    19. #pragma config STVREN = ON      // Stack Overflow/Underflow Reset Enable (Stack Overflow or Underflow will cause a Reset)
    20. #pragma config BORV = LO        // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), low trip point selected.)
    21. #pragma config LPBOR = OFF      // Low-Power Brown Out Reset (Low-Power BOR is disabled)
    22. #pragma config LVP = ON         // Low-Voltage Programming Enable (Low-voltage programming enabled)
    23.  
    24. #define _XTAL_FREQ 8000000
    25. #define FOSC 2000000L
    26.  
    27. #define set_hour RB4 //Buttons
    28. #define set_minut RC2
    29. #define set_week RC1
    30. #define set_time RC3
    31.  
    32. #define SCS_BIT                0x00
    33. #define INT_OSC_8MHZ         (0b01110000 | SCS_BIT)
    34.  
    35. #define Skip_ROM             0xCC
    36. #define Convert_T             0x44
    37. #define Read_scratchpad     0xBE
    38.  
    39. #define Port_18B20             RB5
    40. #define Tx_18B20             TRISB5 = 0
    41. #define Rx_18B20             TRISB5 = 1
    42.  
    43. #define WAIT1                1000
    44. #define WAIT2                500
    45.  
    46. #define DS18B20_CONV_TIME    750
    47. #define DS18B20_RESET_PULSE 480
    48. #define DS18B20_WAIT_TIME     60
    49. #define DS18B20_PULLUP_TIME 2
    50.  
    51. #define ONEWIRE_PRESENT     0
    52. #define ONEWIRE_ABSENT         1
    53.  
    54. unsigned char lsb;
    55.     unsigned char msb;
    56.     unsigned char decimal;
    57.     unsigned char buffer[11];
    58.     unsigned int sign_flag =0;
    59.     unsigned int integer =0;
    60.     unsigned int integer1 =0;
    61.     unsigned int integer2 =0;
    62.     unsigned int integer3 =0;
    63.     unsigned int integer4 =0;
    64.     signed int min,max,minold,minhele,minfraction,maxhele,maxfraction,total,fraction,now;
    65.     int tempmax,minnegativ,maxnegativ;
    66.     char hele[10],deci[10];
    67. bit sec,vis;
    68. int xpulse,secund,minut,hour,x,today_rain,r_regn,rainTMR0,visning,f_gennemlob,negativ,maxxpulse;
    69. char test[10];
    70. unsigned char raindays[31];
    71. volatile unsigned char week_day;
    72. unsigned char mintime[3],maxx[3];
    73. unsigned char maxtime[3],minx[3];
    74. char mintemp[3],maxtemp[3];
    75.  
    76. const char * const day_of_week_names[] = {"Mandag ",
    77.                                           "Tirsdag",
    78.                                           "Onsdag ",
    79.                                           "Torsdag",
    80.                                           "Fredag ",
    81.                                           "Lordag ",
    82.                                           "Sondag "
    83.                                          };
    84.  
    85. static void interrupt isr(void)   // Here is interrupt function - the name is unimportant.
    86. {
    87.  
    88. if(TMR1IF)             // Was this a timer overflow?
    89.     {
    90.           TMR1IF=0;        // Clear interrupt flag, ready for next
    91.          TMR1L=0x00;
    92.          TMR1H=0x80;     // If we set TMR1 to start at 0x8000 (32768), the TMR1 will overflow every 1 second
    93.          //timer_tick=1;    // 1 sec went.
    94.          sec=1;             // adds a sec.
    95.      //RB7=!RB7;
    96.     /*if (sec==60)         // if sec = 60
    97.     {
    98.         sec=0;           // sekund = 0
    99.            minut_tick=1;      // adds 1 minute.
    100.  
    101.     }                    // end "if second"
    102.      */
    103.     }
    104. /*if(TMR2IF)
    105. {
    106. TMR2IF=0;
    107. maxxpulse++;
    108. //if (xpulse==maxxpulse)
    109. //{ xpulse=0;
    110. //sec=1;
    111. if (maxxpulse==25)
    112. { sec=1;
    113. maxxpulse=0;
    114. }
    115. }*/
    116. }
    117.  
    118. void setup (void)
    119. {
    120.  
    121. IRCF0=0; //8 mhz
    122. IRCF1=1;
    123. IRCF2=1;
    124. IRCF3=1;
    125. TRISA=0; //set all port out
    126. TRISA2=1; // set port 2 in
    127. TRISA4=1; // set port 4 ind.
    128. TRISA5=1; // set port 5 ind.
    129. TRISB4=1; // port B 4 in
    130. TRISB5=1; // port b 5 in // temp
    131. TRISB6=0; // b6 ud
    132. TRISB7=1; // port b7 in
    133. TRISC0=0;
    134. TRISC1=1;
    135. TRISC2=1;
    136. TRISC3=1;
    137. TRISC4=0;
    138. TRISC5=0;
    139. TRISC6=0;
    140. TRISC7=0;
    141. OSCCON = INT_OSC_8MHZ;
    142.  
    143. CM1CON0 = 0;
    144.     CM2CON0 = 0;
    145. //Timer 0 is counter to rain. input RA2
    146. TMR0CS=1; //use t0cki.
    147. PSA=1; // no prescaller
    148. TMR0SE=1; // high to low transiton
    149.  
    150. //timer 1 ... ur
    151. TMR1CS1=1; //CLOCK SOURCE S-ELECTIONS
    152. TMR1CS0=0;
    153. //11 =Timer1 clock source is Capacitive Sensing Oscillator (CAPOSC)
    154. //10 =Timer1 clock source is pin or oscillator:
    155. //If T1OSCEN = 0:
    156. //External clock from T1CKI pin (on the rising edge)
    157. //If T1OSCEN = 1:
    158. //Crystal oscillator on SOSCI/SOSCO pins
    159. //01 =Timer1 clock source is system clock (FOSC)
    160. //00 =Timer1 clock source is instruction clock (FOSC/4)
    161. T1CKPS1=0; // <1:0>: Timer1 Input Clock Prescale Select bits
    162. T1CKPS0=0;
    163. //11 = 1:8 Prescale value
    164. //10 = 1:4 Prescale value
    165. //01 = 1:2 Prescale value
    166. //00 = 1:1 Prescale value
    167. T1OSCEN=1;//LP Oscillator Enable Control bit
    168. //1 = Dedicated Timer1 oscillator circuit enabled
    169. //0 = Dedicated Timer1 oscillator circuit disabled
    170. nT1SYNC=1; //: Timer1 Synchronization Control bit
    171. TMR1ON=0;//: Timer1 On bit
    172. TMR1H = 0x80;     // preset for timer1 MSB register
    173. TMR1L = 0x00;     // preset for timer1 LSB register
    174. TMR1GE=0; // gate for timer1 disable.
    175. //T1GCON: TIMER1 GATE CONTROL REGISTER
    176. //bit 7 TMR1GE: Timer1 Gate Enable bit
    177. //If TMR1ON = 0:
    178. //This bit is ignored
    179. //If TMR1ON = 1:
    180. //1 = Timer1 counting is controlled by the Timer1 gate function
    181. //0 = Timer1 counts regardless of Timer1 gate function
    182.   //Timer1 Interrupt prepare
    183.    TMR1IE=1;// PIE1 register
    184.    PEIE=1; //INTCON register
    185.     PIR1=0; // Clear all bits PERIPHERAL INTERRUPT REQUEST REGISTER 1
    186.  
    187.     // internal ext interrupt
    188. //    INTE=1;
    189.  
    190. // TIMER 2.....
    191. T2CKPS0=1;//Prescale 64
    192. T2CKPS1=1;
    193. T2OUTPS0=1; // postscale 10
    194. T2OUTPS1=0;
    195. T2OUTPS2=0;
    196. T2OUTPS3=1;
    197. PR2=0x7D; // 125
    198.  
    199. GIE = 0;  // Global interrupt disable just in case
    200. //ANSELA = 0b00000001;  // Set PORT AN0 to analog input AN1 to AN7 digital I/O
    201. ANSELA=0; // set alle digital.
    202. ANSELB=0;
    203. ANSELC=0;//turn off all analog functions
    204. lcd_init();
    205. //T1CKPS1=1;
    206. //T1CKPS0=1;
    207. //nT1SYNC=1;
    208. //maxxpulse=25;
    209. }
    210. void vis_maxmin(void) // viser max og min
    211. {        
    212.                 lcd_clear();
    213.                 lcd_goto(0x00);
    214.                 lcd_puts(day_of_week_names[mintime[2]]);
    215.                 if (mintime[2]!=1 || mintime[2]!=3)
    216.                 {
    217.                 lcd_puts(" ");
    218.                     }
    219.                 if (mintime[0]<10)lcd_puts("0");
    220.                 utoa(minx, mintime[0], 10);
    221.                 lcd_puts(minx);
    222.                 lcd_puts(":");
    223.                 if (mintime[1]<10)lcd_puts("0");
    224.                 utoa(minx, mintime[1], 10);
    225.                 lcd_puts(minx);
    226.                 lcd_puts(" ");
    227.                 if (minnegativ!=0)
    228.                 {
    229.                     minhele=(500-min)/10;
    230.                     minfraction= (500-min)-(minhele*10);
    231.                     lcd_puts("-");
    232.                 }
    233.                 if (minnegativ==0)
    234.                 {
    235.                  minhele=(min-500)/10;
    236.                 minfraction= (min-500)-(minhele*10);
    237.                 lcd_puts(" ");
    238.                 }
    239.                 utoa(mintemp,minhele,10);
    240.                 if (minhele<10)lcd_puts(" ");
    241.                 lcd_puts(mintemp);
    242.                 lcd_puts(".");
    243.                 utoa(mintemp,minfraction,10);
    244.                 lcd_puts(mintemp);
    245.                 lcd_puts("ß");
    246.  
    247.                 // max temp kl bob bob
    248.                 lcd_goto(0x40);
    249.                 lcd_puts(day_of_week_names[maxtime[2]]);
    250.                 if (maxtime[2]!=1 || maxtime[2]!=3)
    251.                 {
    252.                 lcd_puts(" ");
    253.                     }
    254.                 if (maxtime[0]<10)lcd_puts("0");
    255.                 utoa(minx, maxtime[0], 10);
    256.                 lcd_puts(minx);
    257.                 lcd_puts(":");
    258.                 if (maxtime[1]<10)lcd_puts("0");
    259.                 utoa(minx, maxtime[1], 10);
    260.                 lcd_puts(minx);
    261.              
    262.                 lcd_puts(" ");
    263.                 if (maxnegativ!=0)
    264.                 {
    265.                 maxhele=(500-max)/10;
    266.                 maxfraction= (500-max)-(maxhele*10);
    267.                 lcd_puts("-");
    268.                 }
    269.                if (maxnegativ==0)
    270.                {
    271.                 maxhele=(max-500)/10;
    272.                 maxfraction= (max-500)-(maxhele*10);
    273.                lcd_puts(" ");
    274.                }
    275.            
    276.                 utoa(maxtemp,maxhele,10);
    277.                 if (maxhele<10)lcd_puts(" ");
    278.                 lcd_puts(maxtemp);
    279.                 lcd_puts(".");
    280.                 utoa(maxtemp,maxfraction,10);
    281.                 lcd_puts(maxtemp);
    282.                 lcd_puts("ß");
    283.              
    284.              
    285.  
    286.                        
    287.                
    288. }
    289.  
    290.  
    291. void vaelg_dage (void) // Vælger dagene
    292.     {
    293. int sel,y;
    294.     sel=1;
    295.         x=0;
    296.         __delay_ms(100);
    297.         while (x<40)
    298.     {
    299.     if (!set_hour)  // Ved hver tryk inden for 4 sec vælges næste dag
    300.     {char regn[4];
    301.             lcd_goto(0x40);
    302.         lcd_puts("Regn dag -");
    303.         lcd_goto(0x4a);
    304.         if (sel<10)lcd_puts(" ");
    305.         utoa(regn, sel, 10);
    306.         lcd_puts(regn);
    307.         lcd_goto(0x4c);
    308.         lcd_puts(" :");
    309.      
    310.         y=raindays[sel];
    311.         if (y<100)lcd_puts(" ");
    312.         if (y<10)lcd_puts(" ");
    313.         utoa(regn, y, 10);
    314.      
    315.         lcd_puts(regn);
    316.         lcd_puts(" MM");
    317.         sel++;
    318.         x=0;
    319.         if (sel==30)sel=1;
    320.     __delay_ms(255);
    321.     }
    322.     __delay_ms(100);
    323.         x++;
    324.  
    325.     }
    326. }
    327.  
    328.  
    329.  
    330. void reset_temp (void) //sletter temp.
    331. {
    332.      lcd_clear();                            // sletter skærm
    333.      lcd_goto(0x00);                        // linje 1
    334.      lcd_puts("Nulstil Max-Min temp ?");    // skriver
    335.      lcd_goto(0x45);                        // linje 2
    336.      lcd_puts("JA / NEJ ");                    // spørger
    337.      lcd_goto(0x00);                        // linje 1
    338.     x=0;                                    // tæller 0
    339.     while (x<100)                            // løkke til 100*100 = 10 sec
    340.     {
    341.      if (!set_time)                            // hvis tryk på nulstil
    342.      {
    343.      
    344.          min=0;
    345.          max=0;
    346.          lcd_clear();                        // sletter skærm
    347.          lcd_goto(0x04);                    // linje 1
    348.          lcd_puts("Nulstillet !");            // skriver
    349.          lcd_goto(0x00);                    // linje 1
    350.          __delay_ms(1000);                    // pause 1 sec
    351.         x=99;                                // afslutter løkken
    352.         }
    353.         if(!set_week)x=0;                    // hvis tryk igen, omstart løkke
    354.      
    355.         x++;                                 // lægger til løkken
    356.         __delay_ms(100);                    // pause
    357. }                // end while løkken
    358. }    // SLUT RESET TEMP
    359. void reset_regn (void) //sletter total regn.
    360. {
    361. lcd_clear();                        // sletter skærm
    362. lcd_goto(0x00);                    // går til linje1
    363. lcd_puts(" Nulstil total regn ?");    // skriver
    364. lcd_goto(0x45);                    // går til linje 2
    365. lcd_puts("JA / NEJ ");                // skriver
    366. lcd_goto(0x00);                    // går til linje 1
    367.     x=0;                            // tæller 0
    368. while (x<100)                        // løkke 100 gange *100 = 10 sec.
    369.     {
    370.      if (!set_time)                    // hvis man trykker JA knappen
    371.      {TMR0=0;
    372.          r_regn=0;
    373.          today_rain=0;
    374.          lcd_clear();                // sletter skærm
    375.          lcd_goto(0x04);            // går linje 1
    376.          lcd_puts("Nulstillet !");    // skriver
    377.          lcd_goto(0x00);            // linje 1
    378.          __delay_ms(1000);            // Pause 1 sec
    379.         x=99;                        // slutter løkken
    380.         }
    381.         if(!set_week)x=0;            // hvis der trykkes igen, starter løkken forfra
    382.      
    383.         x++;                         // tæller løkken op
    384.         __delay_ms(100);            // 100 ms pause
    385. }
    386.     }         // SLUT NULSTIL REGN
    387.  
    388. unsigned char reset()
    389. {
    390.     Tx_18B20;
    391.     Port_18B20 = 0;
    392.     __delay_us(DS18B20_RESET_PULSE);
    393.     Rx_18B20;
    394.     __delay_us(DS18B20_WAIT_TIME);
    395.  
    396.     if (Port_18B20 == 1)
    397.     {
    398.         __delay_us(DS18B20_RESET_PULSE);
    399.         return ONEWIRE_PRESENT;
    400.     }
    401.  
    402.     __delay_us(DS18B20_RESET_PULSE);
    403.     return ONEWIRE_ABSENT;
    404. }
    405.  
    406. void write(char WRT)
    407. {
    408.     char i,Cmd;
    409.     Cmd = WRT;
    410.     Rx_18B20;
    411.     for(i = 0; i < 8; i++)
    412.     {
    413.         if((Cmd & (1<<i))!= 0)
    414.         {
    415.  
    416.             Tx_18B20;
    417.             Port_18B20 = 0;
    418.             __delay_us(DS18B20_PULLUP_TIME);
    419.             Rx_18B20;
    420.             __delay_us(DS18B20_WAIT_TIME);
    421.         }
    422.         else
    423.         {
    424.  
    425.             Tx_18B20;
    426.             Port_18B20 = 0;
    427.             __delay_us(DS18B20_WAIT_TIME);
    428.             Rx_18B20;
    429.         }
    430.     }
    431. }
    432.  
    433.  
    434. unsigned char read()
    435. {
    436.     char i,result = 0;
    437.     Rx_18B20;
    438.     for(i = 0; i < 8; i++)
    439.     {
    440.         Tx_18B20;
    441.         Port_18B20 = 0;
    442.         __delay_us(DS18B20_PULLUP_TIME);
    443.         Rx_18B20;
    444.         if(Port_18B20 != 0)
    445.         {
    446.             result |= 1<<i;//i
    447.         }
    448.         __delay_us(DS18B20_WAIT_TIME);
    449.     }
    450.     return result;
    451. }
    452.  
    453. void laestemp (void) //red out temperature-
    454. {
    455.  
    456.                 write(Skip_ROM);
    457.                 write(Convert_T);
    458.                 __delay_ms(DS18B20_CONV_TIME);
    459.  
    460.                 reset();
    461.                 write(Skip_ROM);
    462.                 write(Read_scratchpad);
    463.                 lsb = read();
    464.                 msb = read();
    465.                 if (f_gennemlob==0) lcd_clear();
    466.                 unsigned int sign = 248 & msb;
    467.                 if(sign==0)
    468.                     decimal = lsb & 15;
    469.  
    470.                 if(sign!=0)
    471.                 {
    472.                     decimal = lsb ^ 15;
    473.                     decimal = decimal^255;
    474.  
    475.                 }
    476.  
    477.                 unsigned char places[4]= {0};
    478.                 if((decimal&8) == 8)
    479.                 {
    480.  
    481.                     places[0] =  places[0] + 5;
    482.  
    483.                 }
    484.  
    485.                 if((decimal&4)==4)
    486.                 {
    487.                     places[0] = places[0] + 2;
    488.                     places[1] = places[1] + 5;
    489.                 }
    490.  
    491.                 if((decimal&2)==2)
    492.                 {
    493.                     places[0] = places[0] + 1;
    494.                     places[1] = places[1] + 2;
    495.                     places[2] = places[2] + 5;
    496.                 }
    497.  
    498.                 if((decimal&1)==1)
    499.                 {
    500.                     places[1] = places[1] + 6;
    501.                     if(places[1]>9)
    502.                     {
    503.                         places[1]= places[1]-10;
    504.                         places[0]= places[0]+1;
    505.                     }
    506.  
    507.                     places[2] = places[2] + 2;
    508.                     places[3] = places[3] + 5;
    509.  
    510.                 }
    511.  
    512.  
    513.                 if(sign!=0)
    514.                 {
    515.                     integer1 =(places[0]*1000);
    516.                     integer2 = (places[1]*100);
    517.                     integer3 = (places[2]*10);
    518.                     integer4 = (places[3]);
    519.                     integer = integer1+integer2+integer3+integer4;
    520.                     if(integer==0)
    521.                     {
    522.                         sign_flag=1;
    523.                     }
    524.                     integer = 10000-integer;
    525.  
    526.                     integer1 = integer/1000;
    527.                     integer2 = (integer/100)-(10*integer1);
    528.                     integer3 = (integer/10)-(100*integer1)-(10*integer2);
    529.                     places[0]= integer1;
    530.                     places[1]= integer2;
    531.                     places[2]= integer3;
    532.                     places[3]= integer4;
    533.  
    534.                 }
    535.                 lsb = lsb >> 3;
    536.                 msb = msb << 5;
    537.                 lsb = msb | lsb;
    538.                 if(sign !=0)
    539.                 {
    540.                     lsb =(lsb)^255;
    541.                     buffer[0]='-';
    542.                 }
    543.                 else
    544.                     buffer[0] = '+';
    545.  
    546.                 lsb = lsb >>1;
    547.                 printf("sign %d\n", sign_flag);
    548.  
    549.                 buffer[1] = ((lsb / 100)%10) + 48;
    550.                 buffer[2] = (((lsb / 10)%10) + 48);
    551.                 buffer[3] = (((lsb)%10))+ 48 + sign_flag;
    552.                 buffer[4] = '.';
    553.                 buffer[5] = ((places[0]%10)+48);
    554.                 buffer[6] = ((places[1]%10)+48);
    555.                 buffer[7] = ((places[2]%10)+48);
    556.                 buffer[8] = ((places[3]%10)+48);
    557.                 buffer[9] = ' ' ;
    558.                 buffer[10]= 'C';
    559.              
    560.              
    561. }            
    562.  
    563.  
    564. void vis_klokken(void)
    565. {
    566. char timestr[3];
    567.     lcd_goto(0x00);                    // går til første linje
    568.     lcd_puts("Klokken er: ");        // skriver
    569.     utoa(timestr, hour, 10);        // laver om til streng
    570.     if (hour<10)lcd_puts("0");        // hvis timer er under 10 skriv 0
    571.         lcd_puts(timestr);            // skriver timer
    572.         lcd_puts(":");                // skriver
    573.         utoa(timestr, minut, 10);    // laver om til streng
    574.     if (minut<10)lcd_puts("0");     // hvis minut er under 10 skriv 0
    575.         lcd_puts(timestr);            // skriver minut
    576.         lcd_puts(":");                // skriver
    577.         utoa(timestr, secund, 10);        // laver til streng
    578.     if (secund<10)lcd_puts("0");        // hvis sec er under 10 skriv 0
    579.         lcd_puts(timestr);            // skriver
    580.         lcd_goto(0x40);                // går til anden linje
    581.     lcd_puts("Dagen er  : ");        // skriver
    582.      for (unsigned char i=0;i<7;i++) lcd_putch(day_of_week_names[week_day][i]);
    583. lcd_goto(0x00);                        // går til første linje
    584. }    // slut "sub vis klokken"
    585.  
    586. void start_ur (void) // Starter uret.
    587. {
    588.     RA0=0;
    589. GIE = 1;      // Global interrupt enable
    590. TMR2ON=1;     // timer1 on
    591. }     // slut "sub "start ur"
    592.  
    593. void sluk_ur (void) // Slukker uret
    594. {
    595. GIE = 0;         // Global interrupt disable as we are setting the time
    596. TMR2ON=0;       // slukker timer til uret.
    597. //secund=0;            // sætter sec = 0
    598. RA0=1;         // tænder lys
    599.  
    600. }// slut "sub sluk ur "
    601.  
    602. void stil_ur (void) //Indstiller uret
    603. {
    604.     sluk_ur();         // Stopper tiden
    605.     lcd_clear();
    606.     vis_klokken();     // Viser uret
    607.     //secund=0;
    608.    do                  // Læser på knapperne
    609.    {
    610.     if (!set_hour)     // Stiller timer fremad
    611.    {
    612.        hour++;                    // Lægger en time til
    613.         if (hour==24) hour=0;     // hvis timer = 24 så 0.
    614.         vis_klokken();            // viser vi har tælt en op
    615.         __delay_ms(255);         // venter lidt.
    616.         __delay_ms(255);
    617.                }
    618.     if (!set_minut) // Stiller minutter frem
    619.    {
    620.         minut++;                // lægger 1 minut til.
    621.          if (minut==60) minut=0;// hvis minut = 60 så 0.
    622.            vis_klokken();            // viser vi har talt op.
    623.          __delay_ms(255);         // venter lidt.
    624.          __delay_ms(255);
    625.                }
    626.     if (!set_week)  // Stiller ugedagen
    627.    {
    628.           week_day++;             // lægger 1 dag til.
    629.          if (week_day==7) week_day=0; // hvis dag 7 så dag 0.
    630.          vis_klokken();            // viser vi har talt op.
    631.          __delay_ms(255);         // venter lidt.
    632.                }
    633.      
    634.     } while (!set_time); // Når knappen slippes igen
    635.  
    636. start_ur();  //Starter uret
    637. //     vis_regn();
    638. }// end stil uret
    639.  
    640. void midnat(void)    //thing to do at midnight. shift of date.
    641. {int d;
    642. week_day++;
    643. if (week_day==7) week_day=0;
    644. r_regn=r_regn+today_rain;
    645. for(d=30;d>1;d--)
    646. {
    647. raindays[d]=raindays[d-1];
    648. }
    649.  
    650. raindays[1]=today_rain;
    651. today_rain=0;
    652.  
    653. }        // slut midnat
    654.  
    655.  
    656. void uret(void)
    657.       {
    658.  
    659.            minut++;      // og plusser et minut
    660.     if (minut>=60)  // hvis minut = 60
    661.     {    minut=0;    // minut = 0
    662.         hour++;        // og plusser en time.
    663.     if (hour>=24)    // hvis time er 24
    664.     {    hour=0;        // time = 0
    665.         midnat();    // kører sub midnat.
    666.     }    // slut "if hour"
    667.     }    // slut "if minut"
    668.     }    // slut "sub uret"
    669.  
    670. void fyldarray (void)
    671. {int d;
    672.      for(d=0;d<30;d++)
    673.      {
    674.          raindays[d]=0;
    675.         }
    676.     }     // fyld data
    677.  
    678. void vis_regn(void)
    679.     {
    680.         //lcd_clear();
    681.     char regn[4], idag[4];     // defines
    682. //lcd_clear();                // slet skærm
    683. lcd_goto(0x00);                // går til 0
    684. lcd_puts("Regn Total  : ");    // skriver
    685. if (TMR0<100)lcd_puts(" ");    // højrestiller korrekt
    686. if (TMR0<10)lcd_puts(" ");    // højrestiller igen
    687. utoa(regn, TMR0, 10);        // laver tekststreng
    688. lcd_puts(regn);                // skriver regnen
    689. lcd_puts(" MM");            // i MM
    690. lcd_goto(0x40);                // går til linje 2
    691. lcd_puts("Regn ");            // skriver
    692. for (unsigned char i=0;i<7;i++) lcd_putch(day_of_week_names[week_day][i]);
    693. lcd_puts(": ");            // skriver :
    694.  
    695. today_rain=TMR0-r_regn;        // r_regn er resttal som skal bruges.
    696.  
    697. if (today_rain<100)lcd_puts(" ");    // Højrestiller
    698. if (today_rain<10)lcd_puts(" ");    // højrestiller
    699. utoa(idag, today_rain, 10);            // til tekststreng
    700. lcd_puts(idag);            // skriver
    701. lcd_puts(" MM");            // husker MM
    702.  
    703. }    //slut vis regn
    704. void main (void)
    705. {setup();         //kører setup
    706.  
    707.  
    708.    TMR1ON=1;    // tænder timer1
    709.    sec=0;
    710.    PEIE=1;
    711.    GIE=1;
    712.    TMR1GE=0;
    713.    //TMR0=0;        // timer 0 til 0
    714.    xpulse=0;
    715.    TMR2IE=0; // tænder interrupt timer2
    716.    TMR2ON=0; // timer 2 on.
    717.    TMR0=0; // regn nulstilles
    718.    secund=-1;
    719.    min=0;
    720.    max=0;
    721.    lcd_clear();
    722.        lcd_goto(0x00);
    723.        lcd_puts("1234567890abcdefghij");
    724.        lcd_goto(0x40);
    725.        lcd_puts("abcdefghij1234567890");
    726.        fyldarray();
    727.       __delay_ms(1000);
    728.       lcd_clear();
    729. lcd_goto(0x00);
    730.  
    731.    while (1)
    732.    {
    733.        if (sec==1)
    734.        {
    735.            secund++;   // add 1 sec.
    736.            visning++;  // add til visning
    737.        
    738.            if (secund==60) // hvis det er talt til 60
    739.                {secund =0; // sætter sekund 0
    740.            uret();  // kører sub uret.
    741.        
    742.            }
    743.            if (visning==5)  // hvis talt til 5,
    744.            {
    745.                visning=0;   // sætter tæller til 0
    746.            
    747.                if (vis==0)  // hvis visning = regn
    748.                {vis=1;   // visning = temp
    749.                f_gennemlob=0;
    750.                }
    751.                else
    752.                {vis=0;      // sæt vis = regn
    753.                 lcd_clear();  // sletter skærmm
    754.                }
    755.            
    756.            
    757.            }
    758.        sec=0;
    759.            }
    760.    
    761.        if (vis==0)
    762.        {
    763.            vis_regn();  // viser regnen
    764.        }
    765.        else
    766.        {
    767.            if (!reset() == ONEWIRE_PRESENT)
    768.             {
    769.            laestemp();  // viser temperatur
    770.             f_gennemlob=1;
    771.             }
    772.        }
    773.    
    774. if (!set_time) // indstiller uret.
    775.        {
    776.            stil_ur();
    777.    
    778.        }
    779. if(!set_week)            // hvis tryk på set week  viser max min,
    780.                 {  vis_maxmin();
    781.                 int x;
    782.                 x=0;                // tæller til 0        
    783.                     while (x<100)    // løkke indtil 100*100=10 SEC
    784.                         {
    785.                     if (!set_week) x=0;        // hvis der trykkes igen, nulstiller vi tæller
    786.                         __delay_ms(100);    // i 10 sec.
    787.                         x++;                // tæller op
    788.                         }    //END WHILE tryk på vis max min
    789.                 }        // END IF set_week
    790.      
    791.  
    792. //SET MINUT  NULSTILLER DIVERSE.    
    793. if (!set_minut)        // hvis tryk på set minut  KLAR TIL NULSTILLING AF DIVERSE.
    794.         {
    795.             //sluk_ur();        // slukker uret.
    796.             RA0=1;            // tænder led for at vise vi sletter
    797.               //vis_regn();        // vis regn sub.
    798.                x=0;            // tæller til 0        
    799. while (x<50)                // løkke indtil 50*100=5 SEC
    800. {
    801. if (!set_minut) x=0;        // hvis der trykkes igen, nulstiller vi tæller
    802. __delay_ms(100);            // pause
    803. x++;                        // tæller op
    804. if (!set_week)                // hvis der trykkes på nulstil.
    805. {
    806. reset_regn();                // viser reset sub
    807. }
    808. }
    809. vis_maxmin();                    // viser temperatur sub
    810. x=0;                        // tæller på 0
    811. while (x<50)                // løkke indtil 50*100
    812. {
    813. if (!set_minut) x=0;        // hvis der trykkes nulstiller vi temp.
    814. __delay_ms(100);            // pauser
    815. x++;                        // tæller op
    816. if (!set_week)                // hvis der trykkes på nulstil
    817. {
    818. reset_temp();                // viser rest temp sub
    819. }
    820. }
    821.  
    822.  
    823.  
    824. //start_ur();                    // starter ur igen
    825. RA0=0;                        // slukker LED igen.
    826.         }                    // end set minut
    827.    
    828.    
    829. // SET HOUR  SKIFTER MELLLEM DAGE.
    830. if (!set_hour)
    831. {vis_regn();
    832.     vaelg_dage();
    833.  
    834. }
    835.        // more if.
    836.  
    837.    }
    838. }
    839.  
    840.  
    841.  

    The only problem i have is the wrong showing of negativ degrees
     
    Last edited: Jan 17, 2016
  2. spinnaker

    AAC Fanatic!

    Oct 29, 2009
    4,887
    1,019
    840 lines of code and all you say is "i read out the temperature i get a wrong output". Do you really expect someone to sift through that many lines of code and try to figure it out with no effort on your part? At least narrow the code down to the relevant section.


    If your only issue is reading negative degrees then you are not reading the negative it properly. The bit is different depending on the device. You need to read the datasheet.

    Here is an example for getting the result from a DS1820.

    unsigned integerPart = result.temperature >> 1;
    unsigned fractPart = ((result.temperature & 0b00000001) * 5);

    You will need to adapt to your code.

    I can't remember how to determine if is negative or not but this will indeed return the correct value if positive. I need to run but will look at how the negative flag is determined later if you still need it.
     
  3. ErnieM

    AAC Fanatic!

    Apr 24, 2011
    7,395
    1,607
    I see your point and that is the end of it.

    The first code fragment could possible be useful if the 3 variables it depends on are somehow defined. The second code section is completely useless.

    Show just the smallest piece of code that reproduces your issue. Cut it from your project and create another project to run on your simulator, fit it there, and paste it back.

    On the surface, I suspect this is a rounding issue.
     
  4. MMcLaren

    Well-Known Member

    Feb 14, 2010
    759
    116
    Hi FroceMaster.

    I see a couple things in the code that I'd like to investigate when I get back home in an hour or so. Hang in there.

    Cheerful regards, Mike
     
  5. spinnaker

    AAC Fanatic!

    Oct 29, 2009
    4,887
    1,019
    Here is the format for the DS18B20

    upload_2016-1-17_10-25-12.png

    Bits 11-15 will determine the sign.

    And I think you have more issues than a negative sign. You ar getting numbers in the 1000's of degrees. Are you running a blast furnace?

    Reading one wire is not a trivial task. Attached is code I have written and works except there are issues with Search ROM that occurred when I moved to XC8 that I have not had time to work out.

    You should only need to modify OW_config.h and OW_delay.h to get it to work.

    Here is a sample of how to call it. It assumes only one sensor.

    Code (Text):
    1.  
    2. void temperatureDisplay()
    3. {
    4.  
    5.   struct OW_ROM OWrom;
    6.   struct DSOWTherm_result result;
    7.  
    8.   DSOWTherm_convertAll();
    9.  
    10.   // Give some time for the conversion
    11.   __delay_ms(20);
    12.   __delay_ms(20);
    13.   __delay_ms(20);
    14.   __delay_ms(20);
    15.   __delay_ms(20);
    16.   __delay_ms(20);
    17.   __delay_ms(20);
    18.   __delay_ms(20);
    19.   __delay_ms(20);
    20.   __delay_ms(20);
    21.   __delay_ms(20);
    22.   __delay_ms(20);
    23.   __delay_ms(20);
    24.   __delay_ms(20);
    25.   __delay_ms(20);
    26.   __delay_ms(20);
    27.   __delay_ms(20);
    28.   __delay_ms(20);
    29.   __delay_ms(20);
    30.   __delay_ms(20);
    31.   __delay_ms(20);
    32.   __delay_ms(20);
    33.   __delay_ms(20);
    34.   __delay_ms(20);
    35.   __delay_ms(20);
    36.   __delay_ms(20);
    37.   __delay_ms(20);
    38.   __delay_ms(20);
    39.   __delay_ms(20);
    40.   __delay_ms(20);
    41.   __delay_ms(20);
    42.   __delay_ms(20);
    43.   __delay_ms(20);
    44.   __delay_ms(20);
    45.   __delay_ms(20);
    46.   __delay_ms(20);
    47.   __delay_ms(20);
    48.   __delay_ms(20);
    49.   __delay_ms(20);
    50.   __delay_ms(20);
    51.  
    52.  
    53.  
    54.   if (DSOWTherm_getCentigradeSingle(&result) == OW_SUCCESS)
    55.   {
    56.   DSOWTherm_getROMSingle(&OWrom);
    57.   uart_putStringRom("\r\n\r\nThe temperature of device ");
    58.  
    59.   char output[30];
    60.  
    61.   uart_putStringRom("= ");
    62.  
    63.  
    64.   // This conversion is for the DS1820.  It will also work for the DS18S20
    65.   // Consult datasheet and / or see header file or help file for conversion for your device.
    66.  
    67.   unsigned integerPart = result.temperature >> 1;
    68.   unsigned fractPart = ((result.temperature & 0b00000001) * 5);
    69.  
    70.  
    71.   if (tempUnit == 'F')
    72.   {
    73.  
    74.   float f = (integerPart *  1.8)  + 32;
    75.  
    76.   if (fractPart)
    77.   f = f + .9;
    78.  
    79.   int status = 0;
    80.  
    81.   strcpy(output, ftoa(f, &status));
    82.   strcat(output, " Degrees F");
    83.   uart_putString(output);
    84.   }
    85.   else
    86.   {
    87.  
    88.   char bufIntegerPart[5];
    89.   char bufFractPart[3];
    90.  
    91.   strcpy(output, itoa(bufIntegerPart, integerPart, 10));
    92.   strcat(output, ".");
    93.   strcat(output, itoa(bufFractPart, fractPart, 10));
    94.   strcat(output, " Degrees C");
    95.   uart_putString(output);
    96.  
    97.   }
    98.  
    99.  
    100.   }
    101.   else
    102.   {
    103.   uart_putStringRom("\r\nThere was an error getting the temperature!\r\n");
    104.   uart_putStringRom("Press any key to continue.\r\n\r\n");
    105.   uart_getChar();
    106.   }
    107.  
    108. }
    109.  
     
  6. atferrari

    AAC Fanatic!

    Jan 6, 2004
    2,652
    768
    After learning to test and debug code progressively by adding new sections to what was already working, the above is the best second advise ever.

    If you comply with the first, the second comes almost naturally always.
     
  7. nerdegutta

    Moderator

    Dec 15, 2009
    2,519
    786
    Is this the rain sensor @t06afre helped you with a few years ago?

    I talked to someone right outside of Copenhagen this morning. He said he would stay inside today. They had -10C. :)
     
  8. MMcLaren

    Well-Known Member

    Feb 14, 2010
    759
    116
    Hi FroceMaster,

    It looks like you are not "twos complementing" a negative temperature value correctly (at line 472 and line 540). When you "twos complement" a number you need to complement the number and add 1 to it. Attempting to "twos complement" the integer and fractional portions of the negative temperature value separately may be problematic. That is, after complementing and adding 1 to the fractional portion of the number you'll need a way to propagate a carry from the fractional portion to the integer portion.

    May I suggest you collect the raw "sign extended twos complement" temperature data into a 16-bit variable and perform the "twos complement" on that number and then separate out the integer and fractional portions? A quick experiment using XC8 (below) was used to verify the conversion.

    Good luck on your project. Please don't be afraid to click on the <like> button if this post was helpful.

    Cheerful regards, Mike

    Code (C):
    1.  
    2.   /******************************************************************
    3.    *  DS18B20 "sign extended twos complement" to decimal example    *
    4.    ******************************************************************/
    5.  
    6.       char temp[] = {"          "};     // temperature string
    7.       signed int rawtemp = 0xFFE1;      // raw temperature * 16
    8.       int frac;                         // 4-bit fraction * 16
    9.  
    10.       if(rawtemp < 0)                   // if negative
    11.       { rawtemp = -rawtemp;             // twos complement it
    12.         temp[0] = '-';                  // indicate negative
    13.       }                                 //
    14.   /*                                                                *
    15.    *  separate raw temperature into integer & fractional portions   *
    16.    *                                                                */
    17.       frac = (rawtemp & 15) * 625;      // extract fraction
    18.       rawtemp >>= 4;                    // remove fraction, 0..125
    19.   /*                                                                *
    20.    *  build temperature string. example; raw FFE1 -> "-01.9375°C"   *
    21.    *                                                                */
    22.       if(temp[0] != '-')                //
    23.         temp[0] = (rawtemp/100)%10|'0'; // hundreds
    24.       temp[1] = (rawtemp/10)%10|'0';    // tens
    25.       temp[2] = (rawtemp%10)|'0';       // ones
    26.       temp[3] = '.';                    //
    27.       temp[4] = (frac/1000)%10|'0';     // 1st decimal place
    28.       temp[5] = (frac/100)%10|'0';      // 2nd decimal place
    29.       temp[6] = (frac/10)%10|'0';       // 3rd decimal place
    30.       temp[7] = (frac%10)|'0';          // 4th decimal place
    31.       temp[8] = '°';                    //
    32.       temp[9] = 'C';                    //
    33.  
     
    Last edited: Jan 27, 2016
  9. atferrari

    AAC Fanatic!

    Jan 6, 2004
    2,652
    768
    We try to stay inside here as well: 35C and very humid!
     
  10. MMcLaren

    Well-Known Member

    Feb 14, 2010
    759
    116
    I suspect you were cracking a joke but just in case; How the world separates its decimals.
     
    Last edited: Jan 17, 2016
  11. dannyf

    Well-Known Member

    Sep 13, 2015
    1,835
    367
    It is more than that. Once you have msb.lsb, you can combine them into a 16-signed type, and the conversion into "displayable" decimal is fairly simple. Check the datasheet for sure.

    The code you have is poorly written.
     
Loading...