Common development problems and their solutions
Problems encountered while developing products based on the Electric Imp Platform most commonly result from errors of hardware and software configuration, from a misunderstanding of the Platform’s key concepts and modes of operation, or from incorrect use of impCentral™.
This guide covers the most frequently encountered issues experienced by developers and provides solutions to them.
The problems most commonly encountered while setting up a device are covered separately in our BlinkUp™ Troubleshooting Guide. Please read this guide if you are experiencing difficulties connecting an imp-enabled device to the Internet for the first time. You should also read the ‘Power’ and ‘WiFi’ sections, below, which list and resolve some broader issues which may also impact the BlinkUp process, and the imp003/imp004m/imp005 Hardware Design Guides as these discuss hardware issues (such as SPI flash compatibility) which prevent device start-up but which are indicated by the device’s BlinkUp status LED.
Even if you are not experiencing difficulties with device configuration, we recommend you read the BlinkUp Troubleshooting Guide to gain a working knowledge of the device status codes indicated by a device’s three-colour LED. These indicate not only the key stages through which the device expects to pass every time it starts up and connects to its local network, to the Internet and finally to the Electric Imp impCloud™, but also signal errors encountered during this process. Recognizing and understanding these indicators will help you quickly resolve most configuration and connectivity problems.
Every device disables its LED 60 seconds after power on in order to reduce power consumption. The device can be power cycled to re-enable the LED temporarily, or the imp API method imp.enableblinkup() can be called with
true as its argument. You and your end-users should always ensure the LED is flashing before attempting to configure the device using BlinkUp.
A number of further connectivity problems may be resolved by checking the status of the Electric Imp Public impCloud, through which your device communicates with the wider Internet. When experiencing communications, data logging and other connectivity problems, first check the Public impCloud’s current status (see below) to see whether a scheduled maintenance operation is underway.
You should also make sure you understand how imp-based devices respond to the availability of new impOS firmware, as this can also appear to impact connectivity while a device updates. For methods for managing device and agent restart requests relating to new impOS firmware, see ‘Polite impOS Deployments’.
impCentral’s status menu () lists upcoming scheduled maintenance which may impact connectivity. If impCentral is itself unavailable, status information can also be found at status.electricimp.com, along with details of past outages. We also post status updates via our Twitter account @impstatus.
We recommend you take advantage of the status page’s ‘Subscribe to Updates’ feature to get status warnings sent to your phone by SMS, or mailed to your email address.
When an impOS update is released, devices will be updated the next time they power cycle. If the update process is interrupted — the device is powered down or there is a loss of network connectivity — the device will automatically restart, connect and re-acquire the update.
Update retrieval and installation is signalled by the LED turning green without flashing.
After an update, the device will restart, connect and download the latest Squirrel application firmware as normal. The update status of development devices is reported in impCentral’s device log.
For methods for managing device and agent restart requests relating to new impOS firmware, see ‘Polite impOS Deployments’.
impCentral’s code editor displays agent and device status in a readout to the right of the selected Device Group’s list assigned devices. The device status record is based on the agent’s current knowledge of the device; it may take up to 90 seconds after the event for impCentral to register that the device has disconnected.
In addition, the device menu’s () ‘My Development Devices’ option provides access to a list of all of the devices accessible with your account. Under the ‘MANAGE’ column, the ‘Details’ option will call up a full information readout for the chosen device, including device history (eg. BlinkUps) and logs.
Most problems arising from your use of impCentral can be resolved by consulting the ‘Introduction to impCentral’. Some of the more common of these issues are listed below.
impCentral should work on most any desktop browsers. However, only the following browser versions are formally supported and targeted for new features:
To maintain compatibility with impCentral, users are advised to enable automatic updates. We will always support the two most recent vendor supported versions at any given time. As new versions of these browsers are released, support for the earlier of the two previously favored versions will end: we will not test new features and updates with older browsers.
Each device has its own log and so the impCentral code editor log pane is only populated when a device is selected from the list of assigned devices to the left of the log pane. This list will not be visible if no devices have yet been assigned to the current Device Group.
The log scrolls upward automatically to keep the latest entry in view unless you click the lock icon () at the top of the log pane. Doing so temporarily stops the log from automatically scrolling, allowing you to find and view previous log entries without hindrance. To re-enable automatic scrolling, click on the lock icon once more.
If the device is new and has just been configured for the first time using BlinkUp, you may need to refresh your browser for it to appear under the device menu’s () ‘My Development Devices’ list.
If the device has been assigned to a Device Group, its name will appear underneath the Device Group’s agent code in the code editor. It will also be listed in the Device Group’s ‘Devices’ list.
Finally, it’s important to remember that model code is associated with the device, not the imp slotted into or embedded within it. This is explicit with a module-based device, but it is less clear with card-based development devices, which allow the imp to be removed. For example, if you insert a new imp001 card into a device that has already been configured using BlinkUp, the device will not appear in impCentral as new. impCentral lists devices, not the imps they contains.
The following topics cover problems whose resolution centers on the code run by each device’s agent. Every device has its own unique agent which runs code you develop.
Agents and devices communicate with each other by message. Each type of message must be given a unique (to the model) name string which must be provided by the sender and included in the code the recipient uses to register the function that will be called when the named message is received.
For agent-to-device communications, the callback function is registered using the imp API method agent.on() in the device code. For device-to-agent communications, the callback function is registered using the imp API method device.on().
The equivalent message transmission calls — device.send() for the agent, agent.send() for the device — must be paired with agent.on() and device.on(), respectively. If they are not paired, they will have no effect other than causing a warning to appear in the log.
Developer account agents are currently limited to 1MB in size. This includes code, variable space and buffers for incoming HTTP requests. If a mobile app or website attempts to send the agent an HTTP request that is greater than the currently available memory, it will be returned an HTTP error code 413.
If the app or site makes too many HTTP requests to the agent too quickly, it will receive an HTTP error code 429. The impCloud accepts no more than ten requests each second, adding them to a pool of up to 20 simultaneously open connections. Once there are 20 open connections, no more requests will be accepted until older ones are closed.
For a list of the meanings of other HTTP error codes the requester may receive — and some suggested solutions — see ‘HTTP Request response codes’.
The following topics cover problems whose resolution centers on the code run by each device.
Devices can respond to unexpected losses of network connectivity in one of two ways. The default behavior is to attempt to reconnect immediately. The device will spent one minute trying to do so. If it is unsuccessful, it will enter a deep sleep mode (see below) for nine minutes. During this time, your Squirrel code does not run. At the end of the deep sleep period, the device will awake and perform a warm start. At this point the device will remain disconnected until the Squirrel code performs a task which requires network access, such as the server.log() or agent.send() imp API calls; this causes the device to attempt to reconnect.
The alternative behavior is to continue running Squirrel code as normal. The device will not reconnect until told to do so by your program.
Selecting which of these approaches your device will take involves calling the imp API method server.setsendtimeoutpolicy() in your device code. The default error policy is SUSPEND_ON_ERROR; the alternatives are RETURN_ON_ERROR and RETURN_ON_ERROR_NO_DISCONNECT (the latter is available from impOS™ 38). These error policies are constants that are passed to server.setsendtimeoutpolicy() as its first argument.
In the case of RETURN_ON_ERROR, you may register a function to perform housekeeping when the connection is lost; this is done by passing the function’s name (or an inline function) to the imp API method server.onunexpecteddisconnect(). You must call server.connect() at some future time if you wish to re-establish the link; it will not be done for you.
RETURN_ON_ERROR_NO_DISCONNECT also sees the imp continue executing code. If all of the data waiting to be sent will not fit entirely into the send buffer (which may already contain data to send), the error SEND_ERROR_WOULDBLOCK is returned by the sending method (eg. agent.send()). The device does not disconnect. This policy ensures you are informed and can take appropriate action when the amount of data you are adding would cause Squirrel to block: an occurrence which takes place when impOS has to wait for the buffer to drain before it can add any remaining data from the send command. It also allows you to trap circumstances where the volume of data to be sent might such that the time taken to send it exceeds the timeout setting, causing the imp to return a send error code of SEND_ERROR_TIMEOUT and disconnect (under RETURN_ON_ERROR).
At any time, the device can be put into an extremely low power state by calling any of the imp API methods server.sleepfor(), server.sleepuntil(), imp.deepsleepfor() or imp.deepsleepuntil(). Please see the API documentation for the differences between these calls. Deep sleep effectively shuts the device down: Squirrel code is halted and any data in memory is lost. However, data can be preserved in the device’s nv table, a small part of memory that remains powered up for this purpose. The contents of the nv table will be lost if the device’s power is cut.
Note Deep sleep is not currently available on the imp005. The imp004m does not provides an nv table.
The device may wake from deep sleep early if its wake-up pin has been configured and a wake signal is triggered. However the device is woken, when it wakes it performs a warm start. It will not automatically reconnect to the server.
On wake, your Squirrel program is run afresh; if it sets the timeout policy (see above) early on to RETURN_ON_ERROR, you will need to connect manually using server.connect(). Until the policy is set in code, the default policy, SUSPEND_ON_ERROR, remains in force and so the device will not attempt to connect until Squirrel code which requires server access is run, such as server.log().
The recommended approach to manually putting the device into deep sleep is to do so only when you are sure the device is idling, ie. any and all data that needs to be sent to the server has been transmitted. This can be achieved using the imp API method imp.onidle(). This registers a function name or an inline function to be executed when the device goes idle.
See also ‘Wakeup Pin’, below.
The following topics cover problems whose resolution centers on the device itself: the hardware connected to the embedded imp.
The device disables its LED 60 seconds after power-on in order to reduce power consumption. The device can be power cycled to re-enable the LED temporarily, or the imp API method imp.enableblinkup() can be called with
true as its argument. You should always ensure the LED is flashing before attempting to configure the device using BlinkUp.
A device’s imp is designed to be driven by a 3.3V DC power supply, commonly derived from a 5V USB feed or from connected batteries. The imp’s operational power range is 1.8-3.6V, but WiFi requires at least 2.5V. If the supply voltage drops below 2.5V, the imp will continue to process Squirrel code (provided the supply is 1.8V or greater) but WiFi will be disabled.
A common source of BlinkUp configuration and connection problems is insufficient power to maintain WiFi while the device makes its first connection to the impCloud, during which process it is authorized to connect to the server in future. This can be caused by low batteries, a power supply with insufficient current capacity, or a supply with insufficient voltage. If the power supply can’t support the imp, the imp will attempt to connect, run out of power, reset, and repeat. This can appear as a fast red blink pattern as the imp quickly reboots.
A device’s imp is designed to operate across a wide range of WiFi signal strengths, but positioning the device at extreme distances may cause connectivity to be lost. Walls, particularly those with metal in their construction, will impede the signal between wireless router and imp.
Many premises suffer from ‘dead zones’ where construction idiosyncrasies result in a negligible WiFi signal. If you need to place your device in such a location, you should consider placing a WiFi access point nearby; it can be connected to the router using Ethernet cable or a through-the-mains link such as a powerline network.
The WiFi sub-system in the imp001 through imp004m does not support 802.11n or 802.11a 5GHz operation, only 802.11b/g/n 2.4GHz operation. The imp005 can connect to 802.11a and 802.11n 5GHz networks.
All imps support WEP, WPA and WPA 2 consumer-level wireless security, but are not currently compatible with WPA 2 Enterprise. WiFi networks which require you to log-in through a presented webpage — so-called ‘captive’ networks — are not supported at this time. Many public hotspots operate in this unsupported mode.
The imp communicates with the impCloud through TCP port 31314. If your device is not connecting, check that this port has not been blocked by the router’s firewall, or by another firewall on the path between imp and server. If TCP port 31314 is closed, the imp will fall back to port 993 and then port 443. It also used port 80 to acquire impOS updates. The imp does not require that UDP ports 31314, 993, 443 or 80 be open.
Some routers and access points may over-power the imp’s receiver if the imp is placed very close to them. And vice versa: the imp can overpower those devices too. Do not assume that placing the imp right next to the router is the best way to get a good signal. You can use the imp API method imp.rssi() to determine WiFi signal strengths at given distances from the router.
The imp003, imp004m and imp005 offer a broader array of IO options than did the imp002 or the imp001. To accommodate these options, it has been necessary to adopt a modified nomenclature for their pins. Consequently, Squirrel code addressing pins or peripherals on the imp001 or imp002 will require modification to reference the new pin naming conventions. Using imp001/imp002 pin naming in code developed for later imps — or vice versa — will generate a Squirrel ‘index not found’ error.
The wakeup pin — pin 1 on the imp001 and imp002; pin W on the imp003 and the imp004m (imp005 does not support deep sleep) — can be used to wake the imp from a deep sleep, but only if the pin is configured with this capability before the imp goes into deep sleep. To configure the pin for this role, use the following code:
Once the imp is in deep sleep (see above) setting pin 1 to logic high will wake the device, triggering a warm boot. The imp wakes when the pin is high, not on the rising edge. The external device responsible for signalling the wakeup pin should subsequently drive the pin low; the imp can’t return to sleep if the wakeup pin remains high. An internal pull-down is automatically enabled when the wakeup pin is configured.
Problems controlling and receiving data from connected I²C devices can often be traced to how the peripheral is addressed, or how it is wired up to the device‘s imp.
All peripherals on a given I²C bus must have a unique address. The imp API’s I²C methods which take the address as a parameter expect the 7-bit address to be placed in bits 7 through 1 of an 8-bit value; bit 0 is the read/write status bit. Peripheral datasheet I²C addresses must therefore be bit-shifted one place to the left; use Squirrel’s
<< operator to achieve this:
local impI2Caddress = datasheetI2Caddress << 1;
Some datasheets now present I²C addresses in 8-bit format; these do not need to be shifted. These datasheets often include separate address for read and write operations. Essentially, they are ‘pre-setting’ the read/write bit, bit 0. Use the write address in your Squirrel code; the impOS sets the correct value of the read/write bit for you.
I²C data and clock lines are active low and therefore each require the presence of a pull-up resistor usually of between 1kΩ to 10kΩ resistance. Only one resistor is required per line, irrespective of the number of devices connected. Many I²C peripherals can be purchased on small breakout boards which have pull-ups fitted, but the peripherals themselves do not.
The imp005 module supports USB in host mode. It is the only imp module with USB support, and is limited to a single USB 1.1/2.0 Full Speed (12Mbit/s) device. USB hubs are not supported.
It is up to you to develop suitable driver code for any USB device you intend to connect to the imp005, but the imp API’s usb object provides the tools you need to do so. The USB library will simplify this process for you.