Keypad on Rpi using Pi4J


24 posts
by bdjantl » Thu Mar 28, 2013 1:45 pm
I am trying to connect a keypad to the GPIO ports of my Rpi using the Java Pi4J library. It works as follows: two pins on my keypad feed the keypad with power (3.3V). Six other pins are used to find out which key was pressed on the keypad. The 'power' pins are configured as output on my Rpi, the other pins are configured as input.
However: this can only be determined knowing which of the input pins on the keypad was in the high state = providing the power.
Using the two input pins and the six output pins (of the keypad) I am able to know which of the 12 keys was pressed. For instance power on pin 1 and output on pin 5 means key 7 is pressed, whereas power on pin 2 and output on pin means for instance key 4 is pressed.
My problem is that I can not 'see' which of the input pins provided the power. Is there a way to detect on a GPIO output port if there flows a current?
Or is there any other solution to accomplish this?
-- Jan
Posts: 10
Joined: Thu Jan 31, 2013 8:47 pm
by savageautomate » Sun Mar 31, 2013 8:40 pm
(I have not programmed or wired a keypad before, so I may be speaking from a bit of a disadvantage here...)

Since the Pi's GPIO pins are only digital pins, I don't think you can know which (of the two) power (output) pin is sourcing which input pins. That is ... unless you implement some sort of timed switching technique where your code knows which output pin is ON and which is OFF at a given moment in time and then alternating the states of the two output pins in rapid succession. This may be a bit tricky to work out but may work for your needs.

-Robert
Robert Savage | Follow me @savageautomate
http://www.pi4j.com | http://www.pislices.com
http://www.savagehomeautomation.com
User avatar
Posts: 190
Joined: Thu Aug 16, 2012 3:20 pm
Location: USA
by bdjantl » Mon Apr 01, 2013 5:00 pm
Thanks Robert for your reply.

I found a python example here: http://www.raspberrypi.org/phpBB3/viewtopic.php?f=42&t=36723&p=308604&hilit=keypad#p308604 which gives me - with some modifications for my used GPIO pins (2 out and 6 in) - the correct results.
I have rewritten this in Java using the Pi4J library. However I can't get this to work using the Pi4J library. Any help is highly appreciated!

Code: Select all
import java.util.HashMap;

import com.pi4j.io.gpio.GpioController;
import com.pi4j.io.gpio.GpioFactory;
import com.pi4j.io.gpio.GpioPinDigitalInput;
import com.pi4j.io.gpio.GpioPinDigitalOutput;
import com.pi4j.io.gpio.Pin;
import com.pi4j.io.gpio.PinPullResistance;
import com.pi4j.io.gpio.PinState;
import com.pi4j.io.gpio.RaspiPin;

public class KeypadTest2
{

   /** The Constant PINMAPPING. */
   private static final HashMap<String, Integer> PINMAPPING = new HashMap<String, Integer>();

   /** The gpio. */
   private final GpioController theGpio = GpioFactory.getInstance();
   
   /** The Constant PIN_1_OUT. */
   private static final Pin PIN_1_OUT = RaspiPin.GPIO_15;
   
   /** The Constant PIN_3_OUT. */
   private static final Pin PIN_3_OUT = RaspiPin.GPIO_16;
   
   /** The Constant PIN_4_IN. */
   private static final Pin PIN_4_IN = RaspiPin.GPIO_01;
   
   /** The Constant PIN_5_IN. */
   private static final Pin PIN_5_IN = RaspiPin.GPIO_04;
   
   /** The Constant PIN_6_IN. */
   private static final Pin PIN_6_IN = RaspiPin.GPIO_05;
   
   /** The Constant PIN_7_IN. */
   private static final Pin PIN_7_IN = RaspiPin.GPIO_06;
   
   /** The Constant PIN_8_IN. */
   private static final Pin PIN_8_IN = RaspiPin.GPIO_10;
   
   /** The Constant PIN_9_IN. */
   private static final Pin PIN_9_IN = RaspiPin.GPIO_11;

   /** The pin1. */
   private GpioPinDigitalOutput thePin1 = theGpio.provisionDigitalOutputPin(PIN_1_OUT, PinState.LOW);
   
   /** The pin3. */
   private GpioPinDigitalOutput thePin3 = theGpio.provisionDigitalOutputPin(PIN_3_OUT, PinState.LOW);
   
   /** The pin4. */
   private GpioPinDigitalInput thePin4 = theGpio.provisionDigitalInputPin(PIN_4_IN, PinPullResistance.PULL_UP);
   
   /** The pin5. */
   private GpioPinDigitalInput thePin5 = theGpio.provisionDigitalInputPin(PIN_5_IN, PinPullResistance.PULL_UP);
   
   /** The pin6. */
   private GpioPinDigitalInput thePin6 = theGpio.provisionDigitalInputPin(PIN_6_IN, PinPullResistance.PULL_UP);
   
   /** The pin7. */
   private GpioPinDigitalInput thePin7 = theGpio.provisionDigitalInputPin(PIN_7_IN, PinPullResistance.PULL_UP);
   
   /** The pin8. */
   private GpioPinDigitalInput thePin8 = theGpio.provisionDigitalInputPin(PIN_8_IN, PinPullResistance.PULL_UP);
   
   /** The pin9. */
   private GpioPinDigitalInput thePin9 = theGpio.provisionDigitalInputPin(PIN_9_IN, PinPullResistance.PULL_UP);
   
   private GpioPinDigitalOutput theOutputs[] = { thePin1, thePin3 };
   private GpioPinDigitalInput theInputs[] = { thePin4, thePin5, thePin6, thePin7, thePin8, thePin9 };
   
   /** The first pin. */
   private int theFirstPin = 0;
   
   /** The second pin. */
   private int theSecondPin = 0;

   /**
    * @param args
    */
   public static void main(String[] args)
   {
      KeypadTest2 myKT = new KeypadTest2();
      
      myKT.initMapping();
      
      myKT.eventLoop();
   }

   /**
    * Event loop.
    */
   private void eventLoop()
   {
      while (true)
      {
         // Just stay inside the loop, but do not consume all CPU
         try
         {
            boolean myKeyPress = false;
            GpioPinDigitalInput myInput = null;
            int myInId = -1;
            
            // all outputs low
            for (int myO = 0; myO < theOutputs.length; myO++)
            {
               theOutputs[myO].low();
            }
                        
            while (!myKeyPress)
            {
               // waiting for input
               for (int myI = 0; myI < theInputs.length; myI++)
               {
                  if (theInputs[myI].isLow())
                  {
                     myInId = myI + 4;
                     myInput = theInputs[myI];
                     myKeyPress = true;
                     System.out.print("In = " + myInId);
                     break;
                  }
               }
               
               Thread.sleep(100);
            }
            
            // now test the inputs by setting the outputs from high to low one by one
            for (int myO = 0; myO < theOutputs.length; myO++)
            {
               for (int myO2 = 0; myO2 < theOutputs.length; myO2++)
               {
                  theOutputs[myO2].high();
               }

               theOutputs[myO].low();
               
               // input found?
               if (myInput.isLow())
               {
                  System.out.println("Out = " + myO);
                  
                  theSecondPin = myInId;
                  
                  if (myO == 0)
                  {
                     theFirstPin = 1;
                  }
                  else
                  {
                     theFirstPin = 3;
                  }
                  
                  checkPins();
                  break;
               }
            }
         }
         catch (InterruptedException myIE)
         {
            myIE.printStackTrace(System.err);
         }
      }
   }
   
