Page 1 of 1
power on/off button
Posted: 25 July 2006, 8:32 AM
by pcleats
Don,
I am using some of your code from your reflow project to turn on my project, using a single button. I also need to be able to turn the power back off using the same button.
I guess what I'm asking is what is the best way to modify your code so that it is always polling the switch.
Code: Select all
'
Call Poweron(true)
Call putpin(Relaypin,Power_on)
'
'
Private sub Poweron(ByVal awaitRelease as Boolean)
Do
Call Delay(0.050)
Loop While CBool(GetPin(SwitchPin))
If (awaitRelease) Then
' wait for button-up
Do
Call Delay(0.050)
Loop While Not CBool(GetPin(SwitchPin))
End If
End Sub
Thanks for all the help so far.
Patrick
Posted: 25 July 2006, 9:10 AM
by dkinzer
So you want to use a momentary contact push button to activate and deactivate an external device? If so, you'll probably want to construct your application with a main loop that checks the state of the switch on each pass. If the button is pressed, the external device is activated or deactivated depending on its current state.
Another option is to connect the switch to one of the interrupt inputs and have a task that awaits the interrupt. An outline of the task code is shown below.
Code: Select all
Private Dim deviceIsOn as Boolean
Private Const switchPin as Byte = 6
Sub ButtonTask()
Do
' wait for a button press
Call WaitForInterrupt(zxPinFallingEdge, 0)
' toggle the device state
Call PutPin(RelayPin, IIf(deviceIsOn, Power_off, PowerOn))
deviceIsOn = Not deviceIsOn
' wait for button-up
Do
Call Delay(0.050)
Loop While Not CBool(GetPin(SwitchPin))
' additional de-bounce delay
Call Delay(0.050)
Loop
End Sub
Posted: 25 July 2006, 10:49 AM
by pcleats
Hey Don,
With just a slight mod of your code it works spectacular. I have tried to use interrupts with a different chip, and it was a nightmare trying to get it setup. This works GREAT!
Patrick
Posted: 25 July 2006, 12:46 PM
by dkinzer
pcleats wrote:With just a slight mod of your code it works spectacular.
What change was required? Perhaps you'd post the working code as an example.
Posted: 25 July 2006, 13:22 PM
by pcleats
dkinzer wrote:
What change was required? Perhaps you'd post the working code as an example.
Here is what I had to do
Code: Select all
' wait for a button press
Private Const Power_on As Byte = 0
Private Const Power_off as Byte = 1
Dim deviceIsOn as Boolean
Call WaitForInterrupt(zxPinFallingEdge, 0)
' toggle the device state
Call PutPin(RelayPin, IIf(deviceIsOn, Power_off, Power_On))
deviceIsOn = Not deviceIsOn
if cbool(deviceisOn) = False then
call main
end if
This code works perfectly it is inside my main loop
I Call 'main' in order to clear the display and set everything back to a start condition.
Minor little problem
Posted: 25 July 2006, 14:23 PM
by pcleats
When I put the code listed before in the main loop of my program it allows me to turn the circuit on and off, but I no longer get a realtime display of the voltage and the current.
The displays shows what the circuit read when it started
Here is where I have the code located:
Code: Select all
Sub Main()
Call LCD_Init()
'
do
' wait for a button press
Call WaitForInterrupt(zxPinFallingEdge, 0)
' toggle the device state
Call PutPin(RelayPin, IIf(deviceIsOn, Power_off, Power_On))
deviceIsOn = Not deviceIsOn
if cbool(DeviceisOn) = False then
call Main
'Time delay for switch debounce
Call Delay(0.050)
end if
Call LCD_DisplayStr("Volts RT: Amps")
Call ReadVoltage()
Call ReadCurrent()
Call LCD_DisplayStrAt((fmt(OutputVoltage,2)), 2, 1)'Display Voltage row 2 col 1
Call LCD_DisplayStrAt((fmt(OutCurrent,3)), 2, 13)'Display current row 2 Col 10
loop
End Sub
Why don't I get a realtime display of the voltage and current anymore?
Thanks
Patrick
Posted: 25 July 2006, 15:43 PM
by dkinzer
Well, first off you don't want to call Main() from within Main(). That will overflow the stack and cause the processor to reset or hang. Secondly, I suggested that the power button monitoring be put in its own task. The WaitForInterrupt() causes the task that it's in to pause until the interrupt occurs. So your Main() will not do anything until you press the button.
Here is modified version that may suit your purposes. You may have to add some other code that I don't have, e.g. for the LCD etc. Note that the power button monitoring is is a separate task. That task will only be active for a short time after each button press. Meanwhile, the Main() task displays the data values if the device is on and does nothing if it is off. I'm just guessing that this might be what you want.
Code: Select all
Private Const RelayPin as Byte = 13
Private Const Power_on As Byte = 0
Private Const Power_off as Byte = 1
Private PowerButtonTaskStack(1 to 30) as Byte
Private deviceIsOn as Boolean
Sub Main()
Call LCD_Init()
CallTask PowerButtonTask, PowerButtonTaskStack
Do
If (deviceIsOn) Then
Call LCD_DisplayStr("Volts RT: Amps")
Call ReadVoltage()
Call ReadCurrent()
Call LCD_DisplayStrAt((fmt(OutputVoltage,2)), 2, 1)'Display Voltage row 2 col 1
Call LCD_DisplayStrAt((fmt(OutCurrent,3)), 2, 13)'Display current row 2 Col 10
Else
Call Delay(0.5)
End If
Loop
End Sub
Sub PowerButtonTask()
Do
' wait for a button press
Call WaitForInterrupt(zxPinFallingEdge, 0)
' toggle the device state
Call PutPin(RelayPin, IIf(deviceIsOn, Power_off, Power_On))
deviceIsOn = Not deviceIsOn
' Time delay for switch debounce
Call Delay(0.050)
Loop
End Sub
Posted: 25 July 2006, 15:48 PM
by dkinzer
By the way, in case it's not obvious, the code above is written assuming a switch that presents a logic zero the the ZX when it is closed. This is a common way to connect a switch - ground one side and connect a pullup resistor to the other side with the other resistor lead to +5. Then connect the switch/resistor junction to an input pin of the ZX. It is often recommended to include a series resistor between the ZX and the switch to protect against programming errors.
If your switch is wired to present a logic 1 when it is pressed, you should change zxPinFallingEdge to zxPinRisingEdge.