1 2 3 4 Previous Next

BeagleBone Black

58 posts

I've previously had great results connecting Adafruit 8x8 LED matrix displays to the BeagleBone Black via I2C:

 

I decided to try out the Adafruit bi-color 8x8 LED matrix and hooked it up with the same I2C pins as before.  You'll need to setup the Adafruit_BBIO Python library if you haven't already:

https://learn.adafruit.com/setting-up-io-python-library-on-beaglebone-black/overview

 

You'll also want to grab the Adafruit Python libraries for the Raspberry Pi since they work on BeagleBone Black, too:

https://github.com/adafruit/Adafruit-Raspberry-Pi-Python-Code

 

Here is the BegaleBone Black running the demo program ex_8x8_color_pixels.py from the repo:

https://github.com/adafruit/Adafruit-Raspberry-Pi-Python-Code

 

BeagleBone Black & Adafruit 8x8 bi-color matrix

https://www.youtube.com/watch?v=vnHC6bVj5bc

 

I thought it would be interesting to plot the readings from a sensor over time on the matrix with different colors representing the magnitude of the reading:

20140116_104027.jpg

 

I hooked up a pot to the analog input to simulate a sensor.  Here's the Python script:

https://github.com/pdp7/beaglebackpack/blob/master/plot.py

 

It is Invoked by this shell script so that PYTHONPATH will be set:

https://github.com/pdp7/beaglebackpack/blob/master/plot.sh

 

BeagleBone Black: plot analog sensor on Adafruit bi-color LED matrix

https://www.youtube.com/watch?v=QQNqxHQDj5E

 

Cheers,

Drew

http://twitter.com/pdp7

Introduction

This post briefly documents a BeagleBone Black (BBB) based music box. If you’ve ever wanted a Sonos system but (like me) felt they were a little expensive, then it is worth considering using a compact Linux platform like the BBB for creating something slightly similar. I feel the sound quality is not leagues different (better nor worse) than some more expensive commercial offerings.

finished-front.jpg

It was a quick, fun project and costs about £100 including the cases and the BBB.

The idea for this project was simple - a compact box that connects to the home network and allows the ability to send it music to play (or it can play music stored on-board or on a server). The documentation provides just an overview because the circuits are already documented, and every implementation could be slightly different depending on end user needs, speaker enclosure, etc.

Here is the rear view:

finished-rear1.jpg

 

Shown below is a video of it in action. The sound was recorded from the camera in-built mic so is not representative of actual sound quality. For actual sound quality, refer to the MP3 recording here, which was captured by connecting the headphone output (not line output) directly to an ADC and captured by the PC.

 

Components

The main bits and pieces are the speaker box, the BBB and a DAC/amplifier.

Although a BBB and home-built DAC/amplifier was used, a Raspberry-Pi and Wolfson audio card could be used too, for a similar price.

The home-built DAC and amplifier is easy to assemble; it uses medium-sized SMD components that are hand-solderable, and gives results similar to a Meridian DAC which uses the same chip (a Texas Instruments ic). Full circuits and information are at these two locations: part 2 has the schematic, and part 1 has some more technical detail.

There are plenty of other DACs available including pre-built ones. A search for “I2S DAC” will reveal ones that should be suitable (I have not tried them) – this ebay example is just over £10. (Note that you may require a logic inverter, see the comments sections in the links earlier).

 

The speaker is a Tivoli Audio speaker. It is possible to get these in new condition for about £15-20 frequently on ebay, in various color options. Any speaker enclosure would have been fine. The official Tivoli webshop sells new speakers (slightly different model) from £39 upwards.

 

Design and Implementation

The DAC board was mounted inside the speaker, and the BBB was mounted outside. This allows access to all the BBB ports while making the minimal amount of holes in the Tivoli speaker (Speakers are sealed for good audio reasons).

It won't replace main home music systems but that was not the intention, nor is it stereo (that capability is easy to achieve by adding a second speaker connector, but I didn't require it). This is more a bedroom or home study one-box sound system.

 

Step 1: Fit BBB inside a case

The first step was to get the BBB into its own case. I connected a push-switch to safely power on/off the platform. I also wired up a DB9 connector to interface to the DAC.

case-open.jpg

I used L-shaped single-in-line header pins to solder up the connections and heatshrink at the DB9 connector end. The switch and LED were wired up to the power switch pin on the BBB and to the 3.3V supply (via a 100 ohm resistor) respectively. The push-switch is wired to the P9 header, pin P9_9 and to ground (pin P9_1). The LED 3.3V supply can be taken from P9_3.

 

The photo below shows the LiPo battery fitted. I used a paper sticker on the underside of it, to insulate it further. The BBB doesn’t run hot, but the battery could have a spacer between the PCB and itself if desired.

battery-fitted.jpg

Here is the finished result, powered up. It can be safely powered down by pressing the button again (this feature is by default in the current Debian image).

single-cased.jpg

The other side of the case provides access to the USB port, and a small USB WiFi adapter was fitted. I have not got round to finding a software driver for it yet, so for now I just used Ethernet.

 

Step 2: Speaker modifications

The next step was to put the BBB aside and work on the speaker and DAC. The speaker was opened up, and the wadding was removed and stored in a plastic bag to prevent dust and drilled fragments of plastic getting on it. The speaker cable was chopped and discarded, and the grommet removed.

speaker-first-opened.jpg

The DAC board was fitted with L-brackets http://uk.farnell.com/jsp/search/productdetail.jsp?CMP=i-ddd7-00001003&sku=1466881 and the speaker rear cover was marked up for drilling the holes to secure it, and for the headphone and line jack outputs (3mm holes for the screws, and 6mm holes for the jacks).

l-brackets.jpg

The photo below shows the finished result.  The jacks are rather recessed. This is actually no problem for some headphones (e.g. a pair of low-end AKG I own) but others will have problems. I plan to drill to a recess with a larger drill bit to 7mm and it will cover both of my sets of headphones. Note that you want to make the holes as small as practical.

dac-mounted.jpg

After wiring up the DAC to the speaker, the wadding was placed back in position and the cover was closed up again as shown below. Then the DB9 matching connector was soldered (wires protected with heatshrink). I didn’t bother with a cover for it.

rear-before-securing.jpg

After testing, the hole needs to be sealed (perhaps with epoxy resin glue).

Finally, the BBB was attached to the speaker (rubber feet and adhesive foam pads can be used).

 

Step 3: Try it out!

This step was the easiest.

Plug in the power supply, power up and install the audio player software:

sudo apt-get install mplayer



Then, try to play a music file (either from local storage or from network storage):

/usr/bin/mplayer -ao alsa -volume 10 “songname.mp3"



 

Summary/Next Steps

A quick and simple sound system was created. With a pre-built DAC and amplifier, the hardware implementation can be extremely easy.

There are plenty of software options for creating a library of songs and providing an interface for the user to select something to play. I have not tried them. For now I will just use SSH to select music. Eventually the hope is to create a simple browser based app that will allow one to upload MP3 songs from a PC or mobile phone for instant playback. A wake-up alert in the morning with a random song, or the news, will be a good option too (enabled via browser on mobile phone).

shabaz

BBB - Logic Supply BB100 Case

Posted by shabaz Feb 19, 2014

The Logic Supply BB100 case has be available for a while (also in black), I purchased one recently while buying other gear, these were my thoughts on it

(pictures were from a cameraphone so apologies for the quality - better images at the Logic Supply website of course).

board_inserted.jpg

 

If you need your BeagleBone Black boxed up, there are worse ways. I thought it was very well made and quite flexible. The cover can be mounted at three heights, to accomodate capes (the gaps can then be used for wires and ribbon cables for example. I will probably fit the Olimex 1400mAH LiPo inside it too as shown here.

 

The case is steel (not aluminium) and in my opinion is extremely accurately cut and shaped. The case has sub-millimeter accuracy. The base and shell are less than a millimeter thick, yet extremely tough because of the choice of material.

 

All connectors are spot-on centered into their holes and the tiny narrow microSD card slot doesn't scrape or touch the card at all.

 

The board is held in place with four screws on permanently fitted metal stand-offs. The finished result is about the size of a pack of playing cards.

interior.jpg

 

The exterior finish is a matt type, slightly roughened surface so not gloss shiny/smooth. I think the finish is great.

Initially I wasn't a fan of the D-Sub connector punch-out (I don't like using this connector for serial connections although it is a standard) but I now think it is a great idea, since it can serve as the I/O for 8 pins or more if a serial port is not desired. On the other side there is a circular punch-out ideal for coax shaped connectors or for a switch for example (approx 6.5mm dia hole measured with a ruler). These punch-outs mean that for many use-cases one may not need to ever drill any holes in the case.

Very narrow slots allow for all LEDs on the board to be visible.

case-closed.jpg

 

Lots of spare screws are supplied in two sizes; the flush ultra-tiny ones shown in the photo earlier, or slightly larger pan-head. By only fitting two screws, the lid can become hinged.

The rear has punch-outs for providing screwed attachment to another surface, or thin vertical slots can be used for fitting to a metal chassis. Really nice engineering everywhere on this case.

Four thin rubber feet are supplied for optional fitting.

The case is not cheap but metal cases usually do cost more, and so this case is fairly good value for money especially if you want a case you can use as part of a demonstration for example.

Postal cost is quite low in Europe for this case shipped from Netherlands, so that helps too.

 

As a summary, the case is very nice and practical, and I think it is worth the cost.

shabaz

BBB - Building a DAC - part 2

Posted by shabaz Feb 9, 2014

(BBB - Building a DAC part 1 can be found here).

Part 3 implements a complete design in an enclosure for a Sonos-like solution.

Introduction

The BeagleBone Black (BBB) has a digital audio interface and this was explored slightly in an earlier post.

The findings from that prototype were used to construct up a DAC board and it is described here. The aim was to have a relatively simple, easy-to-assemble board designed for portable use (headphone or small speakers) but with at least iPod-level performance. The circuit is described here and the complete schematic is attached to the post. The entire circuit connects to the BBB using 6 pins and needs no separate power supply. This is a recording using just the microphone from the camera - actual audio quality is much better.

 

For a better quality, the audio from the prototype can be heard in this zipped mp3 file. This was directly recorded from the headphone output so that it is more representative of what the user will hear (the original track that was played through the DAC was downloaded from Amazon, for comparison purposes).

dac-board.jpg

 

Detailed Description

This is the functionality on the board:

dac-layout.png

The DAC integrated circuit and headphone amplifier portion were left unchanged from the part 1 prototype although the DAC was replaced with TI’s PCM5102 which is pin-compatible with the earlier PCM5101A. The PCM5102 device is used in commercial DACs such as Meridian’s Explorer.

The remainder design is kept simple too. Three regulators are used to supply power to the DAC (can be reduced to one to save costs, or replace with the lower cost pin-compatible TC1015-3.3):

supply-schematic.png

An optional speaker output was desired, and the selected device was LM4861 which can run from a single low voltage supply and offers over 1W of power. This is enough to provide loud volume for home use (in the video above, the single mono speaker was a couple of meters away and the audio was played at a volume setting of 15 on mplayer). The circuit uses two of these for stereo, although only one needs fitting for mono summed speaker output (the photo above shows only one populated). The LM4861 input is driven from the headphone output, not the line output, to keep line output and headphone outputs as distortion free as possible.

speaker-amplifier.png

The speakers are muted using the LM4861 shutdown pin driven from the headphone socket built-in switch.

shutdown.png

The board was tested with headphones, a small 4 ohm speaker and a larger home speaker. Sound was as expected, and there are no known issues although more testing needs to be done. The board runs cold unless driving a speaker, in which case the LM4861 which is intended to be run without heatsinking in normal temperatures, would perhaps benefit from a tiny heatsink such as this one. The BBB image that I used outputs 16-bit audio at 48ksample/sec (i.e. the sound is as good as a regular CD player), but the DAC will work at higher resolution and sample rates for those with recordings that would benefit from it. The board was tested on an older Angstrom image and a Debian image. There are discussions in the comments section in the earlier post describing current ongoing exercises to get drivers working for different settings.

 

Summary

The described circuit is low cost and provides hopefully nice performance. The complete schematic and parts list is attached.

pbax

BB-VIEW free pins?

Posted by pbax Feb 3, 2014

Maybe I've missed something, but which pins on the BB-VIEW P1 and P2 are not used by the display? I can't tell from the user manual...

The wonderful Trammel Hudson of NYC Resistor posted the BeagleBone cape PCB to connect the BeagleBone BlackBeagleBone Black to the Adafruit 16x32 RGB LED matrixAdafruit 16x32 RGB LED matrix to create the dazzling Octoscroller:

i.png

OSH Park ~ Octoscroller v2

 

Just ordered updated Octoscroller boards. OSH Park has an awesome zero-friction Eagle CAD to PCB production process.

Drives up to eight chains of 32x16 or 32x32 LED panels with a Beagle Bone Black.

 

Wondering what the Octoscroller is?  Check out Trammel's excellent blog post:

 

Octoscroller » NYC Resistor

Hexascroller has been a central fixture at NYCR for the past few years, with a few ups and downs. It’s replacement, Octoscroller, improves on our classic message alert polygon by having two more sides and two more colors of LEDs.

The brains are a BeagleBone Black running the LEDscape custom PRU firmware. The AM355 CPU in the BBB has two separate realtime microcontrollers built into its die, both with full access to the GPIO lines and cache coherent access to main memory. This bit of hardware/software allows the user application to simply render into a frame buffer, which is then driven to the panels by the PRU.

9702197818_9e7ac1aa82_z.jpg

 

cheers,

drew

http://twitter.com/pdp7

Introduction

There are many compact LCD and OLED displays available, but the documentation tends to be poor. This is just a quick post to record a working configuration (circuit and code) to get a compact OLED display working. A 160x128 OLED display was selected, model DD-160128FC-1A (Farnell code 1498857, also available from Newark). It is a very high quality display.

snoopy.jpg

The display is an Organic LED (OLED) type. For interfacing a similar-sized LCD display, see here.

The code that was written is targetted for the BeagleBone Black (BBB) but can be very easily adapted for any platform. For the BBB, it uses an I/O library called iolib (see here for more details) intended for quickly prototyping a solution. The library code is already included in the zip file attached to this post.

 

The code is prototype level – ideally it would be rewritten to use faster interfaces (e.g. SPI, or PRU processor), but it runs fast enough for many use-cases - with the current code the display update rate is more than sufficient for text information and simple diagrams. Perhaps 30 updates per second are possible with the current code if the entire screen is not being refreshed.

 

The code has a few graphic commands but not much – it is an easy matter to use one of the many existing third party graphics libraries if anything beyond simple text/graphics is required.

The current code has just these capabilities:

  • Point plotting
  • Line plotting
  • Rectangles (filled, unfilled, bordered)
  • Scalable Text
  • Graphic image read from raw file into RAM
  • Graphic image display from RAM

 

Display Dimensions and Notes

The display has a Densitron code DD-160128FC-1A. The screen has the label “UG-6028GDEAF01” on the rear. A connector by Omron (Omron code XF2M35151A  Farnell code 1112561) should fit.

Shown below is a diagram from the datasheet. The screen is very thin (about 1.5mm). There is an in-built controller (Syncoam SEPS525) located in the hatched purple area. The display is organized such that memory address 0 is top-left (where the round blob is shown) like most displays. Personally I prefer to have the origin at bottom-left, so the code uses that reference point as (0,0) instead of top-left.

tech-drawing.png

 

Example Images

These photos were taken in a brightly lit room. The screen appears bright, sharp and has a more rich/saturated quality than LCD displays:

alarm.jpg

 

This animated character is drawn at position (0,0), since co-ordinates are taken from bottom-left in the attached code:

sfighter.jpg

 

An example menu. A circuit board could have buttons to the side:

demo1.jpg

 

Video

Note - The photographs are more representative of what the display looks like in action. The image quality appears extremely bright and sharp when viewed in person – about the same as a mobile phone

The video clip here is only really useful to show the update speeds for the current code. The pulsing/flickering and horizontal banding visible in the video is not apparent in real life.

Click here for the video- having real trouble with it, it is from a camera I don't normally use and the quality is pretty bad - sorry. The final animation is actually quite smooth in real life.

 

Circuit

There is an optional demo board available, but it is quite basic; it has no active components, it is almost just a breakout board. The demo board was intended to speed development up, but the datasheet slowed things right back down again - the datasheet from Densitron is poor and has many errors (they have taken absolutely no care to review it).

This is the required circuit to get the display working in a serial mode:

oled-schematic-main.png

 

An appropriate connector shown here (Farnell code 1112561) should be compatible (35 way, 0.5mm pitch) but was not tested.

 

The display requires a low voltage supply (3.3V max) which matches what the BBB offers. A higher voltage (13V) supply is also required. I didn’t have any appropriate IC over the holiday period, so a Maxim MAX734 was used, with some resistors used to adjust the voltage to 13V. This is not recommended since it is outside the specification of the MAX734, but the circuit is shown below since it worked for the prototype. It is recommended to use a different circuit.

oled-schematic-supply.png

Once assembled, the circuit was connected to the BBB as indicated in the schematic. The 0V, +3.3V and +5V supply rails were powered directly from the BeagleBone, using the BBB header P9 pins 1, 3 and 5 respectively.

 

Software

The code is attached to this post. It is written in C. Refer to the file ‘oled.c’ to see the functions available. The main function currently also resides in that file. It runs five demonstrations when executed.

 

To use it, create a folder off the home directory (/home/root in my case):

mkdir –p development/oled
cd development/oled





The path will now be /home/root/development/oled

Copy the files into this location, then type the following to compile the code:

make install





The demo can now be run by typing:

./oled





 

Summary

It would be worthwhile creating a board for this display, and using it for small projects with the BBB where a high quality image is needed. A good amount of information can be represented on this display. It is easy to use with the example C code library, but will require a 13V supply (a small circuit can be used to generate this from the BBB’s 5V supply rail).

For larger displays, the 4.3” and 7” BB-View displays are available.

 

The revision 1 code is attached below for reference, but is also available here so that changes can be tracked.

20131218_024345-MOTION (1).gif20131223_112415-MOTION (1).gif

20131218_024320.jpg

I previously wrote about using the 8x8 LED matrix with the BeagleBone Black and visualizing Facebook notifications on the matrix.  Adafruit has an interesting tutorial about using multiple 8x8 LED matrix displays together:

 

Animating Multiple LED Backpacks

http://learn.adafruit.com/animating-multiple-led-backpacks

skull2.jpg

The above tutorial was written for the ArduinoArduino, but I wanted to control multiple Adafruit 8x8 LED matrix displaysAdafruit 8x8 LED matrix displays with the BeagleBone BlackBeagleBone Black.  I lucked out when I found Matt Hassel's LED Stock Ticker project for the Raspberry PiRaspberry Pi.  He built upon the Adafruit Python library for the 8x8 matrix and wrote new code to handle scrolling text across multiple displays.  I was able to get Matt Hassel's Python code to run on the BeagleBone Black, and I reworked bi-color matrix code to work with the single color 8x8 matrix displays like my red model.  Here is my GitHub repo for all of my Adafruit LED backpack (8x8 matrix & 7-segment) projects for the BBB:

 

GitHub: pdp7 / beaglebackpack

https://github.com/pdp7/beaglebackpack


A Python program, ticker.py, will scroll a message across the matrix displays.  Before running it, follow Adafruit's instructions to install their Adafruit-BeagleBone-IO-Python library:


Installation on Angstrom | Setting up IO Python Library on BeagleBone Black | Adafruit Learning System

http://learn.adafruit.com/setting-up-io-python-library-on-beaglebone-black/installation

 

Next follow these instructions on the BeagleBone:

cd $HOME

git clone git://github.com/adafruit/Adafruit-Raspberry-Pi-Python-Code.git

git clone git://github.com/pdp7/beaglebackpack.git

cd beaglebackpack

bash ./ticker.sh -r "Happy Holidays 2013"

 

The message should then scroll across the two displays:

 

Happy Holidays: BeagleBone Black LED ticker

https://www.youtube.com/watch?v=wy1r8esEK6E

 

 

Cheers,

Drew

http://twitter.com/pdp7

UPDATE: Kim the Maker Mom did an awesome job on WGN News this morning.  Kids will be lucky to get these awesome STEM/DIY/maker gifts like littleBits, Bigshot Camera, GoldieBlox, Roominate, etc.  At 4m 25s, check out the BeagleBone Black and Adafruit 16x32 RGB LED panel (displaying output from LEDscape designed at NYC Resistor)


VIDEO: http://morningnews.wgntv.com/2013/12/05/tech-toy-gift-ideas/

BLOG: The Maker Mom: Hot Holiday STEM and Tech Gifts for Kids (Boys and Girls) 2013 as seen on WGN Morning News

Maker Mom on TV.JPG

Kim Moldofsky aka Maker Mom (http://www.themakermom.com/p/about.html) will be on Chicago's WGN TV morning news tomorrow around 8:45am US CST (http://wgntv.com/live/) to present STEM gift ideas including a BeagleBone BlackBeagleBone Black bundle provided by Newark element14 (http://www.newark.com/holidaydeals).  She will demo LEDscape (created at NYC Resistor) running on an Adafruit 16x32 RGB LED panelAdafruit 16x32 RGB LED panel:

 

BeagleBone Black sees color with OpenCV - YouTube

 

cheers,
drew

http://twitter.com/pdp7

LaserGoodies has a sale on amazon.com for our Beaglebone Black Cases. To use the offer online, enter CyberLG1 at checkout.

Link to our Product Page

Sale is Good Till 11:59pm PST 12/02/13.

20131126_100016 (1).jpg

Previously, I wrote a blog post about how I displayed the count of my unseen Facebook notifications on a 7-segment display7-segment display connected to the BeagleBone Black BeagleBone Black: BeagleBone Black displays Facebook notifications on Adafruit 7-segment.  I decided to do a similar task with the BeagleBone BlackBeagleBone Black & Adafruit 8x8 LED matrixAdafruit 8x8 LED matrix.  My most recent post that shows how it is interfaced with the BBB: Adafruit 8x8 LED matrix controlled by BeagleBone Black.

20131126_100049 (1).jpg

Here's the Python script that grabs the unseen notification count from the Facebook API and then displays it on the 8x8 matrix8x8 matrix.  One notification is one pixel.

https://gist.github.com/pdp7/7679350


Cheers,

Drew Fustini

http://twitter.com/pdp7

Introduction

In the previous articles, we set up the BeagleBone to have a MySQL database and a web server.  We also wrote a simple web site to control the LEDs on the BeagleBone.

 

In this article, we are going to tie all of the pieces together and create a web site that displays the temperature of the room that the BeagleBone is in.  We are going to do this by taking temperature measurements using the analog input on the BeagleBone and storing the measured values in the database.  We will then create a PHP page that will query the data out of the database and display it to the user in a google chart.

 

Preparing the Database

The first step is to create a new MySQL database:

 

CREATE DATABASE TempDB;

 

Next, we should probably create a new user to log into the database with.  This isn’t strictly necessary, but it is a good idea to not log in as root every time.  Here’s how to create a new user:

 

CREATE USER bone@localhost IDENTIFIED BY ‘bone’;

 

Then we need to give the new user (bone) permissions on the newly created database:

 

GRANT ALL ON TempDB.* to bone@localhost;

BeagleBone - MySQL.png

I usually prefer to create my tables in code rather than through the MySQL prompt.  The reason is that if I ever want to make any changes or start over, I can just drop the table and then rerun my code and it will take care of it.  I find that this makes it faster and easier to make changes to my table.

 

Interfacing with the Database

So, now that the database and user are set up, we can shift over to C++ to create the table and take temperature measurements.  We’ll start by creating a program that just inserts in any old data into the table and then we’ll incorporate a temperature sensor.  Here’s the first cut at the program:

 

#include <mysql.h>

#include <stdlib.h>

#include <stdio.h>

#include <string.h>

 

/// Prints out a MySQL error message and exits

///

/// This function should be called after a MySQL error has been encountered.  This function will then

/// notify the user of the error that has occurred, clean up the existing MySQL connection, and then

/// exit the program.

///

/// @param The MySQL connection to clean up before exiting

void error_exit(MYSQL *con)

{

fprintf(stderr, "%s\n", mysql_error(con));

 

if (con != NULL)

{

mysql_close(con);

}

           

exit(1);

}

 

int main(int argc, const char *argv[])

{

// Initialize a connection to MySQL

MYSQL *con = mysql_init(NULL);

if(con == NULL)

{

error_exit(con);

}

           

// Connect to MySQL

// Here we pass in:

//  host name => localhost

//  user name => bone

//  password => bone

//  database name => TempDB

if (mysql_real_connect(con, "localhost", "bone", "bone", "TempDB", 0, NULL, 0) == NULL)

{

error_exit(con);

}

 

// Create the TempMeas database (if it doesn't already exist)

if (mysql_query(con, "CREATE TABLE IF NOT EXISTS TempMeas(MeasTime DATETIME, Temp DOUBLE)"))

{

error_exit(con);

}

 

// Initialize a MySQL statement

MYSQL_STMT *stmt = mysql_stmt_init(con);

if (stmt == NULL)

{

error_exit(con);

}

           

// Set out insert query as the MySQL statement

const char *query = "INSERT INTO TempMeas(MeasTime, Temp) VALUES(NOW(), ?)";

if (mysql_stmt_prepare(stmt, query, strlen(query)))

{

error_exit(con);

}

 

// Create the MySQL bind structure to store the data that we are going to insert

double temp = 0.0;

MYSQL_BIND bind;

memset(&bind, 0, sizeof(bind));

bind.buffer_type = MYSQL_TYPE_DOUBLE;

bind.buffer = (char *)&temp;

bind.buffer_length = sizeof(double);

 

// Bind the data structure to the MySQL statement

if (mysql_stmt_bind_param(stmt, &bind))

{

error_exit(con);

}

 

// Insert multiple records into the database,

// with different data each time

for (int i = 0; i < 10; i++)

{

temp = (float)i;

mysql_stmt_execute(stmt);

}

 

// Close the MySQL connection

mysql_close(con);

 

return 0;

}

 

The code is surprisingly straight-forward.  We start by creating the table if it does not exist.  Then we create a parameterized query.  Note that we don’t need to recreate the query or rebind the parameters. This is because we pass a pointer to the bind structure.  So, all we need to do is execute the statement every time a new measurement is taken.

 

To build the code, use the following command:

 

g++ tempmeas_initial.cpp -o tempmeas_initial -I/usr/include/mysql –lmysqlclient

 

Then you can run it using:

 

./tempmeas_initial

 

After running the program, we can go over to MySQL and make sure that everything worked like we expected:

MySQL - initial test.png

That looks good, so let’s move on to incorporating a temperature sensor.

 

Temperature Sensor

Now that we know that we can put data into the database, let’s set up a circuit to gather that data:

IMG_1469 (1280x960).jpg

Here we have a MCP9701E temperature sensor connected to analog input #1.  I also did a simple voltage divider to cut the voltage in half since the input voltage is 3.3V and the analog input pins can only handle a maximum of 1.8V.  The sensor output will never be that high (unless it gets really hot), so it is probably unnecessary, but better safe than sorry.

 

Now we can test to make sure that the circuit is working properly by reading the value that it outputs at:

 

Older BeagleBone:

cat /sys/devices/platform/tsc/ain1

 

Newer BeagleBone:

cat /sys/devices/platform/omap/tsc/ain1

 

Reading the Temperature Sensor

The value that is returned is between 0 - 4096 and it is a measurement of the voltage that is connected to ain1.  We need to convert that voltage into a temperature and to do that, we use the information from the datasheet.  Here is the conversion in code:

 

Header:

 

#ifndef MCP9701E_H

#define MCP9701E_H

 

class MCP9701E

{

private:

int _input;

char _buffer[1024];

 

static const float Vdd;

 

static const int TempSensorMin;

static const int TempSensorMax;

 

static const float V0;

static const float Tc;

 

public:

MCP9701E(const char *pin);

float GetTemperature();

void Close();

};

 

#endif

 

Definition:

 

#include "MCP9701E.h"

 

#include <stdlib.h>

#include <fcntl.h>

#include <stdio.h>

#include <unistd.h>

 

/// Input voltage

const float MCP9701E::Vdd = 3.3;

 

/// Maximum and minimum values that can be measured

const int MCP9701E::TempSensorMin = 0;

const int MCP9701E::TempSensorMax = 4096;

 

/// Temperature sensor constants

const float MCP9701E::V0 = 0.3f;

const float MCP9701E::Tc = 0.0195f;

 

/// Handles a MCP9701E temperature sensor

///

/// @param Hardware device to read the temperature measurements from

MCP9701E::MCP9701E(const char *pin)

{

_input = open(pin, O_RDONLY);

}

 

/// Grabs a temperature measurement

float MCP9701E::GetTemperature()

{

// Read the sensor

int status = read(_input, _buffer, sizeof(_buffer));

if (status == -1)

{

fprintf(stderr, "ERROR: Could not get temperature measurement.");

return -999.0f;

}

 

// Reset the sensor

lseek(_input, 0, 0);

 

// Convert the string into an integer

_buffer[status] = '\0';

int value = atoi(_buffer);

           

// Convert the measurement into a temperature

float voltage = ((float) value) / (TempSensorMax - TempSensorMin + 1) * Vdd;

float temp = (voltage - V0) / Tc;

 

return temp;

}

 

/// Closes the temperature sensor

void MCP9701E::Close()

{

if(_input != -1)

{

close(_input);

_input = -1;

}

}

 

Then we can make a small modification to our code that imports numbers into the MySQL database, so that it now imports in actual temperature measurements.  To do this, we replace the previous for loop with the code below:

 

// Initialize the temperature sensor

MCP9701E sensor("/sys/devices/platform/omap/tsc/ain2");

           

// Take a temperature measurement and insert it into the database

for (int i = 0; i < 10; i++)

{

temp = sensor.GetTemperature();

mysql_stmt_execute(stmt);

sleep(60);

}

           

// Close the temperature sensor

sensor.Close();

 

The full version of the code is attached below.

 

To build the code, use the following command:

 

g++ tempmeas.cpp MCP9701E.cpp -o tempmeas -I/usr/include/mysql –lmysqlclient

 

Then you can run it using:

 

./tempmeas

 

Next we can go over to MySQL and verify that actual temperature measurements are being populated in the database:

MySQL - temp meas.png

 

Creating a Web Page

The final piece of the puzzle is to create a web page to display the information in.  To do this, we will use google charts, and slightly modify their line chart example.  All we need to do is add some logic to query the data from the MySQL database:

 

<html>

<head>

<title>BeagleBone Temperature</title>

<script type="text/javascript" src="https://www.google.com/jsapi"></script>

<script type="text/javascript">

google.load("visualization", "1", {packages:["corechart"]});

google.setOnLoadCallback(drawChart);

function drawChart() {

var data = google.visualization.arrayToDataTable([

['Time', 'Temperature'],

<?php

$con = mysqli_connect("localhost", "bone", "bone", "TempDB");

 

$query = "SELECT * FROM TempMeas";

$result = mysqli_query($con, $query);

 

mysqli_close($con);

 

while ($row = mysqli_fetch_array($result))

{

$time = $row['MeasTime'];

$temp = $row['Temp'];

echo "['$time', $temp],";

}

?>

]);

 

var options = {

title: 'BeagleBone Measured Temperature',

vAxis: { title: "Degrees Celsius" }

};

 

var chart = new google.visualization.LineChart(document.getElementById('chart_div'));

chart.draw(data, options);

}

</script>

</head>

<body>

<div id="chart_div" style="width: 900px; height: 500px;"></div>

</body>

</html>

 

The change that we made to the google chart example is the addition of the PHP code.  This code will query all of the data in the database and insert it into the web page that is returned to the user.  If the sensor has been running for a long time, this could be a lot of data.  An improvement would be to limit the measurements to the past hour or so. Even better would be to make it user configurable through the web page!  Here we are just focused on a simple example.

 

Finally, we can visit our web page and check out our results!

temp page.png

Summary

In these articles, we have demonstrated how to turn your BeagleBone into a very powerful web server. MySQL, PHP, and JavaScript are the building blocks of most web sites.  Using these tools, you can create some very exciting sites on your BeagleBone! And if you do, please post them to the comments, I’d love to see what projects you are working on.

Introduction

MySQL is a very popular open source database.  In this project, we will use it to store the measured temperature values, which can then be retrieved by a web page.

 

Installing MySQL

Before we start, if you have not updated opkg in a while, you should probably do that first:

 

opkg update

 

Now on to the task at hand. Installing MySQL.  There is already an opkg package, so we’ll install that:

 

opkg install mysql5

 

This will download and install MySQL.  Unfortunately, if we try and fire up MySQL:

 

/etc/init.d/mysqld start

 

We will see an error:

 

/etc/init.d/mysqld: line 3: /etc/default/rcS: No such file or directory

BeagleBone - mysqld error.png

The fix to this issue is fairly easy.  We need to comment out that line 3 in the script:

 

vi /etc/init.d/mysqld

BeagleBone - mysqld comment out.png

Now when we try and fire up MySQL:

 

/etc/init.d/mysqld start

 

We are successful and we can log into MySQL:

BeagleBone - mysql prompt.png

Warning

At this point it might seem like time for celebration.  We have MySQL installed and are able to run it and log in.  Unfortunately, if we restart then when we log in again we will get an error stating:

 

Cannot make/remove an entry for the specified session.

 

This is really annoying since it won’t let you log in and fix the issue.  I had to resort to reimaging my SD card and trying again. (The steps are here, in case you have to do it as well.)

 

MySQL Configuration

To fix that issue, we need to make some more configuration changes.  First we need to remove some unnecessary links:

 

rm /etc/rc*/*mysqld

BeagleBone - remove mysql links.png

Now this prevents MySQL from starting at boot.  Since we want MySQL to start at boot, let’s see if we can fix that.  To do this, we need to create a new configuration file:

 

vi /lib/systemd/system/mysql.service

 

And put the following text in that file:

 

[Unit]

Description=MySQL database server

After=syslog.target

After=network.target

 

[Service]

ExecStart=/usr/bin/mysqld_safe

ExecStop=/bin/kill -15 $MAINPID

PIDFile=/var/lib/mysql/mysql.pid

Restart=always

 

[Install]

WantedBy=multi-user.target

 

Now we can enable the MySQL service to start at boot and then start the MySQL service:

 

systemctl enable mysql.service

systemctl start mysql.service

 

Then we should be able to check the status of the service and make sure that it is running:

 

systemctl status mysql.service

BeagleBone - mysql service start.png

Now you should be able to restart without getting the log in error and MySQL should be running!

 

Installing MySQL Client Library

The last thing that we need to do is install the MySQL C programming client library:

 

opkg install libmysqlclient-dev

 

Now, let’s test to make sure that it installed correctly and works.  To do this, create small test script:

 

#include <mysql.h>

#include <stdio.h>

 

int main(void)

{

                printf(“MySQL client version: %s\n”, mysql_get_client_info());

 

return 0;

}

 

This will print out the version information for the MySQL client.  To build it type:

 

g++ test.cpp -o test -I/usr/include/mysql –lmysqlclient

 

And then to run it, type:

 

./test

BeagleBone - test code build.png

Now MySQL should be installed on your BeagleBone and ready to use!

 

Video

 

Next Article

In the next article, we will create a C program that will measure the temperature of the room.  It will then write the current temperature into the MySQL database.  Finally, we will create a web interface to retrieve and plot the measured temperatures of the room.

20131120_055834-ACTION.jpg

Similar to my previous post on Interfacing BeagleBone Black with Adafruit 7-segment LED display, I have hooked up the Adafruit 8x8 LED matrix with I2C "backpack"Adafruit 8x8 LED matrix with I2C "backpack".  This means the matrix is connected with just 4 wires (3.3VDC, GND, SDA, SCL) to the BeagleBone Black (e.g. BBB)BeagleBone Black (e.g. BBB) which is mounted on the Adafruit BeagleBone Black Proto PlateAdafruit BeagleBone Black Proto Plate:

20131120_055226.jpg

And like with the 7-segment LED "backpack", the Python module that Adafruit wrote for the Raspberry Pi works with the BeagleBone Black as well (hooray for the common abstraction of Linux and Python ):

https://github.com/adafruit/Adafruit-Raspberry-Pi-Python-Code/blob/master/Adafruit_LEDBackpack/Adafruit_8x8.py

 

I shot a video of it running the Adafruit_8x8.py example program:

 

Adafruit 8x8 LED matrix controlled by BeagleBone - YouTube

 

I'm looking forward to putting this display to use in a project.

 

Cheers,

Drew

http://twitter.com/pdp7

Introduction

In the previous article, we set up the BeagleBone to be a webserver running Lighttpd and PHP.

 

In this article, we are going to build upon that foundation.  We are going to create a web site that lets the user turn on and off an LED on the BeagleBone.  This is a good example of how to create a simple web page that interacts with the BeagleBone and is a step towards our final goal of creating a website to show historical temperature information.

 

Turning a LED On/Off

BeagleBone LEDs can be turned on/off through command line, but in order to do this, we need to figure out what they are named.  The names can be found like this:

 

ls -1 /sys/class/leds

BeagleBone - led location.png

So, turning the usr2 LED on/off would look something like this:

BeagleBone - turn led on-off.png

1 will turn the LED on, and 0 will turn the LED off.

 

By default, some of the LEDs are used to display information to us about what is going on.  So, if you change the state of one of those LEDs, it will be quickly overwritten.  We can see this by looking at the trigger:

 

cat /sys/class/leds/beaglebone::usr0/trigger

BeagleBone - default trigger.png

To modify this so that the LED only changes when we tell it to, we can change the trigger to none:

 

echo none > /sys/class/leds/beaglebone::usr0/trigger

BeagleBone - change trigger.png

 

C Program

Now that we know how to turn on/off the LEDs, we can write a small C program to make it easier for us. The program will take in the number of the LED to change (0-4) and the state to change it to (off = 0, on = 1). Here’s the code:

 

#include <stdio.h>

#include <stdlib.h>

#include <fcntl.h>

#include <unistd.h>

 

int main(int argc, const char *argv[])

{

if (argc != 3)

{

printf("Usage:\n");

printf("\tledCtl <led> <on/off>\n");

printf("\n");

printf("<led>  : Number between 0-3\n");

printf("<on/off>: 1 = on, 0 = off\n");

 

return 1;

}

 

int ledNum = atoi(argv[1]);

if (ledNum < 0 || ledNum > 3)

{

printf("<led>  : Number between 0-3\n");

 

return 1;

}

 

char ledPath[1024];

sprintf(ledPath, "/sys/class/leds/beaglebone::usr%d/brightness", ledNum);

int fid = open(ledPath, O_WRONLY);

 

int onOff = atoi(argv[2]);

switch (onOff)

{

case 0:

write(fid, "0", 1);

break;

case 1:

write(fid, "1", 1);

break;

default:

printf("<on/off>: 1 = on, 0 = off\n");

return 1;

}

 

close(fid);

 

return 0;

}

 

Remember to change the path of the LED to the path that we found earlier.

 

For a simple task like this, we could have just used the command line to turn the LEDs on/off. However, I wanted to put it into a C program so that we set ourselves up better for the future.  When we take temperature measurements and put them into a MySQL database, it will require more logic that is better suited for a small program rather than the command line.

 

The code should be fairly clear.  It is mostly just checking the inputs that the user gave us to make sure that they are reasonable.

 

Before we compile it, we need to create a directory to store the scripts that we are going to be running on our web site:

 

mkdir /www/cgi-bin

 

To compile the code, type:

 

g++ ledctl.cpp -o /www/cgi-bin/ledctl

BeagleBone - ledctl compile.png

 

Then we can run some examples and make sure that it works:

 

/www/cgi-bin/ledCtl

/www/cgi-bin/ledCtl 2 1

/www/cgi-bin/ledCtl 2 0

BeagleBone - ledctl test.png

 

Creating a Web Page

Awesome, now that we have a program to control the LEDs on the BeagleBone, let’s create a web page so that we can control the LEDs over the Internet.  Let’s call the web page ledCtl.php and place the following code in it:

 

<html>

<head>

<title>BeagleBone LED Changer</title>

<style type="text/css">

p { display: table-cell; }

button { width: 75px; margin: 2px auto; }

</style>

<?php

if (isset($_GET['led']) && isset($_GET['onOff']))

{

$led = $_GET['led'];

$onOff = $_GET['onOff'];

 

exec( "/www/cgi-bin/ledctl $led $onOff" );

}

?>

</head>

<body>

<div style="width: 200px; margin: 0px auto;">

<div style="width: 100px; float: left;">

<p>LED #2:</p>

<button type="button" onclick="location.href='ledCtl.php?led=2&onOff=1'">ON</button>

<button type="button" onclick="location.href='ledCtl.php?led=2&onOff=0'">OFF</button>

</div>

<div sytle="width: 100px; margin-left: 100px;">

<p>LED #3:</p>

<button type="button" onclick="location.href='ledCtl.php?led=3&onOff=1'">ON</button>

<button type="button" onclick="location.href='ledCtl.php?led=3&onOff=0'">OFF</button>

</div>

</div>

</body>

</html>

 

Note: We used LEDs #2 and #3 because LED #0 and #1 occasionally blink and override our on/off settings.

 

Then we can test our web page by going to a browser and using our new web page:

BeagleBone - ledCtl.png

Pressing the buttons on the page should change the state of the LEDs on the BeagleBone!

 

Next Article

In the next article, we are going to get MySQL up and running on the BeagleBone.  We will use MySQL as a convenient place to store the temperature measurements that we take.  This will also make it easy to retrieve the data when the user requests historical temperature information through our web page.