   /**
    * Maps a pin combination on a keypad entry.
    */
   private void initMapping()
   {
      PINMAPPING.put("35", (int) '1');
      PINMAPPING.put("36", (int) '2');
      PINMAPPING.put("37", (int) '3');
      PINMAPPING.put("38", (int) '4');
      PINMAPPING.put("39", (int) '5');
      PINMAPPING.put("14", (int) '6');
      PINMAPPING.put("15", (int) '7');
      PINMAPPING.put("16", (int) '8');
      PINMAPPING.put("17", (int) '9');
      PINMAPPING.put("18", (int) '*');
      PINMAPPING.put("34", (int) '0');
      PINMAPPING.put("19", (int) '#');
   }
   
   private void checkPins()
   {
      System.out.println("Pin states = " + theFirstPin + " - " + theSecondPin);
      
      if (theFirstPin != 0 && theSecondPin != 0)
      {
         int myInput = PINMAPPING.get("" + theFirstPin + theSecondPin);
         
         System.out.println("Input read = " + (char) myInput);
         
         theFirstPin = 0;
         theSecondPin = 0;
      }
   }
}


-Jan
Last edited by bdjantl on Mon Apr 01, 2013 5:08 pm, edited 1 time in total.
Posts: 10
Joined: Thu Jan 31, 2013 8:47 pm
by savageautomate » Mon Apr 01, 2013 5:06 pm
You could paste your code at http://pastebin.com/ and then just include a link here.
Robert Savage | Follow me @savageautomate
http://www.pi4j.com | http://www.pislices.com
http://www.savagehomeautomation.com
User avatar
Posts: 190
Joined: Thu Aug 16, 2012 3:20 pm
Location: USA
by bdjantl » Mon Apr 01, 2013 5:09 pm
savageautomate wrote:You could paste your code at http://pastebin.com/ and then just include a link here.


I attached the code in a code-block in my previous comment...
Posts: 10
Joined: Thu Jan 31, 2013 8:47 pm
by savageautomate » Mon Apr 01, 2013 6:39 pm
Got it. Having difficulty understanding code logic without a better understanding on how the keypad works. Any links for documentation on the keypad?

Thanks, Robert
Robert Savage | Follow me @savageautomate
http://www.pi4j.com | http://www.pislices.com
http://www.savagehomeautomation.com
User avatar
Posts: 190
Joined: Thu Aug 16, 2012 3:20 pm
Location: USA
by bdjantl » Mon Apr 01, 2013 6:51 pm
In fact there is. You can find it here: http://www.schurter.com/var/schurter/storage/ilcatalogue/files/document/datasheet/en/pdf/typ_12_key_piezo_keypad.pdf

I am using the 12 key keypad. On page 8 you see a circuit diagram of the keypad. When someone presses a key, one of the vertical lines, pin 1 and 3 on the keypad (connected on GPIO 15 and 16) and one of the horizontal lines (pins 4-6, connected on GPIO 1, 4, 5, 6, 10 and 11) are connected. So... line 1 and 4 'tells' me the user pressed 6 on the keypad.
The python code works with originally works with the number of columns and rows on the keypad, which isn't the case here. But with slight modifications to my situation it shows me that it should be possible to read out the keypad.

Thanks in advance for your time.
-Jan
Posts: 10
Joined: Thu Jan 31, 2013 8:47 pm
by reinaldo.rda » Fri Oct 17, 2014 6:58 pm
bdjantl, you could implement reading the keypad using the Pi4J library? I'm having trouble to read a 4x4 keypad, any help will be appreciated.
Posts: 3
Joined: Thu Aug 14, 2014 1:30 pm
by bdjantl » Fri Oct 24, 2014 9:26 pm
reinaldo.rda wrote:bdjantl, you could implement reading the keypad using the Pi4J library? I'm having trouble to read a 4x4 keypad, any help will be appreciated.


Hi Reinaldo.rda,

What I did first was find out which are the input and output lines on the keyboard. You should setup these lines using the GPIO ports in your code. My keypad had two input lines and six output lines. I also had a schema from this keyboard which identifies the keys on the keypad by combining the input and output lines. For the input lines you create listeners and react on a state change by finding the corresponding output line. From the state change you know which input port was activated. By setting all output lines to high to low, one by one, you can check if the found inputline gets low to. If so, you found the two lines 'crossing' each other, which will give you key pressed on your keypad.
It's a bit cryptic maybe, but this is how I got it working.
Below the example code. It's documented and should give you some more pointers on how to implement this.

Regards,

Jan

Code: Select all
import java.util.HashMap;

import com.pi4j.io.gpio.GpioController;
import com.pi4j.io.gpio.GpioFactory;
import com.pi4j.io.gpio.GpioPinDigitalInput;
import com.pi4j.io.gpio.GpioPinDigitalOutput;
import com.pi4j.io.gpio.Pin;
import com.pi4j.io.gpio.PinPullResistance;
import com.pi4j.io.gpio.PinState;
import com.pi4j.io.gpio.RaspiPin;
import com.pi4j.io.gpio.event.GpioPinDigitalStateChangeEvent;
import com.pi4j.io.gpio.event.GpioPinListenerDigital;

/**
 * The Class PiezoKeypad.
 */
public class PiezoKeypad
{

   /**
    * <pre>
    * Keypad pin schema key = pina + pinb     
    *     o oiiiiii (output/input) 
    * 1 =   3 5 
    * 2 =   3  6 
    * 3 =   3   7 
    * 4 =   3    8 
    * 5 =   3     9 
    * 6 = 1  4 
    * 7 = 1   5 
    * 8 = 1    6 
    * 9 = 1     7 
    * * = 1      8 
    * 0 =   34 
    * # = 1       9
    * </pre>
    *
    * .
    */

   /** The Constant PINMAPPING. */
   private static final HashMap<String, Integer> PINMAPPING = new HashMap<String, Integer>();

   /** The gpio. */
   private final GpioController theGpio = GpioFactory.getInstance();

   /** The Constant PIN_1_IN. */
   private static final Pin PIN_1_OUT = RaspiPin.GPIO_15;

   /** The Constant PIN_3_IN. */
   private static final Pin PIN_3_OUT = RaspiPin.GPIO_16;

   /** The Constant PIN_4_IN. */
   private static final Pin PIN_4_IN = RaspiPin.GPIO_01;

   /** The Constant PIN_5_IN. */
   private static final Pin PIN_5_IN = RaspiPin.GPIO_04;

   /** The Constant PIN_6_IN. */
   private static final Pin PIN_6_IN = RaspiPin.GPIO_05;

   /** The Constant PIN_7_IN. */
   private static final Pin PIN_7_IN = RaspiPin.GPIO_06;

   /** The Constant PIN_8_IN. */
   @SuppressWarnings("unused")
   private static final Pin PIN_8_IN = RaspiPin.GPIO_10;

   /** The Constant PIN_9_IN. */
   @SuppressWarnings("unused")
   private static final Pin PIN_9_IN = RaspiPin.GPIO_11;

   /** The pin1. */
   private final GpioPinDigitalOutput thePin1 = theGpio
         .provisionDigitalOutputPin(PIN_1_OUT);

   /** The pin3. */
   private final GpioPinDigitalOutput thePin3 = theGpio
         .provisionDigitalOutputPin(PIN_3_OUT);

   /** The pin4. */
   private final GpioPinDigitalInput thePin4 = theGpio
         .provisionDigitalInputPin(PIN_4_IN, PinPullResistance.PULL_UP);

   /** The pin5. */
   private final GpioPinDigitalInput thePin5 = theGpio
         .provisionDigitalInputPin(PIN_5_IN, PinPullResistance.PULL_UP);

   /** The pin6. */
   private final GpioPinDigitalInput thePin6 = theGpio
         .provisionDigitalInputPin(PIN_6_IN, PinPullResistance.PULL_UP);

   /** The pin7. */
   private final GpioPinDigitalInput thePin7 = theGpio
         .provisionDigitalInputPin(PIN_7_IN, PinPullResistance.PULL_UP);

   /** The pin8. */
   private final GpioPinDigitalInput thePin8 = theGpio
         .provisionDigitalInputPin(PIN_8_IN, PinPullResistance.PULL_UP);

   /** The pin9. */
   private final GpioPinDigitalInput thePin9 = theGpio
         .provisionDigitalInputPin(PIN_9_IN, PinPullResistance.PULL_UP);

   /** The outputs. */
   private final GpioPinDigitalOutput theOutputs[] = { thePin1, thePin3 };

   /** The input. */
   private GpioPinDigitalInput theInput;

   /** The in id. */
   private int theInId;

   /** The first pin. */
   private int theFirstPin = 0;

   /** The second pin. */
   private int theSecondPin = 0;

   /**
    * Instantiates a new piezo keypad.
    */
   public PiezoKeypad()
   {
      initMapping();

      initListeners();
   }

   /**
    * Check pins.
    *
    * Determins the pressed key based on the activated GPIO pins.
    */
   private synchronized void checkPins()
   {
      if (theFirstPin != 0 && theSecondPin != 0)
      {
         final int myInput = PINMAPPING
               .get(theFirstPin + theSecondPin);

         // inform the externa listeners on the pressed key
         PiezoKeypad.this.fireEvent(myInput);

         theFirstPin = 0;
         theSecondPin = 0;
      }
   }

   /**
    * Find output.
    *
    * Sets output lines  to high and then to low one by one.
    * Then the input line is tested. If its state is low, we have the right output line and therefore
    * a mapping to a key on the keypad.
    */
   private void findOutput()
   {
      // now test the inputs by setting the outputs from high to low
      // one by one
      for (int myO = 0; myO < theOutputs.length; myO++)
      {
         for (final GpioPinDigitalOutput myTheOutput : theOutputs)
         {
            myTheOutput.high();
         }

         theOutputs[myO].low();

         // input found?
         if (theInput.isLow())
         {
            theSecondPin = theInId;

            if (myO == 0)
            {
               theFirstPin = 1;
            }
            else
            {
               theFirstPin = 3;
            }

            checkPins();
            break;
         }
      }

      for (final GpioPinDigitalOutput myTheOutput : theOutputs)
      {
         myTheOutput.low();
      }
   }

   /**
    * Inits the listeners.
    */
   private void initListeners()
   {
      thePin4.addListener(new GpioPinListenerDigital()
      {
         @Override
         public void handleGpioPinDigitalStateChangeEvent(
               final GpioPinDigitalStateChangeEvent aEvent)
         {
            if (aEvent.getState() == PinState.LOW)
            {
               theInput = thePin4;
               theInId = 4;
               findOutput();
            }
         }
      });
      thePin5.addListener(new GpioPinListenerDigital()
      {
         @Override
         public void handleGpioPinDigitalStateChangeEvent(
               final GpioPinDigitalStateChangeEvent aEvent)
         {
            if (aEvent.getState() == PinState.LOW)
            {
               theInput = thePin5;
               theInId = 5;
               findOutput();
            }
         }
      });
      thePin6.addListener(new GpioPinListenerDigital()
      {
         @Override
         public void handleGpioPinDigitalStateChangeEvent(
               final GpioPinDigitalStateChangeEvent aEvent)
         {
            if (aEvent.getState() == PinState.LOW)
            {
               theInput = thePin6;
               theInId = 6;
               findOutput();
            }
         }
      });
      thePin7.addListener(new GpioPinListenerDigital()
      {
         @Override
         public void handleGpioPinDigitalStateChangeEvent(
               final GpioPinDigitalStateChangeEvent aEvent)
         {
            if (aEvent.getState() == PinState.LOW)
            {
               theInput = thePin7;
               theInId = 7;
               findOutput();
            }
         }
      });
      thePin8.addListener(new GpioPinListenerDigital()
      {
         @Override
         public void handleGpioPinDigitalStateChangeEvent(
               final GpioPinDigitalStateChangeEvent aEvent)
         {
            if (aEvent.getState() == PinState.LOW)
            {
               theInput = thePin8;
               theInId = 8;
               findOutput();
            }
         }
      });
      thePin9.addListener(new GpioPinListenerDigital()
      {
         @Override
         public void handleGpioPinDigitalStateChangeEvent(
               final GpioPinDigitalStateChangeEvent aEvent)
         {
            if (aEvent.getState() == PinState.LOW)
            {
               theInput = thePin9;
               theInId = 9;
               findOutput();
            }
         }
      });
   }

   /**
    * Inits the mapping.
    *
    * Maps input/output line to key on keypad.
    */
   private void initMapping()
   {
      PINMAPPING.put("35", (int) '1');
      PINMAPPING.put("36", (int) '2');
      PINMAPPING.put("37"), (int) '3');
      PINMAPPING.put("38"), (int) '4');
      PINMAPPING.put("39"), (int) '5');
      PINMAPPING.put("14"), (int) '6');
      PINMAPPING.put("15"), (int) '7');
      PINMAPPING.put("16"), (int) '8');
      PINMAPPING.put("17"), (int) '9');
      PINMAPPING.put("18"), (int) '*');
      PINMAPPING.put("34"), (int) '0');
      PINMAPPING.put("19"), (int) '#');
   }
}
Posts: 10
Joined: Thu Jan 31, 2013 8:47 pm
by reinaldo.rda » Mon Oct 27, 2014 10:46 am
bdjantl wrote:
reinaldo.rda wrote:bdjantl, you could implement reading the keypad using the Pi4J library? I'm having trouble to read a 4x4 keypad, any help will be appreciated.


