Strange problem with an 18F4580 based project


Closed Thread
Results 1 to 11 of 11

Hybrid View

  1. #1
    malc-c's Avatar
    malc-c Guest

    Default Strange problem with an 18F4580 based project

    Guy's, this is probably aimed at DT or Henrik as they are really familiar with my thermostat project, but I'm open to suggestions.

    My prototype thermostat unit (details can be found at http://www.picbasic.co.uk/forum/showthread.php?t=12712) has been running now for around 6 months, but recently I've had two incidences where the unit appears to be running, but has actually locked up in some way, after I tried fixing a problem with a light that is driven from the unit.

    The first instance the light was out, so whilst everything was still running I detached the cable and reseated the tube then plugged the light (an under cabinet florescent T5 tube) back in. Everything seemed OK until I noticed the snake in each vivarum move right up the cold end of the enclosure. The temperature on the LCD still showed 33.1C and both LEDs were pulsing away as normal, but on opening the viv the heat was obvious. I reset the controller and off went the alarms as both vivs were running at 45c (which was now shown on the display).

    The second instance was the same, but this followed a simple tapping of the tube to get it to light. Only this time I noticed that the temperature readings from the DS18B20's didn't fluctuate (normally they are constantly changing every few seconds by +/- 0.1c).

    It is as if the program in the chip stops running the PID loop or something but where you would expect the LCD to blank out, or the LEDs to stop pulsing if the chip stopped running that doesn't happen. Could it be the fuse settings? Can a PIC go into a state of limbo like this ??

    I've been told that some of the commercial companies hang out on the reptile forums have got wind of my project so I don't really want to paste up the current version of the code in full, so PM me if you need the files. I can obviously post up spinets, if required.

    Comments please

  2. #2
    Join Date
    May 2004
    Location
    NW France
    Posts
    3,648


    Did you find this post helpful? Yes | No

    Default

    Hi, Malc

    @ First sight ... I could think the DS1820 do not update its scratchpad for any reason.
    I read you use fluorescent tubes for lighting ... that rings my bell and I ask you

    1) Which value for the pullup resistor ( usually 4.7k ... when sensor close to processor ! )
    2) do you use ground shielded wire to connect your DSs ???
    3) could you post me the DS identification and temp reading section of your program ? ( to see if any " health " control of the sensor is done )

    may be we could think to some enforced DS chip " good running check " ...
    some control like " heating power always rises, but temp not = default somewhere )

    Alain
    ************************************************** ***********************
    Why insist on using 32 Bits when you're not even able to deal with the first 8 ones ??? ehhhhhh ...
    ************************************************** ***********************
    IF there is the word "Problem" in your question ...
    certainly the answer is " RTFM " or " RTFDataSheet " !!!
    *****************************************

  3. #3
    malc-c's Avatar
    malc-c Guest


    Did you find this post helpful? Yes | No

    Default

    Hi Alain, and thanks for posting.

    Yes I'm using 4.7K resistors on each of the DS18B20's. The cable length is approx 2m from the tip of the sensor to the unit, and made up of three wires twisted (used a drill). My research didn't throw up anything about having to use shielded cable between the sensor and the PIC.

    I'll zip up all the code (including the includes !) and let you check the code. To make things simpler, could you pm me your e-mail address.

    Thanks

  4. #4
    malc-c's Avatar
    malc-c Guest


    Did you find this post helpful? Yes | No

    Default code snippets

    Hope the following help

    Initialization
    Code:
    ;----[DS1820 Options]----Value----Default-----------------------------------
    DEFINE  DS1820_DECIMALS    1                    ' 1
    DEFINE  DS1820_VERIFYCRC   YES                  ' NO
    DEFINE  DS18B20_ONLY       YES                  ' NO
    INCLUDE "DT18x20.pbp"                           ' Include DT18x20 module
    Code:
        FOR Bvar = 0 to 3                               ; assume all sensors are working
            SensorActive(Bvar) = 1
        NEXT Bvar
            
        FOR pid_Channel = 0 TO 3                        ; Set # of bits in resolution
            GOSUB SelectSensor                          ; for all sensors
            GIE = 0                                     ; disable interrupts before 1-wire
            @ DS1820_Resolution 12            
            GIE = 1                                     ; enable interrupts after 1-wire
        NEXT pid_Channel
            
        LOW HeaterOut1                                  ; set heater pins Output to off
        LOW HeaterOut2
        LOW HeaterOut3
        LOW HeaterOut4
        
        Low Lights1                                     ; set lighting pins to off
        Low Lights2
    
        GOSUB SendPWRstat
    The subroutine referred to above
    Code:
    SendPWRstat:
        Bvar = 0
        Bvar.0 = ChannelPWR(0)
        Bvar.1 = ChannelPWR(1)
        Bvar.2 = ChannelPWR(2)
        Bvar.3 = ChannelPWR(3) 
    RETURN
    Now for the main part

    Code:
        FOR pid_Channel = 0 TO 3                        ; cycle thru all sensors
            GOSUB SelectSensor
            DS1820_Error = 0                            ; clear any previous errors
            DS1820_Flags = 0                            ; clear status flags
            GIE = 0                                     ; disable interrupts before 1-wire
              @ DS1820_Stat                             ; check the sensors status
            GIE = 1                                     ; enable interrupts after 1-wire
            PAUSEUS 20
            IF !DS1820_Done THEN SensorError            ; if it's not done by now, error
            GIE = 0                                     ; disable interrupts before 1-wire
              @ DS1820_Read                             ; get the temperature result
            GIE = 1                                     ; enable interrupts after 1-wire
            GOSUB Check4Zeros
            
            DS1820_Flags = 0
            GIE = 0                                     ; disable interrupts before 1-wire
              @ DS1820_Stat
            GIE = 1                                     ; enable interrupts after 1-wire
            IF (DS1820_Error = 0) AND DS1820_Done THEN  ; if there were no errors
                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
    IF Temperatures(pid_Channel) >  alarmhigh(pid_Channel) and Alarm = 1 then AlarmPin = 1
    IF Temperatures(pid_Channel) >  alarmhigh(pid_Channel) and Alarm = 0 then AlarmPin = 0
    IF Temperatures(pid_Channel) <=  alarmhigh(pid_Channel) then AlarmPin = 0
    IF Temperatures(pid_Channel) <=  alarmlow(pid_Channel) then AlarmPin = 0
    if Temperatures(pid_Channel) < alarmlow(pid_Channel)  and Alarm = 1 then AlarmPin = 1
    if Temperatures(pid_Channel) < alarmlow(pid_Channel)  and Alarm = 0 then AlarmPin = 0
       
            GOSUB ShowLCD 
              
            ELSE
        SensorError:
               HeaterDrives(pid_Channel) = 0            ; turn off heater if sensor's bad
               SensorActive(pid_Channel) = 0
               GOSUB ShowError                          ; display error message
            ENDIF
        NEXT pid_Channel
    The other two parts you may be interested in is the checking and displaying sections

    Code:
    AllZeros  VAR Bit
    Check4Zeros:
        AllZeros = 1
        FOR Bvar = 0 TO 8
            IF DS1820_Buffer(Bvar) != 0 THEN AllZeros = 0
        NEXT Bvar
        IF AllZeros THEN DS1820_CRCfailed = 1
    ;------------------------------------------------------------------------------ 
    
    ;----[show output on LCD]------------------------------------------------------- 
    ShowLCD:
        LOOKUP pid_Channel,[$80,$C0,$89,$C9],Bvar       ; Find location
        LCDOUT $FE,Bvar,DEC1 pid_Channel+1,"= "         ; print to LCD     
        TempWD = TempC : GOSUB TempToLCD                ; display TempC
        LCDOUT $DF                                      ; deg symbol
    and the select sensor sub
    Code:
    SelectSensor:
      SELECT CASE pid_Channel
        CASE 0 : @ DS1820_Select  _TempSensor1      ; Select the DS18x20 pin
        CASE 1 : @ DS1820_Select  _TempSensor2
        CASE 2 : @ DS1820_Select  _TempSensor3
        CASE 3 : @ DS1820_Select  _TempSensor4
      END SELECT  
    RETURN

    If you need more drop me an e-mail or I can post up more snipets
    Last edited by malc-c; - 18th December 2010 at 13:46. Reason: added more code

  5. #5
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default

    Malcolm,

    The heater outputs are interrupt driven, so if the main program locks up somewhere due to an unexpected condition, the heaters will continue pulsing at the last drive level given from the PID loops.

    I can't imagine all four DS18B20's having a problem at the same time. The program is checking CRC's.
    If 1 VIV got hot and the others were OK, I might suspect a DS.

    You may need to use the WDT to monitor the main loop.
    Then it'll reset the processor if it gets lost.

    Using ...
    DEFINE NO_CLRWDT 1
    PBP will not add CLRWDT instructions throughout the code.
    Then "strategically" placing CLRWDT statements in your program will clear it as long as the loop is running.

    I say strategically, because if you place a CLRWDT in the area where it's locking up, it won't help.

    Since the problem seems to be repeatable by fiddling with the lights, it should be fairly easy to locate good placements of the CLRWDT statements.

    Blinking an LED in the main loop may help identify when or if it's locked.
    DT

  6. #6
    malc-c's Avatar
    malc-c Guest


    Did you find this post helpful? Yes | No

    Default

    Darrel,

    Thanks for your input - with your prior knowledge of this project I thought you would be best placed to know what is going on.

    OK I'll be perfectly honest, I'm not 100% sure where I would need to place the CLRWDT commands, so here is the main program loop

    Code:
    ;-----------------------------------------------------------------------------
    ; *****  MAIN PROGRAMMING LOOP *****
    ;-----------------------------------------------------------------------------
    
    Main:
    
    
    If SetButton=0 then                                 ; jump to programming
    Gosub SetButtonRelease
    goto mainmenu
    endif
    
    If DecButton=0 then
    Gosub SetButtonRelease
    goto lightoveride                                   ; manual overide of light
    endif
    
    If IncButton=0 then
    Gosub SetButtonRelease
    goto cancelalarm                                   ; manual overide of alarm
    endif
    
    
        FOR pid_Channel = 0 TO 3                        ; cycle thru all sensors
            GOSUB SelectSensor
            GIE = 0                                     ; disable interrupts before 1-wire
            @  DS1820_Convert                           ; start a temperature conversion
            GIE = 1                                     ; enable interrupts after 1-wire
        NEXT pid_Channel
         
    ;----[check for data on com port] 
    
        FOR TempWD = 0 TO 10000
            IF RCIF THEN GOto coms
            PauseUs 100
        NEXT TempWD
    ;--------------------------------    
    
    
        FOR pid_Channel = 0 TO 3                        ; cycle thru all sensors
            GOSUB SelectSensor
            DS1820_Error = 0                            ; clear any previous errors
            DS1820_Flags = 0                            ; clear status flags
            GIE = 0                                     ; disable interrupts before 1-wire
              @ DS1820_Stat                             ; check the sensors status
            GIE = 1                                     ; enable interrupts after 1-wire
            PAUSEUS 20
            IF !DS1820_Done THEN SensorError            ; if it's not done by now, error
            GIE = 0                                     ; disable interrupts before 1-wire
              @ DS1820_Read                             ; get the temperature result
            GIE = 1                                     ; enable interrupts after 1-wire
            GOSUB Check4Zeros
            
            DS1820_Flags = 0
            GIE = 0                                     ; disable interrupts before 1-wire
              @ DS1820_Stat
            GIE = 1                                     ; enable interrupts after 1-wire
            IF (DS1820_Error = 0) AND DS1820_Done THEN  ; if there were no errors
                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
    IF Temperatures(pid_Channel) >  alarmhigh(pid_Channel) and Alarm = 1 then AlarmPin = 1
    IF Temperatures(pid_Channel) >  alarmhigh(pid_Channel) and Alarm = 0 then AlarmPin = 0
    IF Temperatures(pid_Channel) <=  alarmhigh(pid_Channel) then AlarmPin = 0
    IF Temperatures(pid_Channel) <=  alarmlow(pid_Channel) then AlarmPin = 0
    if Temperatures(pid_Channel) < alarmlow(pid_Channel)  and Alarm = 1 then AlarmPin = 1
    if Temperatures(pid_Channel) < alarmlow(pid_Channel)  and Alarm = 0 then AlarmPin = 0
       
            GOSUB ShowLCD 
              
            ELSE
        SensorError:
               HeaterDrives(pid_Channel) = 0            ; turn off heater if sensor's bad
               SensorActive(pid_Channel) = 0
               GOSUB ShowError                          ; display error message
            ENDIF
        NEXT pid_Channel
    
         
    ;   ---------------------------------------------------------------------------
    ;   check lighting periods and turn lights on or off accordingly
    ;   ---------------------------------------------------------------------------
    
        fn = 0                                                      ; select the first Lights
        if lightover = 0 then GOSUB CheckTimes                      ; if manual override set to off then go compare the programed period
        if lightover = 1 then progON=1                              ; if manual override flag set to on then lights on flag set to 1
        IF ProgON THEN                                              ; If in the program period
           IF Lights1 = 0 THEN Lights1 = 1
        ELSE
           IF Lights1 = 1 THEN Lights1 = 0
           IF Lights1 = 0 then LCDOut $FE, $94+9,"          " 
        ENDIF
    
        fn = 1                                                      ; select the second Lights
        if lightover = 0 then GOSUB CheckTimes                      ; compare the programed period
        IF ProgON THEN
            IF Lights2 = 0 THEN Lights2 = 1
    
        ELSE
            IF Lights2 = 1 THEN Lights2 = 0
         LCDOut $FE, $94+9,"          "
         ENDIF
        IF Lights1 = 1 then LCDOut $FE, $94+9,"Light 1 ON"
        IF Lights2 = 1 then LCDOut $FE, $94+9,"Light 2 ON"   
        if Lights1 = 1 and Lights2 = 1 then LCDOut $FE, $94+9,"Lights ON "
        If Lights1 = 0 and Lights2 = 0 then LCDOut $FE, $94+9,"          "
    
         
    ;   ---------------------------------------------------------------------------
    ;   Check for night time drops - if condition matched, drop temp
    ;   ---------------------------------------------------------------------------
    
        fn = 0                            ; select the first setting
        GOSUB CheckTimes2                   ; compare the programed period
        IF ProgON2 THEN
        SetPoints[0]=Droptemp[0]          ; change the corresponding set point to the drop temperature
        LCDOut $FE, $94,"Night"
        ELSE
        SetPoints[0]= normtemp[0]          ; change the corresponding drop temperature to set point
        LCDOut $FE, $94,"     "
        ENDIF    
      
        fn = 1                              ; select the second setting
        GOSUB CheckTimes2                   ; compare the programed period
        IF ProgON2 THEN
        SetPoints[1]=Droptemp[1]          ; change the corresponding set point to the drop temperature
        LCDOut $FE, $94,"Night"
        ELSE
        SetPoints[1]= normtemp[1]          ; change the corresponding drop temperature to set point
        LCDOut $FE, $94,"     "
        ENDIF  
         
        fn = 2                              ; select the third setting
        GOSUB CheckTimes2                   ; compare the programed period
        IF ProgON2 THEN
        SetPoints[2]=Droptemp[2]          ; change the corresponding set point to the drop temperature
        LCDOut $FE, $94,"Night"
        ELSE
        SetPoints[2]= normtemp[2]          ; change the corresponding drop temperature to set point
        LCDOut $FE, $94,"     "
        ENDIF  
         
        fn = 3                              ; select the fouth setting
        GOSUB CheckTimes2                   ; compare the programed period
        IF ProgON2 THEN
        SetPoints[3]=Droptemp[3]          ; change the corresponding set point to the drop temperature
        LCDOut $FE, $94,"Night"
        ELSE
        Setpoints[3]= normtemp[3]          ; change the corresponding drop temperature to set point
        LCDOut $FE, $94,"     "
        ENDIF   
         
         
         
    ;----[Flash Star on LCD]-------------------------------------------------------              
    If alarm=1 then
        LCDOUT $FE,$80 + 18,("*"&FlashStar*$FF)|(" "&~(FlashStar*$FF)) ; flash a star to show sample time, but used to indicate Alarm settings monitored
        FlashStar = !FlashStar 
    endif                             
    
    
    
    
    ;-----------------------------------------------------------------------------
    ; *****  MAIN PROGRAMMING LOOP END *****
    GOTO Main                                
    ;-----------------------------------------------------------------------------
    Could you advise me ??

    Thanks

Members who have read this thread : 0

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