Saturday, May 25, 2013

RFID via USB for the Beaglebone Black or pcDuino Using the Innovations ID-20LA & Sparkfun RFID USB Board

The Innovations ID-20LA is a 125 kHz RFID tag reader that works with input voltages from 2.8 to 5 volts. The Sparkfun RFID USB Reader (Board) provides a socket for the ID-20LA (with its 2mm pin spacing) a mini-USB (B) connector, and broken out pins for a serial connection.

Using the mini-USB connection, it is very easy to connect it to the Beaglebone Black.  The Ångström Linux distribution that comes installed on the Beaglebone Black includes the FTDI-SIO driver/kernel module, so no additional drivers are needed. When connected to the Beaglebone, the RFID reader is mapped to the serial device /dev/ttyUSB0.

For a Python script to read from a serial device, you do need to install the PySerial package (opkg install python-pyserial).


Python Code


import serial
serial = serial.Serial("/dev/ttyUSB0", baudrate=9600)

code = ''

while True:
        data = serial.read()
        if data == '\r':
                print(code)
                code = ''
        else:
                code = code + data

pcDuino 


When working with the pcDuino, everything is the same as for the Beaglebone, except for the command to install the PySerial package. On the pcDuino use the command apt-get install python-serial.

Friday, May 24, 2013

Adafruit TTL Serial JPEG Camera & the Beaglebone Black

The Adafruit TTL Serial JPEG Camera is a 5 volt device, but the serial (TTL) voltage is only 3.3 volt, so it is safe to use with the 3 volt pins on the Beaglebone Black.

See this post for information on how to configure the UART1 (/dev/ttyO1) pins.  This needs to be done every time the Beaglebone Black is rebooted.

Connections


Camera  Beaglebone Black
+5V     P9 7  (SYS_5V)
GND     P9 1  (GND)
RX      P9 24 (uart1_txd)
TX      P9 26 (uart1_rxd)


Code