Hi Reinaldo.rda,

What I did first was find out which are the input and output lines on the keyboard. You should setup these lines using the GPIO ports in your code. My keypad had two input lines and six output lines. I also had a schema from this keyboard which identifies the keys on the keypad by combining the input and output lines. For the input lines you create listeners and react on a state change by finding the corresponding output line. From the state change you know which input port was activated. By setting all output lines to high to low, one by one, you can check if the found inputline gets low to. If so, you found the two lines 'crossing' each other, which will give you key pressed on your keypad.
It's a bit cryptic maybe, but this is how I got it working.
Below the example code. It's documented and should give you some more pointers on how to implement this.

Regards,

Jan

Code: Select all
import java.util.HashMap;

import com.pi4j.io.gpio.GpioController;
import com.pi4j.io.gpio.GpioFactory;
import com.pi4j.io.gpio.GpioPinDigitalInput;
import com.pi4j.io.gpio.GpioPinDigitalOutput;
import com.pi4j.io.gpio.Pin;
import com.pi4j.io.gpio.PinPullResistance;
import com.pi4j.io.gpio.PinState;
import com.pi4j.io.gpio.RaspiPin;
import com.pi4j.io.gpio.event.GpioPinDigitalStateChangeEvent;
import com.pi4j.io.gpio.event.GpioPinListenerDigital;

/**
 * The Class PiezoKeypad.
 */
public class PiezoKeypad
{

   /**
    * <pre>
    * Keypad pin schema key = pina + pinb     
    *     o oiiiiii (output/input) 
    * 1 =   3 5 
    * 2 =   3  6 
    * 3 =   3   7 
    * 4 =   3    8 
    * 5 =   3     9 
    * 6 = 1  4 
    * 7 = 1   5 
    * 8 = 1    6 
    * 9 = 1     7 
    * * = 1      8 
    * 0 =   34 
    * # = 1       9
    * </pre>
    *
    * .
    */

   /** The Constant PINMAPPING. */
   private static final HashMap<String, Integer> PINMAPPING = new HashMap<String, Integer>();

   /** The gpio. */
   private final GpioController theGpio = GpioFactory.getInstance();

   /** The Constant PIN_1_IN. */
   private static final Pin PIN_1_OUT = RaspiPin.GPIO_15;

   /** The Constant PIN_3_IN. */
   private static final Pin PIN_3_OUT = RaspiPin.GPIO_16;

   /** The Constant PIN_4_IN. */
   private static final Pin PIN_4_IN = RaspiPin.GPIO_01;

   /** The Constant PIN_5_IN. */
   private static final Pin PIN_5_IN = RaspiPin.GPIO_04;

   /** The Constant PIN_6_IN. */
   private static final Pin PIN_6_IN = RaspiPin.GPIO_05;

   /** The Constant PIN_7_IN. */
   private static final Pin PIN_7_IN = RaspiPin.GPIO_06;

   /** The Constant PIN_8_IN. */
   @SuppressWarnings("unused")
   private static final Pin PIN_8_IN = RaspiPin.GPIO_10;

   /** The Constant PIN_9_IN. */
   @SuppressWarnings("unused")
   private static final Pin PIN_9_IN = RaspiPin.GPIO_11;

   /** The pin1. */
   private final GpioPinDigitalOutput thePin1 = theGpio
         .provisionDigitalOutputPin(PIN_1_OUT);

   /** The pin3. */
   private final GpioPinDigitalOutput thePin3 = theGpio
         .provisionDigitalOutputPin(PIN_3_OUT);

   /** The pin4. */
   private final GpioPinDigitalInput thePin4 = theGpio
         .provisionDigitalInputPin(PIN_4_IN, PinPullResistance.PULL_UP);

   /** The pin5. */
   private final GpioPinDigitalInput thePin5 = theGpio
         .provisionDigitalInputPin(PIN_5_IN, PinPullResistance.PULL_UP);

   /** The pin6. */
   private final GpioPinDigitalInput thePin6 = theGpio
         .provisionDigitalInputPin(PIN_6_IN, PinPullResistance.PULL_UP);

   /** The pin7. */
   private final GpioPinDigitalInput thePin7 = theGpio
         .provisionDigitalInputPin(PIN_7_IN, PinPullResistance.PULL_UP);

   /** The pin8. */
   private final GpioPinDigitalInput thePin8 = theGpio
         .provisionDigitalInputPin(PIN_8_IN, PinPullResistance.PULL_UP);

   /** The pin9. */
   private final GpioPinDigitalInput thePin9 = theGpio
         .provisionDigitalInputPin(PIN_9_IN, PinPullResistance.PULL_UP);

   /** The outputs. */
   private final GpioPinDigitalOutput theOutputs[] = { thePin1, thePin3 };

   /** The input. */
   private GpioPinDigitalInput theInput;

   /** The in id. */
   private int theInId;

   /** The first pin. */
   private int theFirstPin = 0;

   /** The second pin. */
   private int theSecondPin = 0;

   /**
    * Instantiates a new piezo keypad.
    */
   public PiezoKeypad()
   {
      initMapping();

      initListeners();
   }

   /**
    * Check pins.
    *
    * Determins the pressed key based on the activated GPIO pins.
    */
   private synchronized void checkPins()
   {
      if (theFirstPin != 0 && theSecondPin != 0)
      {
         final int myInput = PINMAPPING
               .get(theFirstPin + theSecondPin);

         // inform the externa listeners on the pressed key
         PiezoKeypad.this.fireEvent(myInput);

         theFirstPin = 0;
         theSecondPin = 0;
      }
   }

   /**
    * Find output.
    *
    * Sets output lines  to high and then to low one by one.
    * Then the input line is tested. If its state is low, we have the right output line and therefore
    * a mapping to a key on the keypad.
    */
   private void findOutput()
   {
      // now test the inputs by setting the outputs from high to low
      // one by one
      for (int myO = 0; myO < theOutputs.length; myO++)
      {
         for (final GpioPinDigitalOutput myTheOutput : theOutputs)
         {
            myTheOutput.high();
         }

         theOutputs[myO].low();

         // input found?
         if (theInput.isLow())
         {
            theSecondPin = theInId;

            if (myO == 0)
            {
               theFirstPin = 1;
            }
            else
            {
               theFirstPin = 3;
            }

            checkPins();
            break;
         }
      }

      for (final GpioPinDigitalOutput myTheOutput : theOutputs)
      {
         myTheOutput.low();
      }
   }

