Delay without using pause


Closed Thread
Results 1 to 40 of 43

Hybrid View

  1. #1
    Join Date
    Aug 2003
    Posts
    985


    Did you find this post helpful? Yes | No

    Default Re: Delay without using pause

    "which would overwrite the values for each vivarium every few seconds. “

    It sounds like you just need to overwrite the appropriate value into the 4 line buffer instead of updating the whole display buffer for every variable,
    or update the LCD location directly, but I would do the former, and write a complete screen every time.

  2. #2
    Join Date
    Aug 2003
    Posts
    985


    Did you find this post helpful? Yes | No

    Default Re: Delay without using pause

    Does viv mean vivarium? Before you listen to me you should see how professional my setup is
    I like the way the LCD doesn’t have a backlight so I faked it with an LED.




  3. #3
    Join Date
    Oct 2009
    Posts
    583


    Did you find this post helpful? Yes | No

    Default Re: Delay without using pause

    Nice Beardie -

    yes Viv is for vivarium, currently have a custom unit of three vivs, plus an incubator as my to royals have been locked several times over the past few months. Here's the incubator, and the existing controller, which is a bit neater than your set up - but hey if it works for you that's the main thing


  4. #4
    Join Date
    Aug 2003
    Posts
    985


    Did you find this post helpful? Yes | No

    Default Re: Delay without using pause

    Well it did six yrs ago

    Can you post the main code that prints to LCD?

    There are a lot of ways to solve it.
    I think I only now properly understand the issue.

    Padding has already been suggested and is one good way.
    Using a word variable you could mean average quite a few
    temperature readings.

  5. #5
    Join Date
    Oct 2009
    Posts
    583


    Did you find this post helpful? Yes | No

    Default Re: Delay without using pause

    LOL - same time as I did mine - so you have no excuses

    I've messed around with the version where I was trying to get a single line for the data from each vivarium that's it's all over the place. So I've posted the previous version which displays the data for all four vivariums, 1 per line of the LCD

    Code:
    ;-----------------------------------------------------------------------------
    ; *****  MAIN PROGRAMMING LOOP *****
    ;-----------------------------------------------------------------------------
    
    Main:
    
    
    SetPoint1 = normtemp1
    SetPoint2 = normtemp2 
    SetPoint3 = normtemp3 
    SetPoint4 = normtemp4 
    
    gosub FlushBuffer:
    
    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
    
    gosub read_dht                                  ; Go and read the AM2302 sensor for humidity
    
    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
    
    FOR TempWD = 0 TO 1000
        IF RCIF=1 THEN GOSUB coms                   ; Check to see id PC application connected
        PAUSE 1
    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                                      ; display info on LCD
    
    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 
        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
        ENDIF
         
    ;   ---------------------------------------------------------------------------
    ;   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
        ELSE
        SetPoints[0]= normtemp[0]                   ; change the corresponding drop temperature to set point
        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
        ELSE
        SetPoints[1]= normtemp[1]                   ; change the corresponding drop temperature to set point
        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
        ELSE
        SetPoints[2]= normtemp[2]                   ; change the corresponding drop temperature to set point
        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
        ELSE
        Setpoints[3]= normtemp[3]                   ; change the corresponding drop temperature to set point
        ENDIF   
                                     
    for x = 0 to 3
        LOOKUP x,[5,9,13,17],Bvar       ; Find location  [$80,$C0,$89,$C9]
        LCDOUT $fe,$80,"Set"
        LCDOUT $fe,$80+Bvar,#setpoints(x)dig 2,#setpoints(x)dig 1        ; print to LCD
        LCDOUT $DF         
    next x
    ;-----------------------------------------------------------------------------
    ; *****  MAIN PROGRAMMING LOOP END *****
    ;-----------------------------------------------------------------------------
    
     
    GOTO Main                                
    
    ;------------------------------------------------------------------------------
    Then this is the subroutine which displays the data on the LCD

    Code:
    ;----[Display temperatures, time and set points on LCD]------------------------
    ShowLCD:
    
        LCDOUT $FE,$C0,"Hot"
        LCDOUT $FE,$C0+5        ; print to LCD     
        TempWD = TempC : GOSUB TempToLCD                ; display TempC
        LCDOUT $DF                                      ; deg symbol
           
    I2CRead SDApin,SCLpin,$D0,$00,[RTCSec,RTCMin,RTCHour,RTCWDay,RTCDay,RTCMonth,RTCYear,RTCCtrl]  ; read DS1307 chip
    If RTCHour.6=1 then
    			
    CounterA=(RTCHour>>4)&$01                           ' Work-Out 12 or 24 hour Display for Hours
    else
    CounterA=(RTCHour>>4)&$03
    endif
    CounterA=CounterA*10+(RTCHour&$0F)                  ' Display Hours appropriately for 12 or 24 hour Mode 
    
    '********* to display time on LCD *****************  Commented out as there is no room on the LCD
    'If RTCHour.6=1 then			
    'LCDOut $FE,$C0+9,"Time ",#CounterA 
    'else
    'LCDOut $FE,$C0+9,"Time ",#CounterA Dig 1,#CounterA Dig 0
    'endif
    'LCDOut ":",#(RTCMin>>4)&$0F,#RTCMin&$0F
    '***************************************************
    
    timeH=(RTCHour>>4)                                  'convert the BCD format of the hours register and store in variable timeH
    timeH=(timeH &$03)*10
    timeH=timeH+(RTCHour&$0F)
    
    timeM=(RTCMin>>4)
    timeM=(timeM &$07)*10
    timeM=timeM+(RTCMin&$0F)                         'convert the BCD format of the mins register and store in variable timeM
    
    ;----[ Time matching - Nighttime temp drop routine ]----- 
    
    CheckTimes2:
    TimeCmpFlags = 0  ; clear flags first 
    
         ; if the Start and Stop times are the same, then Always OFF 
      if (StartHour[fn]=StopHour[fn]) AND _       
         (StartMin[fn]=StopMin[fn]) then AlwaysOFF2                      
    
         ; is it past the Start time?
      if (timeH>StartHour[fn]) OR _              
         (timeH=StartHour[fn] AND timeM >= StartMin[fn])then PastStart2=1
    
         ; is it past the Stop time?
      if (timeH>StopHour[fn]) OR _                
         (timeH=StopHour[fn] AND timeM >= StopMin[fn])then PastStop2=1
    
         ; does the period end the following day?
      if (StopHour[fn]< StartHour[fn]) OR _           
         (StopHour[fn]=StartHour[fn] AND StopMin[fn] < StartMin[fn]) then NextDay2=1
    
      if !NextDay2 then                               ; same day, use AND
          if PastStart2 AND !PastStop2 then ProgON2 = 1
      else                                           ; next day, use OR
          IF PastStart2 OR !PastStop2 then ProgON2 = 1
      endif
        
    AlwaysOFF2:
    return
    
    CheckTimes:
    TimeCmpFlags = 0  ; clear flags first
    
         ; if the Start and Stop times are the same, then Always OFF 
      if (lightsetHR[fn]=lightoffHR[fn]) AND _       
         (lightsetMN[fn]=lightoffMN[fn]) then AlwaysOFF                       
    
       ; is it past the Start time?
      if (timeH>lightsetHR[fn]) OR _              
         (timeH=lightsetHR[fn] AND timeM >= lightsetMN[fn])then PastStart=1
    
         ; is it past the Stop time?
      if (timeH>lightoffHR[fn]) OR _                
         (timeH=lightoffHR[fn] AND timeM >= lightoffMN[fn])then PastStop=1
    
         ; does the period end the following day?
      if (lightoffHR[fn]< lightsetHR[fn]) OR _           
         (lightoffHR[fn]=lightsetHR[fn] AND lightoffMN[fn] < lightsetMN[fn]) then NextDay=1
    
      if !NextDay then                               ; same day, use AND
          if PastStart AND !PastStop then ProgON = 1
      else                                           ; next day, use OR
          IF PastStart OR !PastStop then ProgON = 1
      endif
      
    AlwaysOFF:
    RETURN
    The two subroutines that deal with displaying the non presence of a 18B20 and read the AM2302

    Code:
    ;----[Display Sensor Error]-------------------------------------------------
    
    ShowError:
        LOOKUP pid_Channel,[5,9,13,17],Bvar               ; Find location;LOOKUP pid_Channel,[$83,$C3,$8B,$CB],Bvar [$80,$C0,$89,$C9]             
        LCDOUT $FE,$C0+Bvar,"N/C"           ; print to LCD ;LCDOUT $FE,Bvar," N/C    "                             
    RETURN
    
    ;----[Read humidity sensor]-------------------------------------------------
    
    read_dht:
    
    for loopcount = 0 to 3
        AM2302_Sensor_Num = loopcount+1
        gosub AM2302_Read
        LOOKUP loopcount,[5,9,13,17],Bvar       ; Find location  [$80,$C0,$89,$C9]
        LCDOUT $fe,$94,"Hum"
        LCDOUT $fe,$94+Bvar,dec AM2302_Hum/10,"% "' ".",dec AM2302_Hum//10,"% "         ; print to LCD    
        LCDOUT $fe,$D4,"Cold"
        LCDOUT $fe,$D4+Bvar,dec AM2302_Temp/10
        lcdout $DF
    next loopcount
       
    Return
    I hope that's enough for you to be going on with. ?

    Malc

  6. #6
    Join Date
    Aug 2003
    Posts
    985


    Did you find this post helpful? Yes | No

    Default Re: Delay without using pause

    You were saying if the program is allowed to go it’s hardest the temps change so fast you can’t read them,
    and your mock display only shows integer values which means the sensor moves back & forth several entire degrees each reading?

    If you let it go with no unneeded pauses, how many times would you guess the LCD is updated in one second?

    To clarify, you check for death temperatures, and print to LCD straight after, so the temps are degrees C by that time?
    That would be a good place for a FIFO buffer to store several previous values for averaging.

    From what I understand the problem, if you had no deliberate pause statements,
    everything would be great if the temp sensors didn’t give values all over the place
    because even thought the LCD updated fast the temps wouldn’t change much?

  7. #7
    Join Date
    Oct 2009
    Posts
    583


    Did you find this post helpful? Yes | No

    Default Re: Delay without using pause

    I discovered what was happening. As I only have one DS18B20 used for testing, the code was running the fore next loop to read the sensors and then printing them to the screen, but as the last three were not fitted it would jump out to the sensor error and display N/C for the for vivs 2, 3 and 4. I also removed the decimal for the temps and humidity simply to make things fit on the display.

    In trying to get the LCD to display the data for viv 1 for a few seconds, then viv 2 etc I tried using case statements, and the Cvar as a counter. The idea being if the counter is between 1 and 10 it jumps to a case statement which displays data for viv 1, if it's between 11 and 20 viv 2 etc. Again that didn't work because it had to be a sub routine in order to jump back and test for sensor error.

    The problem I have in using pause statements is in order to maintain stable temperatures in the vivs, the original code was designed to run through the reading of the sensors, calculating the PID (which was based on real life testing to calibrate the values) and drive the heaters. This works well and I would like to retain that precision, and any pause statements end up delaying the read, display and update process which means the precision is lost.

    The DS18B20 and AM2302 are precise to within 0.5c so the data is stable. As we are only talking + or minus a degree or so being the difference between the PID pulsing correctly or being fully on or completely off, any delay between the read sensor cycle could mean that the heater stays on longer and the temperature overshoots. The result would be that the swing between pulses would be similar to a standard on/off thermostat rather than a pulse proportional one.

Similar Threads

  1. Replies: 6
    Last Post: - 28th October 2014, 07:08
  2. Do I need a pause?
    By tazntex in forum Serial
    Replies: 21
    Last Post: - 29th August 2008, 05:32
  3. 1 us delay
    By Pedro in forum mel PIC BASIC Pro
    Replies: 1
    Last Post: - 18th February 2006, 18:28
  4. Pause
    By blue in forum General
    Replies: 7
    Last Post: - 29th December 2005, 15:24
  5. pause 0.5
    By detail in forum mel PIC BASIC Pro
    Replies: 2
    Last Post: - 27th June 2005, 12:32

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