B4J Question [IOT] piface 2 debounce

jayel

Active Member
Licensed User
Longtime User
Hello,

Can I set debounce time on a digital input?

B4X:
Sub Process_Globals

   Private controller As GpioController
   Private pin0,pin1,pin2,pin3,pin4,pin5,pin6,pin7 As GpioPinDigitalInput
     
   
End Sub

Sub AppStart (Args() As String)
   controller.InitializePiFace(0x40, 0)

   pin0.Initialize("pin0",0)
   pin1.Initialize("pin1",1)
   pin2.Initialize("pin2",2)
   pin3.Initialize("pin3",3)
   pin4.Initialize("pin4",4)
   pin5.Initialize("pin5",5)
   pin6.Initialize("pin6",6)
   pin7.Initialize("pin7",7)
  
  
   StartMessageLoop
End Sub

Sub Pin0_StateChange(State As Boolean)
   Log("Pin0 StateChange event: " & State)
End Sub
Sub Pin1_StateChange(State As Boolean)
   Log("Pin1 StateChange event: " & State)
End Sub
Sub Pin2_StateChange(State As Boolean)
   Log("Pin2 StateChange event: " & State)
End Sub
Sub Pin3_StateChange(State As Boolean)
   Log("Pin3 StateChange event: " & State)
End Sub
Sub Pin4_StateChange(State As Boolean)
   Log("Pin4 StateChange event: " & State)
End Sub
Sub Pin5_StateChange(State As Boolean)
   Log("Pin5 StateChange event: " & State)
End Sub
Sub Pin6_StateChange(State As Boolean)
   Log("Pin6 StateChange event: " & State)
End Sub
Sub Pin7_StateChange(State As Boolean)
   Log("Pin7 StateChange event: " & State)
End Sub

John
 

Cableguy

Expert
Licensed User
Longtime User
it would be safer to implement the debouncing through a dedicated circuit... why do you want to do it in code?
 
Upvote 0

Roycefer

Well-Known Member
Licensed User
Longtime User
There are advantages and disadvantages to debouncing in hardware. It's harder to modify a hardware solution than a software solution. Hardware debouncing can also be quite tedious to set up (especially on 8 pins) and might ruin an otherwise elegant hardware design by adding previously unneeded external circuit boards. If you want to do debouncing in software, I suggest you do as follows.

First, you'll need to determine the characteristic duration of bouncing. An oscilloscope will be helpful here, or you can just examine the logs in your posted code (be sure to add some DateTime.Now so you can see how long the bouncing lasts). For each pin, create a global Boolean variable. You can put them in Array. Here is an example for one pin that assumes bouncing has stopped after 5 milliseconds (Debouncing0 is the global Boolean for this pin):
B4X:
Sub Pin0_StateChange(State As Boolean)
   If Debouncing0 Then  'Note that while Debouncing0=False, nothing will happen in this sub
       Debouncing0 = False
       DebounceDelay(0, 5, State)
   End If
End Sub

Sub DebounceDelay(pin As Int, delay As Long, State As Boolean)
    'In this sub, you can use CallSubPlus or a Timer to run a sub in "delay" milliseconds (5 in this example)
    'That sub should set Debouncing0 back to True and then execute whatever code you want in response to the
    'state change (using the State argument)
End Sub
 
Last edited:
Upvote 0

jayel

Active Member
Licensed User
Longtime User
Hello,

Thanks for the solution... it can be done.
Now I found in the examples folder of the pi4J (/opt/pi4J) on the raspberry an example :
B4X:
// START SNIPPET: listen-gpio-snippet


/*
* #%L
* **********************************************************************
* ORGANIZATION  :  Pi4J
* PROJECT       :  Pi4J :: Java Examples
* FILENAME      :  DebounceGpioExample.java
*
* This file is part of the Pi4J project. More information about
* this project can be found here:  http://www.pi4j.com/
* **********************************************************************
* %%
* Copyright (C) 2012 - 2015 Pi4J
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Lesser Public License for more details.
*
* You should have received a copy of the GNU General Lesser Public
* License along with this program.  If not, see
* <http://www.gnu.org/licenses/lgpl-3.0.html>.
* #L%
*/

import com.pi4j.io.gpio.*;
import com.pi4j.io.gpio.event.GpioPinDigitalStateChangeEvent;
import com.pi4j.io.gpio.event.GpioPinListenerDigital;

import java.util.Date;

/**
* This example code demonstrates how to setup a listener
* for GPIO pin state changes on the Raspberry Pi.
*
* @author Robert Savage
*/
public class DebounceGpioExample {

    public static void main(String args[]) throws InterruptedException {
        System.out.println("<--Pi4J--> GPIO Debounce Example ... started.");

        // create gpio controller
        final GpioController gpio = GpioFactory.getInstance();

        // provision gpio pin #02 as an input pin with its internal pull down resistor enabled
        final GpioPinDigitalInput myButton = gpio.provisionDigitalInputPin(RaspiPin.GPIO_02, PinPullResistance.PULL_DOWN);

        //
        // ----- DEBOUNCE -----
        //
        // Bouncing is the tendency of any two metal contacts in an electronic device to generate multiple signals as
        // the contacts close or open; debouncing is any kind of hardware device or software that ensures that only a
        // single signal will be acted upon for a single opening or closing of a contact.
        //
        // Pi4J supports a debounce feature to suppress state change event notifications on GPIO input pins.
        // This feature allows the consumer to set a debounce delay time in milliseconds.  When a pin state change
        // occurs, the initial event will be raised and the debounce delay timer will be started.  Any subsequent
        // pin state changes will be suppressed until after the debounce delay timer has expired.  When the debounce
        // delay timer expires and if the pin state is different than the start when the debounce timer started, a
        // pin event will be raised to notify the consumer of the pin state change.   (You can optionally set a
        // different debounce delay for each pin state or use the example below to set the same delay time for all
        // pin states)
        //
        // Please note that if you make a call to 'getState()', 'isHigh()' or 'isLow()' the actual current state
        // will be returned, the debounce feature only suppresses event notifications, is does not attempt to
        // mask the actual pin state.
        myButton.setDebounce(1000);

        // create and register gpio pin listener
        myButton.addListener(new GpioPinListenerDigital() {
            @Override
            public void handleGpioPinDigitalStateChangeEvent(GpioPinDigitalStateChangeEvent event) {
                // display pin state on console
                System.out.println("[" + new Date() +
                        "] --> GPIO PIN STATE CHANGE: " +
                        event.getPin() + " = " + event.getState());
            }

        });

        System.out.println(" ... complete the GPIO #02 circuit and see the listener feedback here in the console.");

        // keep program running until user aborts (CTRL-C)
        for (;;) {
            Thread.sleep(500);
        }

        // stop all GPIO activity/threads by shutting down the GPIO controller
        // (this method will forcefully shutdown all GPIO monitoring threads and scheduled tasks)
        // gpio.shutdown();   <--- implement this method call if you wish to terminate the Pi4J GPIO controller
    }
}

// END SNIPPET: listen-gpio-snippet

Can't this be implemented in the wrapper that Erel made?

John
 
Upvote 0
Top