Recent changes
Slingshot user guide
tag Guide, user
NFCLamp user guide
tag Guide, user
Homepage
MPL115A2
Compiler Error 42
From the mbed microcontroller Cookbook.  

Websocket and Mbed

As explained in this webpage, the WebSocket protocol allows full-duplex, bi-directional communications between a server and clients.

The websocket server

In this tutorial, we will be using a public server provided by mbed for testing purposes.

So you just have to program your mbed!

If you want more information regarding the server side code, see Websockets Server

This tutorial is divided into three parts:

You may wish to skip to the relevant section after you have chosen whether you are using WiFi or Ethernet

1 - Set up

1.1 - Protocol used by the server

The url format to establish a connection with the server is: ws://sockets.mbed.org/ws/<channel>/<mode> (Don't try and go here, it will not work)

The WebSockets are divided into channels.

There are 3 connection modes:

When the server receives a message from a client in a certain channel who is not in 'ro' mode:

1.2 - Javascript part

This code is very similar to the one presented in second part of this tutorial.

Take note!

You can skip this section if you don't want to write yourself the javascript code.

We present this code for you to modify as you wish, but if you want to just go to the webpage of your own channel:

For instance, to view all messages on the 'samux' channel, visit:
http://sockets.mbed.org/samux/viewer.

If you adapt the last part of the previous url, you can see the activity on your own channel ;)

Code

<!doctype html>
<html>

  <head>
    <style type="text/css">
      body {
        text-align: center;
        min-width: 500px;
      }
    </style>
    <script src="http://code.jquery.com/jquery.min.js"></script>
    <script>
    function log(m) {
		d = document.getElementById("log");
        d.innerHTML = m + "<br/>" + d.innerHTML;
    }

    $(document).ready(function () {
	  
	$("#open").click(function(evt) {
        evt.preventDefault();

        var channel = $("#channel").val();
        var ws = new WebSocket("ws://sockets.mbed.org/ws/" + $("#channel").val() + "/rw");

        ws.onopen = function(evt) { 
			$("#channel").css("background", "#00ff00"); 
			document.getElementById("title").innerHTML = "Websockets streaming on channel: " + $("#channel").val();
		};
        ws.onmessage = function(evt) { log("message: " + evt.data); };
        ws.onclose = function(evt) { log("socket closed"); };
        });

    });

    </script>
  </head>

  <body>
    <h1 id="title">Websockets Streaming</h1>
    <label for="channel">channel:</label>
    <input type="text" id="channel" style="background:#ff0000;"/><br />
    <input type="submit" id="open" value="open" />
    <div id="log"></div>



  </body>
</html>

On this webpage, you must associate your connection with a 'channel'. In this example, I will use the channel samux, but I could use anything. So I fill in the channel field and press open
If the connection is established:

Part 2 - Sending data from the Mbed: Wifi

Materials required

For this part you need:

  • an mbed ;)
  • a Wifly module like this
  • a router

2.1 - Schematics



Schematics

Schematics

2.2 - Code

Libraries required

For this part you need to import these libraries:


You may wish to skim the page on the WiFly module.

The main code:

Code

#include "mbed.h"
#include "Wifly.h"
#include "Websocket.h"

DigitalOut l1(LED1);

//Here, we create an instance, with pins 9 and 10 connecting to the
//WiFly's TX and RX pins, and pin 21 to RESET. We are connecting to the
//"mbed" network, password "password", and we are using WPA.
Wifly wifly(p9, p10, p21, "mbed", "password", true);

//Here, we create a Websocket instance in 'rw' (read-write) mode
//on the 'samux' channel
Websocket ws("ws://sockets.mbed.org/ws/samux/rw", &wifly);


int main() {
    char recv[40];

    while (1) {

        //we connect the network
        while (!wifly.join()) {
            wifly.reset();
        }

        //we connect to the websocket server
        while (!ws.connect());

        while (1) {
            wait(0.5);

            //Send Hello world
            ws.send("Hello World! over Wifi");

            // if a message is available, print it
            if (ws.read(recv)) {
                // show that we receive messages
                l1 = !l1;
            }
        }
    }
}

» Import this programwebsockets_hello_world_wifi

Websocket Hello World over a wifi network


This code is very simple:

ssid, key, mode, channel

Don't forget to adapt:

  • the ssid and the key of your network in the Wifly constructor
  • the mode and the channel of your choice in the WebSocket constructor


2.3 - You should be ready!

Information

You can join the server, create your own channel, send and view messages over your channel just by visiting:

http://sockets.mbed.org


2.4 - Demo

If you are using the javascript code presented at the beginning of this document, you should be able to see the messages on your channel
demo

You can also check that all is working by visiting the webpage of your own channel: http://sockets.mbed.org/your_own_channel/viewer
For instance: http://sockets.mbed.org/samux/viewer

demo

On the mbed side, you can see all messages received (only with the mbed LPC1768):

/media/uploads/samux/hello_world_wifly.png

Et Voilà! We are able to send data on our webpage over a wifi network!

Part 3 - Sending Hello World from the Mbed: Ethernet

Materials required

For this part you need:

3.2 - Code

Library required

For this part you need to import these libraries:

The main code:

Code

#include "mbed.h"
#include "Websocket.h"

Serial pc(USBTX, USBRX);
Timer tmr;

//Here, we create a Websocket instance in 'rw' (write) mode
//on the 'samux' channel
Websocket ws("ws://sockets.mbed.org/ws/samux/rw");

int main() {
    char recv[128];
    while (1) {

        while (!ws.connect())
            pc.printf("cannot connect websocket, retrying\r\n");

        tmr.start();
        while (1) {
            if (tmr.read() > 0.5) {
                ws.send("Hello World! over Ethernet");
                if (ws.read(recv)) {
                    pc.printf("recv: %s\r\n", recv);
                }
                tmr.start();
            }
            Net::poll();
        }
    }
}

» Import this programwebsockets_hello_world_ethernet

Websocket Hello World over an ethernet network


This code is very simple:


Note that the WebSocket API is the same for using a WiFi module or an Ethernet connection

mode, channel

Don't forget to edit:

  • the mode and the channel of your choice in the WebSocket constructor


3.3 - You should be ready!

Information

You can join the server, create your own channel, send and view messages over your channel just by visiting:

http://sockets.mbed.org


3.4 - Demo

If you are using the javascript code presented above in this document, you should be able to see the messages on your channel
demo


You can also check that all is working by visiting the webpage of your own channel: http://sockets.mbed.org/your_own_channel/viewer
For instance: http://sockets.mbed.org/samux/viewer

demo

On the mbed side, you should see all messages received:

/media/uploads/samux/hello_world_eth.png

Et Voilà! We are able to see on our webpage Hello World over an Ethernet network!

Now, if you want, you can write your own webpage to process and display the data coming in on your channel whichever way you wish!

Conclusion

After this tutorial, you are able to send messages to every webpage connected to a websocket server. You can imagine sending data from sensors and print or display values received in the webpage. Sensors are now accessible all over the world. You can take a look to the Internet Of Things project where data are sent and displayed in real time using another HTML5 feature: canvas.




calendar Page history
Last modified 01 Feb 2012, by   user Samuel Mokrani   tag No tags | 11 comments  

11 comments on Websocket and Mbed:

16 Nov 2011

Hello, I must say this is absolutely nice piece of work which solve big problem with connecting to mbed which obtains IP from DHCP. This IP may vary and reachability is limited to reading this IP assigned to mbed from DHCP on terminal or display attached to mbed. But if mbed has no display and is not possible to check IP every time if mbed connected to LAN via cable or wirelessly this is what You will love.

And now comes my question. Because I can see there are 3 connection modes and one of them is named read and write, I would like to ask if there is any plan about adding ability to write data to mbed from internet browser. I think something easy like field to write text with button named "send to mbed" or simple button which will command mbed to send data or stop sending data.

I think websockets opens absolutely new world to every aplication used on mbed where is required any user interface. Because I wanted to add user interface to command mbed I was thinking about any software to write for PC side and use USB connection. But Websockets changes everything.

You can make own server with Tornado and then You have ability to command mbed not only from PC (USB connection limits to have mbed still connected) but from every device with ability to display web pages and it means not only PC but also tablets, smartphones, TVs...

And as I think it is easier to make web page on server then to create program for PC. So I see mbed with endless options at (not only) home automation with not only sensing data but with capability to be commanded and if I add plus like no need to know IP of mbed and beauty user interface...

I must say that this is AWESOME

17 Nov 2011

Hi little,

There is already a webpage which allows to send messages over a channel: http://sockets.mbed.org/[your_channel]/sender. If you connect an mbed on the same channel in rw or ro mode, it will receive all messages which are exchanged over the channel.

You can use a program like this to read messages:

Code

while (1) {
   if(ws.read(recv)) {
      pc.printf("%s\r\n", recv);
   }
   Net::poll();
}
17 Nov 2011

Thank You very much for example how to read data which are sent from web page. Btw as I see You are doing very much for comunity about USB devices and websockets which both I am very interested in so I thank You. This is what makes mbed very usable fo newbies like me.

I never have been in touch with c++ or microcontrollers but with examples and reading series about c++ I was able to proceed step by step further. Started with very minor changes to examples and now I am much far than in June when I started...

21 Dec 2011

I have followed the tutorial, and seem to have it mostly working. When I go to my channel http://sockets.mbed.org/<my_chan> I can see that there is a connection (from my mbed). My mbed is sending a little data at a 0.1s interval like your sample. But when I click the view link (i.e. http://sockets.mbed.org/<my_chan>/viewer), I get the following message:

Websocket viewer: connection not active!

Any ideas on how to debug this? Since the connection is recognized on the main page, it seems to be connected, but reading or writing (I am using "rw" mode on the mbed) does not work. Both pages give that error. Is it possible there is a problem on the server side?

Thanks! I am really excited to get this working.

21 Dec 2011

You may be encountering an issue relating to the recent final publication of the websocket standard - http://www.rfc-editor.org/rfc/rfc6455.txt. This final version included some changes which browsers like Chrome released a week ago or so, but the server has not yet been updated to reflect this. Hence, server and client are incompatible.

We are awaiting a release from the upstream server software developers (http://www.tornadoweb.org) and will try and get it live as soon as it's available.

23 Dec 2011

Hello,

I have a problem regarding on the connection establishment on the web server “http://sockets.mbed.org/sjchia844z” (my channel). I modified the program above, I can connect the wifly module to the Wireless Hotspot but cannot connect to the web server. I used the LED indicator on the mbed to find the problem of the program and found out that the program is stuck on the “while” loop of the connection of the server.

Code

#include "mbed.h"
#include "Wifly.h"
#include "Websocket.h"

int FinalWindTurbineValue = 0;
DigitalOut Light1(LED1);
DigitalOut Light2(LED2);


Serial pc(USBTX, USBRX);

//Here, we create an instance, with pins 9 and 10 connecting to the 
//WiFly's TX and RX pins, and pin 21 to RESET. We are connecting to the 
//network, password, and we are using WPA.
Wifly wifly(p9, p10, p21, "network", "password", true);

//Defining the AnalogIn pins that are connected to the Wind Turbine.
AnalogIn WindTurbine1 (p20);
BusOut    unused(p15,p16,p17,p18,p19); // Make unused analog pin to DigitalOut

//Here, we create a WebSocket instance in 'wo' (write-only) mode
//on the 'sjchia844z' channel
Websocket ws("ws://sockets.mbed.org/ws/sjchia844z/wo", &wifly);

int main() {
    char json_str[100];

    pc.printf("Activating the Wind Turbine Connection.\r\n");
    pc.printf("Starting the Wind Turbine test...\r\n");

    while (1) {
        while (1) {
            Light1 = 1;
            while (!wifly.join())  //we connect to the network
                wifly.reset();

            if (!ws.connected())
             { Light2 = 1; //we connect to the server
                wifly.reset();
             }
            else
             {
             break;}  
        }

        while (1) {
            wait(0.1);
    
             FinalWindTurbineValue = WindTurbine1 * 3.3;
             pc.printf("The Values are %d A.\r\n", FinalWindTurbineValue);
    
                //Here, we format the string we will be sending to the server
                //the format we are sending in is JSON
                sprintf(json_str, "The Values are %d .\r\n", FinalWindTurbineValue);
                ws.send(json_str);  //And we send the string
        }
    }
}

By the way, the state of channel “sjchia844z” has zero connection on the web server. Is there any problems on the program or do I need to configure the mbed web server to my needs?

Thanks

23 Dec 2011

Hello Chia,

You are using the connected() method instead of the connect() method to join the websocket server. The connected() method returns the state of the websocket connection but doesn't connect the server.

I tried this program and it works for me:

Code

#include "mbed.h"
#include "Wifly.h"
#include "Websocket.h"

int FinalWindTurbineValue = 0;
DigitalOut Light1(LED1);
DigitalOut Light2(LED2);


Serial pc(USBTX, USBRX);

//Here, we create an instance, with pins 9 and 10 connecting to the
//WiFly's TX and RX pins, and pin 21 to RESET. We are connecting to the
//network, password, and we are using WPA.
Wifly wifly(p9, p10, p21, "network", "password", true);

//Defining the AnalogIn pins that are connected to the Wind Turbine.
AnalogIn WindTurbine1 (p20);
BusOut    unused(p15,p16,p17,p18,p19); // Make unused analog pin to DigitalOut

//Here, we create a WebSocket instance in 'wo' (write-only) mode
//on the 'sjchia844z' channel
Websocket ws("ws://sockets.mbed.org/ws/sjchia844z/wo", &wifly);

int main() {
    char json_str[100];

    pc.printf("Activating the Wind Turbine Connection.\r\n");
    pc.printf("Starting the Wind Turbine test...\r\n");

    while (1) {
        Light1 = 1;
        while (!wifly.join())  //we connect to the network
            wifly.reset();

        while (!ws.connect()) {
            Light2 = 1; //we connect to the server
        }

        while (1) {
            wait(0.1);

            FinalWindTurbineValue = WindTurbine1 * 3.3;
            pc.printf("The Values are %d A.\r\n", FinalWindTurbineValue);

            //Here, we format the string we will be sending to the server
            //the format we are sending in is JSON
            sprintf(json_str, "The Values are %d .\r\n", FinalWindTurbineValue);
            ws.send(json_str);  //And we send the string
        }
    }
}

Hope that helps

Sam

05 Jan 2012

Hello again,

Is it possible to replace the websocket address to a localhost inside the mbed program for testing purposes as I would like to use AutoBahn websocket to connect the mbed to the localhost webserver I created.

By the way, Thanks for the solution, tried out and it worked! :) Also, I found out that websocket connection require a strong Wifi connection so that's why it could not work for weeks...

Many Thanks.

04 Apr 2012

Hello, i have a question. How to increase the buffer for incoming data? I send to mbed a large string and the mbed crashes, you use "char recv[40];" i increment recv to 512 and dont works well :( .

10 Apr 2012

user Diego io0set wrote:

Hello, i have a question. How to increase the buffer for incoming data? I send to mbed a large string and the mbed crashes, you use "char recv[40];" i increment recv to 512 and dont works well :( .

I solved, and I added REALLY RPC to websockets :)

3 weeks, 6 days ago

Hello. This is amazing application of the mbed. I am not completely clear what a "router" in the ethernet application means. Does'nt mbed have an onboard ethernet port? Why can't that be used to connect to the network directly? Awaiting your response. Thank you in advance.

Please login to post comments.