#! /usr/bin/perl # hipirpidebounce.pl - Test of switch debouncing - Perl HiPi GPIO Package # Uses Integration method # # James M. Lynes Jr. - KE4MIQ # Created: October 22,2019 # Last Modified: 06/12/2020 - Initial HiPi version # # Notes: Multiple switch test version # From C code by Kenneth Kuhn # # Would be called periodically to test for # and debounce switch changes. Requires "pinmax" consecutive # zeros to set "pinval" to zero. Pin is active low, pulled high. # # Tested on a RPi 3B+ # # RPI J8 - GPIO Pin Definitions # ----------------------------- # 3V3 (1) (2) 5V # SDA/GPIO2 (3) (4) 5V # SCL/GPIO3 (5) (6) GND # PB1/GPIO4 (7) (8) GPIO14 # GND (9) (10) GPIO15 # PB2/GPIO17 (11) (12) GPIO18 # ENCA/GPIO27 (13) (14) GND # ENCB/GPIO22 (15) (16) GPIO23 # 3V3 (17) (18) GPIO24 # RED/GPIO10 (19) (20) GND # YEL/GPIO9 (21) (22) GPIO25 # GRN/GPIO11 (23) (24) GPIO8 # GND (25) (26) GPIO7 # GPIO0 (27) (28) GPIO1 # GPIO5 (29) (30) GND # GPIO6 (31) (32) GPIO12 # GPIO13 (33) (34) GND # GPIO19 (35) (36) GPIO16 # GPIO26 (37) (38) GPIO20 # GND (39) (40) GPIO21 use strict; use warnings; use HiPi qw( :rpi ); use HiPi::GPIO; use Time::HiRes qw(sleep); # Duplicate this hash for each switch/push button my %pin1 = ( pin => 0, # Current pin value(HiPi: $pin->value) pinctr => 0, # Pin value accumulator pinmax => 10, # Max value accumulation - adjust as needed pinval => 1, # Debounced value - 0 or 1 pinvalold => 1, # Old debounced value - 0 or 1 pingpio => 4, # GPIO pin to read and debounce - PB1 ); my %pin2 = ( pin => 0, # Current pin value(HiPi: $pin->value) pinctr => 0, # Pin value accumulator pinmax => 10, # Max value accumulation - adjust as needed pinval => 1, # Debounced value - 0 or 1 pinvalold => 1, # Old debounced value - 0 or 1 pingpio => 17, # GPIO pin to read and debounce - PB2 ); # Define hash pointers my $pin1 = \%pin1; my $pin2 = \%pin2; # Setup my $gpio = HiPi::GPIO->new; # Create a GPIO object # Create two push button inputs my $pb1 = $gpio->get_pin($pin1->{pingpio}); # Create pin object for pb1 $pb1->mode(RPI_MODE_INPUT); # Set pin to input $pb1->set_pud(RPI_PUD_UP); # Turn on internal pull-up resistor my $pb2 = $gpio->get_pin($pin2->{pingpio}); # Create pin object for pb2 $pb2->mode(RPI_MODE_INPUT); # Set pin to input $pb2->set_pud(RPI_PUD_UP); # Turn on internal pull-up resistor # Loop while(1) { $pin1->{pin} = $pb1->value; # Read pb1 my $pb1state = debounce($pin1); # Debounce pb1 if($pb1state != $pin1->{pinvalold}) { print "PB1: $pb1state\n"; $pin1->{pinvalold} = $pb1state; } $pin2->{pin} = $pb2->value; # Read pb2 my $pb2state = debounce($pin2); # Debounce pb2 if($pb2state != $pin2->{pinvalold}) { print "PB2: $pb2state\n"; $pin2->{pinvalold} = $pb2state; } } # Switch debounce - Integration Method sub debounce { my($pin) = @_; # Reference to the specific %pin hash if($pin->{pin} == 0) { if($pin->{pinctr} > 0) { # Latch minimum accumulator at zero $pin->{pinctr}--; # Zeros decrease the value accumulator } } elsif($pin->{pinctr} < $pin->{pinmax}) { $pin->{pinctr}++; # Ones increase the value accumulator } if($pin->{pinctr} == 0) { $pin->{pinval} = 0; # Set value to zero when accumulator goes to zero } elsif($pin->{pinctr} >= $pin->{pinmax}) { $pin->{pinval} = 1; # Set value to one when accumulator goes to max $pin->{pinctr} = $pin->{pinmax}; # Latch max accumulator at max } return $pin->{pinval}; }