Electric Imp’s impCentral™ development environment provides all of the tools you need to create and deploy software to your imp-enabled connected product. In this stage of the guide, you will use impCentral to enter your first impExplorer™ Developer Kit program.
impCentral runs in a desktop web browser. It has been optimized for Firefox and Google Chrome, but it will run in other popular browsers on Linux, macOS and Windows, such as Safari and Edge. Internet Explorer is not supported.
The first time you log in, impCentral presents a convenient quick start wizard:
Click Create Your First Product.
A new panel will appear in which you can enter the name of your first Product and your first Device Group :
Enter Connected Product
as the Product’s name, Hello World
as the Device Group’s name, and then click Create.
impCentral will now present its code editor:
You program imp-enabled devices using a language called Squirrel. This is very similar to C and its many derivatives, including C++, JavaScript and Swift. The Squirrel Programming Guide will help you learn how to write applications in Squirrel, and we have a full Squirrel reference.
All Squirrel programs will need to use at least some of the imp API, which provides access to the objects and classes that encapsulate your device: its hardware, its imp and its Internet connection.
For this example, we’ve written the code for you: just copy and paste it into the code editor’s Device Code pane (the one on the right).
Once you’ve done this, click Build and Force Restart to run the program:
Of course, nothing will happen because you have not yet assigned your impExplorer to the Hello World Device Group. Let’s do that now.
Click the Assign Devices button.
A panel will appear listing your devices. You should see just one: your impExplorer, identified by its unique Device ID :
As you can see, this impExplorer, like yours, currently belongs to no Product or Device Group — just click the Assign button to add your impExplorer to the group shown in the code editor.
impCentral now adds your impExplorer to Hello World. This causes the impExplorer to download and run the code you entered. If your impExplorer is connected, it should begin flashing its three-colour LED (not the status LED) :
You’ll also see messages like these in the code editor log pane at the bottom of the window:
[Status] Downloading new code; 4.68% program storage used
The log is a useful testing tool that will help you observe how your code is working and gain vital clues when it does not.
You’re now ready to move on to the next stage: Add Internet Interactivity.
impCentral provides a structure to help you organize your work. A Product is the over-arching entity which embodies all of the elements that make up a connected product or family of connected products.
You can create as many Products as you like in impCentral.
impCentral organizes devices into groups. All of the devices in a given Device Group run the same code, which is deployed to that group.
There are different types of Device Group: here we focus on Development Device Groups which are used to create and test your code before it goes to production. Development Device Groups have an integrated code editor for this purpose.
For a given Product, you can create as many or as few Device Groups as you need.
The navigation strip at the top shows how your project is organized. In this example, Hello World is a Development Device Group that is part of Connected Product, which belongs to the account getting_started:
You can create as many Products as you like in impCentral.
Every imp-enabled device has a unique ID. In addition, devices can be identified by the network MAC address and by a human-friendly name. Development devices have no name to begin with, but you can enter one as follows:
Note Go to the My Development Devices view to find any devices which are not currently assigned to a Device Group (‘unassigned’ devices).
Though very simple, the code illustrates some key aspects of how imp-enabled devices work.
For example, line 2 shows how we can make use of one of Electric Imp’s ready-to-use code libraries, in this case a driver for the impExplorer’s WS2812 RGB LED. Libraries provide a powerful means to extend your code, so we’ll look at them in more detail in a later page. For now, accept that line 2 loads a library that represents the RGB LED. We use the library in line 23 to create an instance of the library’s class. This instance is assigned to the variable led. We call its methods in line 13: set() to specify the colour in the form of an array of three numbers representing red, green and blue values, and draw() to update the LED.
Class? Instantiate? Methods? If these terms are unfamiliar to you it’s because you may not have encountered object-oriented programming before. Squirrel is an object-oriented language. An object is a software construct that combines data (called ‘properties’) with functions (called ‘methods’) that work with that data. Classes are template objects and are primarily used to create working copies (‘instances’).
We use our first object in line 18: hardware, which is an imp API object we use to control device hardware connected to a device’s imp. The hardware object has properties for all of the imp’s pins and standard component-communication buses. We use one of the bus properties here: spi257, which represents one of the impExplorer’s two Serial Peripheral Interface buses. We know spi257 is a property of hardware because the two are linked by a period:
hardware.spi257
This says ‘get me the spi257 property of the object hardware’. The use of the period to indicate this relationship is called ‘dot syntax’. In fact, spi257 is an object too, with properties and methods of its own. One such method is configure(), used in line 19 to set up the bus.
The brackets after configure()’s name tells the device to call (run) that method — configure() takes a value which tells the device how the bus should operate: in a certain mode (MSB_FIRST) and at a certain speed (7500KB per second). All of the possible values you can pass to configure() are listed in the imp API documentation.
We’ve used the variable spi to refer to the hardware.spi257 object, for convenience. But we could have written line 19 out in full. In fact, that’s what we’ve done with line 20 which says ‘configure the object pin1, a property of the object hardware’. This sets the imp001’s pin 1 as a digital output with an initial value of High (1). This activates the impExplorer’s power gating system, ensuring the RGB LED is sufficiently powered.
Lines 5 through and 7 introduce Squirrel’s <-
operator, which is used to mark a variable as a global and to assign it an initial value; future assignments of a global variable use the =
operator, as you can see in line 18. The <-
operator is also used to create and add an entry into a ‘table’, a Squirrel data structure comprising key-value pairs. Why use the same operator for both these situations? Because Squirrel stores all global variables in its system table.
We create three globals here: spi, which we’ll later use as an easy reference to hardware.spi257; led, which we'll use to refer to the WS2812 RGB LED; and state, which records whether the LED is lit or not.
Line 14 is also important. It calls the imp API method imp.wakeup() — which we now know means ‘the method wakeup() of object imp’. This method tells the imp to run the function named in the second parameter when the number of seconds specified in the first parameter have elapsed. In this case, we pass the name of the function we’ve just run.
It’s important to remember that flash (without the brackets) is a reference to a function, but flash() (with the brackets) is an instruction to execute that function now — which is what we need to start the loop, in line 26.
This is how program loops are implemented on imp-based devices. Unlike other embedded systems, imps have their own operating system, and when your code comes to an end or a pause, this OS has an opportunity to perform essential system tasks, specifically maintaining contact with the impCloud™ and impCentral. If we had used a classic delay loop, such as
local i = 0;
do {
i++;
} while (i < 10000);
we would dominate (‘block’) the imp’s single execution thread and prevent impOS from performing its housekeeping functions for the duration of the loop. This should be avoided.
Using a timer to re-activate the program is an example if the Electric Imp Platform’s event-driven programming methodology: code is run only when triggered to do so by an event. If impOS has done its work, and there’s no user code that needs to be run yet, the device can slow down to conserve power, or even go into a sleep state.