OFF-the-wall idea for momentary ON switch

MrDEB

Well-Known Member
Looking to build a digital kitchen timer that shuts off after timing out and/or a 10 second delay waiting for user input.
Here is the screenshot of the on/off section of the kitchen timer. Going to use an 18Fxxxx pic
maybe need a diode on the pic output pin to prevent applying voltage to the unpowered pic. unpowered pic?
 
When you mentioned edge cases in post #93 I thought you were referring to if the time was 12:59 and the minutes button (swt_2) was pressed then it would go to 13:00.

Mike.
 
That's the kind of thing I meant.

I believe in the code if you add a minute to 12 hours, hours resets to zero. Maybe 12 hours is enough but 12:01 is way closer to 12:00 than to 00:01. I didn't examine it closely, but the logic looked a bit messed up. Perhaps assuming "MINIUTES" meant minutes was a bad assumption on my part.

Maybe it means mini-ute, like this one. You, being from down under, know far more about utes than I do.

 
Code:
    if SWT_0 = 0 then hours = (Hours + 1) end if    //add 1 hour
    if hours > 12 then hours = 0 end if             //12 hour limit
    if SWT_1 = 0 then Hours = (hours - 1) end if    //subtract hours
    if hours > 12 then hours = 0 end if
   
        if swt_3 = 0 then miniutes = (miniutes + 1) end if
        if miniutes >= 60 then hours = hours + 1 miniutes = 0 end if      //add 1 to hours
        if swt_4 = 0 then miniutes = (miniutes - 1) end if
       
            if swt_5 = 0 then seconds = (seconds + 1)  end if   //add seconds
            if seconds = 60 then miniutes = miniutes + 1  seconds = 0 end if
            if swt_6 = 0 then seconds = (seconds - 1) end if   //subtract seconds
           ' if seconds < 0 then seconds = 0 end if
Strange how the switch numbers go 0,1,3,4,5,6 and I mentioned swt_2 - the missing one. Doh.

Note (you too MrDEB) the middle section and work out what it does at 12:59

MrDEB, it might be a good idea to make a subroutine to add time (seconds,minutes,hours) that does adjustment too.

Mike.
Edit, something like (made up basic),
Code:
Sub addTime(secs as byte,mins as byte, hrs as byte)
    seconds=seconds+secs
    minutes=minutes+mins
    hours=hours+hrs
    while(seconds>60)
        seconds=seconds-60
        minutes=minutes+1
    wend
    while(minutes>60)
        minutes=minutes-60
        hours=hours+1
    wend
    if hours>12 then hours=0
    return
end sub
Not sure about the hours bit.
Call by doing addTime(0,1,0) to add 1 minute etc.
 
