Quantcast
Channel: MEL PICBASIC Forum
Viewing all articles
Browse latest Browse all 4745

Help with word variable

$
0
0
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 :)

Viewing all articles
Browse latest Browse all 4745

Trending Articles