BeagleBone and USB GSM Stick

More sysadmin than electronics today!

I have an O2 USB modem and I was wondering about getting the BeagleBone hooked up to it.  It would be cool to have the BeagleBone “phone home” if is was out in the field logging, or whatever.

Front side of my USB GSM modem

As you can see form the photo of the back-side it’s a Huawei Mobile Broadband E1752C USB modem.

The back side of the Huawei Mobile Broadband E1752C USB stick

It turns out to be really easy to use this (or any other USB GSM modem) with Ubuntu.  It a little “old school” without a GUI to work in, but hay, command line is king after all!.. It brings back memories of using pppd and chat scripts when I used Linux to connect over a copper phone line to the “Internet!”.

On the O2 network here in Ireland my /etc/ppp/peers/o2 file looks like this:

connect "/usr/sbin/chat -v -f /etc/chatscripts/o2"
user "o2"
password "o2"
ipcp-max-failure 5
lcp-echo-failure 5
lcp-echo-interval 30


# compression

And my chat script looks like this:


""    AT
OK    "ATD*99#"

Nice little trick here for the PIN entry.. You need it the first time the modem boots up, but not for re-connecting the “TIMEOUT 5 ERROR-AT-OK” will allow the PIN code to fail (because it already been entered) and not stop the script.

As I want to remote connect to BeagleBone, I’ve got it to send it’s IP address back to base (every time the PPP interface comes up).  You will need to set up shared SSH keys between your server and the Bone to get this to work without a password.

Then I created the following little script ( /etc/ppp/ip-up.d/001updateIP ):

# scp the current IP address back to base...
# (MMcK 2012-11-19)

/sbin/ifconfig -a \
    | awk '/inet addr/ { print $2 }' \
    | awk -F: '{ print $2 }' \
        > /tmp/bone.ipaddr

/usr/bin/scp -q /tmp/bone.ipaddr <me>@<my server>:

Now every time the Bone comes online over the PPP interface I can connect to it by looking up it’s new IP address.

BeagleBone and GPS

Tonight brings us to GPS’s and how to get the BeagleBone to know where it is in the world.

I had a request during the week for a unit that would track and monitor a refrigerated truck.  So first thing that sprung to mind was a BeagleBone, I’ve already looked into the 1-wire network and setting up a DS18B20.. That is the temperature monitoring out of the way.

Now on to position… I know I could just get an off the shelf USB GSP module, but I’ll need the Bone’s one USB port to hook up a GSM modem, and sure I could put a USB hub in and connect both to the one port. But there has to be a nicer solution that can make use of one of the other UARTS on the Bone.  A dig around in my parts box and I found this old skool GPS receiver. Back in the day when I have a Palm Treo “Smart” phone.This unit has bluetooth (yepee!), but without a USB dongle won’t be much use… unless there is an internal serial line I can hack into.  Time to crack this bad boy open and see what is inside.  Turns out it is a re-badged Holux GPS receiver called the GPSlim236.

The GPSlim236 GPS module (with bluetooth)

What are the connectors on the left? Looks like these might be worth a poke at with the scope, see what is going on.

Cool.. Pin 3 (up from the bottom left pin) we see some serial data, and it even sweeter, it looks like it’s at 3.3V levels too.

The GPS serial data on the DSO (measured on pin 3)

A little more poking around with the DSO, I find the three pins needed.. 1) Gnd, 2) Data out and 3) +5V

The pinouts for the GPSlim263 module

So now I can hook up the GPS module to the BeagleBone on a spare UART and get the GPS data in that way.  Much easier that trying to get Bluetooth working!  I was already testing my RFID module out on UART1, so time to config UART2. UART2 Rx comes in on header P9, pin 22 [MUX pin spi0_sclk] and needs to be set up (along with TX).

echo 1 > /sys/kernel/debug/omap_mux/spi0_d0
echo 21 > /sys/kernel/debug/omap_mux/spi0_sclk

With a dig around I found the default serial config for the GPS data is 38400,n81.  Drop into Minicom and config the port (/dev/ttyO2), and bingo:


We have position data now… cool..!

BeagleBone and RFID

The BeagleBone has 6 UARTS on it.. (OK well 4 that are easy to use.) I thought it might be cool to look up a RFID reader I got a while ago. The reader caught my eye while I was ordering a few parts form, the part is a Electronic brick – 125Khz RFID Card Reader.  I had played about with it on my Arduino, but again without good ethernet connectivity I did not get too far.  Sure you could make a selfcontained door entry system, but a networked one give one many more options!

Electronic brick – 125Khz RFID Card Reader

Back into the world if pin decoding and mux’ing on the BeagleBone.. A quick search found this great page with all the info I needed:

The RFID module works off 5V… Ummm need to do something about the levels! As the “brick” only outputs data I only have to worry about level shifting from 5 to 3.3V.  What could be easier? A simple resistor based voltage divider should do it the trick. A 10K from the output of the RFID module, to the UART1_RXD pin (P9_26) and another resistor from P9_26 to ground.

The wires above are: White – Data, Red – +5V, Black – 0V (hidden from view!)

Check the levels on the scope…

Vertical scale is at 1V/div… so we are getting 2.5V or there abouts.  Should be OK to drive the UART on the BeagelBone.

On my Ubuntu distro I had to install the python-serial package before running this code. Now time for some Python:

import serial, os
import sys

# -------------- configurable settings ---------
PORT = '/dev/ttyO1'     # set tty port
                        # NOTE: ON BEAGLE BONE O1 is the Letter O
BAUD_RATE = 9600        # set baud rate
RX_PIN = 'uart1_rxd'    # port pin for RX
MUX_MODE = 0            # MUX mode for PIN
MODE_EXT = 32           # Enable receive on pin too!

open('/sys/kernel/debug/omap_mux/' + RX_PIN, 'wb').write("%X" % (MODE_EXT + MUX_MODE))

ser = serial.Serial(PORT, BAUD_RATE)   # open serial port
have_tag_data = 0

while True:
        a =                 # read byte
        if ord(a) == 3:
                print "Tag stop!"
                have_tag_data = 0
        if ord(a) == 2:
                print "Tag start!"
                have_tag_data = 1
        if have_tag_data>1:
                print (have_tag_data-1), ord(a)         # print byte and count
                have_tag_data += 1
        if have_tag_data==1:
                have_tag_data += 1

Run it and watch the numbers change for different tags:

root@bbone1# python

Tag start!
1 51
2 68
3 48
4 48
5 52
6 55
7 53
8 56
9 66
10 53
11 57
12 55
Tag stop!
Tag start!
1 48
2 49
3 48
4 48
5 48
6 66
7 57
8 52
9 66
10 55
11 50
12 57
Tag stop!

So 2.5V can drive the UART no problems… All good!

BeagleBone and GPIO pin mux’ing

On my last BeagleBone post I have a relay driven through a transistor, the base of which is connected through a 1k0 resister to the pin 24 on the P8 pin header.  So how do we drive this pin?

The AM335x ARM Cortex™-A8 Processor can do a load more than the BGA package has connectors for, so to get around this “hardware limitation”, the pins can be set up for different functions.. enter pin muxing.

First we need to make sure the pin we want to use is in the correct mode! For this you’ll need to manual for your BeagleBone (its the SRM or System Reference Manual your looking for.. for latest rev, you’ll find it here). On the A6 rev manual head to page 48 and on.

The names for the pins (signal names) are shown beside the pin outs for the header connectors P8 (table 8, page 48) and P9 (table 11, page 53). If you login to your BeagleBone (as root, sudo, su -l or what ever you need to do!), you will see all these signal names (for mode 0) in the folder /sys/kernel/debug/omap_mux.

For my relay pin I need to set this to mode 7 (from table 10, page 51) can see the mode 7 signal name is “gpio1[1]“.  To find out the current mode, type:

cat /sys/kernel/debug/omap_mux/gpmc_ad1

That should return three lines:

name: gpmc_ad1.gpio1_1 (0x44e10804/0x804 = 0x0007), b NA, t NA
signals: gpmc_ad1 | mmc1_dat1 | NA | NA | NA | NA | NA | gpio1_1

From this we know that the pin is in the correct mode (7).  If it was not in the correct mode or a change of mode is required then it’s easy:

echo <mode> > /sys/kernel/debug/omap_mux/gpmc_ad1

There is a little more that can be done with the mode number, internal pull up resistors can be enabled or disabled.  The mode is made up from the following byte:

Bit 0 \
Bit 1 |- Mode
Bit 2 /
Bit 3: 1 - Pull disabled, 0 - Pull enabled
Bit 4: 1 - Pull up, 0 - Pull down
Bit 5: 1 - Input, 0 - Output

There are 66 GPIO pins between the two headers. These are 4 controllers driving these pins GPIO0, GPIO1, GPIO2 and GPIO3. To configure a pin we need to use a simple formula to find out the software GPIO reference for it or the GPIO pin number.

The pins GPIO number is made up of two parts: 1) The chips base number, 2) the pin number itself.  It’s all in the pin label: GPIO<base>_<pin_no>.

GPIO pin number = <base> x 32 + <pin_no>

For the physical pin GPIO1_1 [P8, pin 24] the GPIO pin number is found via this formula:

GPIO pin number = 1 x 32 + 1 = 33

Now we need get this pin ready to do something..  All IO ports on the BeagleBone are mapped to the file system (such in the Unix model for IO).  The file system location for this action is here: /sys/class/gpio. Getting a GPIO pin ready is done by “exporting” it.

echo 33 > /sys/class/gpio/export

This will cause a new folder to exist in the gpio directory…

gpio33 -> ../../devices/virtual/gpio/gpio33

We can go in and have a look inside this folder:

-rw-r--r-- 1 root root 4096 Nov  7 15:43 active_low
-rw-r--r-- 1 root root 4096 Nov  7 15:43 direction
-rw-r--r-- 1 root root 4096 Nov  7 15:43 edge
drwxr-xr-x 2 root root    0 Nov  7 15:43 power
lrwxrwxrwx 1 root root    0 Nov  7 15:42 subsystem -> ../../../../class/gpio
-rw-r--r-- 1 root root 4096 Nov  7 15:42 uevent
-rw-r--r-- 1 root root 4096 Nov  7 15:51 value

Set up the direction of the pin:

echo out > direction

Want to turn the port on/high…? easy:

echo 1 > value

Off again…

echo 0 > value

See what state it’s in?

cat value

Cool… I can hear my relay clicking on and off in the lab!

Some more info on this can be found here: