Pages

2012-07-28

The TextStar Serial LCD Display from Cat's Whisker Technologies is a nice little 16x2 display. It's quite a sophisticated screen including 4 buttons to transmit characters too. It's a perfect companion for the Raspberry Pi as you can run it straight off the 3.3v supply and TTL serial pins without the need for an RS232 converter like a MAX232. It couldn't be easier!

As the video shows I have written some software to use the 4 buttons as page buttons.

A: Date and time

B: Shows the latest number entry on jerbly.uk.to - my other Raspberry Pi

C: Twitter feed from @Raspberry_Pi

D: eth0 and wlan0 ip addresses

The ip address screen is really useful if you are set up for DHCP. Just plug in and it shows you the address needed to access your Raspberry Pi on the network.

Connecting it up

Simply connect the 3.3v, ground, UART TX and RX pins from the Raspberry Pi to the pins on the TextStar as show in these photos:

Setup the OS

By default there is a VT100 terminal running on /dev/AMA0 which will interfere with the software. Simply edit /etc/inittab and comment out the line like so:

On Raspbian:

#T0:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100

On Arch:

#c2:2345:respawn:/sbin/agetty -8 -s 115200 ttyAMA0

and then reboot.

Code

Cat's Whisker Technologies have good documentation for the display on their web site. Follow their instructions to configure your display for TTL and set the Baud rate so it matches your python code. I've used 9600 as this is way fast enough. I have implemented some of the special commands to control scrolling and so on as you can see in the code below. The code is also available on GitHub: screen.py

2012-07-21