   /**
    * Inits the listeners.
    */
   private void initListeners()
   {
      thePin4.addListener(new GpioPinListenerDigital()
      {
         @Override
         public void handleGpioPinDigitalStateChangeEvent(
               final GpioPinDigitalStateChangeEvent aEvent)
         {
            if (aEvent.getState() == PinState.LOW)
            {
               theInput = thePin4;
               theInId = 4;
               findOutput();
            }
         }
      });
      thePin5.addListener(new GpioPinListenerDigital()
      {
         @Override
         public void handleGpioPinDigitalStateChangeEvent(
               final GpioPinDigitalStateChangeEvent aEvent)
         {
            if (aEvent.getState() == PinState.LOW)
            {
               theInput = thePin5;
               theInId = 5;
               findOutput();
            }
         }
      });
      thePin6.addListener(new GpioPinListenerDigital()
      {
         @Override
         public void handleGpioPinDigitalStateChangeEvent(
               final GpioPinDigitalStateChangeEvent aEvent)
         {
            if (aEvent.getState() == PinState.LOW)
            {
               theInput = thePin6;
               theInId = 6;
               findOutput();
            }
         }
      });
      thePin7.addListener(new GpioPinListenerDigital()
      {
         @Override
         public void handleGpioPinDigitalStateChangeEvent(
               final GpioPinDigitalStateChangeEvent aEvent)
         {
            if (aEvent.getState() == PinState.LOW)
            {
               theInput = thePin7;
               theInId = 7;
               findOutput();
            }
         }
      });
      thePin8.addListener(new GpioPinListenerDigital()
      {
         @Override
         public void handleGpioPinDigitalStateChangeEvent(
               final GpioPinDigitalStateChangeEvent aEvent)
         {
            if (aEvent.getState() == PinState.LOW)
            {
               theInput = thePin8;
               theInId = 8;
               findOutput();
            }
         }
      });
      thePin9.addListener(new GpioPinListenerDigital()
      {
         @Override
         public void handleGpioPinDigitalStateChangeEvent(
               final GpioPinDigitalStateChangeEvent aEvent)
         {
            if (aEvent.getState() == PinState.LOW)
            {
               theInput = thePin9;
               theInId = 9;
               findOutput();
            }
         }
      });
   }

   /**
    * Inits the mapping.
    *
    * Maps input/output line to key on keypad.
    */
   private void initMapping()
   {
      PINMAPPING.put("35", (int) '1');
      PINMAPPING.put("36", (int) '2');
      PINMAPPING.put("37"), (int) '3');
      PINMAPPING.put("38"), (int) '4');
      PINMAPPING.put("39"), (int) '5');
      PINMAPPING.put("14"), (int) '6');
      PINMAPPING.put("15"), (int) '7');
      PINMAPPING.put("16"), (int) '8');
      PINMAPPING.put("17"), (int) '9');
      PINMAPPING.put("18"), (int) '*');
      PINMAPPING.put("34"), (int) '0');
      PINMAPPING.put("19"), (int) '#');
   }
}


bdjantl, thanks for your help, I made small changes to the code that you sent and it worked perfectly for reading a 4x4 keypad using pi4j, following code.

Code: Select all
import com.pi4j.io.gpio.GpioController;
import com.pi4j.io.gpio.GpioFactory;
import com.pi4j.io.gpio.GpioPinDigitalInput;
import com.pi4j.io.gpio.GpioPinDigitalOutput;
import com.pi4j.io.gpio.Pin;
import com.pi4j.io.gpio.PinPullResistance;
import com.pi4j.io.gpio.PinState;
import com.pi4j.io.gpio.RaspiPin;
import com.pi4j.io.gpio.event.GpioPinDigitalStateChangeEvent;
import com.pi4j.io.gpio.event.GpioPinListenerDigital;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.List;

public class KeypadTest {

   private List<PropertyChangeListener> listener = new ArrayList<PropertyChangeListener>();
   public static final String KEY = "key";
   private char keyPressed;

   /** The Constant KEYPAD. */
   private static final char keypad[][] = { { '1', '2', '3', 'A' },
         { '4', '5', '6', 'B' }, { '7', '8', '9', 'C' },
         { '*', '0', '#', 'D' } };

   /** The gpio. */
   private final GpioController theGpio = GpioFactory.getInstance();

   /** The Constant PIN_1_IN. */
   private static final Pin PIN_1_IN = RaspiPin.GPIO_07;

   /** The Constant PIN_2_IN. */
   private static final Pin PIN_2_IN = RaspiPin.GPIO_00;

   /** The Constant PIN_3_IN. */
   private static final Pin PIN_3_IN = RaspiPin.GPIO_02;

   /** The Constant PIN_4_IN. */
   private static final Pin PIN_4_IN = RaspiPin.GPIO_03;

   /** The Constant PIN_5_OUT. */
   private static final Pin PIN_5_OUT = RaspiPin.GPIO_01;

   /** The Constant PIN_6_OUT. */
   private static final Pin PIN_6_OUT = RaspiPin.GPIO_04;

   /** The Constant PIN_7_OUT. */
   private static final Pin PIN_7_OUT = RaspiPin.GPIO_05;

   /** The Constant PIN_8_OUT. */
   private static final Pin PIN_8_OUT = RaspiPin.GPIO_06;

   /** The pin1. */
   private final GpioPinDigitalInput thePin1 = theGpio
         .provisionDigitalInputPin(PIN_1_IN, PinPullResistance.PULL_UP);

   /** The pin2. */
   private final GpioPinDigitalInput thePin2 = theGpio
         .provisionDigitalInputPin(PIN_2_IN, PinPullResistance.PULL_UP);

   /** The pin3. */
   private final GpioPinDigitalInput thePin3 = theGpio
         .provisionDigitalInputPin(PIN_3_IN, PinPullResistance.PULL_UP);

   /** The pin4. */
   private final GpioPinDigitalInput thePin4 = theGpio
         .provisionDigitalInputPin(PIN_4_IN, PinPullResistance.PULL_UP);

   /** The pin5. */
   private final GpioPinDigitalOutput thePin5 = theGpio
         .provisionDigitalOutputPin(PIN_5_OUT);

   /** The pin6. */
   private final GpioPinDigitalOutput thePin6 = theGpio
         .provisionDigitalOutputPin(PIN_6_OUT);

   /** The pin7. */
   private final GpioPinDigitalOutput thePin7 = theGpio
         .provisionDigitalOutputPin(PIN_7_OUT);

   /** The pin8. */
   private final GpioPinDigitalOutput thePin8 = theGpio
         .provisionDigitalOutputPin(PIN_8_OUT);

   /** The outputs. */
   private final GpioPinDigitalOutput theOutputs[] = { thePin5, thePin6,
         thePin7, thePin8 };

   /** The input. */
   private GpioPinDigitalInput theInput;

   /** The in id. */
   private int theLin;

   /** The in id. */
   private int theCol;

