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! :D

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.