Monday, August 19, 2013

Python Matrix Keypad Package

I packaged up the Matrix Keypad code into a downloadable and installable PyPI package. Let me know if you have any issues but it seems download and install well with PIP and once you make the symlinks to the adafruit code you should be good to go.

Also if there is anyone that has a Beagle Bone that can help me port this over to it aswell I would appreciate it. I've had a few requests but I don't own one yet to do the work on. (unless someone ones to send me one :) )

https://pypi.python.org/pypi/matrix_keypad

Introduction

Python Library for Matrix Keypads. Written and tested on a Model B Raspberry Pi. Supports both a 3x4 and 4x4 keypad included
Current Version:
 v1.1.1
Project Page:Project_Page
PyPI page:PyPI_Page

Author

Prerequisites

If the I2C Port expander MCP23017 or MCP23008 is being used, the Adafruit Python library for I2C and the MCP will need to be installed.
You can clone the whole library like so:
git clone https://github.com/adafruit/Adafruit-Raspberry-Pi-Python-Code.git
or the two files needed can be pulled out, Adafruit_I2C.py & Adafruit_MCP230xx.py.

Install

You can use the source from just downloading the files or Install it as a library via PIP:
pip install matrix_keypad
After the install you will need to create links to the Adafruit I2C and MCP230xx code since they are not installed as packages.:
sudo ln -s [path to Adafruit python cod]/AdafruitMCP230xx/*.py /usr/local/lib/python2.7/dist-packages/matrix_keypad
Note: you will have to change the part in the brackets and maybe the path to the where the matrix keypad package is

Files Included

README.txt
LICENSE.txt
setup.py
matrix_keypad/
    __init__.py
    matrix_keypad_RPi_GPIO.py
    matrix_keypad_MCP230xx.py
    matrix_keypad_demo.py
    matrix_keypad_demo2.py

Usage

See the demo scripts included to see this all in action.
To call the library select which one you intend to use and use the correct line:
from matrix_keypad import MCP230xx
or:
from matrix_keypad import RPi_GPIO
Then initialize and give the library a short name so it is easier to reference later. For the MCP version:
kp = MCP230xx.keypad(address = 0x21, num_gpios = 8, columnCount = 4
The variables here are the I2C address, then if you are using the MCP23017 or MCP23008 you have to put the number of GPIO pin avaialable (default is 8), Then the "columnCount" is 3 for the 4x3 keypads and 4 for the 4x4 keypads.
For the standard GPIO version you only have to reference the 'column count if you want to change it to the 4x4, it defaults at the 3x4:
kp = RPi_GPIO.keypad(ColumnCount = 4)
It is possible to just check to see if a digit is currently pressed.:
checkKeypad = kp.getKey()
Or a simple function to call the keypad library and loop through it waiting for a digit press
def digit():
    # Loop while waiting for a keypress
    digitPressed = None
    while digitPressed == None:
        digitPressed = kp.getKey()
    return digitPressed

Version History

v0.1.0:
Initial Scripts
v1.0.0:
Initial package build
v1.0.1:
Initial package build and push to PyPI
v1.0.2:
Updating the matrix_keypad_demo2.py to demo selecting the 4x4 keypad
v1.0.3:
Moved Version Log in README
Updated README Links
v1.0.4:
Updated References to include the PiLarm code as the inspiration for the "...demo2.py" code
v1.0.5:
Updates to the code in both main libs to fix some indenting and other issues from coping the code from blogger to a text file.
Updates to the keypad picking section for the constants to make it actually work
v1.0.6:
Fixes to more indenting issues. :(
v1.1.0:
Updated main libs and the demo code.
Added install directions to handle the links to the adafruit code
v1.1.1:
Updated ...demo.py and demo2.py to reflect new package name.
Updated README as well

Code References

Column and Row scanning adapted from Bandono's matrixQPI which is wiringPi based.
matrix_keypad_demo2.py is based on some work that Jeff Highsmith had done in making his PiLarm that was featured on Make.

Monday, August 5, 2013

Scrapwood Bike Stand

I had built this a while back but just found all the pictures I took during the process. I spent a ton of time measuring this all out so it would fit together tight and be very strong. It's a bit overkill but it does the job so well. This was about a half sheet of plywood left over from building the router table cabinet. I was tired of leaning my bike against things in the shop so I whipped this up.

















Yes that is Flex-seal :) lol


















Thursday, August 1, 2013

Adafruit's Simple RF receiver, Testing on an Arduino

I just picked up Adafruit's Simple RF receiver right now I was testing the Momentary type (M4) Which means that while you press the keypad button the corresponding pin on the receiver goes high. I am hoping the next time I order something from them I remember to get the latching one instead because that is what I really need. Anyway since I don't have a project for this one in mind I just wanted to do some testing... so I just plugged it directly into my Arduino( avoiding the Serial pins since I needed those to display the pin states) This is the only way I could fit it on the board without putting it on a bread board. (quick and dirty!)

The VT pin isn't of to much concern for me right now so it just tucks in between the two pin banks :)

Check out the code below. This is great but if I don't want to constantly poll for buttons I may miss one. So my intention is to order a latching version, when you press the button on the keypad the pin goes high and stays high until you press it again. My thought is that if I am powering the receiver from the arduino then I can read it maybe once a second or even less often then when a high state is detected then I can simple "reboot" the receiver by dropping the +5v pin to ground. So until I get one in I will hope it resets back to ground on all the signal pins like I need

/*--------------------------------------------------------
Adafruit's Simple RF Receiver example
http://www.adafruit.com/products/1096                                  
Author: Chris Crumpacker                               
Date: August 2013 

This library 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 2.1 of the License, or (at your option) any later version.

This library 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
Lesser General Public License for more details.
                                                           
Sketch Notes: This is set as if you put the reciever directly
onto an arduino with gnd in pin 2 and the VT pin in the 
gap between the pin banks.
--------------------------------------------------------*/