This post shows how to drive two 7 segment displays from 6 gpio pins on the Raspberry Pi without a continual refresh loop. The software is simple with very low cpu usage - only processing when you want to change the displayed numbers. The electronics are pretty easy too (I'm a novice myself!) It's also a fun way to learn about BCD (Binary-coded decimal) and latches.

Basically you take 6 gpio pins through current limiting resistors and then on to the second breadboard. You'll see from the picture below that I have added an LED as a confidence indicator for each gpio pin. I've labelled these in the picture for the latches and data lines that then need to be wired up to the HEF4543Bs:

If you look at the data sheet for the HEF4543B you'll see that the labels I've put on this picture match. These labels are also used in the software later.

LD = Latch disable (for first digit)

DD = 8 (BCD bit)

DC = 4 (BCD bit)

DB = 2 (BCD bit)

DA = 1 (BCD bit)

LD2 = Latch disable (for second digit)

The gpio pins for the latches are then connected directly to the two ICs, The data pins are connected in parallel to both ICs:

Now follow the data-sheets for the ICs and the displays to connect the IC output pins to the 7 segment displays. The phase input (PH) and the blanking input (BI) should both be connected to ground. I left a longer loop of wire on the blanking input as I was considering using it to blank the display but this would have used another gpio pin. Instead, if you check the data-sheet, you'll find that if you set the data to a decimal number higher than 9 it will blank the display anyway.

Note, this is all 3.3v and I've used another couple of 220ohm resistors to limit the current into the ICs.

Software

To set a number on the display you follow this sequence:

Keep what's on the display now - latch disable = off

Set the data pins for the required number

Disable the latch to take the value to the display - latch disable = on

For timing purposes wait for a short period

Keep what's on the display now - latch disable = off

The Python below counts from 0 to 99 in a continuous loop as seen in the video above.

This uses numdisplay.py and adds a very simple web interface. Run this up and go to http://{ip address}:8092/num/{number}. e.g. http://192.168.0.2:8092/num/12 to display 12.

Kits

I'm considering putting some kits together with the resistors, ICs and displays for people to buy if there's enough interest. It may turn out to be more cost effective if I buy some in bulk and then sell on to you. Let me know if you would be interested by leaving a comment below. Thanks.

2012-07-02

This post shows how I've set up Motion with the Raspberry Pi GPIOs to indicate motion detection and video production on LEDs and a push button snapshot control. As part of this project I have created a Python service to allow easy scripted control of the GPIOs. This allows you to set up commands you want to run on GPIs and simple command line access to set GPOs high, low or flash. If you're new to these blog posts take a look at: Battery powered, Wireless, Motion detecting Raspberry Pi and Motion Google Drive Uploader and Emailer.

The electronics

The circuit uses the "low to glow" principle - set the GPO low to light the LED. I won't repeat a load of GPIO information available elsewhere, here's a very good article to read: Getting Started with Raspberry Pi GPIO and Python. I'm using 3.3v for the positive rail, pins 11, 12 and 13 for the red, yellow and green LEDs and 7 and 22 for the two buttons.

Flashing an LED from Motion

Motion has a number of configuration options which allow you to run shell commands when specific events occur. For example on_motion_detected, defined as Command to be executed when a motion frame is detected. The Motion web interface allows you to change all of these on the fly without restarting the service - great for testing. The on_motion_detected event does not have a sibling event like "on_motion_not_detected" so you can't easily switch an LED on on the first event and off on the second. Therefore you have to write a little bit of code to light the LED, wait for a short period and then switch it off. This is a common thing to want to do - a momentary indicator.

Another common thing to want to do is to flash an LED continuously, this gives you 3 indications for each LED: On, Off and Flash. But flashing can only be achieved by repeatedly setting the GPO high and low. I wanted to flash the red LED while Motion is in the "event window" this is defined by two events:

on_event_start: Command to be executed when an event starts. An event starts at first motion detected after a period of no motion defined by gap.

on_event_end:Command to be executed when an event ends after a period of no motion. The period of no motion is defined by option gap.

Taking a Motion snapshot

There are a few controls available for Motion through the action section of its web interface. The snapshot action captures a jpeg and creates a symlink to it called lastsnap.jpg. I then show this snapshot on my web site (http://jerbly.uk.to/picam) next to the live feed. You can trigger a snapshot from the command line using curl like this:

curl http://localhost:8080/0/action/snapshot

All I needed was a way to run commands when a button is pressed. I needed to capture the GPI state going from False normally to True briefly (while the button is down) and then back to False again when it's released.

So, instead of writing more and more little scripts to handle controlling the GPIOs I wrote a service to do it for me. This allows me to echo simple instructions like "red flash" and "red high" to the service and it takes care of continuously flashing the GPO or setting it high etc.

My GPIO service

The code is available on GitHub here: Jerbly Raspberry Pi code. Download gpioservice.py and the example config file gpioservice.cfg to somewhere on your Raspberry Pi. Then, before you run it up, change the config file. This is very important as the config file determines which pins should be set as inputs and outputs and it also sets the initial mode of the pin (e.g. high). So you want to get this right before you start it up and blow something up!

The service gives you the follow features:

Name to pin mapping: so you can send "red flash" or "motor low" commands

Common modes:

High: set the pin high

Low: set the pin low

Flash: flip the pin between high and low every 0.25 second

LowShot: set the pin low for 0.25s then leave it high

HighShot: set the pin high for 0.25s then leave it low

Commands are sent through a named pipe (fifo) which has write permissions for all, this means you don't have to be root to control the GPOs!

Run shell commands for button presses on GPIs

The code in gpioservice.py uses two secondary threads alongside the main thread. The main thread is a blocking reader of the named pipe, it just parses the input on the pipe and sets the mode on the GPO objects. The GPO thread sleeps for 0.25s each loop, inverts the current flash state and then runs through each GPO object calling its action method. The action method determines, based on the mode, whether to set the pin high or low. It's this that means you can have flash, lowshot and highshot. The GPI thread sleeps for 0.1s each loop and then calls the action method on all the configured GPI objects. The action method reads the input and uses a state variable to trigger the command to run when the state first changes from False to True and not to continuously call the command if the button is held down. (Other modes may be added to this in the future so you can have "button held" operations).

Note that the fifo is configured at the top. The service takes care of creating this and setting the permissions. Then in the gpi_pins section you can see how to briefly flash the green LED when the button is pressed on pin 7.

Here's the Motion events section from my Motion config file:

# Command to be executed when an event starts. (default: none)
# An event starts at first motion detected after a period of no motion defined by gap
on_event_start echo "red flash" >> /tmp/gpopipe
# Command to be executed when an event ends after a period of no motion
# (default: none). The period of no motion is defined by option gap.
on_event_end echo "red high" >> /tmp/gpopipe
# Command to be executed when a picture (.ppm|.jpg) is saved (default: none)
# To give the filename as an argument to a command append it with %f
; on_picture_save value
# Command to be executed when a motion frame is detected (default: none)
on_motion_detected echo "green lowshot" >> /tmp/gpopipe
# Command to be executed when motion in a predefined area is detected
# Check option 'area_detect'. (default: none)
; on_area_detected value
# Command to be executed when a movie file (.mpg|.avi) is created. (default: none)
# To give the filename as an argument to a command append it with %f
on_movie_start echo "yellow low" >> /tmp/gpopipe
# Command to be executed when a movie file (.mpg|.avi) is closed. (default: none)
# To give the filename as an argument to a command append it with %f
on_movie_end /etc/motion/movie_end %f
# Command to be executed when a camera can't be opened or if it is lost
# NOTE: There is situations when motion doesn't detect a lost camera!
# It depends on the driver, some drivers don't detect a lost camera at all
# Some hang the motion thread. Some even hang the PC! (default: none)
; on_camera_lost value

Note that the on_movie_end setting calls a script that I have placed in /etc/motion to handle controlling the LEDs and uploading to Google Drive:

In Action

This first video shows the green lowshot by pressing the button connected to pin 7:

This second video shows the sequence when I trigger a motion event on the camera and start a recording. Note just after I remove the card from the camera there are two motion frame flashes on the green LED too.