   /**
    * Instantiates a new piezo keypad.
    */
   public KeypadTest() {
      initListeners();
   }

   /**
    * Find output.
    *
    * Sets output lines to high and then to low one by one. Then the input line
    * is tested. If its state is low, we have the right output line and
    * therefore a mapping to a key on the keypad.
    */
   private void findOutput() {
      // now test the inuts by setting the outputs from high to low
      // one by one
      for (int myO = 0; myO < theOutputs.length; myO++) {
         for (final GpioPinDigitalOutput myTheOutput : theOutputs) {
            myTheOutput.high();
         }

         theOutputs[myO].low();

         // input found?
         if (theInput.isLow()) {
            theCol = myO;
            checkPins();
            try {
               Thread.sleep(200);
            } catch (InterruptedException e) {
            }
            break;
         }
      }

      for (final GpioPinDigitalOutput myTheOutput : theOutputs) {
         myTheOutput.low();
      }
   }

   /**
    * Check pins.
    *
    * Determins the pressed key based on the activated GPIO pins.
    */
   private synchronized void checkPins() {

      notifyListeners(this, KEY, this.keyPressed,
            this.keyPressed = keypad[theLin - 1][theCol]);

      // System.out.println(keypad[theLin - 1][theCol]);
   }

   /**
    * Inits the listeners.
    */
   private void initListeners() {
      thePin1.addListener(new GpioPinListenerDigital() {
         @Override
         public void handleGpioPinDigitalStateChangeEvent(
               final GpioPinDigitalStateChangeEvent aEvent) {
            if (aEvent.getState() == PinState.LOW) {
               theInput = thePin1;
               theLin = 1;
               findOutput();
            }
         }
      });
      thePin2.addListener(new GpioPinListenerDigital() {
         @Override
         public void handleGpioPinDigitalStateChangeEvent(
               final GpioPinDigitalStateChangeEvent aEvent) {
            if (aEvent.getState() == PinState.LOW) {
               theInput = thePin2;
               theLin = 2;
               findOutput();
            }
         }
      });
      thePin3.addListener(new GpioPinListenerDigital() {
         @Override
         public void handleGpioPinDigitalStateChangeEvent(
               final GpioPinDigitalStateChangeEvent aEvent) {
            if (aEvent.getState() == PinState.LOW) {
               theInput = thePin3;
               theLin = 3;
               findOutput();
            }
         }
      });
      thePin4.addListener(new GpioPinListenerDigital() {
         @Override
         public void handleGpioPinDigitalStateChangeEvent(
               final GpioPinDigitalStateChangeEvent aEvent) {
            if (aEvent.getState() == PinState.LOW) {
               theInput = thePin4;
               theLin = 4;
               findOutput();
            }
         }
      });
   }

   private void notifyListeners(Object object, String property, char oldValue,
         char newValue) {
      for (PropertyChangeListener name : listener) {
         name.propertyChange(new PropertyChangeEvent(this, property,
               oldValue, newValue));
      }
   }

   public void addChangeListener(PropertyChangeListener newListener) {
      listener.add(newListener);
   }
}
Posts: 3
Joined: Thu Aug 14, 2014 1:30 pm
by bdjantl » Mon Oct 27, 2014 10:53 am
Glad I could help!

Regards, Jan
Posts: 10
Joined: Thu Jan 31, 2013 8:47 pm
by raspdroid » Thu May 14, 2015 8:54 pm
Hello,

Thanks for sharing the code

I'm using this code but not work to me.
http://pastebin.com/KksTVSt8

If I pulse "6" the console display this:
8
7
7
7
8
7
7


I have a 3x4 keypad with 7 pins. Unfortunately I have no datasheet. I used Raspberry Pi B+ wiht Pi4J (Maven).

Can you help me set my keypad with Pi4J?

Best regards
User avatar
Posts: 397
Joined: Thu Nov 06, 2014 9:15 am
Location: Gran Canaria :: Spain
by mikronauts » Thu May 14, 2015 9:26 pm
Take a look at my article at

http://www.mikronauts.com/raspberry-pi/ ... nd-python/

it is for a 4x4 keypad, however it would also work for 3x4 (with minor mods)
http://Mikronauts.com - home of EZasPi, RoboPi, Pi Rtc Dio and Pi Jumper @Mikronauts on Twitter
Advanced Robotics, I/O expansion and prototyping boards for the Raspberry Pi
User avatar
Posts: 1203
Joined: Sat Jan 05, 2013 7:28 pm
by bdjantl » Thu May 14, 2015 9:44 pm
Hi,

Getting the right response really depends on the wiring of your keypad.
The code detects a 'high' on the input and then tries to find the corresponding output. The 'crossing' defines the pressed 'button' on the console.
You do not have a datasheet, but is there any indication on the keypad? A number or a name? Most of the time a search on the internet will eventually give you the vendor and probably a datasheet or wiring scheme for your keypad.

The result you display (8, 7, 7, 7, 8, 7, 7) is this the result of pressing 6 on the console only once?

While I developed the code initially for the Raspberry Pi B, the same code is running momentarily on the B+ as well. So using a Raspberry Pi B+ should not be the problem.

Regards,

Jan

raspdroid wrote:Hello,

Thanks for sharing the code

I'm using this code but not work to me.
http://pastebin.com/KksTVSt8

If I pulse "6" the console display this:
8
7
7
7
8
7
7


I have a 3x4 keypad with 7 pins. Unfortunately I have no datasheet. I used Raspberry Pi B+ wiht Pi4J (Maven).

Can you help me set my keypad with Pi4J?

Best regards
Posts: 10
Joined: Thu Jan 31, 2013 8:47 pm
by raspdroid » Thu May 14, 2015 11:41 pm
mikronauts wrote:Take a look at my article at

http://www.mikronauts.com/raspberry-pi/ ... nd-python/

it is for a 4x4 keypad, however it would also work for 3x4 (with minor mods)


Thank you,

I enable I2C but not detected
Code: Select all
sudo i2cdetect -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --

I have it connected to these pins
Code: Select all
 /** The Constant PIN_1_IN. */
   private static final Pin PIN_1_IN = RaspiPin.GPIO_24;

   /** The Constant PIN_2_IN. */
   private static final Pin PIN_2_IN = RaspiPin.GPIO_25;

   /** The Constant PIN_3_IN. */
   private static final Pin PIN_3_IN = RaspiPin.GPIO_26;

   /** The Constant PIN_4_IN. */
   private static final Pin PIN_4_IN = RaspiPin.GPIO_23;

   /** The Constant PIN_5_OUT. */
   private static final Pin PIN_5_OUT = RaspiPin.GPIO_27;

   /** The Constant PIN_6_OUT. */
   private static final Pin PIN_6_OUT = RaspiPin.GPIO_28;

   /** The Constant PIN_7_OUT. */
   private static final Pin PIN_7_OUT = RaspiPin.GPIO_29;


