#! /usr/bin/perl # hipipolledencoder.pl - Rotary Encoder Driver for Perl HiPi RPi GPIO Package # # James M. Lynes Jr. - KE4MIQ # Created: November 19,2019 - Polled encoder test version # Last Modified: 11/19/2019 - Remove loop delay and invert encoder bits # 06/12/2020 - Initial port to the HiPi Package # # Notes: 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); use Data::Dumper; my $pinA = 27; # ENCA pin J8-13 - GPIO27 my $pinB = 22; # ENCB pin J8-15 - GPIO22 my $value = 7200000; # Current value my $last = 0; # Previous value my $inc = 10; # 1, 10, 100 Hz etc. my $gpio = HiPi::GPIO->new; # Create a GPIO Object my $EncApin = $gpio->get_pin($pinA); # Encoder pin A Object $EncApin->mode(RPI_MODE_INPUT); $EncApin->set_pud(RPI_PUD_UP); my $EncBpin = $gpio->get_pin($pinB); # Encoder pin B Object $EncBpin->mode(RPI_MODE_INPUT); $EncBpin->set_pud(RPI_PUD_UP); while(1) { rotary(); print "Value: $value\n"; # Display the current value } sub rotary { my $msb = !($EncApin->value); # Input is active low - pulled high my $lsb = !($EncBpin->value); # So, need to invert it my $encoded = ($msb << 1) | $lsb; my $sum = ($last << 2) | $encoded; # Test for valid state transitions if($sum == 0b1101 || $sum == 0b0100 || $sum == 0b0010 || $sum == 0b1011) { $value = $value + $inc; } if($sum == 0b1110 || $sum == 0b0111 || $sum == 0b0001 || $sum == 0b1000) { $value = $value - $inc; } $last = $encoded; }