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.
'
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
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.
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
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!
' 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.
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
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?
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.
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
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.