I'm not using resistors or diodes, I am connecting directly to the Raspberry PI.

Best regards

path4189.png
path4189.png (40.66 KiB) Viewed 259 times
User avatar
Posts: 397
Joined: Thu Nov 06, 2014 9:15 am
Location: Gran Canaria :: Spain
by raspdroid » Fri May 15, 2015 12:50 am
bdjantl wrote:Hi,

Getting the right response really depends on the wiring of your keypad.
The code detects a 'high' on the input and then tries to find the corresponding output. The 'crossing' defines the pressed 'button' on the console.
You do not have a datasheet, but is there any indication on the keypad? A number or a name? Most of the time a search on the internet will eventually give you the vendor and probably a datasheet or wiring scheme for your keypad.

The result you display (8, 7, 7, 7, 8, 7, 7) is this the result of pressing 6 on the console only once?

While I developed the code initially for the Raspberry Pi B, the same code is running momentarily on the B+ as well. So using a Raspberry Pi B+ should not be the problem.

Regards,

Jan




Thank you for the help Jan,

Getting the right response really depends on the wiring of your keypad. The code detects a 'high' on the input and then tries to find the corresponding output. The 'crossing' defines the pressed 'button' on the console.

Ok, I understand

Code: Select all
You do not have a datasheet, but is there any indication on the keypad? A number or a name? Most of the time a search on the internet will eventually give you the vendor and probably a datasheet or wiring scheme for your keypad.


No, sorry. I have nothing. A friend gave me 10 units free of charge. They are for safes.

Is this:

http://www.cerrajerialouzao.com/tienda/ ... e-arfe.jpg
http://www.arcasterrassa.com/es/recambi ... arron.html
http://www.solostocks.com/img/caja-fuer ... 8923z0.jpg

With this code:
http://pastebin.com/rPTmYFrA

When is running on Raspberry Pi from Eclipse if I pressed the firts time "3" nothing happens.
Then I pressed "6" and the output in console is "5 5 5", if I pressed again "3" the output in console is "2 2", if I pressed "8" the output is "7 7", if I pressed "A" the output is "B B 0 A B".

If I debug and put a breakpoint in the line "if (theInput.isLow();" and I pressed the key:
1 - nothing happens
2 - nothing happens
3 - "GPIO 24" <GPIO 24> - PIN_1_IN
4 - nothing happens
5 - nothing happens
6 - "GPIO 25" <GPIO 25> - PIN_2_IN
7 - "GPIO 23" <GPIO 23> - PIN_4_IN
8 - "GPIO 26" <GPIO 26> - PIN_3_IN
9 - nothing happens
A - "GPIO 23" <GPIO 23> - PIN_4_IN
0 - "GPIO 26" <GPIO 26> - PIN_3_IN
B - nathing happens

Best regards
User avatar
Posts: 397
Joined: Thu Nov 06, 2014 9:15 am
Location: Gran Canaria :: Spain
by bdjantl » Fri May 15, 2015 9:57 am
Hi,

As far as I can see, your wiring scheme of the keypad is probably more simple than mine.
I had to follow specific - non logical - combinations in order to get the proper results.
When you look at my code, you will find a function called initMapping. This is - kind of - where the magic happens.
The combination of input and output pins results in the pressed digit on the keypad (for instance 3 and 5 on my keypad result into 1).
In the same code you will find the wiring scheme at the top op the code. Look for the comment "Keypad pin schema".

I assume your keypad is more simple. Since you have 7 lines, 3 of them correspond to the "columns" on you keypad whereas the other 4 lines correspond to the 4 "rows". Combining the column with the row, you'll find the pressed digit.

You have to experiment with this. The first 3 wires may be the columns and the other 4 the rows. But it could also be the first 4 lines are the columns and the last 3 lines are the columns.

You will then have to remove one input pin and add an extra output pin to match your keypad. I only have PIN_1_OUT and PIN_3_OUT. You will have to add PIN_2_OUT. Or even add ad PIN_4_OUT if the horizontal lines resemble the output. The same goes for the input pins.
Doing so, you have to change the listeners as well, to fit to your input pins.
Finally adapt the initmapping. In your case this will most likely be starting with 11 -> 1; 21 -> 2; 31 -> 3; 21 -> 4 (if columns are output and rows are input) Otherwise you will get 11 -> 1; 12 -> 2; 13 -> 3, etc.

It is quite a bit of rewriting, but it should be straight forward.

Regards,

Jan
Posts: 10
Joined: Thu Jan 31, 2013 8:47 pm
by raspdroid » Fri May 15, 2015 4:29 pm
Hello!,

Thank you for the reply. Very helpful to me.

I changed the Keypad. I bought a 4x4 Keypad. Like this https://www.parallax.com/sites/default/ ... d-v1.2.pdf

And I edit the code -> http://pastebin.com/JxdCbAhs

Some keys works but other not.

The firts time if I pressed a key nothing happens.

Then if I pressed "C"
theFirstPin= 1 theSecondPin= 6
C


Then if I pressed "1"
theFirstPin= 4 theSecondPin= 8
1


Then if I pressed "8"
theFirstPin= 4 theSecondPin= 6
C
theFirstPin= 1 theSecondPin= 6
C


Then if I pressed "*"
theFirstPin= 4 theSecondPin= 5
*


Then if I pressed "5"
theFirstPin= 4 theSecondPin= 7
B


Then if I pressed "B"
theFirstPin= 1 theSecondPin= 7
B


Then if I pressed "7"
theFirstPin= 1 theSecondPin= 6
7


Then if I pressed "#"
theFirstPin= 4 theSecondPin= 6
7
theFirstPin= 4 theSecondPin= 5
*
theFirstPin= 4 theSecondPin= 5
*
theFirstPin= 4 theSecondPin= 5
*
theFirstPin= 1 theSecondPin= 5
D



Works but not very well.

Best regards

UPDATED: So works better but with errors:
Code: Select all
if (myO == 0){
               theFirstPin = 1;
            } else if (myO == 1) {
               theFirstPin = 2;
            } else if (myO == 2) {
               theFirstPin = 3;
            } else if (myO == 3){
               theFirstPin = 4;
            }
Last edited by raspdroid on Fri May 15, 2015 5:12 pm, edited 1 time in total.
User avatar
Posts: 397
Joined: Thu Nov 06, 2014 9:15 am
Location: Gran Canaria :: Spain
by bdjantl » Fri May 15, 2015 4:46 pm
For this keypad, the pins 1 to 4 are the input pins.
On page 2 of the document, they describe how to read this keypad: first pull the input pins to low, one by one.
When one has been pulled low, poll the other 4 lines (5 to 8) to find out which of the rows was 'active'.
At the 'crossing' of both lines, you will find the key pressed.