Last edited:
Thanks
The switch numbering was corrected in post#100
contemplating SIMPLIFY
instead of 6 buttons to set the time desired, look at using a rotary switch, not a rotary encoder (too confusing for senior citizens IMO,
another option I thought of was adding a repeat time function
if baking cookies, just use repeat instead of having to readjust the timer.
need to search my junk drawer for rotary switches and knobs
 
If I am interpreting this right?
one button to cycle through HOURS, MINUTES, SECONDS using LCD for indication
two buttons for +/-
going to try that out using only three buttons to select the time amount, one for start and one for START and one for POWER LATCH ON
5 buttons total
 
USING TUMBLEWEEDS SUGGESTION IN POST#106 I rewrote the code so I only have 3 pushbuttons for time selection instead of 6. Am sure its not the best but? Now add an interrupt timmer.
Code:
{
*****************************************************************************
*  Name    : UNTITLED.BAS                                                   *
*  Author  : [select VIEW...EDITOR OPTIONS]                                 *
*  Notice  : Copyright (c) 2024 [select VIEW...EDITOR OPTIONS]              *
*          : All Rights Reserved                                            *
*  Date    : 1/12/2024                                                      *
*  Version : 1.0                                                            *
*  Notes   :                                                                *
*          :                                                                *
*****************************************************************************
}
{
*****************************************************************************
*  Name    : UNTITLED.BAS                                                   *
*  Author  : [select VIEW...EDITOR OPTIONS]                                 *
*  Notice  : Copyright (c) 2024 [select VIEW...EDITOR OPTIONS]              *
*          : All Rights Reserved                                            *
*  Date    : 1/7/2024                                                       *
*  Version : 1.0                                                            *
*  Notes   :                                                                *
*          :                                                                *
*****************************************************************************
}
{
*****************************************************************************
*  Name    : UNTITLED.BAS                                                   *
*  Author  : [select VIEW...EDITOR OPTIONS]                                 *
*  Notice  : Copyright (c) 2021 [select VIEW...EDITOR OPTIONS]              *
*          : All Rights Reserved                                            *
*  Date    : 8/15/2021                                                      *
*  Version : 1.0                                                            *
*  Notes   :                                                                *
*          :                                                                *
*****************************************************************************
}



Device = 18F43K22
Clock = 16
// int osc and IO pin libraries
Include "intosc.bas"

#option DIGITALIO_INIT = true       // automatically call setalldigital
Include "setdigitalio.bas"

#option LCD_DATA = PORTD.4
#option LCD_RS = PORTD.2
#option LCD_EN = PORTD.3
Include "LCD.bas"
Include "convert.bas"
Include "utils.bas"
Include "ISRTimer.bas"
//SWITCHES
Dim swt_0 As PORTB.0
Dim SWT_1 As PORTB.1
Dim SWT_2 As PORTB.2
Dim SWT_3 As PORTB.3
Dim SWT_4 As PORTB.4
Dim SWT_5 As PORTB.5
Dim SWT_6 As PORTB.6
Dim SWT_7 As PORTB.7

//LEDS

Dim led0 As PORTC.0  //HOURS+
Dim led1 As PORTC.1  //HOURS-
Dim led2 As PORTC.2  //MINIUTES+
Dim led3 As PORTC.3  //MINIUTES-
Dim led4 As PORTC.4  //SECONDS+
Dim led5 As PORTC.5  //SECONDS-
Dim led6 As PORTC.6
Dim led7 As PORTC.7

Dim x As Byte
Dim TIME As Byte
Dim ms As Byte
Dim Hours As Byte
Dim Minutes As Byte
Dim seconds As Byte
Dim Press As Byte

Sub OnTimer()
    Inc(ms)
End Sub

Sub Debounce ()
     DelayMS(300)
 End Sub
 
 
 
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 
Sub Hrs()
Repeat
    If SWT_1 = 0 Then Hours = (Hours + 1) Debounce()End If     //add 1 hour   
    If Hours > 12 Then Hours = 0 End If             //12 hour limit
    If SWT_2 = 0 Then Hours = (Hours - 1) Debounce()End If    //subtract hours\
    If Hours > 12 Then Hours = 0 End If
    //TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT   
 //DISPLAY DESIRED TIME
     WriteAt(1,1,"HOURS =  ")
    ' WriteAt(2,1,"               ")   //redresh display
      WriteAt(2,1,DecToStr(Hours))
      'WriteAt(2,7,DecToStr( Minutes))
      'WriteAt(2,14,DecToStr(seconds))
      DelayMS(30)
Until
      swt_0 = 0   
      End Sub      //PRESS = 11
//TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT     
      


Sub Min()
Repeat
    If SWT_1 = 0 Then  Minutes = ( Minutes + 1) Debounce()End If
        If  Minutes >= 60 Then Hours = Hours + 1  Minutes = 0 End If      //add 1 to hours
        If SWT_2 = 0 Then  Minutes = ( Minutes - 1) Debounce()End If
 //TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT   
 //DISPLAY DESIRED TIME
     WriteAt(1,1,"MINIUTES =  ")
    ' WriteAt(2,1,"               ")   //redresh display
     ' WriteAt(2,1,DecToStr(Hours))
      WriteAt(2,1,DecToStr( Minutes))
     ' WriteAt(2,14,DecToStr(seconds))
      DelayMS(30)
 Until
       swt_0 = 0 
        End Sub  //PRESS = 2
//TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT     



Sub Sec()
Repeat
    If SWT_1 = 0 Then seconds = (seconds + 1) Debounce() End If   //add seconds
            If seconds >= 60 Then  Minutes =  Minutes + 1 seconds = 0 End If
            If SWT_2 = 0 Then seconds = (seconds - 1) Debounce()End If   //subtract seconds
            If seconds < 0 Then seconds = 0 End If
   //TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT   
 //DISPLAY DESIRED TIME
     WriteAt(1,1,"SECONDS  =  ")
    ' WriteAt(2,1,"               ")   //redresh display
      'WriteAt(2,1,DecToStr(Hours))
      'WriteAt(2,7,DecToStr( Minutes))
      WriteAt(2,1,DecToStr(seconds))
      DelayMS(30)
 Until swt_0 = 0
         End Sub     //PRESS = 3
      //TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT     

// set switch port to inputs and enable pullups
    TRISB = $ff                // set as inputs
    WPUB = $ff                // enable pullups on all PORTB pins
    INTCON2.bits(7) = 0        // set bit RBPU = 0 turns on pullups
    TRISC = 0                                                       
    TRISA = 0
    TRISD = 0
    
    Press = 1
    Hours = 0
    Minutes = 0
    seconds = 0
    
     //set all portc LED off
 PORTC = 0
//PRESS INDICATES DESIRED HOURS, MINIUTE, SECONDS SELECTION 
    
    While (true)
    //XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
 //ENTER DESIRED TIME ROUTINE
 If Press = 1 Then Hrs()End If      //pRESS TO KEEP TRACK OF MENU SELECTION
  Press = Press + 1
 If Press = 2 Then Min() End If
  Press = Press + 1
 If Press = 3 Then Sec() End If
 Press = 1
 Wend
 
Can I ask if OnTimer is a built in function that gets called from an interrupt every millisecond or does it need to be setup?

Mike.
 
Can I ask if OnTimer is a built in function that gets called from an interrupt every millisecond or does it need to be setup?
The file ISRTimer contains a timer-based interrupt that allows you to register callback events, and it needs to be setup to do that. As it is right now, the "Sub OnTimer()" isn't called by anything since the Timer has not been setup or enabled.

the interrupt is called after the START button is pressed
...which must be in code that you haven't shown.
 
The file ISRTimer contains a timer-based interrupt that allows you to register callback events, and it needs to be setup to do that. As it is right now, the "Sub OnTimer()" isn't called by anything since the Timer has not been setup or enabled.
That's why I wondered if it was a built in routine. I was going to suggest reading the keys on interrupt (with repeat and rollover) and placing them in a fifo buffer for use as needed. Sounds like a bad idea now.

Mike.
 
After considering all the options, I don't think I really need the interrupt.
just a countdown timer and a counter that counts in seconds
You're keeping track of hours,minutes,secs so I would think you'd want a timer interrupt to keep basic time for you. ISRTimer provides an easy way to do that.

I was going to suggest reading the keys on interrupt (with repeat and rollover) and placing them in a fifo buffer for use as needed. Sounds like a bad idea now.
Maybe not, Mike. The Timer module allows you to create and manage multiple timers and events, so you could easily have a timer to keep track of time and another to handle key presses.

However, in this case it'll likely just confuse things and require an additional 10+ pages of posts
 
been attempting to display the COUNT DOWN portion of this mess
the sub COUNTDWN is displaying binary (255) instead of actual seconds, minutes.
I slowed the code down = reason for delayms(1500) suggestions?
Code:
Device = 18F43K22
Clock = 16
// int osc and IO pin libraries
Include "intosc.bas"
Include "ISRTimer.bas"

#option DIGITALIO_INIT = true       // automatically call setalldigital
Include "setdigitalio.bas"

#option LCD_DATA = PORTD.4
#option LCD_RS = PORTD.2
#option LCD_EN = PORTD.3
Include "LCD.bas"
Include "convert.bas"
Include "utils.bas"
Include "ISRTimer.bas"
//SWITCHES
Dim Sel As PORTB.0
Dim Plus As PORTB.1
Dim Minus As PORTB.2
Dim SWT_3 As PORTB.3    //start countdown
Dim SWT_4 As PORTB.4
Dim SWT_5 As PORTB.5
Dim SWT_6 As PORTB.6
Dim SWT_7 As PORTB.7

//LEDS

Dim led0 As PORTC.0  //HOURS+
Dim led1 As PORTC.1  //HOURS-
Dim led2 As PORTC.2  //MINIUTES+
Dim led3 As PORTC.3  //MINIUTES-
Dim led4 As PORTC.4  //SECONDS+
Dim led5 As PORTC.5  //SECONDS-
Dim led6 As PORTC.6
Dim led7 As PORTC.7



Dim Desired_Time As Byte
Dim x As Byte
Dim TIME As Byte
Dim ms As Byte
Dim Hours As Byte
Dim Minutes As Byte
Dim seconds As Byte
Dim Press As Byte

            
 Sub Countdwn()
  Repeat
  WriteAt(1,1,"HRS   MIN   SEC")
        
      If  seconds >= 60 Then minutes = minutes - 1  End If      //subtract 1 minute
      
      WriteAt(2,1,DecToStr(Hours))
      minutes = minutes - 1
      WriteAt(2,7,DecToStr(Minutes))
      seconds = seconds - 1
      WriteAt(2,14,DecToStr(seconds))
         DelayMS(1500)                 //set this for a 1 second interval
  Until
         Hours = 0 and
         minutes = 0 and
         seconds = 0
    
 End Sub   
    



Sub OnTimer()
    led2 = 1
    DelayMS(500)
    led2 = 0
    DelayMS(500)
End Sub

Sub Debounce ()
     DelayMS(300)
 End Sub
 
 // OnTimer event, flash LED...


 
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 
Sub Hrs()
Repeat
    If Plus = 0 Then Hours = (Hours + 1) Debounce()End If     //add 1 hour   
    If Hours > 12 Then Hours = 0 End If             //12 hour limit
    If Minus = 0 Then Hours = (Hours - 1) Debounce()End If    //subtract hours\
    If Hours > 12 Then Hours = 0 End If
   ' H_rs = (hours * 360000)   //number of MS in 1 hour
    //TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT   
 //DISPLAY DESIRED TIME
     WriteAt(1,1,"HOURS =  ")
      WriteAt(2,1,DecToStr(Hours))
      DelayMS(30)
Until
      Sel = 0       //select Miniutes desired
      End Sub      //PRESS = 11
//TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT     
      


Sub Min()
Repeat
    If Plus = 0 Then  Minutes = ( Minutes + 1) Debounce()End If
        If  Minutes >= 60 Then Hours = Hours + 1  Minutes = 0 End If      //add 1 to hours
        If Minus = 0 Then  Minutes = ( Minutes - 1) Debounce()End If
       ' M_in = (minutes * 60000)
 //TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT   
 //DISPLAY DESIRED TIME
     WriteAt(1,1,"MINIUTES =  ")
     WriteAt(2,1,DecToStr( Minutes))
     DelayMS(30)
 Until
       Sel = 0    //select seconds desired
        End Sub  //PRESS = 2
//TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT     



Sub Sec()
Repeat
    If Plus = 0 Then seconds = (seconds + 1) Debounce() End If   //add seconds
            If seconds >= 60 Then  Minutes =  Minutes + 1 seconds = 0 End If
            If Minus = 0 Then seconds = (seconds - 1) Debounce()End If   //subtract seconds
            If seconds < 0 Then seconds = 0 End If
          '  S_ec = (seconds * 1000)
   //TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT   
 //DISPLAY DESIRED TIME
     WriteAt(1,1,"SECONDS  =  ")
      WriteAt(2,1,DecToStr(seconds))
      DelayMS(30)
 Until Sel = 0        // desired time selected
         End Sub     //PRESS = 3
      //TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT     

// set switch port to inputs and enable pullups
    TRISB = $ff                // set as inputs
    WPUB = $ff                // enable pullups on all PORTB pins
    INTCON2.bits(7) = 0        // set bit RBPU = 0 turns on pullups
    TRISC = 0                                                       
    TRISA = 0
    TRISD = 0
    
    Press = 1
    Hours = 0
    Minutes = 0
    seconds = 0
    
     //set all portc LED off
 PORTC = 0
//PRESS INDICATES DESIRED HOURS, MINIUTE, SECONDS SELECTION



    
While (true)
 
I can't solve all your problems, but maybe this will help.

"this mess
the sub COUNTDWN is displaying binary (255) instead of actual seconds, minutes."

1. Could you explain exactly what this means? 255 is not a binary number, so I don't have a clue what you're talking about.

2. Previous versions of the code had the following statements when writing to the display. Unfortunately it's commented out there and removed from the most recent listing, so you don't understand why it's necessary....

Code:
' WriteAt(2,1,"               ")   //redresh display
[Edited to add code tags to preserve formating]

When you write to an LCD display, only the characters you're printing are changed. Anything that was displayed previously longer than the new text is not erased.

So if you write a long line, followed by a short line, you'll have garbage on the screen.

Say you write "ABCDEFGHIJKLMNOP" followed by "123456", the display will show

123456GHIJKLMNOP

because it wasn't cleared out between writes.

By the way, you might want to fix your spelling errors:

WriteAt(1,1,"MINIUTES = ")

3. As has been explained hundreds of times, delay statements are going to cause problems when you're trying to keep track of time.
 
Last edited:
That is so weird. I edited my post above because "the aystem" deleted all of the blank spaces.

This is what I typed AND what I saw when I clicked edit:



but this is what the finished post displayed:



So apologies to those who saw the "system reformatted" version and thought I was crazy.

To add a little explanation. When writing to an LCD, only the characters specified are changed. So a long message followed by a short message will leave remnants of the first message. By printing a message with the same number of blanks as the number of characters on the display between messages, the line is basically erased.

Code:
WriteAt (1,1, "                ")
'number of spaces equal to the number of characters  on the display, usually 16 or 20

This writes 16 spaces on the top line of the display.
 
Cookies are required to use this site. You must accept them to continue using the site. Learn more…