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.

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.
|
|
The following ASCII encoded characters are supported:
0123456789
ABCDEFGHIJKLMNOPQRSTUVWXYZ
abcdefghijklmnopqrstuvwxyz
! ' ( ) { } [ ] - _ .
, is not supported
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 }
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.
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.
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.

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.
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 }
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
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 }

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

What you DON'T need

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.

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.
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 $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.
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!
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.
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!
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.
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).
Pretty much the same as above, but instead of measuring between rising edges, I'm measuring between a rising edge and a falling edge.
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 }
Scroll the mbed MAC address across the screen - a nice little demo, which I've wanted to do for aaages!
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 }
No tags
|
1 reply
Please login to post comments.
Great stuff Daniel...
Couple of suggestions which would make it easier for people like me to use this for displaying arbitrary data:
1. Make the PHP script accept an argument via POST which sets the value to be displayed at the next poll by the mbed with something like displayvalue="hello world!"
2. Combined with the above, it would be great if the PHP script could support multiple displays, for example with a &displayid=1234 option. The displays would then poll the script for their own id.