Introduction
The QuickStart Library (QSL) is an additional library that sits on top of the SmartMesh C Library that handles most application logic, so the user need only supply low-level hardware drivers, and use a handful of APIs to connect to a network and send data. This removes the need for intricate knowledge about the SmartMesh IP mote and network, greatly reducing firmware development time for your microcontroller. The raw C Library functions can be mixed with the QSL, giving the user full access to all mote APIs should need arise.
The library also includes example code for certain platforms (currently only the Raspberry Pi), and this guide will also cover some details on setting these up.
This is a step-by-step guide for how to get started with data publishing from a SmartMesh IP Mote with an external microcontroller (MCU) connected serially. By following these steps, you can make your application publish data into a SmartMesh IP network by utilizing only a few intuitive functions from the SmartMesh QuickStart Library (QSL).
1.1 Necessary Hardware
- Microcontroller/development board of your choice
- With necessary programmer
- SmartMesh IP Mote (DC9003A-B)
- With 6 female-female jumper cables
- SmartMesh IP Manager (DC2274A-A)
- SmartMesh Interface Board (DC9006A)
- With USB to USB-micro cable
- Computer (should support Python and Java)
1.2 Necessary Software
- FTDI Serial Drivers
- IDE/programmer/debugger of your choice
- SmartMesh C Library
- SmartMesh QuickStart Library
- Git (optional)
1.3 Acronyms, Abbreviations, and Definitions
API | Application Programming Interface |
---|---|
CLI | Command Line Interface |
FSM | Finite State Machine |
GPIO | Genearal-Purpose Input/Output |
HDLC | High-Level Data Link Control |
OS | Operation System |
QSL | QuickStart Library |
RPi | Raspberry Pi |
UART | Universal Asynchronous Receiver/Transmitter |
2 Prepare Libraries
2.1 About
The SmartMesh QSL abstracts the complexity of the SmartMesh IP mote startup and network search/join procedure into a few intuitive functions. It utilizes the SmartMesh C Library, which provides a full implementation of the serial API of the SmartMesh IP mote.
While the QSL provides sufficient functionality for sending/receiving data and configuring the most important network settings on a SmartMesh IP mote, more advanced applications that need access to all parameters should access the mote serial API directly.
2.2 Download
There are two ways to download the QuickStart Library:
Clone The Source Code
- Clone the repository: TODO: Add link when public repo created
- Checkout the latest release: TODO: Refer to latest release
Initialize and update the neccessary C Library submodule:
(...)
/QuickStart_Library
$ git submodule init
(...)
/QuickStart_Library
$ git submodule update
Download Zip/Tar
- Go to the QSL release page and download the latest zip/tar: TODO: Add link when public repo created
- Go to the C Library release page and download the latest zip/tar: TODO: Can possibly be added as attachment to QSL release. If not: Make a note about why it needs to be downloaded separately
- Unzip the files using your favourite compression tool.
2.3 Directory Structure
The QSL repository contains the following directories:
- sm_qsl/ contains the QuickStart Library as a collection of headers (.h) and source code files (.c).
- sm_clib/ is a submodule that contains the underlying C Library, with sample applications for its direct use.
- sm_clib/ is the C Library itself as a collection of headers (.h) and source code files (.c).
- ports/ contains an example of the necessary C Library ports.
- examples/ contains sample applications which use the C Library directly.
- sm_clib/ is the C Library itself as a collection of headers (.h) and source code files (.c).
- examples/ contains sample applications utilizing the QSL
- rpi/SimplePublish/ contains an example that connects and starts publishing random data, where the necessary porting functions have been implemented for the Raspberry Pi.
- rpi/SimplePublish/ contains an example that connects and starts publishing random data, where the necessary porting functions have been implemented for the Raspberry Pi.
The SmartMesh C Library will be in the sm_clib/ directory from the separate unzipped folder if you chose the zip download.
The SmartMesh QuickStart Library, and C Library it depends on, are both designed so you can drop their directories into your application without modification, i.e. these two folders from the structure above:
- sm_qsl/
- sm_clib/sm_clib/
You are free to modify them to suit your needs; however, we recommend you avoid changing the contents of these two directories, as this will allow you to easily replace them with future revisions.
In addition to the files in these folders, you need to implement a handful of functions, as discussed in the next section.
2.4 Port to Your Hardware
The QSL and the underlying C Library are written to be used as-is in any C-based platform; however, you have to implement a handful of functions to adapt them to a specific platform. These functions are implemented in the example code provided for certain platforms (presented in later chapters), so you can skip the details of this section for now if you plan on using these (or simply wish to have a look at the examples first).
The necessary functions are declared in following header files:
- dn_uart.h: These functions allow the SmartMesh C Library to send bytes over the serial port, and receive bytes from the serial port. A "flush" function is provided in case the serial (UART) driver of the user platform is frame-oriented rather than byte-oriented.
- dn_lock.h: These functions allow the SmartMesh C Library to operate in a multi-threaded environment. If this is the case in the user system, the implementation of these functions would typically consist of pending/posting a mutual exclusion semaphore (mutex); if not, simply use stub functions (i.e. "empty functions").
- dn_endianness.h: These functions are used to match multi-byte API fields (which are big-endian) to the endianness of the platform.
- dn_time.h: These functions allows the QSL to perform timing and schedule tasks.
- dn_watchdog.h: These functions allow the QSL to make sure any watchdog in the user application is fed during processes that can take some time (e.g. searching for a network). If no watchdog is present, simply use stub functions.
The QSL is currently meant to be run in a single threaded environment, thus you can just use stub functions for the prototypes in dn_lock.h. If you wish to run the QSL in a multi-threaded environment, you should create your own mutex (separate from the prototypes in dn_lock.h) to be locked/unlocked before/after calls to the QSL API.
3 Install FTDI Serial Drivers
To be able to connect to and configure the mote and manager, your computer will need the necessary FTDI Serial Drivers. Most modern OSes come with FTDI drivers pre-installed (e.g. Linux), but you may have to install them manually if they do not configure automatically when you plug in the interface board or manager. Follow the installation guide corresponding to your OS if you have any trouble.
If installed correctly, the interface board or manager should appear as a group of 4 serial ports when connected via USB:
- Windows: 4 COM ports can be viewed using the Device Manager (Control Panel -> System -> Hardware -> Device Manager -> Ports)
- Linux: $ dmesg | grep FTDI should detect FTDI converters attached to /dev/ttyUSBn to /dev/ttyUSBn+3
The ports of interest are the third and fourth, which map to the CLI and API, respectively, as defined by Table 1.
Device | Serial Port Number | Usage | Baudrate | Data Bits | Parity | Stop Bits |
---|---|---|---|---|---|---|
SmartMesh IP Manager | third* | CLI | 9600 | 8 | No | 1 |
fourth* | API | 115200** | 8** | No** | 1** | |
SmartMesh IP Mote | third* | CLI | 9600 | 8 | No | 1 |
fourth* | API | 115200** | 8** | No** | 1** |
*: Refers to the serial ports created by the FTDI drivers.
**: Default values (can be changed).
Note that for Windows, the COM port assignment will change whenever you connect the interface board (or manager) to a different USB port.
4 Prepare Mote
4.1 Select Slave Mode
By default, the motes in starter kits are configured for master mode; a demo mode where the API is disabled and an application is run that generates sample data and controls joining. To use the mote alongside an external MCU, the mote has to be configured for slave mode; the API is enabled and the mote expects a serially attached application to control it.
- Start by connecting the mote to your computer via the interface board, as shown in Figure 1.
- Identify the port name that maps to the CLI. For example, if you are in Windows and see the four COM ports pictured below, the CLI will be accessible through COM14.
- Connect to the mote CLI with a third-party serial terminal of your choice (e.g. putty). See Table 1 for configuration details.
Use the get mode command to see the current mode:
> get mode
master
Use the set mode command to switch to slave mode, followed by reset for the change to take effect. After rebooting, a new get mode should confirm the persistent mode change.
> set mode slave
> reset
> SmartMesh IP mote, ver 1.3.3.1 (0x100)
> get mode
slave
- Disconnect the mote from the interface board and make sure to remove its battery (if any), as we will power the mote from the MCU.
4.2 Connect to Your Microcontroller
You will need to connect 4 wires between your MCU and the mote for power and serial communication, as shown in Table 2. In addition you need to ground the mote RX Request to Send (RTS) and TX Clear to Send (CTS); unless your MCU cannot wake on data and has to use these accordingly (the mote does not need incoming flow control).
Table 3 lists the names (equal to those found on the silkscreen) of the P1 pin header on the DC9003A mote board visible in Figure 2.
MCU | Mote |
---|---|
3.3 V | VBAT |
Ground | GND |
UART TX | RX |
UART RX | TX |
Name | Pin # | Name | |
---|---|---|---|
TX CTSn | 1 | 2 | TX RTSn |
TX | 3 | 4 | GND |
RX | 5 | 6 | RX RTSn |
RX CTSn | 7 | 8 | CO TX |
CO RX | 9 | 10 | GND |
RESETn | 11 | 12 | F P ENn |
I MISO | 13 | 14 | I MOSI |
I SSn | 15 | 16 | I SCK |
GND | 17 | 18 | TCK |
TMS | 19 | 20 | TDO |
TDI | 21 | 22 | VUSB_3V6 |
PGOOD | 23 | 24 | GND |
VBAT | 25 | 26 | KEY |
EHORBAT | 27 | 28 | RSVD |
I/O 1 | 29 | 30 | I/O 2 |
V+ | 31 | 32 | +5V |
5 Prepare Manager
If you installed the correct drivers, you only have to insert the USB port in your computer: The manager will power up and start creating a network automatically.
Similar to the mote via the interface board, you should now see 4 new serial ports, where the third and fourth give you access to the CLI and API, respectively.
5.1 Factory Default Values
By default the manager is shipped with a well-known network ID and join key that your application will need to connect to its network, so you do not need to configure anything. However, it is useful to know about certain commands available through the CLI. These commands are presented in the next section, while relevant default values for its configuration parameters are listed in Table 4.
Parameter | Comment | Default Value |
---|---|---|
netid | Network ID | 1229 |
commjoinkey | Common Join Key (hex) | 44 55 53 54 4E 45 54 57 4F 52 4B 53 52 4F 43 4B |
basebw | Base bandwidth, i.e. period between packets [ms] | 9000 |
Refer to the SmartMesh IP User's Guide for a complete list of default configuration parameters for the manager.
5.2 Useful CLI Commands
With the manager connected to your computer via USB:
- Just like with the mote, identify the correct serial port name and connect to the CLI with a serial terminal of your choice (again, see Table 1 for configuration details).
Unlike the mote, you will first have to login to have access to the commands we want:
login> login user
- You now have access to a wide range of commands, where the most interesting ones are shown below.
6 User Application
This Chapter presents how to use the QSL in your application. We begin by presenting details about the API, followed by an example of how a user application might look.
More explicit examples of code are given for certain platforms in later chapters (currently only for the Raspberry Pi).
6.1 The QuickStart API
Instead of reading the full user guide for the SmartMesh IP network and mote serial API, the QuickStart Library allows you to get started with simple data publishing by familiarizing yourself with only a handful of functions. These functions define the API and are listed below, followed by a detailed explanation.
QuickStart API
bool dn_qsl_init( void ); bool dn_qsl_isConnected( void ); bool dn_qsl_connect(uint16_t netID, const uint8_t* joinKey, uint16_t srcPort, uint32_t service_ms); bool dn_qsl_send( const uint8_t* payload, uint8_t payloadSize_B, uint16_t destPort); uint8_t dn_qsl_read(uint8_t* readBuffer); |
6.2 Example Application
Assuming you have downloaded the libraries and ported the necessary functions, your application simply needs to include the QSL header file, dn_qsl_api.h, and use the API as described in the previous section.
Below is a short example of how an application can send a data struct every 5 seconds, followed by parsing any downstream data received since the last transmission.
6.3 Further Tips
Base Bandwidth vs Service Request
Every mote is given a base bandwidth (service) upon joining the network (default 9000 ms) that specifies how often the mote can publish data. As noted in the QSL API, you can specify that the mote should request a specific service when connecting. However, this process can add between 20 - 60 seconds for connect to complete. Unless the motes in your network actually need individual bandwidths, you should rather change the base bandwidth granted by the manager: This is easily changed with the set config CLI command.
Change Network ID and Join Key
The default network ID and join key is well known, so unless you change these, anyone can potentially connect to your network. You can easily change both with the set config CLI command on the manager, and then use the same in your application.
Aggregate Data
If your application wants to publish data periodically etc. you should (if possible) aggregate many measurements into each transmission, rather than sending one for each measurement. The SmartMesh IP Network is designed with power consumption in mind, and its motes use very little power, except when transmitting data. Also, since the total bandwidth of a network is limited (36.4 packets/sec for the embedded manager), you will run into trouble if 40 motes requests a bandwidth to transmit messages every second (i.e. a service of 1000 ms).
Back Off Mechanism
Sending can fail if the mote is very busy. The following back off algorithm is recommended such that you only publish at a level that the network can tolerate:
- If send fails (but you are still connected), double the interval between packets. Upon subsequent failures, increase to 3x, 4x, ..., 255x.
- When send succeeds after failing, decrease the interval along the same pattern: 5x, 4x, ..., 1x.
Use the Access Control List
The manager maintains an Access Control List (ACL) which associates a mote's MAC address with a mote-specific join key. Once an ACL entry has been set, the manager will not let motes join the network that are not in the ACL. You can add a mote manually to the ACL through the set acl CLI command.
7 SimplePublish for Raspberry Pi
The QSL includes a SimplePublish example for the RPi: Along with files that implement the necessary porting functions, this example code is a single main.c file that attempts to connect with the default network ID and join key. Upon success, it starts publishing random data with an interval matching the service it requested. The example also prints any downstream user data that arrives between each transmission.
In the following sections we will guide you through the steps necessary to get the example up and running. We use a Raspberry Pi 3 Model B v1.2 running Raspbian Jessie, but the instructions will include tips on how to make it work on other models and for older versions of Raspbian.
7.1 Prepare the Raspberry Pi
We assume that you have already installed the latest release of Raspbian Jessie on a RPi, and that you wish to use the UART available on the GPIO header.
7.1.1 Disable Serial Console
The built in serial port that we want to use to communicate with the mote is by default used by the console, thus we have to disable this. To make things more complicated, the available UART has changed for the Raspberry Pi 3: The added Bluetooth module has "stolen" the high performance hardware serial port from the GPIO header; replacing it with a port that is partly software and a bit flaky. Hence, depending on which model you are using, the device name of interest to you will differ:
- Raspberry Pi 3: /dev/ttyS0
- Raspberry Pi 1-2: /dev/ttyAMA0
In Raspbian Jessie (as of May 2016) a serial port alias has been introduced to mend the effects of the changed serial portname: serial0 will point to the UART available on the GPIO header, i.e. ttyS0 for the RPi 3 and ttyAMA0 for older models. This alias is used in the SimplePublish example, thus it should work on any RPi model running the latest release of Jessie.
It seems the serial port alias does not work for the Raspberry Pi 1: You will have to edit the UART portname in dn_uart.c to ttyAMA0.
Enable Serial and Lock CPU Core Frequency
The serial port is disabled by default in Jessie. Also, on the RPi 3 the flaky serial port (ttyS0) can give you trouble unless you lock the CPU frequency.
To fix this, edit /boot/config.txt:
$ sudo nano /boot/config .txt |
and add the following line(s) at the bottom:
Raspberry Pi 3
enable_uart=1 core_freq=250 |
enable_uart=1 |
You can also enable the GPIO serial port via the GUI: Menu > Preferences > Raspberry Pi Configuration > Interfaces > Serial
Stop and Disable Getty Service
Raspberry Pi 3
Remove Console from Commandline
First, make a backup of /boot/cmdline.txt in case you mess something up (it contains kernel parameters):
$ sudo cp /boot/cmdline .txt /boot/cmdline_backup .txt |
Then edit the original:
$ sudo nano /boot/cmdline .txt |
You should see something like the example below, where serialDeviceName can be serial0 or ttyAMA0, depending on which Raspberry Pi you use.
/boot/cmdline.txt
1 | dwc_otg.lpm_enable=0 console=<serialDeviceName>,115200 console=tty1 root= /dev/mmcblk0p2 rootfstype=ext4 elevator=deadline fsck .repair= yes root wait |
Remove the line console=<serialDeviceName>,115200, before saving and rebooting for the changes to take effect.
7.1.2 Connect to Mote
The GPIO pins for the RPi is listed in Table 5, with the relevant pins color coded. Table 6 shows the mapping between the RPi and the mote. Note that you can of course just connect the RX RTSn and TX CTSn to GND on the mote itself, as can be seen in the example in Figure 4.
If you choose to connect the mote via the DC9006 interface board, you should not connect any other wires (not even the RX RTSn and TX CTSn to GND), as this will lead to an API bus conflict.
Long cables may corrupt the API bus communication: e.g. using an official I/O extender cable for the RPi might not work.
Note the the two 5 volt pins right above the ground and two UART pins: You might fry the mote if you mistakenly connect to these!
Name | Pin # | Name | |
---|---|---|---|
3.3 V | 1 | 2 | 5 V |
SDA1, I2C | 3 | 4 | 5 V |
SCL1, I2C | 5 | 6 | GND |
GPIO 04 | 7 | 8 | TXD0 |
GND | 9 | 10 | RXD0 |
GPIO 17 | 11 | 12 | GPIO 18 |
GPIO 27 | 13 | 14 | GND |
GPIO 22 | 15 | 16 | GPIO 23 |
3.3 V | 17 | 18 | GPIO 24 |
SPI MOSI | 19 | 20 | GND |
SPI MISO | 21 | 22 | GPIO 25 |
SPI CLK | 23 | 24 | SPI CE0 N |
GND | 25 | 26 | SPI CE1 N |
ID SD | 27 | 28 | ID SC |
GPIO 05 | 29 | 30 | GND |
GPIO 06 | 31 | 32 | GPIO 12 |
GPIO 13 | 33 | 34 | GND |
GPIO 19 | 35 | 36 | GPIO 16 |
GPIO 26 | 37 | 38 | GPIO 20 |
GND | 39 | 40 | GPIO 21 |
RPi | Mote |
---|---|
3.3 V | VBAT |
GND | GND |
TXD0 | RX |
RXD0 | TX |
GND | RX RTSn |
GND | TX CTSn |
The GPIO header for models older than Raspberry Pi B+ is similar, but does not have pins 27 - 40.
7.2 Compile and Run
This section shows you two ways to compile and run the QSL with the provided example SimplePublish code:
- Directly on the RPi with a makefile.
- Remotely on a computer using NetBeans.
The former is quick and easy, but the latter is recommended if you plan on further developing any code for the RPi.
7.2.1 Makefile
7.2.2 NetBeans
NetBeans is a free, open source IDE that can be installed on any OS that support Java. By simply adding the RPi as a remote build host, NetBeans will make sure to synchronize files and build the project remotely; returning any console output as you run the application on your RPi.
8 9 Test Downstream Data
The aforementioned DustLink apps that you can create has currently not implemented support for sending downstream messages to motes (although you might have noticed the "Fields toMote" that implies that its support is in the pipline). As an alternative, we present two simple ways to test sending downstream data to a mote. Both of these use tools part of the SmartMesh SDK, so the first thing you will have to do is to fetch this:
- If you are on Windows, the simplest way to do this is to download and unzip the latest executables from the SmartMesh SDK Release page on GitHub (look for SmartMeshSDK-X.X.X.X-win.zip).
- Otherwise, you will have to download and compile/run the Python source code directly. This has several library requirements, so it could be smart to have a look at these dustcloud installation instructions.
9.1 SimpleIPDownstreamMgr
SimpleIPDownstreamMgr is a simple console application that only asks you to specify the name of the port that the serial API of the manager is connected to (e.g. COM15). It will then connect to said manager, fetch a list of all operational motes connected to the network and start sending "Hello, World!" to each of them every 5 seconds, addressed to port 60000. The SimplePublish example application is set to listen to the same port, and should be able to parse and print the message.
If you have DustLink running and connected to the manager, it will occupy the port with the manager serial API, thus preventing any other application to do the same. In other words, you have to stop DustLink when using this application.
9.2 APIExplorer
APIExplorer is a GUI that allows you to interact with the full API of all SmartMesh devices. The interesting API command here is sendData:
- Set network type to SmartMesh IP, device type to manager and press load.
- Enter the port name that the serial API of the manager is connected to (e.g. COM15) and press connect.
- Select sendData from the command drop down list
- Enter the necessary fields (options has to be 0) and press send.
If you have DustLink running and connected to the manager, it will occupy the port with the manager serial API, thus preventing any other application to do the same. In other words, you have to stop DustLink when using this application.