Electric Imp and 150,000 other makers of great things meet at Maker Faire 2016

At Maker Faire this weekend, May 20-22, Electric Imp is demonstrating a number of projects utilizing the Electric Imp Developer Kit (Maker Faire special $20 at the event). All of the projects are feeding to a dweet.io dashboard, and all of the code used in the demos can be downloaded from Electric Imp’s Maker Faire 2016 GitHub repository.


Electric Imp will in the main Expo Hall Zone 2 near the Make Electronics stage. We look forward to seeing you there.


Here are link to instructables for each project we will be demo’ing at the event:

Internet of Cowbell

An Internet-connected cowbell which rings every time a button is pressed. It will also ring whenever someone tweets #morecowbell. The dweet.io dashboard keeps track of how many rings since the start of Maker Faire 2016.


This Internet-connected candy machine dispenses M&Ms at the press of a button or by tweeting #snackbot — the amount of candy you get is dependent on your number of twitter follows!. The dweet.io dashboard keeps track of how many followers have seen your SnackBot tweets.

Environmental Sensor Tail

Part of the Developer Kit, this clip-on tail includes temperature, air pressure, ambient light, and humidity sensors. We are showing part of an instructable to build your own environment monitoring station.


At Maker Faire we are using the clip-on RGB LED tail to demonstrate how our customers can manage commercial devices at scale with the impFactory. In particular, we will be highlighting the ability to deploy over-the-air updates to devices in the field. There are a number of instructables using the RGB LED tail as an ambient display, including Neo Weather and ISS Overhead.

Twitter Printer

We are showing a thermal receipt printer which has been connected to the Internet with an imp001 card. Every time somebody tweets #makerfaire or #electricimp, the tweet is printed. We are keeping a running count of tweets on a dweet.io dashboard.

Scrolling Twitter Display

At the booth, we are using the display to show in real time the number of IoT things messages processed by our public cloud. Meanwhile, this instructable gives step-by-step instructions for building a scrolling twitter display using an Electric Imp Developer Kit.

Beta version of Amazon Web Services and Kinesis Firehose libraries posted

Developers interested in working with Amazon Web Services (AWS) now have an easy way to integrate it with their imp-based project thanks to the beta release of Electric Imp’s forthcoming AWS library.

The library code contains a Squirrel class that can be used to generate correctly structured requests intended for AWS endpoints, sign the requests using Amazon’s “Signature Version 4”, and send them. It’s intended to be used internally by wrapper classes for specific AWS services.

To use the class yourself – for example if there is no corresponding wrapper class for the service you’re working with – you’ll need the following info:

  • Service name (eg. “iam” or “firehose”)
  • Region (eg. “us-east-1”)
  • Access Key ID and Secret Access Key (from IAM)
  • Knowledge of the required headers and request body contents and formatting

Here’s an example:

#require "AWSRequestV4.class.nut:0.1.0"


aws <- AWSRequestV4("firehose", "us-east-1", ACCESS_KEY_ID, SECRET_ACCESS_KEY);

local headers = {
    "X-Amz-Target": "Firehose_20150804.PutRecord"

local body = {
    "DeliveryStreamName": "myDeliveryStream",
    "Record": {
        "Data": http.base64encode("my super important data string")

aws.post("/", headers, http.jsonencode(body), function(response) {
    server.log(response.statuscode + ": " + response.body);

All the class’ methods are detailed in our public GitHub repository, where you can also get hold of the source code.

In addition, we’re providing a wrapper class for the new Kinesis Firehose service that was announced last week. It uses AWSRequestV4 internally, so that has to be included in your code too:

#require "AWSRequestV4.class.nut:0.1.0"
#require "AWSKinesisFirehose.class.nut:0.1.0"

Again, there’s a full write-up of the AWSKinesisFirehose class’ methods on GitHub.

If you try out the libraries, please let us know how you got on – and any issues you encountered.

Code share: Community member posts driver for TI FDC2114

Forum contributor @scottalucas has posted a driver class that allows you to integrate Texas Instruments’ FDC2114 EMI-resistant 12-Bit capacitance-to-digital converter into your own imp-based project.

According to TI, capacitive sensing “is a low-power, low-cost, high-resolution contactless sensing technique that can be applied to a variety of applications ranging from proximity detection and gesture recognition to remote liquid level sensing”. It’s this latter role for which @scottalucas chose the part.

The FDC2114 communicates with the imp over an I²C bus. It has four channels that each convert capacitance to a binary value, and @scottalucas recommends configuring all four even if you don’t make use of every one.

The best way to implement the FDC2114 appears to be by using TI’s FDC2114EVM evaluation module, which is a $29 unit that combines the FDC2114 with a set of capacitive sensors.


TI’s FDC2114EVM combines the FDC2114 converter chip and a set of capacitive sensors.

Says @scottalucas: “The driver can also take a ‘recipe’ as an input. The recipe follows the format that is output by the chip’s evaluation board software. It is a JSON file. A cut and paste of the JSON file should work as the ‘recipe’ variable. The eval board is great for finalizing values for your specific sensor.”

Anyway, you can get all the details – and of course the driver code – at @scottalucasGitHub repo.

How to add a TMP36 temperature sensor to your project

If you’re looking to incorporate Analog Devices’ TMP36 solid-state temperature sensor into your imp-based project, Frank Braswell of Systems of Merritt has just posted a guide to using this device.

Frank’s post covers both the surface-mount and through-hole versions of the TMP36. He provides guidance on wiring the parts up and includes some basic code to read the sensor and extrapolate Celsius and Fahrenheit values from the raw data. The TMP36 is read via an analog input.

TMP36 and imp

Systems of Merritt’s sensor set-up
(Source: Frank Braswell/Systems of Merritt)

You can read Frank’s post here.

You’ve got mail! A physical mailbox sensor project

For the past few weeks, I’ve been using the Electric Imp platform to prototype an Internet-connected mailbox. The device, which is roughly half the size of a postcard, is designed to let users track the physical mail that they send and receive. It has also been an opportunity to go through the process of designing an Internet-connected device from the ground up in a short timespan.

Impee Mailbox

The complete snailmail sensor

This project was inspired by the availability of cheap NFC stickers – at prices as low as 25 cents per tag, they cost significantly less than a stamp. If these could be placed on envelopes and packages in the same way we currently use stamps, it would be very simple to track mail as it traveled to its final destination.

Impee Mailbox

Inside your mailbox, the sensor is ready to check for arrivals

To begin tracking mail using this system, senders place an NFC tag sticker on mail before it is sent. They then register the tag with the recipient using a handy REST API running on the imp’s agent. This allows the recipient can know when to expect mail before it arrives. When tagged mail is delivered, the device identifies it using an NFC reader and notifies both the sender and receiver.

The device also handles traditional, untagged mail. Ambient light and proximity sensors can tell in real time when the mailbox is opened for delivery and how full it is, and send push notifications to the owner when these events occur.

Impee Mailbox

You’ve got mail!

The final product is a small device designed to be placed in an apartment or home mailbox. Its small footprint and user-installable NFC antenna are designed to fit in a variety of mailbox shapes and sizes and the battery life is estimated at several months. The software it runs makes significant use of Electric Imp’s libraries, including the IFTTT library for incredibly simple push notifications. For more technical details on how it was made (and source files), check out its GitHub repository.

Electric Imp adds five new web service, utility and hardware code libraries

We’ve posted a handful of new code libraries that are ready to be included and used in your own device or agent code.

• IFTTT (If This Then That) is a service that allows you to easily connect triggers to actions across a plethora of products and services. Our IFTTT library allows an agent to trigger events on the IFTTT Maker Channel.

• The Prowl library wraps Prowl’s API for sending push notifications for any other device running Prowl.

• Weather Underground is a commercial weather service that provides real-time weather information via the Internet. This library lets you query the service’s forecast, historical, astronomy and tide databases.

• The ConnectionManager library contains a device-side class designed to simplify server connection and disconnection flows.

• The LIS3MDL Magnetometer library helps you use this low-power, highly configurable three-axis magnetic sensor with support for user-defined interrupts. This library supports the I²C interface.

More information and links to individual library documents here.

Using Electric Imp’s Plot.ly library and Environment Tail sensors

Plotly is an online service that provides an easy way to graph and share data sets. Its capabilities range from graphing simple time-series data to visualizing 3D scatterplots and doing basic statistical analysis. It provides APIs for working with many languages and data sources, and today I’ll show how to use Electric Imp’s new Plotly library to easily graph data collected from Electric Imp-connected sensors.

I’ll start off by setting up a free Plotly account. If you already have one, skip right to the next section, past the picture.

Head over to the Plotly website and click the ‘Sign Up’ button to get started. Plotly has a free plan that allows for unlimited public plots and up to ten private ones. Once you’ve successfully signed up, visit the Plotly API settings page. Grab the Username and API Key as shown below. You’ll need these later when you start coding on the imp.


After creating an account, get your Plot.ly username and API key

Now we need a source of data to plot. We’re going to use the Electric Imp Env Tail, a convenient board that plugs directly into the standard April Imp breakout board and gives us access to a whole range of environmental data like temperature and humidity. You can buy the Env Tail (the pack also includes an imp001 card, April breakout board and our RGB LED Tail) from Amazon.com.

Env Tail

The sensor-packed Env Tail

We’re going to take the device code for this straight from our weather station project:

Now that we have data coming out of the imp, we will use the Plotly library to generate a graph. Include the library at the top of your agent source file and then instantiate it as shown below. Remember to replace our dummy username and API key values with the ones you created or copied earlier.

That’s all we need to do! If you want to take a look at the plot, either visit the link that we printed to the logs or look at the newly created file in your Plotly file list. As more data comes in, you’ll need to refresh the plot to see it update.

Going Further

Plotly has a lot of features that we haven’t gone into here, including ways to customize your graph, create different kinds of graphs, and do basic statistical analysis.

To explore the other features that this library supports and see advanced example usage, check out the documentation in the library’s Github repository.

For a list of other sensors that you can drop in support for with an Electric Imp library, look at our list of hardware driver libraries and other drivers available via our GitHub repo.

One year on: ORBneXT unwraps colorful kit for customizers

Advanced Lumonics Labs’ ORBneXt is an always-on, real-time desktop data display that allows you to track a virtually endless array of data. It lets you to visualize important information with colors that provide instant knowledge at a glance. ORBneXt is based on the Electric Imp platform, of course, and we’re proud to have Advanced Lumonics Labs as a partner. So here, one year on from the company’s initial ORBneXt Kickstarter campaign, is an update from Michael Costigliola, R&D lead at Advanced Lumonics Labs.

To celebrate the first anniversary of the ORBneXt release, we have announced the ORBneXt Developer Kit. The ORBneXt Developer Kit allows you to create your own customizable data display device.

We created the ORBneXt Developer Kit to meet the demand from those users who were clamoring for control over the ORBneXt in order to customize it for their needs. So we’re providing the hardware – you the user provide your own customizable application developed and installed through your Electric Imp developer account and the IDE.

ORBneXT Dev Kit
The ORBneXt Developer Kit…

If you already own an ORBneXt device, you can either purchase an ORBneXt Developer Board and use your existing ORBneXt LED Board, or you can purchase an ORBneXt Developer Board and an ORBneXt LED Board, and build an all new ORBneXt device leaving your original ORBneXt device intact. We have priced out the components so that you can purchase them a la carte as needed – boards, glass, base plate, etc.

The ORBneXt Developer Kit is for serious users who already know how to program using the Electric Imp platform. An Electric Imp developer account is required. We provide a code sample to get you started, but from there on you’re free to develop your own code and device. The sky is the limit.

ORBneXt LED Board

…and the ORBneXt LED Board (available separately)

If you’d like more information about the ORBneXt Developer Kit, click here for an overview, or visit ORBneXt.com to place your order now!

How to create your own desktop tools with the Build API

Electric Imp’s Build API comprises a set of HTTPS endpoints you can call in code to perform the same tasks that the web-hosted IDE provides. Now, the IDE is a good development tool for imp-based projects, but for some developers it has a few limitations. For instance, you can’t download models to your computer, whether for archiving, because you want to work on the code in your favorite text editor rather than the IDE’s own, or you’re working collaboratively with someone. Equally, you can’t upload code back; this has to be done with cut and paste, and that’s cumbersome, especially if you end up working on your text files and the IDE. It’s hard to keep them in sync.

No longer. The Build API allows you to work directly with your own tools and the Electric Imp Cloud in just the same way that the IDE talks to the Electric Imp platform.


One way to do this is to use command line tools. The Build documentation includes many examples of using the command line function curl to interact with the Build API. My colleague Matt Haines will be separately posting about how he created a JavaScript interface for the API and a Node.js-based command line system. However, I’m going to tell you about creating a GUI desktop application that can talk to the Electric Imp server via Build.

I actually wrote my app, Squinter, some time before Build became available. It was originally a program that allowed me to use my own library files: embed a #import directive in some Squirrel code in a text file, and Squinter would ‘compile’ the library file’s contents – a class for interacting with Twitter, say – into the code in the main file. ‘Squinter’ is short for ‘Squirrel Integrator’, by the way. It automatically put the compiled code onto the pasteboard ready to be pasted into the IDE.


Squinter is a commands and log-based app

Build allowed me to upload the compiled code straight to the server, and to extend Squinter into a device and model management tool as well. I can create Squirrel projects as before, but now also create models to go with them. I can assign devices to those models, upload new code and restart the devices so they run the update. I can view the logs posted by a device and its agent, either all in one go or in real time as they are posted.

How is it done?

First, I work on Mac OS X, so Squinter was written using Objective-C. However, since Build is a Rest API operating over standard HTTPS, it’s easy to implement on Linux and Windows too, using standard OS APIs. I’ll talk a little bit about the Mac’s API, Cocoa, but mostly I’ll look at the principles behind Squinter’s use of Build.

I implemented Build as a class containing methods by which Squinter’s main code can interact with an instantiated object. You can view the class, BuildAPIAccess, on GitHub.

BuildAPIAccess also incorporates subsidiary methods that allow it to generate the requests that will be sent to the Build API server and handle the responses. So it has a series of methods for generating GET, PUT, POST and DELETE requests over HTTP, and these are used by a set of methods that map the functionality provided by Build.

Want a list of models? That involves sending a GET request to build.electricimp.com/models, so my BuildAPIAccess class’ getModels: method calls the class’ makeGETrequest: method and passes it the endpoint path. makeGETrequest: in turn calls setRequestAuthorization: to add my API key to the request, entered into the main program. The complete request is returned to getModels: for checking.

- (void)getModels 
    // Set up a GET request to the /models URL - gets all models
    NSURLRequest *request = [self makeGETrequest:
            [_baseURL stringByAppendingString:@"models"]];
    [self launchConnection:request :kConnectTypeGetModels];

- (NSURLRequest *)makeGETrequest:(NSString *)path 
    NSMutableURLRequest *request = [NSMutableURLRequest 
            requestWithURL: [NSURL URLWithString:path]];
    [self setRequestAuthorization:request];
    [request setHTTPMethod:@"GET"];
    return request;

- (void)setRequestAuthorization:(NSMutableURLRequest *)request 
    [request setValue:[@"Basic " 
            stringByAppendingString: [self encodeBase64String:_harvey]] 
    [request setTimeoutInterval:30.0];

This method now calls launchConnection:, which maintains an array of connections in flight. It uses standard Mac OS X tools for issuing a request and adds the new connection to the array. The connection is an object that combines an NSURLConnection object, which manages the transmission of the request and the receipt of data; the data that is returned; and a number of properties for error codes and to indicate the action the connection is being made to perform.

OS X manages the interplay between Mac and server; all I need to do is handle data as it comes in, making sure it is appended to the correct entry in the connection list, and then to process that data in the right way when the server has finished sending.

- (void)launchConnection:(id)request :(NSInteger)actionCode 
    // Create a default connexion object to store connection details
    Connexion *aConnexion = [[Connexion alloc] init];
    aConnexion.actionCode = actionCode;
    aConnexion.errorCode = -1;
    aConnexion.receivedData = [NSMutableData dataWithCapacity:0];

    if (actionCode == kConnectTypeGetLogEntriesStreamed) 
            [request setTimeoutInterval:3600.0];

    aConnexion.connexion = [[NSURLConnection alloc] initWithRequest:
            request delegate:self];
    if (!aConnexion.connexion) 
        // Inform the user that the connection failed.
        errorMessage = @"[ERROR] Could not establish a connection 
            to the Electric Imp server.";
        [self reportError];
        // Connection established, so notify the main app 
        // to trigger the progress indicator and then add 
        // the new connexion to the list of current connections
        if (_connexions.count < 1)
            NSNotificationCenter *nc = 
                    [NSNotificationCenter defaultCenter];
            [nc postNotificationName:@"BuildAPIProgressStart" 

        [_connexions addObject:aConnexion];

The Build API returns JSON-encoded data, so I use standard tools to decode and convert it into key-value pairs just like Squirrel tables. Checking the values of certain keys tells me that the operation was successful, and I can then extract the list of models I requested. This gets stored in an array of NSDictionary objects, each a key-value description of one of my models. The format of the dictionary is defined by Build.

Finally, I notify Squinter’s main program – in Mac OS X terms, its ‘application delegate’ – which taps into the exposed BuildAPIAccess class property models to get the names of all the models and populate a menu with them.

Exactly the same process is used to GET (via getDevices:) a list of devices from the endpoint /devices, and ultimately these are then added to sub-menus of the models they are assigned to:


Models and their assigned devices

The code checks the device’s powerstate property and appends a blue dot if the device is online (or white if it isn’t).

Menu entries provide access to model- and device-specific operations: get model info, assign a device to a model, save the model as a Squinter project for local work and so on. Models can be deleted or renamed; devices likewise. All these operations trigger methods which call suitable BuildAPIAccess class methods that, as above, generate and issue an appropriate HTTPS request to the Build API itself.


Create projects and link them to models

Squinter isn’t an IDE &ndash it’s simply a tool for managing models, devices and local Squirrel projects, and logging the results of those operations. Coding I do in a text editor – TextWrangler, since you ask. Squinter’s toolbar contains an ‘Open Project Files’ button, which loads the agent and device code files into the text editor, along with any local library files they #import. Squinter parses the code for these and for #require statements that pull in Electric Imp libraries. Again, these are listed in menus for direct access to the source files (or the Libraries page in the Dev Center).


A list of local libraries in the source – and Electric Imp libraries

When I've saved some code changes – Squinter watches out for these using Bryan Jones’ VDKQueue class – I can click on the Compile button to combine library and code files. Squinter holds the compiled Squirrel internally; the source files remain unchanged. A click on Upload sends the code as a Build API code revision entity to the project’s model via a POST request. When I see in Squinter’s log that the upload was successful, I restart the device. Or I may instead see a syntax error report, so I go and check my source code.


Squinter’s toolbar provides access to frequently used functions – like upload code

Squinter started out as a bit of fun. I could use it to develop my imp software, and found it particularly useful as a way of managing projects and local library files. However, until the Build API freed me from the IDE, Squinter could never be my main development tool. Thanks to Build, it now is. I don’t even have to go back to the IDE for logs – Build allows me to stream a device’s log entries right onto Squinter’s own log window as they are posted. I haven’t been back to the IDE since.

Adopt the Build API yourself and soon neither will you.

BuildAPIAccess is available under the MIT license on GitHub

Add cellular comms to an imp with Adafruit’s FONA GSM/GPRS board

People still make phone calls and send SMS text messages these days, and these forms of voice and messaging communication have a role to play in the Internet of Things. They can be used for notification purposes – you get a text message when your device’s battery level drops below a critical level, for instance – or as a way to communicate when there is a problem with WiFi.

So how do you go about adding cellular network connectivity to your imp-based project? There are two methods.

The first of these requires no hardware and utilizes an external web service to provide cellular voice and messaging functionality for you. According to Programmable Web, there are 255 of these services, among them Twilio, Nexmo, Plivo and Tropo. Electric Imp has a Twillio library you can embed in your code. Web APIs are generally the most effective and quite often the cheaper way to send out text messages and to dial phone numbers. They are also very useful in situations where your device isn’t be able to receive a good phone signal.

However, not all web APIs provide options for your imp to receive messages or handle incoming calls. Those that do, may not be able to provide a local phone number for you (typically the case in countries other than say the US and the UK) and you would need to sign up to obtain one (terms and conditions apply!, etc.). Then there’s the issue of Internet connectivity. No Internet for your imp, no SMS.

The second method, which is the focus of this article, is to attach a GSM/GPRS module or breakout board to your device. The add-on handles making and receiving phone calls and messages, and can allow HTTP connectivity to the agent URL in case of loss of WiFi. Of the two add-ons, modules can be excessively complicated to implement, so a breakout board is the best option when you’re implementing cellular comms for the first time. One such breakout board is Adafruit’s inexpensive FONA.


Adafruit’s FONA Mini Cellular GSM Breakout is an all-in-one cellular development board based on SIMCom’s SIM800L module, which offers voice and SMS functionality as well as HTTP connectivity through GPRS. It’s very compact – just 45 x 34 x 8mm – and quite ingenious in that the power electronics are handled using an on-board LiPo battery charging chip rather than complex circuitry. This is a necessity: there are no off-the-shelf DC-DC converters to provide output voltages within the required 3.7 to 4.4V range, and does mean that FONA will only work with a LiPo battery attached.

Adafruit FONA

Adafruit’s FONA GSM/GPRS breakout board

Another fantastic design feature of the FONA development board are the extensive pinouts:

  • Power Status pin – this tells you if the module if powered.
  • Ring Indicator (or SMS indicator) pin – this tells you is the phone is ringing (or an SMS has arrived).
  • Network Status pin – this tells you the connectivity status of the SIM800L. It outputs different pulses depending on whether it is connected and registered to a cellular network provider, or has made a GPRS data link.
  • Reset pin – this is used to reboot the board.
  • Key pin – this is power on/off controller. It can be tied to ground to keep it permanently switched on, or you use it to manually turn board on or off by pulsing low for two seconds.
  • RX and TX pins – these are used to communicate with the SIM800L module using UART. SIM800 has auto-baud detection.
  • Speaker pins – allow an external speaker to be connected.
  • Microphone pins – allow an external electret microphone to be connected.
  • 5V Battery charging pin – this is used to keep the LiPo battery charged. The alternative is to use the USB port for charging (USB is solely for charging, not for data).
  • Vio Pin – this pin is used to determine the voltage of the logic levels for the logic shifter circuitry (FONA can handle 5V or 3V3 logic levels).
Adafruit FONA

Lots of useful pins

Connecting FONA to an April Dev Board

The only additional electronics needed to connect FONA to April is a 5V voltage regulator to drive FONA’s battery charger, and even this is required only if you don’t wish to power the FONA separately using the USB power port. The regulator should be at minimum 1.5A, but ideally higher. The regulator occasionally gets hot if charging a discharged battery, but this is normal.

Adafruit FONA

FONA, meet imp
Click for larger image

As the diagram above illustrates, the other connections are:

  • Connect FONA’s RX/TX pins to any of the following imp pin pairs: 1 and 2 (uart12), 5 and 7 (uart57) or 8 and 9 (uart1289).
  • Connect FONA’s RST pin to any other available imp pin which must then be configured as a digital output.
  • Connect up all GND pins.
  • Connect FONA’s Key pin to GND to ensure it remains powered up.
  • Connect FONA’s Vio pin to the April’s 3V3 pin.
  • Connect FONA’s 5V charging Pin to the output of your 5V Voltage Regulator, or connect a 5V USB power supply to FONA’s USB port.
  • Connect a 3-7V LiPo/Li-ion battery to FONA’s battery connector. A battery is always required for FONA to work properly.
Adafruit FONA

Don’t forget a SIM card (the slot is on the back)

Getting the imp to Communicate with FONA

The first step is to configure your imp’s UART connection using the imp API method uart.configure().

The default baud rate for FONA’s SIM800L module is 115,200, although it will auto detect the baud rate once the first “AT” command has been sent by the imp (this can be seen as a GSM module’s “Hello, World!” request). If FONA is powered up (FONA’s Power Status pin can also be used to confirm this), after sending “AT”, you should receive an “OK” response.

If your connections match the diagram above then you would configure the Imp UART as follows:

fona <- hardware.uart57;
fona.configure(115200, 8, PARITY_NONE, 1, NO_CTSRTS, 

A callback function is required to capture the incoming messages from FONA, here named fonaUARTdataHandler(). This function is called every time incoming frames are dropped into a memory buffer, ie. data is received through the RX pin. You then apply the uart.readstring() method to read this byte of data.

In our case, we need to create our own buffer to store multiple bytes of data – all the characters the SIM800L sends. Here we use a string, but if you are pushing your imp’s dynamic runtime memory you may be better creating blobs of fixed byte size to reserve memory space upfront. For example:

// Create global character buffer
fonaFeedback <- "";

// Implement received data handler
function fonaUARTdataHandler() {
  fonaFeedback += fona.readstring();

You should monitor the size of the character buffer, and it’s up to you to clear this buffer when you have analysed its contents.

To see what information will be placed in the character buffer, let’s work through an example which is shown below in a sequence diagram. You’ll need to refer to the SIM800L AT command document to understand the commands’ actions.

Example 1

Four commands are sent to the SIM800L: AT, ATE0, ATI and AT+CSQ. The SIM800L will terminate its response with an “OK”, or an “ERROR” response with an error code if something went wrong. The “OK” response would be seen as a sequence of four characters: <CR><LF>OK<CR><LF> or “\r\nOK\r\n”.

As you can see from the diagram, your imp will spend lots of time waiting for the GSM module to respond, and this is why the UART callback is so useful: it allows your code to operate asynchronously. However, you do need to keep track of the conversation between imp and SIM800L so that the right commands are sent at the right time. Code to create a non-blocking response checker on the imp would be something like this:

ATCmd_Response <- 0;
tHandler <- null;

function fonaUARTdataHandler() {
  fonaFeedback += UART.readstring();

  // Look out for OK and ERROR responses
  local respOK = fonaFeedback.find("\nOK\r");
  local respERROR = fonaFeedback.find("\nERROR\r");

  if (respOK != null || respERROR != null) {
    // Cancel timeout wakeup
    if (tHandler != null) imp.cancelwakeup(tHandler);
    if (respOK != null) {
      ATCmd_Response = 1;
    } else if (respERROR != null) {
      ATCmd_Response = 2;
    imp.wakeup(0.1, talk2Fona);

function talk2Fona() {
  if (!ATCmd_Response) {
    // Use this to repeat the command or use another
    // call back function to handle the timeout case

    tHandler = imp.wakeup(5.0, talk2Fona);
  } else {
    if (ATCmd_Response == 1) {
      // i.e. OK
      // Can now do something
      // Check fonaFeedback for additional data (if applicable)
      // Otherwise clear it
      fonaFeedback = "";
      ATCmd_Response = 0;
    } else if (ATCmd_Reponse == 2) {
      // i.e. ERROR
      // Can now do something else
      // Check fonaFeedback for additional data (such as error code)
      // Otherwise clear it
      fonaFeedback = “”;
      ATCmd_Response = 0;

// You need to create a startup routine to get talking to FONA


Unprompted Communications

Another thing to remember when developing your code is that the SIM800L will also generate a number of unsolicited messages which arrive unprompted via UART. For example, when the SIM800L receives an SMS, it will send a +CMTI message, ie.


You need to get the message number off this notification, which in this case is “1”, and then return


to read message number 1.

The SIM800L will then respond with the message in the following format:

+CMGR:"REC UNREAD","+447700000000","","Date+Timestamp"

followed by the text of the SMS. You can always request this message to be sent to you again. The only change will be that “REC UNREAD” becomes “REC READ”.

This read sequence is also captured in detail with the following sequence diagram (click it to view a larger version).

Example 2

See Section 19.3 at back of the AT Command Set document for a full list of unsolicited result codes that the SIM800L can send.

Using FONA to Text Other Cell Phones

The hardest part of learning how to send an SMS via a GSM module, such as the SIM800L, is working out how to send a “Ctrl-Z” command to terminate your message string. Once you’ve got that, the rest is relatively straightforward. The answer is: append a “\x1A” after your message string.

The AT commands that are used to send an SMS are as follows:

  • AT+CMGF=1 (ie. Select SMS Message Format. A 0 (PDU mode) or a 1 (Text mode) denotes the input/output format of messages. You can also save this (using the AT&W_SAVE command) if you want to permanently keep your formatting choice.
  • AT+CMGS="[the phone number]""[your SMS message]" e.g.
    local dataString = "AT+CMGS=\"+447700000000\"\r\"hello world\"\x1A";

  • +CMGS:[MESSAGE_REF] – Message reference in integer format (response when SMS sent)
  • +CMTI:"SM",[MESSAGE_NUM] – Message number in integer format (response when new SMS arrives)
  • AT+CMGR=[MESSAGE_NUM] (which matches the message number received from +CMTI)
  • +CMGR:"REC UNREAD","[the phone number that sent SMS]","","Date+Timestamp"\n"[the message]\r\nOK\r

Using FONA to communicate with Imp Agent via HTTP

Getting the FONA to send data to the imp’s agent via HTTP is a little convoluted but not difficult. The following sequence diagram describes the process. It’s large, so click on the thumbnail below to view the full-size image:

Example 3

The first thing to note is that this sequence is not a repeatable sequence. Once attached to a GPRS service, the SIM800L will remain attached until you manually detach it. Using the attach GPRS command while already attached won’t produce any error. However, trying to get a new IP address (open a GPRS context) using


will create an error if the device has already done so. Thus it is important to check these things first by using


to query the GPRS context.

The second issue is the timing between each command and waiting for a response to come back.There can sometimes be extended delays, such as waiting for a new local IP address to be given. The other case is waiting for a URL to respond to your GET or POST request following the


(in the case of a GET request) or


(in the case of a POST request) and then waiting for the data to arrive via GPRS, which is then related to amount of data and the connection speed.

Once you have received confirmation such as a


for GET or


for POST you will then need to issue an AT+HTTPREAD command to get the data from the FONA. The SIM800L stores the data locally, and there is a size limit here. For larger downloads, a chunked download method needs to be impemented; refer to the document ‘SIM800 Series_IP_Application_Note v1.00’ for further information. This has a lot of guidance on HTTP communications.

The SIM800L will present the data via the UART in the following format:


then supply the data content, which could be text, JSON, HTML or even binary, and finally


That is it. You now have a means to communicate with an agent via HTTP and for you to read the agent’s response.

If the process needs to be continued you can issue the following if new key/values or new URLs are needed:

AT+HTTPPARA="URL","enter URL/?keys=values"

When you’re done, you terminate the HTTP communications using:


and then finally detach the GPRS connection:


If it seems that nothing is happening and you want to get an idea as to what’s going on, you could use in your code an AT+HTTPSTATUS? command which will query the SIM800L to learn what is going on.