I checked your code and saw that you defined pins 1 to 4 beïng output pins. I think it needs to be the other way around. Pins 1 - 4 are input pins. Pins 5 - 8 should be output pins.
You can still use your code, but then you have to rewire GPIO1,2,3,4 to GPIO5,6,7,8 and vice versa.
Otherwise you will have to make GPIO1,2,3,4 input pins with listeners on it and GPIO5,6,7,8 output pins.

Mapping looks OK to me.

Regards, Jan
Posts: 10
Joined: Thu Jan 31, 2013 8:47 pm
by raspdroid » Sun May 17, 2015 6:34 pm
Hi!,

Thank you for the reply,

This code works, but only for the row 1, if I pressed in the other rows nothing happen.
http://pastebin.com/PP1yhhsD

This is the jar file with dependencies (Pi4J), In case anyone has a Parallax 4x4 keypad and want to test.

(do not forget sudo)
Code: Select all
sudo java -jar Keypad2-0.0.1-SNAPSHOT-jar-with-dependencies.jar


e.g.:
Pressed D:
RowID:1 ColumnID:1
Key: D


Pressed #:
RowID:1 ColumnID:2
Key: #


Pressed 0:
RowID:1 ColumnID:3
Key: 0
RowID:1 ColumnID:3
Key: 0
RowID:1 ColumnID:3
Key: 0


Pressed *:
RowID:1 ColumnID:4
Key: *


The remaining rows are not found.

Please, Can someone tell me where I'm wrong?

Regards, Javi
User avatar
Posts: 397
Joined: Thu Nov 06, 2014 9:15 am
Location: Gran Canaria :: Spain
by bdjantl » Mon May 18, 2015 6:54 am
Strange behaviour, I agree.
You could try to initialize all input pins with pull down resistance. And then check if the state changed to high when a button is pressed.
In the documentation of the keypad, the write about the same way. But if the documentation is right, it should work either way.

Regards, Jan
Posts: 10
Joined: Thu Jan 31, 2013 8:47 pm
by raspdroid » Mon May 18, 2015 9:29 am
If I changed to DOWN nothing happen:

Code: Select all
  /** The pin1. */
   private final GpioPinDigitalInput COLUMN_1 = theGpio
         .provisionDigitalInputPin(PIN_1_IN, PinPullResistance.PULL_DOWN);
   
   /** The pin2. */
   private final GpioPinDigitalInput COLUMN_2 = theGpio
         .provisionDigitalInputPin(PIN_2_IN, PinPullResistance.PULL_DOWN);

   /** The pin3. */
   private final GpioPinDigitalInput COLUMN_3 = theGpio
         .provisionDigitalInputPin(PIN_3_IN, PinPullResistance.PULL_DOWN);

   /** The pin4. */
   private final GpioPinDigitalInput COLUMN_4 = theGpio
         .provisionDigitalInputPin(PIN_4_IN, PinPullResistance.PULL_DOWN);


Code: Select all
 private void initListeners()
   {
      COLUMN_1.addListener(new GpioPinListenerDigital()
      {
         @Override
         public void handleGpioPinDigitalStateChangeEvent(
               final GpioPinDigitalStateChangeEvent aEvent)
         {
            if (aEvent.getState() == PinState.HIGH)
            {
               theColId = 1;
                findOutput();
            }
         }
      });
      COLUMN_2.addListener(new GpioPinListenerDigital()
      {
         @Override
         public void handleGpioPinDigitalStateChangeEvent(
               final GpioPinDigitalStateChangeEvent aEvent)
         {
            if (aEvent.getState() == PinState.HIGH)
            {
               theColId = 2;
                findOutput();
            }
         }
      });
      COLUMN_3.addListener(new GpioPinListenerDigital()
      {
         @Override
         public void handleGpioPinDigitalStateChangeEvent(
               final GpioPinDigitalStateChangeEvent aEvent)
         {
            if (aEvent.getState() == PinState.HIGH)
            {
               theColId = 3;
                findOutput();
            }
         }
      });
      COLUMN_4.addListener(new GpioPinListenerDigital()
      {
         @Override
         public void handleGpioPinDigitalStateChangeEvent(
               final GpioPinDigitalStateChangeEvent aEvent)
         {
            if (aEvent.getState() == PinState.HIGH)
            {
               theColId = 4;
                findOutput();
            }
         }
      });
   }


With pins 1-4 as PULL_UP if I pressed one quickly detect the state LOW.

This 4x4 Keypad it is typically used for Arduino . It has no markings. I guess that is the Parallax (but it's only a guess)

In this tutorial for Arduino the connections are otherwise.
There is a ribbon with 8 wires running from the bottom of the keypad.
With the keypad face up, the wires connect in sequence from left to
right to Arduino digital pins 2 - 9.


The features are equal:
Pad Size: 77 x 70 x 0.8mm
Cable Length: 3-1/3″ or 85mm
Weight: 9g
Connector: Dupont 8 pins, 0.1″ (2.54mm) Pitch
Mount Style: Self-Adherence


Regards
User avatar
Posts: 397
Joined: Thu Nov 06, 2014 9:15 am
Location: Gran Canaria :: Spain
by raspdroid » Tue May 19, 2015 8:36 pm
Hello!,

This code works for the Column 1 and Rows 1,2,3,4. If I press the rest of the columns always I get the 1 column. Otherwise appears normal behavior.

http://pastebin.com/DYyM4L8c

e.g.

If I pressed 1:
The Row 1 is HIGH
The Row 1 is LOW
RowID:1 ColumnID:1
Key: 1


If I pressed 4:
The Row 2 is LOW
The Row 2 is HIGH
RowID:2 ColumnID:1
Key: 4


If I pressed 7:
The Row 3 is LOW
The Row 3 is HIGH
RowID:3 ColumnID:1
Key: 7


If I pressed *:
The Row 4 is LOW
The Row 4 is HIGH
RowID:4 ColumnID:1
Key: *


Now if I pressed any other button from the columns 2,3 or 4 print column 1.
e.g.
If I pressed B:
The Row 2 is LOW
The Row 2 is HIGH
RowID:2 ColumnID:1
Key: 4


Row is OK, but the column should be the 4.

Any idea how to fix it?

Regards
User avatar
Posts: 397
Joined: Thu Nov 06, 2014 9:15 am
Location: Gran Canaria :: Spain
by raspdroid » Tue May 19, 2015 10:05 pm
I take other way. Based on the logic of library for Python by Chris Crumpacker.
https://pypi.python.org/pypi/matrix_keypad

This is the code, works fine :D

http://pastebin.com/21edWhGS

Code: Select all
String digit = null;
      while (digit != "none"){
         digit = PINMAPPING.get(CopyOfRPi_4x4_Matrix.getKey());
         if(digit!=null){
            System.out.println(digit);
            try {
               Thread.sleep(100);
            } catch (InterruptedException e) {
               e.printStackTrace();
            }
         }
      }


Thank very much for the help.

King regards
User avatar
Posts: 397
Joined: Thu Nov 06, 2014 9:15 am
Location: Gran Canaria :: Spain