RS Display Board

Hot new App!!

Connect your mbed to the internet via an Ethernet cable, when plugged into the dispBoB. Import this program, then type a short message into this web app. The message you typed then shows up on the dispBoB!! Cool or what! Source code here

This is a purpose built breakout board, utilizing the PCA9635 IO bus expander as an LED driver. The dispBoB library requires the inclusion of the PCA9635 library in order to function correctly.

298

API

Import library

Public Member Functions

  dispBoB (PinName sda, PinName scl, PinName en)
  Create a dispBoB object defined on the I2C master bus.
void  init (void)
  Initialise device.
virtual void  cls (void)
  Clear screen.
virtual void  locate (char pos)
  Set cursor position.
void  scroll (string str, float speed)
  Write a scrolling string (right to left) to display.
void  bus (short leds)
  Same functionality as the bus() function on the PCA9635.
int  putc (int c)
  Write a character to the display.
int  printf (const char *format,...)
  Write a formated string to the LCD.

Libraries

dispBoB

PCA9635

Additional notes

The following ASCII encoded characters are supported:

0123456789
ABCDEFGHIJKLMNOPQRSTUVWXYZ
abcdefghijklmnopqrstuvwxyz
! ' ( ) { } [ ] - _ .

Information

, is not supported

Simplest of simple programs

Import program

00001 #include "mbed.h"
00002 #include "dispBoB.h"
00003 
00004 dispBoB db(p28, p27, p26);
00005 
00006 int main() {
00007     db.init();      //ALWAYS initialise screen
00008     db.cls();       //clear screen
00009     db.printf("%d%", 123456);   //print to the dispBoB as you would 
00010                                 //using the standard stdio.h printf() function
00011 }

Example Projects

The display is very simple to interface. Simply download this file and this file

Next, in the includes section of your .cpp file type #include "dispBoB.h"

All of the functions are explained in the API above.

1 - Simple Clock

The C time.h library is a useful way of implementing a reliable clock into any program. I've gone for the UNIX timestamp approach, which is a measure of the number of seconds since midnight 1st Jan 1970 Coordinated Universal Time (UTC). Luckily the time.h library contains a nice set of functions to convert this into a nicely formatted string. Find out more about time.h on the mbed here.

Import program

00001 #include "mbed.h"
00002 #include "dispBoB.h"
00003 
00004 dispBoB db(p28, p27, p26);              //instantiate dispBoB object
00005 
00006 int main() {
00007     db.init();
00008     set_time(1309776930);               //set UNIX timestamp -  it's Mon, 04 Jul 2011 10:55:30 GMT where I am
00009     
00010     while(1){                           //loop forever
00011         time_t rawtime = time(NULL);    //update to instantaneous time
00012         
00013         char buffer[32];                //create a local char array object called buffer
00014         strftime(buffer, 32, "%H.%M.%S\n", localtime(&rawtime)); //store string formatted time
00015         
00016         db.locate(0);                   //position cursor to initial position on screen
00017         db.printf("%s", buffer);        //print buffer to dispBoB
00018     }
00019 }

The current UNIX timestamp can be found here.

/media/uploads/d_worrall/_scaled_db1_004.jpg

2 - Counter

This next small project demonstrates how the mbed can be interfaced with a rising edge trigger (say a laser beam or a button etc.) to create a counter, which increments upon trigger. The specific trigger in this example is a laser beam and reflector fed into a digital input on pin 12 of the mbed and requires a pull-up resistor, which can be activated from within the mbed itself.

/media/uploads/d_worrall/dsc01434.jpg

Import program

00001 #include "mbed.h"
00002 #include "dispBoB.h"
00003 
00004 dispBoB db(p28, p27, p26);          //instantiate a dispBoB object
00005 InterruptIn trigger(p12);           //set up the trigger as an external interrupt
00006 
00007 int counter = 0;                    //initialise counter object to zero
00008 
00009 void count(){                       //function to call upon interrupt
00010     counter++;                      //increment counter object
00011     db.locate(0);
00012     db.printf("%06d", counter);     //print counter info to dispBoB 
00013 }
00014 
00015 int main() {
00016     trigger.mode(PullUp);           //activate internal pull up (hardware specific)
00017     db.init();
00018     db.cls();                       //clear screen
00019     trigger.rise(&count);           //attach count() to interrupt on rising edge of trigger
00020     db.printf("%06d", counter);     //display an inital count "000000"
00021 }

3 - Digital thermometer

The TMP102 temperature sensor use an I2C interface to connect to external devices. Its library can be found here. The following code shows (yet again), how simple it is to implement programs combining the dispBoB with other devices

Import program

00001 #include "mbed.h"
00002 #include "dispBoB.h"
00003 #include "TMP102.h"
00004 
00005 dispBoB db(p28, p27, p26);          //instantiate a dispBoB object
00006 TMP102 temperature(p9, p10, 0x90);  //instantiate a TMP102 object
00007 
00008 int main() {                   
00009     db.init();     
00010     db.cls();                       //clear screen
00011     while(1){
00012         db.locate(0);               //position to start
00013         db.printf("%f", temperature.read());  //print temperature
00014         db.printf("%c", ".C");      //degrees celsius
00015         wait(1);                    //wait 1 second before looping
00016     }
00017 }

/media/uploads/d_worrall/tmp102.jpg

4 - Real-time FTSE100 data

Now this is exciting and really demonstrates the power of the mbed as an intelligent interfacing device! In the office, I'm constantly checking the BBC headlines, the current FTSE100 data and all the real-time data that the internet has to offer. So wouldn't it be just brilliant to have it displaying on the dispBoB all the time, so that I don't have to distract myself from whatever I'm doing?

What you need

  • mbed
  • mbed 7 Segment Display Board aka dispBoB
  • Ethernet Cable (RJ45 jack etc.)
  • A website with PHP support (don't worry about this yet)
  • A spare Ethernet socket to the world wide web....

/media/uploads/d_worrall/_scaled_dsc01400.jpg

What you DON'T need

  • PHP skillz
  • FTSE100 Knowledge

/media/uploads/d_worrall/_scaled_dsc01399.jpg

A quick briefing on screen-scraping

In order to access the current FTSE100 index (it's actually 15mins delayed, but I mean 'current' to the outside world instead of to financiers working in the City) I need to first of all find a good reliable source of FTSE100 data.

Here seems fairly good. Now the data I really want is the number in the top right hand corner.

Yahoo Finance

If you right click and select View Page Source the source code for the webpage should pop up and in here it should be possible to find the number I want...

...Some time later...

It happens to be placed between 2 html tags <span id="yfs_l10_^ftse"> and </span>. So what I want to do is get my mbed to scour through the source code, find these tags and strip out the important number in between (This is called screen-scraping). Then it can post it to the dispBoB to satisfy my addiction to real-time FTSE100 data.

But the mbed runs on C and string-handling would be done better in some other language. So I decide to get somebody else to do the donkey work. I'll offload the task of screen-scraping to some poor server out there in the cyber-world.

PHP Funtimes

I've never written a web application before and I managed this in one morning, so you should be able to do it in no time. I signed up for free web-hosting with these people. After that, I created a new domain name http://www.mbed.net16.net/ and then through the helpful file manager application created a new .php file within the public_html directory. I called it dispBoBApp.php, but you can call it whatever you like.

Being a PHP noob I then did a quick google search and read-up on all things PHP basic.

Here is my web programme

PHP

<?php

$url = "http://uk.finance.yahoo.com/q?s=^FTSE";      //assign url to variable

$data = file_get_contents($url);                     //declarations
$ftse100_id_start = '<span id="yfs_l10_^ftse">';
$ftse100_id_end = '</span>';
$comma = ',';

$start = strpos($data,$ftse100_id_start)+25;         //figure out tag positions
$end = strpos($data,$ftse100_id_end,$start);
$ripped_data = substr($data,$start,$end-$start);     //copy through data between tags

$comma_pos = strpos($ripped_data, $comma);           //locate and rip out any annoying commas
$ripped_data = substr_replace($ripped_data, "", $comma_pos, 1);

print $ripped_data;

?>

Here is the resulting webpage. If you access it during the week during working hours it should show the FTSE100 index. What's even more exciting, is that if you wait a couple of seconds and refresh the page, the number changes!! Perfect!

Next, all I have to do is connect the mbed to the web and stream off this number.

It actually reads off the source code for the webpage I just created, but 000webhost.com have stuck a bit of extra code on the end for their own purposes.

Server generated source code

6018.52
<!-- www.000webhost.com Analytics Code -->
<script type="text/javascript" src="http://analytics.hosting24.com/count.php"></script>
<noscript><a href="http://www.hosting24.com/"><img src="http://analytics.hosting24.com/count.php" alt="web hosting" /></a></noscript>
<!-- End Of Analytics Code -->

So in my mbed code I'm going to still have to do a bit of parsing, just it will be much less labour intensive than had I just screen-scraped directly from yahoo finance. Well actually that's where I went wrong. If I use the sscanf() function from the stdio.h library I can tell my mbed to read off numbers until it sees something which isn't a number i.e. a line break, and then chuck everything it's just read into a new variable, say int value. Sorted!

mbed code

A quick browse through the mbed cookbook reveals this page on HTTPClients and Ethernet connexions. The example code is a bit fluffy, but useful for developing, so I merge/copy and paste it with/into my code and add dispBoB in the declares area.

Import program

00001 #include "mbed.h"
00002 #include "EthernetNetIf.h"
00003 #include "HTTPClient.h"
00004 #include "dispBoB.h"
00005 #include "stdio.h"
00006 
00007 EthernetNetIf eth; 
00008 HTTPClient http;
00009 dispBoB db(p28, p27, p26);
00010   
00011 int main() {
00012 
00013     EthernetErr ethErr = eth.setup();           //Setup ethernet connection
00014     if(ethErr) return -1;
00015   
00016     db.init();                                  //initialise screen
00017     db.cls();
00018     
00019     HTTPText txt;                               //instantiate HTTPStream object
00020     while(1){
00021         HTTPResult r = http.get("http://mbed.net16.net/v1/dispBoBApp.php", &txt);   //load page into buffer
00022         if(r==HTTP_OK){
00023             string str = txt.gets();            //load web page into string
00024 
00025             char buf[10];                       //instantiate buffer and string to store FTSE100
00026             string value;                                  
00027             str.copy(buf,9,0);                  //load buffer with chunk of web page
00028 
00029             sscanf(buf, "%s", value);           //scan until decimal point
00030             
00031             db.scroll("FTSE100", 0.2);          //print info to dispBoB
00032             db.locate(0);
00033             db.printf("%s", value);                    
00034         }
00035         wait(2);                                //wait 2 seconds before looping, so we don't pester the servers too much
00036     }
00037 }
00038 
00039 
00040 
00041 
00042 
00043 
00044 

So now I have a real-time update of the FTSE100 right in front of me all day.

Here's an exciting clip of me setting up the mbed and finally getting it to display the FTSE100 index!

Several more interesting things which you can do with the display

(a) - interval stopwatch

Using the same wiring as in the Counter example (ex. 2 above), it is quite easy to recode the mbed to measure the time between two consecutive rising edges. Naturally, you could measure falling edges or both rising and falling - it really depends on what you want to do.

Import program

00001 #include "mbed.h"
00002 #include "dispBoB.h"
00003 
00004 dispBoB db(p28, p27, p26);          //instantiate a dispBoB object
00005 InterruptIn trigger(p12);           //set up the trigger as an external interrupt
00006 Timer t;
00007 
00008 bool b = false;
00009 
00010 void trig(){                        //function to call upon interrupt
00011     db.locate(0);
00012     db.printf("%06d", t.read_ms()); //print current time reading 
00013     if(b == false){
00014         t.start();                  //start timer
00015         b = true;
00016     } else {
00017         t.stop();                   //stop timer
00018         db.printf("06d", t.read_ms());  //print out stopwatch time in milliseconds
00019         t.reset();                  //reset and restart timer
00020         t.start();
00021     }
00022 }
00023 
00024 int main() {
00025     trigger.mode(PullUp);           //activate internal pull up (hardware specific)
00026     db.init();                      //ALWAYS initialise the dispBoB 
00027     db.cls();                       
00028     trigger.rise(&trig);            //attach trig() to interrupt on rising edge of trigger
00029 
00030     db.printf("%06d", t.read_ms()); //print initial time reading (000000)
00031     
00032     //To change the timebase just replace the read_ms() function with
00033     //read() for seconds and read_us() for microseconds. These use a 32bit 
00034     //int microsecond counter, so have a max time of ~30mins
00035 }

All I'm doing is setting up an interrupt, which stops the timer, reads and prints out the time delay and then restarts the stopwatch every time the 'trigger' is cut (i.e. a rising edge is experienced on pin 12).

(b) - pulse width measurement

Pretty much the same as above, but instead of measuring between rising edges, I'm measuring between a rising edge and a falling edge.

Import program

00001 #include "mbed.h"
00002 #include "dispBoB.h"
00003 
00004 dispBoB db(p28, p27, p26);          //instantiate a dispBoB object
00005 InterruptIn trigger(p12);           //set up the trigger as an external interrupt
00006 Timer t;
00007 
00008 void up(){                          //call this on rising edge
00009     t.start();                      //start timer
00010 }
00011 
00012 void down(){                        //call this upon falling edge
00013     t.stop();                       //stop timer
00014     db.locate(0);
00015     db.printf("%06d", t.read_ms()); //print counter info to dispBoB 
00016     t.reset();                      //reset timer
00017 }
00018 
00019 int main() {
00020     trigger.mode(PullUp);           //activate internal pull up (hardware specific)
00021     db.init();                      //ALWAYS initialise dispBoB
00022     db.cls();                      
00023     trigger.rise(&up);              //attach up() to interrupt on rising edge of trigger
00024     trigger.fall(&down);            //attach down() to interrupt on falling edge of trigger
00025     db.printf("%06d", t.read_ms()); //display an initial count "000000"
00026     
00027     //To change the timebase just replace the read_ms() function with
00028     //read() for seconds and read_us() for microseconds. These use a 32bit 
00029     //int microsecond counter, so have a max time of ~30mins
00030 }

(c) - display MAC address

Scroll the mbed MAC address across the screen - a nice little demo, which I've wanted to do for aaages!

Import program

00001 #include "mbed.h"
00002 #include "dispBoB.h"
00003 #include "stdio.h"
00004 
00005 dispBoB db(p28, p27, p26);                  //object instantiation
00006 extern "C" int mbed_mac_address(char *);
00007 
00008 int main() {
00009     uint64_t uid = 0;
00010     char mac[6];
00011     mbed_mac_address(mac);                  //this copies the MAC address into the 
00012     uid = mac[0] << 40 | mac[1] << 32 |     //variable 'uid'
00013           mac[2] << 24 | mac[3] << 16 |
00014           mac[4] << 8  | mac[5] << 0;   
00015     char MACAddressBuffer[9];
00016     sprintf(MACAddressBuffer, "%x", uid);   //convert type uint64_t --> char* (format hex)
00017     db.scroll(MACAddressBuffer, 0.2);       //scroll foramtted MAC address across dispBoB
00018 }