Skip to main content

Your First Program: ‘Hello, World’

Getting a new development device to turn on an LED is the classic ‘Hello, World’ application: it shows that the core hardware works. That’s what we’re going to do here. Your impExplorer™ Developer Kit has a built-in WS2812 RGB LED, so we’ll use that to get the device to announce its presence with a visual “Hello, World!”


 

1. Power up the impExplorer Developer Kit

Power up you impExplorer Developer Kit so that it connects to the Internet. If you haven’t configured your impExplorer Developer Kit for Internet access yet, this section will show you how.

2. Open impCentral

If you’ve just completed the previous section of the Getting Started Guide, you’ll have impCentral open on your computer. If not, load it up now and sign in using the account log-in details you created in the first part of this Guide.

Locate the Connected Product Product and its Test Hardware Device Group that you created in the previous section:

  • Click Account in the nav var.
  • Select your personal account.
  • Find Connected Product in the Products list.
  • Click Development Zone in the MANAGE column.
  • Find Test Hardware in the Development Device Groups list.
  • Click Code in the MANAGE column.

impCentral’s code editor will now appear.

3. Program Your Device

You program all imp-enabled devices using a language called Squirrel. This is very similar to C and its many popular derivatives, such as C#, JavaScript and Swift. Our 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 on-board imp, its Internet connection and the device’s own hardware.

The Code

For this example, we’ve written the code for you: just copy and paste it into the code editor’s Device Code pane. You can delete any code already there from the previous section.

To run the code, click the Build and Force Restart button. This tells impCentral to check the code’s syntax and then package it up for retrieval by all the devices assigned to the Device Group. It then tells those devices to restart. Every time an imp-enabled device connects to the Internet, it checks if there is new or updated application code for it to install. If there is, it replaces any code it already has and runs the new software. For your impExplorer Developer Kit, the new code is the program you just pasted into impCentral.

You should not only see the LED in the circuit blinking on and off, but also messages like these in the log pane:

[Status] Downloading new code; 4.30% program storage used

What the Code Does

Though very simple, the code illustrates some key aspects of how imp-enabled devices work. 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 Developer Kit’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 section. For now, accept that line 2 loads a library that represents the RGB LED. We instantiate that class in line 23, and 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 objet-oriented programming before. As we noted earlier, 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 the 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 Developer Kit’s two SPI 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’ parameters.

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 Developer Kit’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. We’ll explore this event-driven nature further in the next section.

The code you just entered isn’t interactive: you have no way of controlling the LED while the program is running. We’ll implement code to change the state of the LED remotely, via the Internet, in the next section.