The following Python code sets the picture size to 640 x 480 pixels, takes a picture and saves it to the /tmp directory with a file name made up of the date and time (including seconds, so duplicate names shouldn't be a problem).

import serial
import time
import datetime

# Initialize camera
serial = serial.Serial("/dev/ttyO1", baudrate=38400)
serial.write(b'\x56\x00\x26\x00')
resp = ""
time.sleep(1)
while(serial.inWaiting() > 0):
        data = serial.read()
        resp += data
        if "Init end\r\n" in resp:
                print "Ready"
                break

# Set image size to 640 x 480
serial.write(b'\x56\x00\x54\x01\x00')
resp = ""
time.sleep(1)
while (serial.inWaiting() > 0):
        data = serial.read()
        resp += data
        if b'\x76\x00\x54\x00\x00' in resp:
                print "Size set"
                break

# Take picture
serial.write(b'\x56\x00\x36\x01\x00')
resp = ""
time.sleep(2)
while(serial.inWaiting() > 0):
        data = serial.read()
        resp += data
        if b'\x76\x00\x36\x00\x00' in resp:
                print "Picture taken"
                break

#Get JPG size
serial.write(b'\x56\x00\x34\x01\x00')
resp = ""
time.sleep(1)
while(serial.inWaiting() > 0):
        data = serial.read()
        resp += data
        if b'\x76\x00\x34\x00\x04\x00\x00' in resp:
                msb = serial.read()
                lsb = serial.read()
                print "Image file size: %d bytes" % (ord(msb) << 8 | ord(lsb))

# Write image to file
serial.write(b'\x56\x00\x32\x0C\x00\x0A\x00\x00\x00\x00\x00\x00%c%c\x00\x0A'
% (msb,lsb))
time.sleep(5)
now = datetime.datetime.now()
filename = "%d.%02d.%02d.%02d.%02d.%02d.jpg" % \
(now.year,now.month,now.day,now.hour,now.minute,now.second)
resp = serial.read(size=5)
if b'\x76\x00\x32\x00\x00' in resp:
        with open("/tmp/" + filename, 'wb') as f:
                while(serial.inWaiting() > 0):
                        data = serial.read()
                        f.write('%c' % data)
        print "Image written to /tmp/%s" % (filename)


Example Serial Communication between an Arduino & a Beaglebone Black (Beaglebone Black Side)

This is the Beaglebone Black portion of the example of serial communication between an Arduino Uno and a Beaglebone Black.  Click here for the Arduino portion of this example.  As noted in the Arduino posting, this example uses an RFID card reader (as part of a larger project), but it is intended as an example of serial communication, not as a complete RFID application.


Connections


See the Arduino portion of this example for information on how to connect the Arduino Uno and the Beaglebone Black (including the logic level converter).

To configure the UART/serial port on the Beaglebone Black, see this post.


Python Code


For this code to work, you need to have  the PySerial package installed. Use the command opkg install python-pyserial to install it (assuming that you are running Ångström Linux).

This program reads the data sent from the Arduino via the serial connection.  The RFID card data from the Arduino begins with a ^ and ends with \r\n.  As the code stands for now, the Beaglebone Black responds to to the received data by sending the card number back with the status message OK and the current date and time. The application will ultimately need to check the RFID tag number against a database and record the use of the tag, but this example is really just intended to show an example of serial communication.


import serial
import time
import datetime
import re

serial = serial.Serial("/dev/ttyO1", baudrate=38400)

resp = ""

while True:
        while (serial.inWaiting() > 0):
                data = serial.read()
                resp += data
                if "\r\n" in resp:
                        now = datetime.datetime.now()
                        timestamp = "%02d/%02d/%d %02d:%02d:%02d" % \
                        (now.month,now.day,now.year,now.hour,now.minute,now.second)
                        matchObj = re.match(r'\^([0-9A-F]+)\r\n', resp)
                        print matchObj.group(1)
                        resp = ""
                        serial.flush();
                        serial.write(matchObj.group(1) + " OK: " + timestamp + "\n")

Thursday, May 23, 2013

uart1.dts: Configuration File to Enable UART1 on Beaglebone Black


Configuring the pins on the Beaglebone Black is different (more complex?) than the configuration process on the Beaglebone. The following configuration file and notes on its use are taken from the new book, Bad to the Bone: Crafting Electronic Systems with the Beaglebone and Beaglebone Black by Steven F Barrett and Jason Kridner (pp. 219-20).  This is also available from various places on the Web, but I'm posting it here for my own reference (and for use by anyone who finds it here).

I've made a couple changes in the steps described in the notes because of a difference in a directory name.


/* Copyright (C) 2013 CircuitCo
 * Copyright (C) 2013 Texas Instruments
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Genral Public License version 2 as
 * published by the Free Software Foundation.
 */

/dts-v1/;
/plugin/;

/ {
    compatible = "ti,beaglebone", "ti,beaglebone-black";

    /* identification */
    part-number = "uart1";
    version = "00A0";

    fragment@0 {
        target = <&am33xx_pinmux>;
        __overlay__ {
            pinmux_serial1: pinmux_serial1_pins {
                pinctrl-single,pins = <
             0x184 0x20 /*P9_24(ZCZ ball D15) RX-enabled MODE 0*/
             0x180 0x20 /*P9_26(ZCZ ball D16) RX-enabled MODE 0*/
            >;
                };
            };
    };
    
    fragment@1 {
        target = <&ocp>;
        __overlay__ {
    serial1_pinmux_helper {
        compatible = "bone-pinmux-helper";
        status     = "okay";
        pinctrl-names = "default";
            pinctrl-0 = <&pinmux_serial1>;
            };
        };
    };
    
    fragment@2 {
        target = <&uart2>;   /* really uart1 */
        __overlay__ {
            status = "okay";
        };
    };
};

//***************************************************************************
//uart1.cpp - configures BeagleBone uart1 for transmission and 9600 Baud
// and repeatedly sends the character G via uart1 tx pin (P9, 24)
//
// To configure the UART first do:
// # dtc -O dtb -o uart1-00A0.dtbo -b 0 -@ uart1.dts
// # cp uart1-00A0.dtbo /lib/firmware/uart1-00A0.dtbo
// # echo uart1 > /sys/devices/bone_capemgr.9/slots
// # Path for the command above may vary -
// # echo uart1 > /sys/devices/bone_capemgr.8/slots
//
//Check that the pinmux has been configured via:
// # cat /sys/kernel/debug/pinctrl/44e10800.pinmux/pinmux-pins
// pin 96 (44e10980): serial1_pinmiux_helper.14 (GPIO UNCLAIMED)
//function pinmux_serial1_pins group pinmux_serial1_pins
// pin 97 (44e10984): serial1_pinmux_helper.14 (GPIO UNCLAIMED)
//funcion pinmux_serial1_pins group pinmux_serial1_pins
//
//***************************************************************************

Note (June 10, 2013):  After rebooting the Beaglebone Black, the echo command needs to be run again. Including a line like this in a Python script runs the echo command. You may need to adjust the path, as noted above.

os.system("echo uart1 > /sys/devices/bone_capemgr.9/slots")

Wednesday, May 22, 2013

Taking Larger Pictures with a pcDuino & a LinkSprite JPEG Color Camera (TTL Interface)

I posted a couple days ago about using the LinkSprite JPEG Color Camera (TTL Interface) to take pictures with a pcDuino. The default image size is 320 x 240 pixels.  From reading some of the comments online, it sounded like some people had problems changing the image size. I have found, however, that I can switch the image size to 640 x 480 without any trouble.  The only change, in addition to issuing the command to change the image size, is the longer pause after the read image data command.

Here is the revised code for taking pictures measuring 640 x 480 pixels -


import serial
import time
import datetime

# Initialize camera
serial = serial.Serial("/dev/ttyS1", baudrate=38400)
serial.write(b'\x56\x00\x26\x00')
resp = ""
time.sleep(1)
while (serial.inWaiting() > 0):
data = serial.read()
resp += data
if "Init end\r\n" in resp:
print "Ready"
break

# Set image size to 640 x 480
serial.write(b'\x56\x00\x54\x01\x00')
resp = ""
time.sleep(1)
while (serial.inWaiting() > 0):
        data = serial.read()
        resp += data
        if b'\x76\x00\x54\x00\x00' in resp:
                print "Size set"
                break


# Take picture
serial.write(b'\x56\x00\x36\x01\x00')
resp = ""
time.sleep(1)
while (serial.inWaiting() > 0):
data = serial.read()
resp += data
if b'\x76\x00\x36\x00\x00' in resp:
print "Picture taken"
break

#Get JPG size
serial.write(b'\x56\x00\x34\x01\x00')
resp = ""
time.sleep(1)
while (serial.inWaiting() > 0):
data = serial.read()
resp += data
if b'\x76\x00\x34\x00\x04\x00\x00' in resp:
msb = serial.read()
lsb = serial.read()
print "Image file size: %d bytes" % (ord(msb) << 8 | ord(lsb))

# Write image to file
serial.write(b'\x56\x00\x32\x0C\x00\x0A\x00\x00\x00\x00\x00\x00%c%c\x00\x0A' % (msb,lsb))
time.sleep(7)  # Increased to 7 seconds, otherwise image is clipped 
now = datetime.datetime.now()
filename = "%d.%02d.%02d.%02d.%02d.%02d.jpg" % \
(now.year,now.month,now.day,now.hour,now.minute,now.second)
resp = serial.read(size=5)
if b'\x76\x00\x32\x00\x00' in resp:
with open("/var/www/" + filename, 'wb') as f:
while (serial.inWaiting() > 0):
data = serial.read()
f.write('%c' % data)
print "Image written to /var/www/%s" % (filename)


Note that this approach to changing image size is not permanent - you will need to set the size every time.

While changing the image size does not pose any problems from what I have seen, changing the baud rate of the camera is a very different matter. I have read several posts online indicating that people have rendered the camera inoperable by trying to change the baud rate.

Sunday, May 19, 2013

Taking Pictures with a pcDuino & a LinkSprite JPEG Color Camera (TTL Interface)

Here is a very basic example showing how to use the LinkSprite JPEG Color Camera (TTL Interface) from Sparkfun with a pcDuino.

The user manual for the camera is available here.

Note (May 24, 2013): I have also gotten a TTL Serial JPEG Camera with NTSC Video from Adafruit. It is the same camera as the Linksprite Sparkfun (with some minor differences in the board and the connector).  The material presented below also works with the Adafruit camera. Adafruit Learning systems has a tutorial on using the camera with an Arduino and a utility for testing the camera.  They also have code on their GitHub site that includes some python examples apparently intended for the Raspberry Pi.

Connections


The labels for the connections on the camera board are just above the connector.

Camera pcDuino
TV     Not Connected
RXD    Digital Pin 1 (TX)
TXD    Digital Pin 0 (RX)
GND    GND
VCC    5V

Note: If you have problems with getting serial I/O to work on the pcDuino's 0 and 1 pins, try the setuart2 utility discussed in the pcDuino forum.

Python Code


The following code is designed to be run from the command line on the pcDuino. It just takes a picture and saves it to a file in the /tmp/ directory. The file name is made up of the current date and time (down to seconds).   

import serial
import time
import datetime

# Initialize camera
serial = serial.Serial("/dev/ttyS1", baudrate=38400)
serial.write(b'\x56\x00\x26\x00')
resp = ""
time.sleep(1)
while (serial.inWaiting() > 0):
        data = serial.read()
        resp += data
        if "Init end\r\n" in resp:
                print "Ready"
                break

# Take picture
serial.write(b'\x56\x00\x36\x01\x00')
resp = ""
time.sleep(2)
while (serial.inWaiting() > 0):
        data = serial.read()
        resp += data
        if b'\x76\x00\x36\x00\x00' in resp:
                print "Picture taken"
                break

#Get JPG size
serial.write(b'\x56\x00\x34\x01\x00')
resp = ""
time.sleep(1)
while (serial.inWaiting() > 0):
        data = serial.read()
        resp += data
        if b'\x76\x00\x34\x00\x04\x00\x00' in resp:
                msb = serial.read()
                lsb = serial.read()
                print "Image file size: %d bytes" % (ord(msb) << 8 | ord(lsb))

# Write image to file
serial.write(b'\x56\x00\x32\x0C\x00\x0A\x00\x00\x00\x00\x00\x00%c%c\x00\x0A' % (msb,lsb))
time.sleep(3)
now = datetime.datetime.now()
filename = "%d.%02d.%02d.%02d.%02d.%02d.jpg" % \
        (now.year,now.month,now.day,now.hour,now.minute,now.second)
resp = serial.read(size=5)
if b'\x76\x00\x32\x00\x00' in resp:
        with open("/tmp/" + filename, 'wb') as f:
                while (serial.inWaiting() > 0):
                        data = serial.read()
                        f.write('%c' % data)
        print "Image written to /tmp/%s" % (filename)


If you are interested in changing the image size, see this post

Saturday, May 18, 2013

TCS34725 RGB Color Sensor & the Beaglebone Black

I posted earlier abut using the TCS34725 RGB Color Sensor board from Adafuit on my Raspberry Pi blog and I also posted on this blog abut using it with a pcDuino. The TSC34725 connects via I2C, so it is easy to connect to the Beaglebone Black. The same sample Python code that runs on Raspberry Pi  and the pcDuino also runs on the Beaglebone Black with one small modification.

The Ångström Linux distribution that comes with the Beaglebone includes the I2C tools (such as i2cdetect). You will, however, need to install the python-smbus module. Be sure to run opkg update first, and then  run the following command to install the python-smbus package: opkg install python-smbus.

Connections


TCS34725  Beaglebone Black

SDA       P9 20
SCL       P9 19
3V3       P9 3
GND       P9 1


Python Code


The only difference in the code is that the Beaglebone Black uses I2C bus 1 for the SCL and SDA pins -

import smbus
import time
bus = smbus.SMBus(1) # Beaglebone Black uses bus 1
# I2C address 0x29
# Register 0x12 has device ver. 
# Register addresses must be OR'ed with 0x80
bus.write_byte(0x29,0x80|0x12)
ver = bus.read_byte(0x29)
# version # should be 0x44
if ver == 0x44:
    print "Device found\n"
    bus.write_byte(0x29, 0x80|0x00) # 0x00 = ENABLE register
    bus.write_byte(0x29, 0x01|0x02) # 0x01 = Power on, 0x02 RGB sensors enabled
    bus.write_byte(0x29, 0x80|0x14) # Reading results start register 14, LSB then MSB
    while True:
        data = bus.read_i2c_block_data(0x29, 0)
        clear = clear = data[1] << 8 | data[0]
        red = data[3] << 8 | data[2]
        green = data[5] << 8 | data[4]
        blue = data[7] << 8 | data[6]
        crgb = "C: %s, R: %s, G: %s, B: %s\n" % (clear, red, green, blue)
        print crgb
        time.sleep(1)
else:
    print "Device not found\n"


To keep this example simple, I have left the timing/power consumption for the analog to digital converters on the sensor board and sensor gain at their default values. For more information about these (and other settings) see the datasheet.

Note that if you want to use the i2cdetect utility on the Beaglebone Black to check the address of the connected I2C device, you need to run the command i2cdetect -r  -y 1.

TCS34725 RGB Color Sensor & the pcDuino

I posted earlier about using the TCS34725 RGB Color Sensor board from Adafuit on my Raspberry Pi blog. The TSC34725 connects via I2C, so it is easy t connect to the pcDuino. The same sample Python code that runs on Raspberry Pi also runs on the pcDuino with one small modification.

Connections


TCS34725  pcDuino

SDA       SDA
SCL       SCL
3V3       3V3
GND       GND


Python Code


The only difference in the code is that the pcDuino uses I2C bus 2 for the SCL and SDA pins -


import smbus
import time
bus = smbus.SMBus(2) # pcDuino uses bus 2
# I2C address 0x29
# Register 0x12 has device ver. 
# Register addresses must be OR'ed with 0x80
bus.write_byte(0x29,0x80|0x12)
ver = bus.read_byte(0x29)
# version # should be 0x44
if ver == 0x44:
    print "Device found\n"
    bus.write_byte(0x29, 0x80|0x00) # 0x00 = ENABLE register
    bus.write_byte(0x29, 0x01|0x02) # 0x01 = Power on, 0x02 RGB sensors enabled
    bus.write_byte(0x29, 0x80|0x14) # Reading results start register 14, LSB then MSB
    while True:
        data = bus.read_i2c_block_data(0x29, 0)
        clear = clear = data[1] << 8 | data[0]
        red = data[3] << 8 | data[2]
        green = data[5] << 8 | data[4]
        blue = data[7] << 8 | data[6]
        crgb = "C: %s, R: %s, G: %s, B: %s\n" % (clear, red, green, blue)
        print crgb
        time.sleep(1)
else:
    print "Device not found\n"


To keep this example simple, I have left the timing/power consumption for the analog to digital converters on the sensor board and sensor gain at their default values. For more information about these (and other settings) see the datasheet.

Saturday, May 4, 2013

RFID for the pcDuino using the Innovations ID12 & Sparkfun RFID USB Reader Breakout

I have posted on my other blogs about using the ID12 RFID reader (125 kHz) with the Sparkfun USB Reader Breakout to provide an easy way to connect the RFID reader by a serial (UART) connection to a Raspberry Pi  or an Arduino Uno. While the name of the breakout board makes it clear that it is primarily intended for USB connections, the board breaks out the pins for connecting to the serial pins (digital 0 & digital 1) on the pcDuino.  The simple Python code in this example is the same as the code used with the Raspberry Pi.

The code requires the PySerial module. You can install it using the following apt-get command (assuming your pcDuino has functioning network connection):

sudo apt-get install python-serial

Connections:


RFID Breakout  pcDuino
VCC            5V
GND            GND
TX             Digital 0 (RX)
TXR            Digital 1 (TX)


Python Code: 


import serial
serial = serial.Serial("/dev/ttyS1", baudrate=9600)

code = ''

while True:
    data = serial.read()
    if data == '\r':
        print(code)
        code = ''
    else:
        code = code + data


If you have problems with getting serial I/O to work on the pcDuino's 0 and 1, try the setuart2 utility discussed in the pcDuino forum

Thursday, May 2, 2013

Installing OpenJDK 6 on the Beaglebone Black

Note (10/02/2013): For information on installing Java 7 on the Beaglebone Black, see this post.

My new Beaglebone Black arrived yesterday. There isn't an OpenJDK 6 package for the version of Ångström Linux on the Beaglebone Black as there was for the previous Beaglebone.  This means that you need to locate and download the .ipk files that opkg uses to install software.

You can install Java by following the instructions at http://beaglebone.cameon.net/home/doing-java-development. Use the links provided on the page to download the .ipk files needed to install the packages listed.

You may need to install libgif4 before you can install openjdk-6-common. If you do, be sure to run opkg update first, then try opkg install libgif4.

Before you can install the openjdk-6-vm-zero package, you will need to download and install the libffi5 package. You can download the libff5 package from http://www.angstrom-distribution.org/repo/?pkgname=libffi5. You want the armv7a version.  The installation process is the same as described on the Cameon page at the link above.