[SOLVED] Programming a button to switch and debounce button

Hello,

I am new here and have Problems with the button. I have a hard time to switch on or off the light. The button is doing what he want’s to do.

I think The button has to be debounced. And the LED should have a state (on|off)

Here is my script.
hope someone can help me.
(I understand German too)


var Lichtstatus = 0
rule "Lichtschalter an"
when
        Item button1 changed
then
        if (channel1.state == OFF && Lichtstatus == 0){
        channel1.sendCommand(ON)
        Lichtstatus = 1
        }
end

rule "Lichtschalter aus"
when
        Item button1 changed
then
        if(channel1.state == ON && Lichtstatus == 1){
        channel1.sendCommand(OFF)
        Lichtstatus = 0
        }
end

Without knowing what things/items you are using we can’t help.
Please show all definitions of items.

BTW: This forum is read worldwide, so English is the requested language.

Thank you for your quick response.
I have no things. Here is my items-file

//This is the Items File


Switch channel1 "Channel 1" {gpio="pin:21 activelow:yes initialValue:high"}
Switch channel2 "Channel 2" {gpio="pin:20 activelow:yes initialValue:high"}
Switch channel3 "Channel 3" {gpio="pin:16 activelow:yes initialValue:high"}
Switch channel4 "Channel 4" {gpio="pin:26 activelow:yes initialValue:high"}
Switch channel5 "Channel 5" {gpio="pin:12 activelow:yes initialValue:high"}
Switch channel6 "Channel 6" {gpio="pin:19 activelow:yes initialValue:high"}
Switch channel7 "Channel 7" {gpio="pin:13 activelow:yes initialValue:high"}
Switch channel8 "Channel 8" {gpio="pin:6 activelow:yes initialValue:high"}

Contact button1 "Lichtschalter" [%s]" {gpio="pin:24 activelow:yes debounce:5"}


Sorry, I’m not using GPIO, so I can’t give much hints .
Doesn’t the switching work without a rule?

It’s maybe not the correct use, but would a threadsleep help to debounce the button ?

var Lichtstatus = 0
rule "Lichtschalter"
when
        Item button1 changed
then
        if (channel1.state == OFF && Lichtstatus == 0){
        channel1.sendCommand(ON)
        Lichtstatus = 1
    return
        }
    else if(channel1.state == ON && Lichtstatus == 1){
        channel1.sendCommand(OFF)
        Lichtstatus = 0
    return
        }
        Thread::sleep(250)
    end

I have not used the GPIO binding, so I have no experience with this, but according to the documentation (and your items configuration), the input pin that is connected to your button is already “debounced”, i.e. the debouning is taken care of by the binding. You may need to play around with different debounce intervals, though.

I think your problem is more with your rules than with the debounce (or lack thereof).

I am going to assume that your “physical button” is a momentary switch (i.e. a switch with only one stable position). Let’s assume the switch is OPEN when at rest. When you press it, it goes to CLOSED - and then “automatically” moves back to OPEN when you let go.

This means that for any button press (including the “let go”-part) you have two state changes, and your rule triggers on both. I think you should start by changing your rule to only trigger on one of these (that would normally be the “press”-part, i.e. you ignore the “let go”-part).

Try to change the rule trigger of the last rule you published to the following:

when 
  Item button1 changed to CLOSED
then

(and remove the return statements and the Thread:sleep())

2 Likes

So I use all my GPIO’s on RPI with this configuration:

	/*Contact*/
	
	Contact Contact_LivingRoomL (Group_LightSwitches,Group_History) {gpio="pin:23 debounce:0 activelow:yes"}  //SW1
	Contact Contact_LivingRoomR (Group_LightSwitches,Group_History) {gpio="pin:18 debounce:0 activelow:yes"} //SW2
	
	//Contact Contact_HallwayL {gpio="pin:7 debounce:0 activelow:yes"}//SW5
	//Contact Contact_HallwayR {gpio="pin:8 debounce:0 activelow:yes"}//SW6
	
	Contact Contact_Hallway_Bathroom (Group_LightSwitches,Group_History) {gpio="pin:24 debounce:0 activelow:yes"}  //SW3
	Contact Contact_BathroomR (Group_LightSwitches,Group_History) {gpio="pin:25 debounce:0 activelow:yes"} //SW4
	
	Contact Contact_MasterBedroomL (Group_LightSwitches,Group_History) {gpio="pin:15 debounce:0 activelow:yes"} //SW3A
	//Contact Contact_MasterBedroomR {gpio="pin:3 debounce:0 activelow:yes"}//SW8
	
	Contact Contact_BedroomL (Group_LightSwitches,Group_History) {gpio="pin:7 debounce:0 activelow:yes"} //SW7
	Contact Contact_BedroomR (Group_LightSwitches,Group_History) {gpio="pin:8 debounce:0 activelow:yes"} //SW8
	
	Contact Contact_BalconyL (Group_LightSwitches,Group_History) {gpio="pin:3 debounce:0 activelow:yes"} //SW7
	Contact Contact_BalconyR (Group_LightSwitches,Group_History) {gpio="pin:1 debounce:0 activelow:yes"} //SW8

Then my rule is:

rule "Switch pressed"
when
    Item Group_LightSwitches changed from OPEN to CLOSED 
then 
	//received update
	Thread::sleep(5) // cant remember why i did this.....
	Presence_Home.sendCommand(ON) // If someone pressed a switch someone needs to be home right??

       // Some error checking just in case....
	val changedSwitch = Group_LightSwitches.members.filter[switchPressed | switchPressed.lastUpdate != null].sortBy[lastUpdate].last
	if(changedSwitch == null) logWarn("FILE", "Something is amiss, no Item has a valid lastUpdate!")

	val sceneItemTemp = changedSwitch.name.toUpperCase().replace("CONTACT","SCENE") as String
	
	val sceneItem = Group_RoomScenes.members.findFirst[roomName | sceneItemTemp.contains(roomName.name.toUpperCase())] as NumberItem
	
	logInfo("Light switch", "Scene is now " + sceneItem)
	if (sceneItem!=null){
        if(sceneItem.state == 0){
		    if (vTimeOfDay.state.toString.contains("NIGHT")){
			   sceneItem.sendCommand(2)
		    }
		   	else{
				sceneItem.sendCommand(1)
		   	}
	    }
	    else {
			sceneItem.sendCommand(0)
	    }
	}
end 

You need to debounce the button with hardware
Look up pull up or pull down resistor

Dear Openhab community
Thank you for the quick answers, your effort and sharing your knowledge with me.

I did it like Kjetil Asdal said it. The main problem was that I did not use “changed to CLOSED”.

I removed the status variable because it blocked the switch in the basicui.

Thanks for the many thoughts in my troubleshooting


rule "Lichtschalter An"
when
        Item button1 changed to CLOSED
then
        if (channel1.state ==OFF){
        channel1.sendCommand(ON)}
end


rule "Lichtschalter Aus"
when
        Item button1 changed to CLOSED
then
        if (channel1.state ==ON){
        channel1.sendCommand(OFF)}
end