mbed Application Board Hands-On Demos

These examples for the application board were developed for the ARM University Program Faculty Workshop at ESWEEK 2013. They are based on selected code examples and I/O libraries posted earlier in the cookbook’s mbed application board page. Libraries used have also been updated to the most recent versions as of 9/22/13. While working through the demos, keep this web page open in one browser tab while the compiler is open in another browser tab so that it is possible to quickly switch back and forth between the two web pages. PowerPoint slides used prior to this material at the workshop to introduce mbed to faculty are also available.

Hands-On Demo 1- Blink LED

This first demo just blinks an LED on the mbed module and the application board is not required. It is the default project code for a new project in the online cloud compiler. A new user account must be setup to use the cloud compiler and the mbed module must be plugged in first to setup a new account. The mbed module appears as a USB flash drive, open the flash drive, and click on the file“mbed.htm” and follow the instructions to signup for a new account. Logon, click on the compiler link (upper right) and select new when the compiler appears. Select a name for your new program and click "OK". The project files are all stored on a cloud server. You must always logon first to use the compiler. Click “compile” and save the compiled bin file to the mbed flash drive. Hit the reset button on the mbed module, to run the most recently downloaded code. Click on “main.cpp” to view the C++ code in the compiler window. In the code, note the use of the mbed DigitalOut() and wait() APIs.

/media/uploads/4180_1/2013-09-22_0002.jpg
The default blink LED project

/media/uploads/4180_1/ccblinkled.png
Blink LED code viewed in cloud compiler

app-board-blink_led_lpc1768.bin - has the compiled code. Save it on the mbed flash drive, hit the mbed reset button and the LED should blink.

Hands-On Demo 2 – Bubble Level

For the second demo, the mbed must first be carefully plugged into the mbed application board. Note the correct orientation in the photo below. There are also small “GND” and “VOUT” silkscreen labels on the board and mbed module that should line up (near USB cable on left in image below). There should be an extra row of black socket pins on both sides of the mbed module. The second demo uses the board’s three axis accelerometer and the LCD display working in graphics mode to build an electronic version of a bubble level. Clicking on the “import program” link below copies all of the project files into the cloud compiler and sets up a new project. The project can then be compiled and downloaded to the mbed module. As the board is tilted, the X and Y G forces are used move the small black bubble on the display. The LCD graphics library has a handy member function to draw circles and the library code for the accelerometer returns G force readings, so the code is relatively short.

//Uses x & y acceleration to simulate a bubble level
//on the application board LCD display
#include "mbed.h"
#include "MMA7660.h"
#include "C12832_lcd.h"

C12832_LCD lcd; //On board LCD display
MMA7660 MMA(p28, p27); //I2C Accelerometer
DigitalOut connectionLed(LED1);//Accel OK LED

int main()
{
    int x=0,y=0;
    lcd.cls(); //clear LCD screen
    if (MMA.testConnection())
        connectionLed = 1; //Accelerometer init OK
    while(1) {
        //read X,Y +/-Gs and scale for #display pixels
        x = (x + MMA.x() * 32.0)/2.0;
        y = (y -(MMA.y() * 16.0))/2.0;
        lcd.fillcircle(x+63, y+15, 3, 1); //draw bubble
        lcd.circle(63, 15, 8, 1);
        wait(.1); //time delay
        lcd.fillcircle(x+63, y+15, 3, 0); //erase bubble
    }

}



Import programapp-board-Bubble-Level

This demo uses the application board’s three axis accelerometer and the LCD display working in graphics mode to build an electronic version of a bubble level.


app-board-bubble-level_lpc1768.bin - has the compiled code. Save it on the mbed flash drive and hit reset.


/media/uploads/4180_1/2013-09-22_0004.jpg
A bubble level display using accelerometer data. Tilting the board moves the solid black bubble.

Hands-On Demo 3 – Temperature Alarm

The third demo uses the board’s I2C temperature sensor to measure the board’s temperature. After a few minutes of operation, the board is typically around 5C above room temperature. The temperature is displayed on the LCD using text mode with printfs. Pot 1 (blue dial near LCD) is used to adjust a temperature alarm setting (also shown on LCD). When the board temperature is below the alarm setting, the RGB LED is green and when it is above the RGB LED changes to RED and the speaker outputs a tone. The RGB LED and speaker are attached using hardware PWM outputs and setup using the mbed PwmOut API . The pot voltage is read in and scaled between 0.0 and 1.0 by the mbed AnalogIn API.

#include "mbed.h"
#include "LM75B.h"
#include "C12832_lcd.h"

C12832_LCD lcd; //Graphics LCD
LM75B tmp(p28,p27); //I2C Temperature Sensor
PwmOut r(p23); //RGB LED with 3 PWM outputs for dimmer control
PwmOut g(p24);
PwmOut b(p25);
PwmOut speaker(p26); //Speaker with PWM driver
AnalogIn pot1(p19); //Reads Pot 1 - near LCD
AnalogIn pot2(p20); //Reads Pot 2 - near RGB LED
Serial pc(USBTX,USBRX); //used for printf to PC over USB

int main ()
{
    float board_temp;
    float alarm_temp = 0.0;
    // generate a 800Hz tone using PWM hardware output
    speaker.period(1.0/800.0); // 800hz period
    r=1.0; //RGB LED off - PWM 100% duty cycle
    g=1.0;
    b=1.0;

    while (1) {
        lcd.cls();
        lcd.locate(0,0); //clears LCD
        board_temp = tmp; //read temperature
        lcd.printf("Board Temperature = %.2f\n\r",board_temp);
        alarm_temp = 50.0 * pot1; //read alarm temp
        lcd.printf("Temp Alarm Setting = %.2f\n\r",alarm_temp);
        if(board_temp > alarm_temp) { //check temp for alarm
            r = 1.0 - pot2; //RGB LED red
            g = 1.0;
            speaker = 0.5; //alarm tone using PWM
        } else {
            g = 1.0 - pot2; //RGB LED green
            r = 1.0;
            speaker = 0.0;
        }
        wait(1.0);
        pc.printf("%.2f\n\r",board_temp); //send temp to PC
    }
}



Import programapp-board-TempAlarm

This demo uses the application board’s I2C temperature sensor to measure the board’s temperature. Pot 1 (blue dial near LCD) is used to adjust a temperature alarm setting. Alarm uses speaker and RGB LED.


app-board-tempalarm_lpc1768.bin - has the compiled code. Save it on the mbed flash drive and hit reset.

/media/uploads/4180_1/2013-09-22_0006.jpg
A temperature display and alarm that also sends data to the PC using printf()

Sending data to the PC in Demo 3

This demo also sends the temperature reading to the PC using a USB virtual comm port at 9600 baud. Windows users will first need to install the mbed virtual comm port driver (with the mbed module attached). A terminal application also needs to be downloaded and installed such as TeraTerm. After installing the driver and starting the mbed program, start TeraTerm, click the serial port and select the COMx port showing “mbed” in the name and click "OK"as seen below. The number of the mbed COM port will vary from PC to PC.

/media/uploads/4180_1/teratermselect.png
Connecting a PC terminal application to mbed's USB virtual com port

/media/uploads/4180_1/teratermrunning.png
Data on a PC from mbed program's printf()s via the USB virtual com port

Macs and Linux users can use the built-in terminal and connect at 9600 baud to the mbed device. When the mbed is connected, on Macs the new mbed USB serial device name (need the number at end) can be found using the command "ls /dev/tty.usbmodem*". In Linux, use the command "ls /dev/ttyACM*". Note the mbed device name with the number included that should appear. Start a terminal application and use the command "screen yourmbeddevicename". When properly connected, you should see temperature outputs in the terminal application window from the “pc.printf()” statement in the code as shown in the image above. In case of problems, more details can be found in the handbook's serial communication web pages. During serial data transfers, the blue power/status LED in the center of the mbed module will flicker to indicate activity.

File System Drivers

Data logging could be added to the thermostat with just a few additional lines of code. File system drivers are available for an external SD card, USB flash drives, and the mbed module’s 2M flash. More details can be found in the mbed handbook under File System. The Application Board Waveplayer Demo reads a *.wav audio file from a USB flash drive and plays it on a speaker.

Hands-On Demo 4 – RTOS and Threads

This demo uses the mbed RTOS to run eight threads (including main). The threads are using different I/O devices. Several of the threads output to the LCD and an OS mutex lock is used to control access to the LCD and make the LCD thread safe. Additional details are available in the handbook's mbed RTOS web pages.

ThreadFunction
1Counts up every second and outputs count to LCD
2Counts up every half second and outputs count to LCD
3Displays a sine wave on LCD, speed controlled by Pot 1
4Reads Pot 2 and value is used to set LCD contrast
5Displays a random color on RGB LED
6Outputs two tone alarm sound to speaker
7Joystick controls mbed module LEDs
8 (main)Starts other threads and outputs contrast setting to LCD



// example to test the mbed Lab Board lcd lib with the mbed rtos
// Pot1 changes the contrast
// Pot2 changes the speed of the sin wave

#include "mbed.h"
#include "rtos.h"
#include "Small_6.h"
#include "Small_7.h"
#include "Arial_9.h"
#include "stdio.h"
#include "C12832_lcd.h"


C12832_LCD LCD;
AnalogIn Pot1(p19);
AnalogIn Pot2(p20);
PwmOut Speaker(p26);
PwmOut RGBLED_r(p23);
PwmOut RGBLED_g(p24);
PwmOut RGBLED_b(p25);
DigitalIn joyfire(p14);
BusIn joy(p15,p12,p13,p16);
BusOut leds(LED1,LED2,LED3,LED4);

// mutex to make the lcd lib thread safe
Mutex lcd_mutex;

// Thread 1
// print counter into first line and wait for 1 s
void thread1(void const *args)
{
    int i;
    while(true) {       // thread loop
        lcd_mutex.lock();
        LCD.locate(0,0);
        LCD.set_font((unsigned char*) Small_6);
        LCD.printf("Thread1 count: %d",i);
        lcd_mutex.unlock();
        i++;
        Thread::wait(1000);
    }
}

// Thread 2
// print counter into third line and wait for 0,5s
void thread2(void const *args)
{
    int k;
    while(true) {       // thread loop
        lcd_mutex.lock();
        LCD.locate(0,20);
        LCD.set_font((unsigned char*) Arial_9);
        LCD.printf("Thread 2 count : %d",k);
        lcd_mutex.unlock();
        k++;
        Thread::wait(500); // wait 0.5s
    }
}

// Thread 3
// print a sine function in a small window
// the value of pot 1 changes the speed of the sine wave
void thread3(void const *args)
{
    int i,k,v;
    double s,a;
    k = 1;
    lcd_mutex.lock();
    LCD.rect(89,0,127,17,1);
    lcd_mutex.unlock();
    while(true) {       // thread loop
        v = Pot1.read_u16();  // get value of pot 1
        lcd_mutex.lock();
        for (i=90; i<127; i++) {
            s = 8 * sin((long double)(i+k) /5);   // pixel to print
            a = 8 * sin((long double)(i+k-1) /5); // old pixel to erase
            LCD.pixel(i,9 + (int)a ,0);           // erase pixel
            LCD.pixel(i,9 + (int)s ,1);           // print pixel
        }
        LCD.copy_to_lcd();  // LCD.pixel does not update the lcd
        lcd_mutex.unlock();
        k++;
        Thread::wait(v/100);   // value of pot1 / 100
    }
}

