PID thermostat Issue


Results 1 to 6 of 6

Threaded View

  1. #1
    Join Date
    Oct 2009
    Posts
    583

    Default PID thermostat Issue

    Several years ago, Darrel (god rest his soul) and Henrik helped me no end in developing a 4 channel controller for my reptiles. I've used this code as a basis to develop simplified version, and to see if I can use a DTH11 sensor to incorporate humidity readout. Here is what I've got

    Code:
    '*******************************************************************************
    ' Set Config - 18F2520
    '*******************************************************************************
    ASM 
      __CONFIG    _CONFIG1H, _OSC_HS_1H
      __CONFIG    _CONFIG2L, _PWRT_ON_2L  
      __CONFIG    _CONFIG2H, _WDT_ON_2H & _WDTPS_512_2H
      __CONFIG    _CONFIG3H, _MCLRE_ON_3H & _LPT1OSC_OFF_3H & _PBADEN_OFF_3H  
      __CONFIG    _CONFIG4L, _LVP_OFF_4L & _XINST_OFF_4L
    ENDASM
    
    '*******************************************************************************
    ' LCD (20 x 4) set up
    '*******************************************************************************
    
    DEFINE LCD_DREG  PORTB                  ' LCD Data port
    DEFINE LCD_DBIT  0                      ' starting Data bit (0 or 4)
    DEFINE LCD_EREG  PORTB                  ' LCD Enable port
    DEFINE LCD_EBIT  5                      '     Enable bit  (on EasyPIC 5 LCD)
    DEFINE LCD_RSREG PORTB                  ' LCD Register Select port
    DEFINE LCD_RSBIT 4                      '     Register Select bit   (on EasyPIC 5 LCD)
    DEFINE LCD_BITS  4                      ' LCD bus size (4 or 8 bits)
    DEFINE LCD_LINES 4                      ' number of lines on LCD
    DEFINE LCD_COMMANDUS 2000               ' Command delay time in us 
    DEFINE LCD_DATAUS 50                    ' Data delay time in us 
    
    '*******************************************************************************
    ' Defines Statements
    '*******************************************************************************
    
    DEFINE  OSC 20                          ' 18F4520 / 18F2520, 20mhz crystal
    clear    
    
    '*******************************************************************************
    'Analog and Comparator settings
    '*******************************************************************************
    
    ADCON0 = %00000000                      'AD converter module disabled
    ADCON1 = %00001111                      'All Digital
    ADCON2 = %00000000
    CMCON = 7                               'Disable Comparators
    
    '*******************************************************************************
    'Pins & Ports
    '*******************************************************************************
    
    TempSensor1   VAR PORTA.5        ' Pin assigned to Sensor (EasyPIC5)
    HeaterOut1    VAR PORTA.4        ' Output
    
    '*******************************************************************************
    'Interrupts
    '*******************************************************************************
    
    DEFINE WRITE_INT 1
    INCLUDE "DT_INTS-18.bas"     ; DT's Base Interrupt System
    
    ASM
    INT_LIST  macro    ; IntSource,        Label,  Type, ResetFlag?
            INT_Handler   TMR1_INT,  HeaterDrive,   ASM,  yes
        endm
        INT_CREATE                    ; Creates the interrupt processor
    ENDASM
    
    T1CON = %00000001                 ; free-running, 1:4 prescaler
    @   INT_ENABLE   TMR1_INT         ; enable Timer1 interrupts
    
    '*******************************************************************************
    'DS18B20 Defines
    '*******************************************************************************
    DEFINE  DS1820_DECIMALS    1                    ' 1
    DEFINE  DS1820_VERIFYCRC   YES                  ' NO
    DEFINE  DS18B20_ONLY       YES                  ' NO
    INCLUDE "DT18x20.pbp"             ' Include DT18x20 module
    
    '*******************************************************************************
    'Inc PID routine
    '*******************************************************************************
    INCLUDE "incPID.pbp"              ' Include the PID routine.
    
    '*******************************************************************************
    'Varibles 
    '*******************************************************************************
    
    TempWD            VAR WORD        ' temporary WORD variable
    FlashStar         VAR BIT
    GIE               VAR INTCON.7
    spMode1           VAR BYTE
    SetPoint1         VAR WORD[1]
    Temperatures      VAR WORD
    HeatCycle         VAR BYTE  BANK0 SYSTEM
    HeaterDrives      VAR BYTE[4] BANK0 SYSTEM
      HeatDrive1      VAR HeaterDrives[0]
    SensorActive      VAR BIT
    ChannelPWR        VAR BIT
    
    '*******************************************************************************
    'EEPROM data
    '*******************************************************************************
    
    EE_spMode1        DATA 0                        ' 0=Manual mode, temp is set by Pot.
    EE_SetPoint1      DATA WORD 250                 ' 25.0 deg. after programming if not in manual mode
    EE_pid_Kp1        DATA WORD $0700               ' PID constants    $0700, $0080, $0200
    EE_pid_Ki1        DATA WORD $0080    
    EE_pid_Kd1        DATA WORD $0200
    EE_pid_Ti1        DATA 8                        ' Update I-term every 8th call to PID
    EE_pid_I_Clamp1   DATA 250                      ' Clamp I-term to max ±100
    EE_pid_Out_Clamp1 DATA WORD 255                 ' Clamp the final output to 255
    EE_CH1PWR         DATA 1 
    
    
    READ EE_spMode1,        spMode1
    READ EE_SetPoint1, WORD SetPoint1
    READ EE_pid_Kp1,   WORD pid_Kp
    READ EE_pid_Ki1,   WORD pid_Ki
    READ EE_pid_Kd1,   WORD pid_Kd
    READ EE_pid_Ti1,        pid_Ti
    READ EE_pid_I_Clamp1,   pid_I_Clamp
    READ EE_pid_Out_Clamp1, WORD pid_Out_Clamp
    read EE_CH1PWR,         ChannelPWR
    
    '*******************************************************************************
    'Initialization
    '*******************************************************************************
    
    LCDOUT $FE,1:FLAGS=0:PAUSE 250:LCDOUT $FE,1:PAUSE 250 ' Initialize LCD
        
    @   DS1820_Select  _TempSensor1           ; Select the DS18x20 pin
    @   DS1820_Resolution 12                  ; Set # of bits in resolution
    
    LOW HeaterOut1                        ; set heater pin to Output
    
    '*******************************************************************************
    'Main Program 
    '*******************************************************************************
    Main:
        
    @  DS1820_Convert                     ; start a temperature conversion                                     
    @ DS1820_Stat                         ; check the sensors status
                                              ; enable interrupts after 1-wire
    PAUSEUS 20
    GIE = 1                                 ; disable interrupts before 1-wire
    @ DS1820_Read                             ; get the temperature result
    @ DS1820_Stat
    GIE = 1                   
    
    IF DS1820_Error = 0 THEN              ; if there were no errors
    LCDOUT $FE,$80                    ; line 1, col 0
    TempWD = TempC : GOSUB TempToLCD  ; display TempC
    'TempWd = TempC
    pid_Error = SetPoint1 - TempC  
    TempWD = pid_Error                ; Display the error value
    Gosub PID
    IF pid_Out.15 THEN pid_Out = 0    ; only keep positive values
        HeatDrive1 = pid_Out
    ELSE                                  ;--- Error reading Sensor --------
        gosub senserror
    ENDIF
    
    GOTO Main                                
    
    '*******************************************************************************
    'Interrupt
    '*******************************************************************************
    ASM
    HeaterDrive
          incf    HeatCycle,F       ; HeatCycle
    
          movf    _HeatDrive1,W      ; HeatDrive1
          subwf   HeatCycle,w
          btfsc   STATUS,C
          bcf     _HeaterOut1
          btfss   STATUS,C
          bsf     _HeaterOut1
          
    
      INT_RETURN
    ENDASM
    '*******************************************************************************
    'Display Temp
    '*******************************************************************************
    TempToLCD:
        IF TempWD.15 THEN LCDOUT "-"          ; if negative, display minus sign
        TempWD = ABS(TempWD)                  ; get the positive value
        LCDOUT DEC TempWD/DS1820_DIG          ; Display the Integer portion
    @   if (DS1820_DECIMALS > 0)              ; if using decimals
            LCDOUT "."                        ;   display decimal point
            TempWD = TempWD//DS1820_DIG       ;   get decimal portion
    @       if (DS1820_DECIMALS > 1)          ; with DECIMALS=2, next DIG is 1
                LCDOUT  DEC1 TempWD DIG 1 
    @       endif
    @       if (DS1820_DECIMALS >= 1)         ; with DECIMALS=1, next DIG is 0
                LCDOUT  DEC1 TempWD DIG 0 
    @       endif
    @   endif
    RETURN
    '*******************************************************************************
    'Sensor Error
    '*******************************************************************************
    senserror:        
    LCDOUT $FE,1,"Sensor Error"
    HeatDrive1 = 0
    pause 1000
    LCDOUT $FE,1,"            "
    return
    The only issue I have with this code is that unlike the 4 channel version (which has been keeping my vivariums at a stable temperature for the past 4 years) is that it jumps out to the sensor error routine to often for my liking. Other than that it behaves just like the 4ch version and maintains a stable temperature around the set point. Any suggestions as to reduce the frequency that it detects a miss-read would be welcome.

    OK now on to the second part.

    I've used this code below to read the DTH11 sensor and display the results on an LCD

    Code:
    ASM 
      __CONFIG    _CONFIG1H, _OSC_HS_1H
      __CONFIG    _CONFIG2L, _PWRT_ON_2L  
      __CONFIG    _CONFIG2H, _WDT_ON_2H & _WDTPS_512_2H
      __CONFIG    _CONFIG3H, _MCLRE_ON_3H & _LPT1OSC_OFF_3H & _PBADEN_OFF_3H  
      __CONFIG    _CONFIG4L, _LVP_OFF_4L & _XINST_OFF_4L
    ENDASM
    
    
    '*******************************************************************************
    ' LCD (20 x 4) set up
    '*******************************************************************************
    
    DEFINE LCD_DREG  PORTB                  ' LCD Data port
    DEFINE LCD_DBIT  0                      ' starting Data bit (0 or 4)
    DEFINE LCD_EREG  PORTB                  ' LCD Enable port
    DEFINE LCD_EBIT  5                      '     Enable bit  (on EasyPIC 5 LCD)
    DEFINE LCD_RSREG PORTB                  ' LCD Register Select port
    DEFINE LCD_RSBIT 4                      '     Register Select bit   (on EasyPIC 5 LCD)
    DEFINE LCD_BITS  4                      ' LCD bus size (4 or 8 bits)
    DEFINE LCD_LINES 4                      ' number of lines on LCD
    DEFINE LCD_COMMANDUS 2000               ' Command delay time in us 
    DEFINE LCD_DATAUS 50                    ' Data delay time in us 
    
    '*******************************************************************************
    ' Defines Statements
    '*******************************************************************************
    
    DEFINE  OSC 20                          ' 18F4520 / 18F2520, 20mhz crystal
    ADCON1 = $0F
    clear    
    
    '*******************************************************************************
    'Analog and Comparator settings
    '*******************************************************************************
    
    ADCON0 = %00000000                      'AD converter module disabled
    ADCON1 = %00001111                      'All Digital
    ADCON2 = %00000000
    CMCON = 7                               'Disable Comparators
    
    '*******************************************************************************
    'Port and Register settings  (interrupts)
    '*******************************************************************************
        
    TRISA  = %00010111              
    TRISB  = %00000011               
    T0CON  = %11000111
    
    T1CON = %00000001                               ; free-running, 1:1 prescaler
    TMR1H = %11111111
    TMR1L = %11111011
    
    
    '*******************************************************************************
    
    LCDOUT $FE,1:FLAGS=0:PAUSE 250:LCDOUT $FE,1:PAUSE 250 ' Initialize LCD
    
    '*******************************************************************************
    
    dht var byte[32]
    humidite var byte
    haut var byte
    bas var byte
    temp var byte
    x var byte
    dht11 var portA.5
    
    '*******************************************************************************
    start:
    TRISA.5 = 0 '
    high dht11
    pause 2000 ' wait 2 sec
    low dht11 : pause 18' send 20ms low
    high dht11 : pauseus 30 ' send 40us hi
    TRISA.5 = 0
    PulsIn PORTA.5, 1, haut
    if haut < 15 then goto start
    for x = 31 to 0 step-1
    PulsIn PORTA.5, 1, dht[x] ' 1
    next x
    For x = 31 to 0 step-1
    if dht(x)>=9 and dht(x)<=21 then dht(x)=0 'if pulsewidth between 20 and 40uS then read as '0'
    if dht(x)>=29 and dht(x)<=41 then dht(x)=1 'if pulsewidth between 60 and 80uS then read as '1'
    next x
    humidite=dht[31]*128+dht[30]*64+dht[29]*32+dht[28]*16+dht[27]*8+dht[26]*4+dht[25]*2+dht[24]*1
    temp=dht[15]*128+ dht[14]*64+dht[13]*32+dht[12]*16+dht[11]*8+dht[10]*4+dht[9]*2+dht[8]*1
    lcdout  $FE,1 
    lcdout  $FE,$C0,"Humidite = ",#humidite,"% "
    lcdout  $FE,$80,"Temperature = ",#temp,$DF,"C"
    goto start
    The part I'm stumped with is how to use the data from the DTH11 to replace that of the 18B20. If I read the data sheet for the DHT11 once triggered to send data, it sends a 40 bit serial data which includes 8 bit temperature and 8 bit humidity (presumably bits 8-15 for temp and bits 24 to 31 for humidity by the code high-lighted). The data sheet for the 18B20 states that you can set the resolution for temp to digital conversion between 9 and 12 bits, but I'm sure it sends the actual temperature value as 2 x 8 bit bytes ??

    Constructive comments welcome.
    Last edited by Scampy; - 23rd February 2015 at 20:25.

Similar Threads

  1. DS18B20 thermostat
    By snuff28 in forum mel PIC BASIC Pro
    Replies: 8
    Last Post: - 19th April 2013, 14:19
  2. 4 Channel Thermostat using PID loops
    By malc-c in forum Code Examples
    Replies: 36
    Last Post: - 18th March 2013, 10:17
  3. Thermostat for refrigerator
    By fratello in forum mel PIC BASIC Pro
    Replies: 2
    Last Post: - 8th August 2012, 22:58
  4. Thermostat
    By koossa in forum Off Topic
    Replies: 15
    Last Post: - 16th November 2010, 10:06
  5. Pulse proportional thermostat
    By malc-c in forum mel PIC BASIC Pro
    Replies: 6
    Last Post: - 12th December 2009, 02:00

Members who have read this thread : 1

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts