Thursday, December 31, 2015

Raspberry Pi Prompting User for Lighting an LED

Project 1 - Prompting a user to light up an LED

Welcome back kinder!  Today I spend a few hours playing with the GPIO pins on the Raspberry Pi 2.  I really didn't know what to expect, so I bought a kit from Sunfounder.  The instructions as everyone else mentioned stink so I just tossed them aside and googled everything.  The kit itself is good with the exception of their labeling...there is none.  I had to use my multimeter to figure out which resistors where of which ohmage... ohmeratude... ohmwhatever.  Yes the resistors do have the little color coded bands on them, but when I went to check them, it didn't match various web sites and color keys.  I suspect either the colors on the bands are off, or I just can't tell the difference between their black and brown.  Other than that so far so good!

Step 1, figure out the resistors to use

Why is using a resistor important you ask?  I didn't know the answer either, so I googled it and apparently if you don't add resistors in front of LEDs then the LED will try to draw as much current from the Pi as possible, therefor potentially burning it out. For my first test I went with the 1k ohm resistors.  Why that amount, I have no idea, but the very project page in the manual I tossed was using that so I thought it was safe.  Apparently If you use a higher ohm resistor it will RESIST more voltage than a lower ohm resistor.  So it makes it safer it seems... [note to self, look into this later, hopefully without burning out the Pi first]

Step 2, first test with a breadboard and GPIO

What's a breadboard you say? Basically it is a circuit board that doesn't require soldering and is great for tinkerers like us.  I initially went the quick and dirty route and wired up the led to the breadboard and the LED longer leg (the anode aka the positive lead) directly to the 3.3v pin on the GPIO (pin 1) and the LED shorter leg connects to the 1k ohm resistor which connects to GPIO GND (ground pin 6).  As UNexpected, it worked on the first shot (go me!).

PS - sorry for no pictures, I didn't take any on the first round.

Step 3, turning an LED on and off

This part was a little tricky at first. The important take away was that in Step 2 you change the POSITIVE lead from pin 1 (3.3v) to pin 11 (aka GPIO17).  OK small aside here.  When programming with the Pi and interacting with the GPIO board you have 2 ways of referencing the pins on the Pi.  
  1. Using the actual pin number (1,2,3,4,5...).  In python you reference this by using:
    GPIO.setmode(GPIO.BOARD)
    GPIO.setup(11, GPIO.OUT)
  2. Using the pin BCM name (Broadcom SOC channel)
    GPIO.setmode(GPIO.BCM)
    GPIO.setup(17, GPIO.OUT)
More information from stackoverflow.

Now comes the fun part, using python to turn the LED on and off.  Through some googleing and self learning, but first a little rant: 

[rant] I came to the realization that I don't much care for Python as a language. I knew nothing about Python coming in and I guess this is to be expected since I'm coming from Java mostly.  I hate the tabbing structure of everything from functions, to if blocks to try blocks.  I miss curly brackets so.  Next up is the typeless language structure.  I found that when I was prompting someone for input and I wanted to make sure it was a number, I had to either check the type or try/catch the input and the force a casting like this: int(somevar).  I would prefer to declare my variable types ahead of time so that the runtime would throw errors properly.  Next up is "elif"...really?  Could type out "else if".  What is this perl?  Finally back to tabbing.  Seriously, it makes it quite the chore to know if you are still within a nested if block or the outer while loop etc.  Anyway noob statements I know, I'll get used to it or try out the Java implementation.[/rant]

I'm attaching my first program here.
To run the program use the following command in the same directory that you uploaded the file:
sudo python3 p0-led.py
If you run into an issue where it won't run at all you most likely need to set it as executable:
sudo chmod a+x p0-led.py

Step 4, multiple LEDs!

This was a little trickier.  First off I did some reading and apparently you can share the ground between multiple LEDs.  Not sure how true this is, but it seems to work, but I still put a 1k ohm resistor in front of each LED just to be safe.  I lined the 3 LEDs in a row on the breadboard and ran all 3 resistors on the negative lead (short leg) of each LED to the global ground wire on the board.  Then I ran each positive lead on the LEDs to the following GPIO pins that accept input from the Pi (11, 12, 13) aka (GPIO17, GPIO18, GPIO27 - no idea why they skipped names).  Here is a picture of the breadboard and a bad picture of the Pi pins (sorry) with Pin 1 being the top right and Pin 2 being bottom right.  Click each image for a larger version.


Now comes the fun part again Python!  I really do mean it, it is fun!  So first off I learned something.  Those warning message you get about "RintimeWarning: This channel is already in use" were nagging me so I looked it up.  They are actually important.  The trick is properly closing out your code with:
GPIO.cleanup()
That releases the resources associated with those pins and resets them back to INPUT. Now that opened a can of worms and I must be a good programmer and catch  my errors and release connections etc.  It is overkill for this kind of project, but it was fun to learn.  The first thing I realized is that I need to learn how methods are defined in python.  Simply they work like this:
def YOUR FUNCTION(yourInputs)

Everything in the method is tabbed in and you can do standard return statements too.  Next up is learning how to prompt someone for input with the "input()" method!  Here is what my method looks like to prompt a user:

def promptLED():
print ("\n\nChoose LED to light up")
print ("1 = Green")
print ("2 = Red")
print ("3 = Yellow")
print ("4 = All")
print ("0 = exit")
return input("> ")

Now when you call the promptLED() method, it will prompt the user for an input and then returns the value of the input back to the main program.  From there I pass it to another method that inspects the input and then lights up the proper LED:

def exeChoice(userchoice):
choice = 0
try:
choice = int(userchoice)

if (choice == 1):
print ("[info] Lighting green LED")
GPIO.output(ledGreen, True)
time.sleep(1)
GPIO.output(ledGreen, False)

Ignore the try up there, it is caught later below.  For now the important part is the line that says:
choice = int(userchoice)
This line forces the choosing of a NUMBER and it throws an error if it gets anything but that - hence the try.  There is also an else in there to handle cases where it is not 1,2,3,4 or 0.

The next line of importance is:
time.sleep(1)
This simply pauses execution of everything for 1 second.  It can take decimals for shorter time.  NOTE: you have to import "time" at the top of your program:
import time

In exeChoice, I return a number ranging from -1 to 4.  -1 is an error and 0 is exit.  The main program is within a while loop to constantly prompt the user.  If it sees a -1 it shows an error and reprompts the user.

# holds response code from last LED method call
lastResponse = -1

# Exit if we have a 0 response, otherwise keep prompting
while (int(lastResponse) != 0):
promptChoice = promptLED()
lastResponse = int(exeChoice(promptChoice))

There is more to the program, but half the fun is looking at code, so here you go:

Link to the full program here
To run it make sure it has execute rights and run:
sudo python3 p1-multi-led-prompts.py

WOOO HOOO and happy coding!

Saturday, December 26, 2015

A Pi is Born!

Merry Christmas, I'm Back!!!

This Christmas I received a wonderful present - a Raspberry Pi 2 (Model B) via CanaKit.  Time to kick the tires!

First impressions:

I can't believe how easy it was to set this up using the CanaKit. This kit came preloaded with an 8g micro sd card with NOOBS (New Out Of the Box Software - essentially a super easy installer for Rasbian OS).  I plugged in the HDMI cable to my tv, plugged in the included WiFi USB dongle to the Pi, and then plugged in the power (which turns it on).  It loaded up and I checked the box for Raspbian OS (running version 4.1 - Jessie) and clicked "Install".  It took a while to run, probably 10+ minutes.  I walked away and came back without checking the clock. After the boat load sequence ran, I was presented with a giant raspberry wallpaper - WOO HOO!

Initial Configuration:

Now that I'm up and running it is time to do some configurations.  First up change the user "pi" password.  Go to Menu (aka Start Menu for windows people) -> Preferences -> Raspberry Pi Configuration.  Here you can do stuff like change the keyboard, timezone, change password, setup whether you want to log in to the GUI or command line.  Next up WiFi.  This was easy.  I clicked on the WiFi icon in the upper right of taskbar, clicked my router id and entered the password and I was all set.  Nice.  Now for the most important part - getting up to date with apt-get.  Open a terminal (which is conveniently in the taskbar) and type in:
sudo apt-get update
"sudo" says run this as the almighty "root" user
"apt-get" is the application that does updates (i.e. windows update)
"update" says update your repository listings so it knows what dependencies to download when you go to update/install a program

After that runs a bit type:
sudo apt-get upgrade
This upgrades everything you have installed that needs updating.

Remoting into Pi:

This was very easy with SSH, however I wanted to do this with a GUI too.  After a couple of quick googles, I found this link:
https://www.raspberrypi.org/documentation/remote-access/vnc/
Very easy to follow and spot on.  I used tightvnc viewer on windows.  The only caveat is that whatever "X" display you set it to (i.e. 0 or 1) you have to connect to that via the viewer like this:
192.168.0.99:1
As a quick note, if you left the defaults in the initial config for networking you can use the hostname of the Pi like this:
raspberrypi:1

This works swell so now I think it would be great to save the CPU cycles and only boot into CLI (command line interface).  This can be done either via the configuration GUI mentioned earlier or via a command line GUI application so I did it that way.  Open a command prompt and type in:
sudo raspi-config
Once that loads choose the option for boot and then choose command line with auto login.  Reboot and test. WOO HOO!

Final Thoughts:

I'm impressed overall.  The OS boots quite fast and shuts down fast.  General navigation even through VNC is nicely responsive with no lag.  Browsing the internet is SLOW, but that is to be expected.  The built in browser is based on "Epiphony" which I'm reading is a GNOME Web browser (WebKit based).  I'm not impressed so I tried to install Chromium, but that failed the "sudo apt-get install chromium" so I installed Midori.  It is faster, but not by much.  Either way I won't be doing much browsing on the Pi if I can help it, but heck that's not why I'm using this bad boy, this is a maker machine and I want to make something...  Now comes the hard part, picking a project.  There are some easy installs like a MAME emulator, a media center (XBMC), but all those are just premade stuff and I already have a Roku and an old school NES so it's time to build something.