// Thread 4
// input pot 2 and change the contrast of LCD
void thread4(void const *args)
{
    int k;
    while(true) {         // thread loop
        k = Pot2.read_u16();  // get the value of poti 2
        k = k >> 10;          // need only 6 bits for contrast
        lcd_mutex.lock();
        LCD.set_contrast(k);
        lcd_mutex.unlock();
        Thread::wait(500);    // wait 0.5s
    }
}
// Thread 5
// RGB LED
void thread5(void const *args)
{
    while(true) {         // thread loop
        RGBLED_r = 0.5 + (rand() % 11)/20.0;
        RGBLED_g = 0.5 + (rand() % 11)/20.0;
        RGBLED_b = 0.5 + (rand() % 11)/20.0;
        Thread::wait(1667);    // wait 1.5s
    }
}
// Thread 6
// Speaker
void thread6(void const *args)
{
    while(true) {         // thread loop
        Speaker.period(1.0/800.0);
        Speaker = 0.01;
        Thread::wait(1000);    // wait 1.0s
        Speaker.period(1.0/969.0);
        Speaker = 0.01;
        Thread::wait(1000);    // wait 1.0s
    }
}

// Thread 7
// Joystick controls onboard mbed LEDs
void thread7(void const *args)
{
    while(true) {         // thread loop
        if (joyfire) {
            leds = 0xf;
        } else {
            leds = joy;
        }
        Thread::wait(200);    // wait 0.25s
    }
}



int main()
{
    int j;
    LCD.cls();

    Thread t1(thread1); //start thread1
    Thread t2(thread2); //start thread2
    Thread t3(thread3); //start thread3
    Thread t4(thread4); //start thread4
    Thread t5(thread5); //start thread5
    Thread t6(thread6); //start thread6
    Thread t7(thread7); //start thread7

    while(true) {       // main is the next thread
        lcd_mutex.lock();
        LCD.locate(0,9);
        LCD.set_font((unsigned char*) Small_7);
        j = LCD.get_contrast();    // read the actual contrast
        LCD.printf("contrast : %d",j);
        lcd_mutex.unlock();
        Thread::wait(500);   // wait 0.5s
    }
}



Import programapp-board-RTOS-Threads

This demo uses the mbed RTOS to run eight threads (including main). The threads are using different I/O devices on the application board. Several of the threads output to the LCD and an OS mutex lock is used to control access to the LCD and make the LCD thread safe.



app-board-rtos-threads_lpc1768.bin - has the compiled code. Save it on the mbed flash drive and hit reset.



/media/uploads/4180_1/2013-09-22_0010.jpg
RTOS running eight threads with a mutex lock on the LCD display

Internet of Things

Instructor Demo – Internet Clock

This demo uses the TCP/IP networking stack and RTOS, to obtain the current time from an NTP server via the Internet and automatically set the mbed real-time clock. After setting the clock, the current time is displayed every second on the LCD. A network cable is required attached to a network with DHCP service enabled for the mbed module. Some networks may have security settings that require the mbed MAC address to be setup in the DHCP server. Another approach of setting up a "network bridge” can be used on any laptop that has an active Wi-Fi connection and an Ethernet jack to attach mbed to the Internet.

/media/uploads/4180_1/2013-09-22_0012.jpg
A clock automatically set to the correct time via the Internet

#include "mbed.h"
#include "EthernetInterface.h"
#include "NTPClient.h"
#include "C12832_lcd.h"

C12832_LCD lcd; //Graphics LCD
EthernetInterface eth; //Networking functions
NTPClient ntp; //NTP client

int main()
{
    eth.init(); //Init and use DHCP
    wait(2);
    lcd.cls();
    lcd.printf("Getting IP Address\r\n");
    if(eth.connect(60000)!=0) {
        lcd.printf("DHCP error - No IP");
        wait(10);
    } else {
        lcd.printf("IP is %s\n", eth.getIPAddress());
        wait(2);
    }
    lcd.cls();
    lcd.printf("Trying to update time...\r\n");
    if (ntp.setTime("0.pool.ntp.org") == 0) {
        lcd.printf("Set time successfully\r\n");
        while(1) { //update time display every second
            lcd.cls();
            lcd.locate(0,0);
            time_t ctTime;
            ctTime = time(NULL);
            lcd.printf("%s\r\n", ctime(&ctTime));
            lcd.printf("Current Time (UTC)");
            wait(1);
        }
    } else {
        lcd.printf("NTP Error\r\n");
    }
    eth.disconnect();
}




Import programapp_board-NTPclock

Clock display on app board LCD is set using an NTP network time server. DHCP service must be enabled for mbed to get an IP address. A network cable is needed.



app_board_ntpclock_lpc1768.bin - has the compiled code. Save it on the mbed flash drive and hit reset.

Instructor Demo - Websockets for Sensor Data

This example streams acceleration and temperature data from the application board to a websocket server using HTML5. Visit app-board viewer to see a real time feed when the program is running. If data does not appear, a web page reload may be needed. Various IOT cookbook pages have additional information, tutorials, and videos.

/media/uploads/4180_1/appboardwebsockets.png
Real time sensor feed from mbed to a websocket server displayed on a web page

#include "mbed.h"
#include "EthernetInterface.h"
#include "Websocket.h"
#include "MMA7660.h"
#include "LM75B.h"

MMA7660 acc(p28, p27);// accelerometer
LM75B tmp(p28,p27);// temperature sensor
DigitalOut l1(LED1);
 
int main() {
    char json_str[100];   
    if (acc.testConnection())
        l1 = 1;
    EthernetInterface eth;
    eth.init(); //Use DHCP
    wait(2);
    eth.connect(60000);
    printf("IP Address is %s\n\r", eth.getIPAddress());    
    // See the output on http://sockets.mbed.org/app-board/viewer
    Websocket ws("ws://sockets.mbed.org:443/ws/app-board/wo");
    ws.connect();
    while (1) {
        // create json string with acc/tmp data
        sprintf(json_str, "{\"id\":\"app_board_eth_EW2013\",\"ax\":%d,\"ay\":%d,\"az\":%d, \"tmp\":%d}", (int)(acc.x()*360), (int)(acc.y()*360), (int)(acc.z()*360), (int)tmp.read());       
        // send str
        ws.send(json_str);      
        wait(0.1);
    }
}



Import programapp-board-Ethernet-Websocket

Websocket demo for app board by C. Styles with updated libraries. DHCP service and a network cable is required.



app-board-ethernet-websocket_lpc1768.bin - has the compiled code. Save it on the mbed flash drive and hit reset.


Websocket demo displaying live sensor data on a webpage



Instructor Demo – Offline Compiler and Breakpoints

This demo uses the ARM/Keil tools uVision (offline) compiler to show debugging with hardware breakpoints via the USB cable. It is first necessary to download and install the compiler locally on the PC. The free demo version download for Windows is limited to 32K code size, but the demo version becomes the full version with a license file or when connected to a Flex license server on the network. A firmware upgrade to the mbed module and a new USB serial driver are also required. Mixed C++ and ARM assembly language debugging is supported as well as full I/O pin level hardware emulation. An existing mbed cloud compiler project can be exported in a zip file to the offline compiler for initial setup, whenever hardware debugging using the offline compiler is required.

/media/uploads/4180_1/hardwaredebug.png
Hardware breakpoints via the mbed USB cable in the ARM/Keil tools uVision offline compiler

Video of an early test of the new breakpoint feature in the offline compiler

For more information about using mbed in a school lab see the how to set up an mbed lab checklist.


Report

2 comments on mbed Application Board Hands-On Demos:

12 Oct 2013

Have just tried 2 of the above demos - Internet Clock and Websockets for Sensor Data, they both worked first time and I'm very impressed!

26 Oct 2013

I tried the Internet Clock. Worked from the first time - with the bridge connection. This is very impressive indeed. Also the other programs on the YouTube channel of "TheGBurdell" is pretty amazing.

Please login to post comments.