Your very own IoT: Let's talk WiFi - Embedded.com

Your very own IoT: Let’s talk WiFi

Welcome back! In today’s post, we will talk about WiFi—a few general concepts about it, its relationship to the CC3200, some practical ways to use it, and lastly, a little step-by-step project.

WiFi (a.k.a wireless LAN) is a way to connect multiple clients in a wireless network. It is so common nowadays that we hardly even think about it anymore unless we are away from home and must go into “hunting” mode to find it wherever we can. Even though we take WiFi for granted, the internals of it are quite interesting and complicated. The set of protocols to describe the MAC (or media access control) and physical layers of this communication is specified by the IEEE 802.11 standard, which was first introduced in 1997 and has seen a magnificent amount of improvement since then. The standard covers multiple variations (and some that even account for future applications), but I will focus on the most relevant ones today. In consumer networking products, you will encounter these four common varieties of the IEEE 802.11 standard:

  • 801.11b: This operates in the microwave 2.4GHz frequency range and allows throughput of 11 Mbit/s.
  • 802.11g: This operates in same range (2.4GHz) and allows a rate of 54 Mbit/s.
  • 802.11n: This introduces MIMO (multiple input, multiple output) antenna technology and operates mainly in same 2.4GHz range but adds optional support for the 5GHz frequency range. This version supports data rates up to 600 Mbit/s.
  • 802.11ac: This improved version of 802.11n supports wider channels in the 5GHz range and adds a more advanced MIMO variation, allowing the increased maximal throughput of 1.3 Gbit/s.

As you have probably noticed, wireless operates on two main frequencies: 2.4GHz and 5GHz. The first one is mainly used because it does not require FCC licensing. The primary reason for the licensing waiver is that microwave ovens operate on this frequency. Early microwaves used to produce too much noise around 2.4GHz and because of this, the frequency band was considered useless for communications. Ironically, it is now one of the main household communication frequency bands, and is also used for Bluetooth, RF remote controls, etc.

The second one, 5GHz, is a fairly recent addition to common household devices. It brings interesting advantages including wider channels, less noise, higher throughput, and (since less effort is needed to get a good SNR) longer battery life, but it also comes at a price of reduced range and poor wall penetration because of its shorter wavelength.  

Now that we all understand the concepts, let’s get back to our development board.

In general, nearly all of the small MCU-class WiFi-enabled boards out there today are 2.4GHz, 802.11b/g/n variety only. There are early signs of 5GHz-enabled system-on-chips appearing, but these SoCs are still very expensive and very, very rare. Our CC3200 Launchpad is no exception; it only supports 2.4GHz networks, so if your router is set to exclusively operate in the 5GHz range (for whatever reason), you will not be able to connect. Keep that in mind.

When it comes to WiFi, the CC3200 board can operate in several different ways:

  1. It can connect to an existing WiFi network as any normal device would do. (This is the simplest way to get started.)
  2. It can connect to an existing WiFi network, but then go into low power mode and implement a communication scheme called beacon skipping* where the device sleeps and only rarely responds to access point packets, thus conserving precious energy.
  3. It can work in AP mode making it an access point. This is very useful especially for initial setup if you want to provide your device with local WiFi credentials. The idea is to connect to the device’s own network and provide the local WiFi name and password so the device can then drop the AP mode and switch to acting as a client.
  4. It can work in WiFi direct mode—a mode meant for peer-to-peer communication between WiFi devices that support this mode.

*Somehow in my mind it becomes “bacon skipping” and the thoughts drift away…

A few words about security: WiFi, like any wireless communication, holds a vast potential for security risks. This was understood very early into the adoption of wireless technology, and a few standard solutions arose. The first (and weakest) is WEP encryption with a pre-shared key, and it gives some very basic security that is rarely used nowadays. WPA and WPA2 with technology-standard TKIP or AES encryptions are the standard choices. Stronger, enterprise level solutions exist but are rarely used—even by enterprises.

Now, after this introduction, let us talk about applications. Together, we will make an application that posts sensor information to an internet site that aggregates the information and plots it as pretty graphs. The solution will work in three distinct phases:

  1. Provisioning phase: The board will function as an access point and a web server. The user will be able to connect to the access point, open the web browser, and see a web page where he needs to provide network and web credentials for a household access point and the data aggregation site.
  2. Setup phase: The board will terminate the web server, connect to the data aggregation website, and set up the plots.
  3. Sensor Machine phase: The board will run in periodic cycles, reading sensor data and posting it to the web

Next page >

This project is a little big to fit into one post, so today we will work on the first part.

I will make all the sources available on GitHub.

The library we will be using most heavily today is called . (Notice the capital W and capital F). It brings many of the low level functions we will be using together with an exported object walled WiFi. However, there is one little bug in the library itself that prevents me from using it as-is, so I have added a fix to my local version and I suggest you do the same. The bug is about a variable inside the library called “role”; it is not being updated properly and causes the board to get stuck in AP mode without the ability to switch back to normal client mode. I have tried to limit my intervention in the library as much as possible, so the impact is minimal.

My local updated version of WiFi.cpp is also available on the GitHub. To use it, put it into your “/Applications/Energia.app/Contents/Resources/Java/hardware/cc3200/libraries/WiFi/ ”  folder.

To start an AP mode, we will use a function called “beginNetwork() ” that can be called with an SSID and password or just with an SSID. Since it is the first stage, we want the network to be open and to give the user unrestricted access for setup purposes. Theoretically, we should be able to do WiFi.beginNetwork(“CC3200Logger”) ,
but from my experiments, it seems there is another little bug; the network it comes up as password-protected, but the problem is that  I don’t know the password because I didn’t create one. I came up with a simple solution. Before calling beginNetwork(), I explicitly specify that this is an open (unprotected) network:

 unsigned char  val = SL_SEC_TYPE_OPEN;
 sl_WlanSet(SL_WLAN_CFG_AP_ID, WLAN_AP_OPT_SECURITY_TYPE, 1, (unsigned char *)&val);

This seems to solve this problem, and the access point now lets you connect without a password.

The next step is to enable the server on port 80, and since the class to do this is called WiFiServer, we will declare it as:

 WiFiServer server(80);
 server.begin();
To put it into action inside the loop (as it needs to accept connections):

   WiFiClient client = server.available();

Now our solution is ready for the next step—we need to be able to present some sort of “enter user/password” web page and later parse the response and act accordingly.

The little page I made for our needs right now is:

CC3200 logger for embedded.com blog

 

Welcome to cc3200 web logger


 

Please enter network credentials:


 


   SSID:

   

   Password:

   


   
   
 


Notice the hidden “e” element; it is there just to simplify the parsing of the response.

To serve the page, I used part of the routine from the “Examples->WiFi->WiFiWebServer” sketch, which keeps me from reinventing the wheel.  

Two last things I want to focus on today are a) parsing the input from a web browser (the filled-out form) and b) switching to WiFi client mode from AP mode.

Parsing the input can be tricky with the limited resources we have, particularly reading and reviewing large portions of data. Instead, I chose to go with simple state machine, parsing input byte after byte.

Most of the stuff the web browser sends us is “not interesting.” I call this state “SEEN_NOTHING” and the machine remains in it until it sees the beginning of what might be interesting information. It then traces the “interesting” string until it finds a complete token. If at any stage there is a mismatch, the machine discards the state and goes back to “SEEN_NOTHING”.

The idea is demonstrated in this schematic:

The SSID and password are stored in the data structure called “credentials”. We will use this structure later on to store and retrieve the credentials from Launchpad’s flash memory.

Now that we (hopefully!) have all the information needed to connect to the home WiFi network, the procedure to do so is first to disconnect the current client with client.stop();.
Then, just for good measure, I call WiFi.disconnect(); (This might be redundant, so tell me about your results.)

Now comes a bit of magic—calling low level functions to switch the mode to client instead of AP and stop the networking.

sl_WlanSetMode(ROLE_STA);
sl_Stop(0xff);

followed by restart of the networking and the usual call to connect to the network as a client.

sl_Start(NULL,NULL,NULL);
WiFi.begin(credentials.ssid, credentials.pass);

This will be all for this post, and you are welcome to look at the source and leave your comments. Next time we will cover sensors acquisition, and if time permits,  posting the results to the web.

Stay tuned!

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.