#define GROUNDPIN  2
#define POWERPIN   3

// Arduino Pin Numbers
int signalPin[4] = { 4, 5, 6, 7 };
// Reciever Pin Names
const char* pinName[] = { "D3", "D2", "D1", "D0" };
// Keyfob Pin Names
const char* buttonName[] = { "D", "C", "B", "A" };

int lastSignalState[] = { 0, 0, 0, 0 };
int signalState = 0;
float onTime = 0.00;

void setup() {
  // Set the ground pin to a Low output
  pinMode(GROUNDPIN, OUTPUT);
  digitalWrite(GROUNDPIN, LOW);
  
  // Set the +5v pin to a High output
  pinMode(POWERPIN,OUTPUT);
  digitalWrite(POWERPIN, HIGH);
  
  // Setting the signal pins as inputs
  for (int i = 0; i < 4; i++) {
    pinMode(signalPin[i], INPUT);
  }
  
  // Starting the serial interface
  Serial.begin(19200);
}

void loop(){
  // For each of the 4 pins we loop thru and check the state.
  for (int i = 0; i < 4; i++) {
    // Read the current pin
    signalState = digitalRead(signalPin[i]);
    
    if (signalState != lastSignalState[i]) {
      // if the state has changed...
      if (signalState == HIGH) {
        // ...and the current state is HIGH...
        Serial.print("Receiver Pin: ");
        Serial.println(pinName[i]);
        Serial.print("Keyfob Button: ");
        Serial.println(buttonName[i]);
        Serial.println("Switched ON");
        Serial.println("------------------------------");
        onTime = millis();
      } 
      else {
        // ...and the current State is LOW...
        Serial.print("Receiver Pin: ");
        Serial.println(pinName[i]);
        Serial.print("Keyfob Button: ");
        Serial.println(buttonName[i]);
        Serial.print("Switched OFF after ");
        Serial.print(((millis() - onTime) / 1000.00));
        Serial.println(" seconds");
        Serial.println("------------------------------");
      }
    }
    // save the current state to the last state array
    lastSignalState[i] = signalState;
  }
}