Help with word variable


Closed Thread
Results 1 to 4 of 4
  1. #1
    Join Date
    Oct 2009
    Posts
    583

    Default Help with word variable

    Hi Guys,

    I've been having a lot of issues with a project to produce a single channel version of a pulse proportional thermostat that uses PID routines developed in conjunction with the Late Darrell Taylor and Henrik back in 2009. Each time I strip the code to remove the unwanted channels from the original 4 channel version it somehow becomes unstable. The 4 channel version has become very large over the years as I've developed it, around 25K with the include files, so I can't (and really don't want to) post the lot up, and as I' wasn't sure where the unsuitability was coming from I've started from scratch, but with the same variables to make porting some parts easier.

    I've gone back to basics and started with the reading of a DS18B20 sensor. Rather than use DT's elaborate DT18x20.pbp library file, I've used a simple bit of code that gets the data from the one wire input and places it in the variable TempC

    The problem I have is is that the setpoint variable uses three digits to represent the temperature, eg 280 is the setpoint for 28.0C, and when I copied the code over for the PID routine I found the output LED was either on or off and didn't pulse when the temperature came close to the set point. Looking at the code, there is a line that works out the error value by taking the value in the set point for the channel - TempC which is the value read from the sensor. On checking that value, TempC is four digits, so I'm getting something like 2768 for the value of TempC for when the temperature is 27.68 degrees C. So using the formula that results in 280-2768 which results in a negative figure. What I need to do is to make TempC into a 3 digit value, 276, so that when the equation is run I get a positive error, 280-276=4.

    Here's the code (minus the PID library's)

    Code:
    '*******************************************************************************
    '*  Name    : Single ver X.pbp                                                 *
    '*  Author  : Malcolm Crabbe.  Uses library files from Darrel Taylor           *
    '*  Mentors :                                                                  *
    '*  Date    : Nov 2015                                                         *
    '*  Version :                                                                  *
    '*  Target  : 18F4620 running at 40 Mhz (10 mhz xtal - HS_PLL)                 *                   
    '*          : 1 x DS18x20                                                      * 
    '*******************************************************************************
    
    
    ; config settings 18F4620, 10mhz crystal
    ASM 
     
      __CONFIG    _CONFIG1H, _OSC_HSPLL_1H & _FCMEN_OFF_1H  & _IESO_OFF_1H  
      __CONFIG    _CONFIG2L, _PWRT_ON_2L   & _BOREN_OFF_2L
      __CONFIG    _CONFIG2H, _WDT_ON_2H & _WDTPS_512_2H
      __CONFIG    _CONFIG3H, _PBADEN_OFF_3H
      __CONFIG    _CONFIG4L, _LVP_OFF_4L & _XINST_OFF_4L
    
    ENDASM
    
    DEFINE  OSC 40
    ADCON1 = $0F
    clear
    
    ;----[Include Files]------------------------------------------------------------
    INCLUDE "incPID_mc.pbp"                         ' Include the multi-channel PID routine.
    PID_Channels CON 1
    
    ;----[Port settings]------------------------------------------------------------
    
    CMCON = $07                 ' Turn OFF all comparators
    ADCON0 = %00000000          ' AD converter module disabled
    ADCON1 = %00001111          ' All Digital
    ADCON2 = %00000000          '
    
    TRISA = %11000111           ' A0,A1,A2,A6,A7 input A3,A4,A5 output 
    TRISB = %00000000           ' All output
    TRISC = %10010000           ' C0,C1,C2,C3,C5,C6 output, C4 & C7 input
    TRISD = %00000001           ' D0 input, D1,D2,D3,D4,D5,D6,D7 output
    TRISE = %00000000           ' All output
    
    
    ;----[LCD ]---------------------------------------------------------------------
    
    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 
    
    LCDOUT $FE,1:FLAGS=0:PAUSE 250:LCDOUT $FE,1:PAUSE 250 ' Initialize LCD
    
     
    '----[Pin assignments ]---------------------------------------------------------
    TempIn          VAR PORTD.0        ' 18b20 data pin
    HeaterOut1      VAR PORTD.4        ' Pin assigned to Heater 1 
     
    ;----[Variables/Aliases - Temperature]------------------------------------------
    
    TempWD              VAR WORD                      ' temporary WORD variable
    TempC               VAR WORD
    Temperatures        VAR WORD
    SetPoints           VAR WORD[1]                   ' used to store the desired temperature setting
      SetPoint1         VAR SetPoints[0]
    ChannelPWR          VAR BIT
    HeatCycle           VAR BYTE  BANK0 SYSTEM
    HeaterDrives        VAR BYTE[4] BANK0 SYSTEM      ' outputs  
      HeatDrive1        VAR HeaterDrives[0]  
    spModes             VAR BYTE[1]                   ' controls how set point is adjusted PC or direct 
      spMode1           VAR spModes[0]
    Bvar                VAR BYTE                      ' temporary BYTE variable
    
    ;----[EEPROM Data]-------------------------------------------------------------
    DATA @0,0
    
    EE_spMode1        DATA 0                        ' 0=Manual mode,
    EE_SetPoint1      DATA WORD 280                 ' 28.0 deg. after programming if not in manual mode
    EE_pid_Kp1        DATA WORD $0700               ' PID constants
    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 125                      ' Clamp I-term to max ±100
    EE_pid_Out_Clamp1 DATA WORD 255                 ' Clamp the final output to 255
    EE_CH1PWR         DATA 1                        ' this needs to be set to 1 to enable heater channel
      
    GOSUB SendPWRstat
    
    DATA @0,0
    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(0)
    
    ;-------------------------------------------------------------------------------
    ;    *********************  MAIN PROGRAMMING LOOP ************************
    ;-------------------------------------------------------------------------------
      
    main:
     
        OWOUT TEMPIN,1,[$CC,$44]
        HIGH TEMPIN
        PAUSE 1000
        OWOUT TEMPIN,1,[$CC,$BE]   
        OWIN TEMPIN,0,[TempWD.LowByte,TEMPWD.HighByte]
        TempC = TempWD*/1600 
        LCDout $FE,1,DEC (TempC/100),".",#TempC dig 1,"C"    
    
    pid_Channel = 0 
      
        Temperatures(pid_Channel) = TempC
        pid_Error = SetPoints(pid_Channel) - TempC
        GOSUB PID
        IF pid_Out.15 THEN pid_Out = 0         ; only keep positive values
        IF ChannelPWR(pid_Channel) THEN
        HeaterDrives(pid_Channel) = pid_Out
        ELSE
        HeaterDrives(pid_Channel) = 0
        endif  
    
    ;----[TMR1 interrupt handler]---------------------------------------------------
    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
    
    LCDOut $FE, $C0,"Set  ",#setpoints(0)dig 2,#setpoints(0)dig 1,$DF,"C"
    LCDOut $FE, $D4,"tempC  ",dec tempC   'debug only
    LCDOut $FE, $D4+14,dec setpoints(0)    'debug only
    
    goto main
    
    SendPWRstat:
        Bvar = 0
        Bvar.0 = ChannelPWR(0)
    RETURN
    Any help would be welcome.... it's late and my brain hurts

  2. #2
    Join Date
    Aug 2003
    Posts
    985


    Did you find this post helpful? Yes | No

    Default Re: Help with word variable

    Quote Originally Posted by Scampy View Post
    So using the formula that results in 280-2768 which results in a negative figure. What I need to do is to make TempC into a 3 digit value, 276, so that when the equation is run I get a positive error, 280-276=4.
    Can’t you either divide the 2768 by 10, or multiply the 280 by 10 first?

  3. #3
    Join Date
    Oct 2009
    Posts
    583


    Did you find this post helpful? Yes | No

    Default Re: Help with word variable

    Well I did say it was late !

    OK that works - and gives a better result for when the current temperature is below the set point, but gives values of 655xx when the curent temp exceeds the setpoint. Also the heatdriver that controlls the LED on port D4 doesn't work as it should. It should be on constant, and then start pulsing at around 1sec frequency as the temperature nears the set point, with the pulse duration getting shorter as the difference between the current temperature and setpoint gets smaller.

    I've attached the PID include file hoping someone can advise
    Attached Files Attached Files

  4. #4
    Join Date
    May 2013
    Location
    australia
    Posts
    2,386


    Did you find this post helpful? Yes | No

    Default Re: Help with word variable

    a pid_out of 65535 would be interpreted as - 1 by your code and therefore ignored

    Code:
    ASM
    HeaterDrive
    ........
    you have no code to call this routine
    as well as no interrupt code at all that might call it either

Similar Threads

  1. Word Variable and I2C
    By Scampy in forum mel PIC BASIC Pro
    Replies: 8
    Last Post: - 21st May 2014, 08:45
  2. Stumped with word variable
    By Scampy in forum mel PIC BASIC Pro
    Replies: 30
    Last Post: - 11th November 2013, 13:11
  3. adding new word variable ?
    By iugmoh in forum General
    Replies: 4
    Last Post: - 21st February 2008, 00:26
  4. WORD vs BYTE variable lengths
    By bartman in forum General
    Replies: 0
    Last Post: - 28th November 2005, 21:16
  5. word variable to 25lc640
    By TONIGALEA in forum mel PIC BASIC Pro
    Replies: 5
    Last Post: - 6th July 2004, 19:59

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