Jorjin Ameba Arduino Library

Today we will have a look at the Arduino-like Jorjin Ameba board with built in support for WiFi and NFC. Taking the pricetag of 25$ into account makes this an easy choice for your IoT projects!

For this post I created a Jorjin Ameba library which can be imported directly into the Arduino IDE seamlessly, thus making the classic blink example a breeze.

We will walk through the following steps

  • Specs of jorjin board and “special features”
  • How to run the example
  • Demo

The Jorjin board

board

Overview of the Jorjin Ameba WiFi board.

The Jorjin Ameba WiFi board has built-in WiFi and  NFC thus making it very much prepared for IoT.

As can be seen from the above image, the Ameba board has an Arduino-like form factor with a similar pinout. For the simple LED blink example, we will be using a digital pin.

Getting the example up and running

To run the example we need to install the Ameba board libraries and the Ameba specific uNabto files. We also need a device name and key, both of which can be created at developer.nabto.com

Furthermore an LED (and appropriate resistor) is needed.

Step 1: Download General Ameba Libraries install

Follow the steps laid out here to install the general Ameba libraries into the Arduino IDE OR read it right here:

Open up the Arduino IDE. Click File -> Preferences and then copy this

https://github.com/Ameba8195/Arduino/raw/master/release/package_realtek.com_ameba_index.json

into the Additional Boards Manager URLs input field. Click OK

Now click Tools –> Board: -> Boards Manager

Here we search for Ameba and click Install

The Jorjin Ameba board Arduino libraries are now installed

Step 2: uNabto libraries install

There are two ways of getting the uNabto libraries.

Using git

git clone --recursive https://github.com/nabto/unabto-jorjin-sdk

then change directory to the unabto-jorjin-sdk folder and run

bash Make.sh

OR download the release zip file unabto-jorjin-sdk.zip

No matter which way, we can now add the library to the Arduino IDE via Sketch -> Include Library -> Add .ZIP Library... and then browse to and add the unabto-jorjin-sdk folder that was just downloaded.

Run the example

We can now open the LightSwitch.ino example by going to File -> Examples -> Nabto-Ameba -> LightSwitch

Here we need to enter the SSID and password of the wireless network we want to attach to. Furthermore we need to input the device name and key we created at developer.nabto.com

Finally we need to remember to wire the LED and resistor up like so (try switching pins around if it does not work at first)

jorjin_wiring

Wiring of the LED. Image taken from the Ameba documentaion, available from here (signing up is required)

When the example is compiled and uploaded to the device we simply need to press the reset button (see the above image). The board should now reset, connect to the specified wifi network and run uNabto.

We can now control the LED by going to devicename.demo.nab.to in the Nabto client of your choice. (devicename is the unique name created at portal.nabto.com). Simply use the guest account for this demo. We can now control the LED by moving the slider.

Demo

As always, the full code can be found at Github. If you feel like experimenting with the many uses of the Nabto framework, please visit our developer portal where you can manage up to 10 devices for free !

Dartino + uNabto

The experimental open-source project Dartino enables you to write software for embedded systems using the modern Dart language and a set of libraries, that let you be highly productive. So why not add another powerful library? Thanks to  improvements to the FFI library in the latest Dartino SDK, we are now able to use the uNabto framework from within Dartino!

dartino-logo

Note: Due to remaining limitations of the Dartino FFI library this is currently only working on a local PC. Thanks to the Dartino team this might be resolved in the near future…stay tuned!

Why use uNabto in your Dartino solution?

Have you ever thought about connecting to your embedded system running Dartino from outside your local network without nerve-racking router and firewall configurations or heavy and intransparent cloud services? Running the uNabto server on your embedded system, you can establish a fast and secure Peer-to-Peer connection using only a static ID – from everywhere, no matter what is in between.

So how does Nabto do this? The drawing below gives a brief overview. Your embedded system represents the Device running the uNabto server. As soon as it connects to the internet it identifies itself at the Nabto Basestation, using its unique ID. If a Client wants to connect to the embedded system, a connect request with the ID is sent to the Basestation, and a direct connection to the device is established. A client can be a HTML page running in a desktop browser extension (IE, Firefox) or the Nabto Mobile App (iOS, Android), or a custom Nabto API Client. If you prefer Cordova also check out our recently released Nabto Cordova Plugin.

nabto-security

Get the sample application

We published a sample application including the uNabto Dartino library on GitHub. In order to set it up, follow the three steps below.

Step 1: Clone the repository

$ git clone --recursive https://github.com/nabto/unabto-dartino
$ cd unabto-dartino

Step 2: Download and unzip the latest Dartino SDK

Linux:
$ curl "https://storage.googleapis.com/dartino-archive/channels/dev/raw/0.4.0-dev.0.0/sdk/dartino-sdk-linux-x64-release.zip" -o "/tmp/dartino-sdk.zip"
$ unzip /tmp/dartino-sdk.zip

Mac OS:
$ curl "https://storage.googleapis.com/dartino-archive/channels/dev/raw/0.4.0-dev.0.0/sdk/dartino-sdk-macos-x64-release.zip" -o "/tmp/dartino-sdk.zip"
$ unzip /tmp/dartino-sdk.zip

Step 3: Build the C library

$ mkdir build
$ cd build
$ cmake ..
$ make
$ cd ..

Use the sample application

The sample application acts as an embedded device that controls a virtual living room light. To connect to the application we first need to assign a unique Device ID and a pre-shared encryption Key to it. You can get them from developer.nabto.com after adding a new Device. Both id and key are passed as strings to the constructor of the uNabto server:

main() {
  // Configure the uNabto server with a server ID and a pre-shared key obtained
  // from `developer.nabto.com`.
  var unabto = new UNabto("devicename.demo.nab.to", "35d0dca...");

You can now fire up the application on you local PC with the Dartino tool:

$ ./dartino-sdk/bin/dartino run src/app.dart

You should see a log printout similar to this:

15:18:54:118 unabto_common_main.c(127) Device id: 'devicename.demo.nab.to'
15:18:54:118 unabto_common_main.c(128) Program Release 123.456
15:18:54:118 unabto_app_adapter.c(698) Application event framework using SYNC model
15:18:54:118 unabto_context.c(55) SECURE ATTACH: 1, DATA: 1
15:18:54:118 unabto_context.c(63) NONCE_SIZE: 32, CLEAR_TEXT: 0
15:18:54:118 unabto_common_main.c(206) Nabto was successfully initialized
15:18:54:118 unabto_context.c(55) SECURE ATTACH: 1, DATA: 1
15:18:54:118 unabto_context.c(63) NONCE_SIZE: 32, CLEAR_TEXT: 0
15:18:54:118 unabto_attach.c(787) State change from IDLE to WAIT_DNS
15:18:54:118 unabto_attach.c(788) Resolving dns: devicename.demo.nab.to
uNabto version 123.456.
15:18:54:330 unabto_attach.c(809) State change from WAIT_DNS to WAIT_BS
15:18:54:353 unabto_attach.c(474) State change from WAIT_BS to WAIT_GSP
15:18:54:364 unabto_attach.c(266) ######## U_INVITE with LARGE nonce sent, version: - URL: -
15:18:54:375 unabto_attach.c(575) State change from WAIT_GSP to ATTACHED

The uNabto server is now ready and you can connect to it from any client. When entering you device ID into your browser or Nabto App, you can see the uNabto Demo client. Using the light switch you can now turn the virtual living room light on and off from everywhere!

dartino-firefox

Light 1 turned ON!
Light 1 turned OFF!

For demonstration purposes, the example application closes the server connection after ~10 seconds.

The sample application in detail

The sample application is quite straightforward since all complicated interfacing to the native C library is done in the uNabto library. We only need to include it with

import 'unabto.dart';

In the main() function we construct the uNabto server object by passing the Device ID and the pre-shared Key as parameters. However, the server is started later with the init() function. You also might want to check if there were any errors doing that.

  var unabto = new UNabto("devicename.demo.nab.to", "35d0dca...");

  // Get version information.
  print("uNabto version ${unabto.version}.");

  // Attempt to init and start the server.
  int result = unabto.init();
  if (result != 0) {
    print("Init error: $result.");
  } else {

To handle incoming events from the client we register handler functions for every query ID. We’ll come back to the handlers later on.

    // Register two event handlers for the `light_write.json` and
    // `light_read.json` queries.
    unabto.registerReceiver(1, onLightWrite);
    unabto.registerReceiver(2, onLightRead);

You can now do other stuff. The sample application just sleeps for 10 seconds to demonstrate how to close the uNabto server in the end.

    // This is where the main app code would usually run.
    // In this sample we just sleep a bit.
    sleep(10000);

    // Clean-up: Deallocate foreign memory and functions.
    unabto.close();

The following handler takes care of the query with ID #1. It reads the light’s ID and the light’s new state from the incoming readBuffer. The new state is applied to the virtual light. Afterwards, it returns the new state to the client by writing it to the outgoing writeBuffer.

void onLightWrite(UNabtoRequest appRequest, UNabtoReadBuffer readBuffer,
    UNabtoWriteBuffer writeBuffer) {
  // Read the request parameters.
  int lightId = readBuffer.readUint8();
  int lightOn = readBuffer.readUint8();

  // Set the light state.
  int lightState = setLight(lightId, lightOn);

  // Write the response parameter.
  writeBuffer.writeUint8(lightState);
}

The following handler takes care of the query with ID #2. It reads requested light’s ID from the incoming readBuffer, retrieves the state of the virtual light and returns the light’s state to the client by writing it to the outgoing writeBuffer.

void onLightRead(UNabtoRequest appRequest, UNabtoReadBuffer readBuffer,
    UNabtoWriteBuffer writeBuffer) {
  // Read the request parameters.
  int lightId = readBuffer.readUint8();
  int lightState = readLight(lightId);

  // Write the response parameter.
  writeBuffer.writeUint8(lightState);
}

Diving deeper

If you want to explore the whole available interface of the uNabto library have a look at it on GitHub. It also demonstrates how to use the Dartino FFI library to access a foreign library and work with its structures and byte arrays.

Finally, if you want to modify the underlying uNabto C library checkout the files in this directory. For example, In the unabto_config.h you can turn off the logging or disable remote connections.

Nabto + FreeRTOS running on Cortex-M7 using the ST STM32F746G-DISCO Board

This post is outdated. Please have a look at the updated version incorporating our new AppMyProduct platform.

When working with STM32 ARM Cortex-M microcontrollers, the free embedded software STM32Cube from ST provides all necessary drivers and a collection of middleware components to reduce the initial development effort. One of the mentioned middleware components is the popular FreeRTOS real-time operating system Nabto is partnering with to create a powerful combined FreeRTOS+Nabto solution. This article explains the implementation of a demo project running Nabto + FreeRTOS on a STM32F746G-DISCO board.

nabto+stm32

STM32F74G-DISCO board running the demo

What you need

This demo is based and tested on the STM32F746G-DISCO board, but should be portable to similar STM32 boards. Same applies to your favorite IDE.

Why Nabto and how does it work?

Have you ever thought about connecting to your STM32 device from outside your local network without nerve-racking router and firewall configurations or heavy and intransparent cloud services? Running the uNabto server on your STM32 device, you can establish a fast and secure Peer-to-Peer connection using only a static ID – from everywhere, no matter what is in between.

So how does Nabto do this? The drawing below gives a brief overview. Your STM32 board represents the Device running the uNabto server. As soon as it connects to the internet it identifies itself at the Nabto Basestation, using its unique ID. If a Client wants to connect to the STM32 board, a connect request with the ID is sent to the Basestation, and a direct connection to the device is established. A client can be a HTML page running in a desktop browser extension (IE, Firefox) or the Nabto Mobile App (iOS, Android), or a custom Nabto API Client. If you prefer Cordova also check out our recently released Nabto Cordova Plugin.

Screen Shot 2016-02-29 at 13.23.22

Nabto in the STM32Cube Architecture

As mentioned before the STM32Cube provides a Hardware Abstraction Layer API and a selection of Middleware components. The uNabto server we want to implement builds on top of the STM32Cube middleware, as can be seen in the following diagram:

nabto+stm32cube-architecture.png

The uNabto server itself is divided into two layers:

  • The actual uNabto framework (uNabto SDK)
  • The uNabto Platform Adapter abstraction layer between the uNabto framework and the STM32Cube middleware

Hence, we only need to implement the uNabto Platform Adapter, in order to port the uNabto server to the STM32 platform.

Implementing the Platform Adapter

The Platform Adapter acts as link between the generic uNabto framework and the STM32Cube middleware layer, including the LwIP TCP/IP stack which will be used for networking. The LCD Log Utility is used to display the Nabto output on the screen.

The adapter is divided into single files, as suggested in the Nabto documentation (TEN023 Writing a uNabto device application, chapter 12):

  • unabto_config.h: Basic uNabto configuration
  • unabto_platform_types.h: Defines all necessary uNabto types
  • unabto_platform.h: Platform specific ad-hoc functions
  • network_adapter.c: Init, close, read and write functionality for network data
  • time_adapter.c: Time functions
  • dns_adapter.c: DNS resolving
  • random_adapter.c: Random generator
  • log_adapter.c: Logging

If you are interested in how the platform adapter is implemented in detail, check the adapter files in the Inc and Src directories of the demo on GitHub.

Implementing the Nabto Thread

After creating the Platform Adapter the uNabto Server is ready to use and the actual uNabto Device Application can be implemented. This is done in Src/nabto.c. Since the server will run in its own FreeRTOS thread, we first create the following thread method.

static void nabto_thread(void *argument)
{
  const char* nabtoId = "<DEVICE ID>";
  const char* presharedKey = "<KEY>";

  struct netif *netif = (struct netif *) argument;

  // Initialize Nabto
  nabto_main_setup* nms = unabto_init_context();
  nms->ipAddress = netif->ip_addr.addr;
  nms->id = nabtoId;
  nms->secureAttach = 1;
  nms->secureData = 1;
  nms->cryptoSuite = CRYPT_W_AES_CBC_HMAC_SHA256;

  const char *p;
  unsigned char *up;
  for (p = presharedKey, up = nms->presharedKey; *p; p += 2, ++up)
    *up = hctoi(p[0]) * 16 + hctoi(p[1]); // convert hex string to byte array

  unabto_init();

  for (;;) {
    osDelay(10);
    unabto_tick();
  }
}

It initializes the server among others with your unique Nabto ID and the pre-shared encryption key from developer.nabto.com (insert in highlighted lines). Then it starts an infinite loop calling the unabto_tick() method. This triggers the framework to check for new UDP packets and send responses. The time between ticks should be around 10 milliseconds, which is achieved by a hard OS delay.
To start the Nabto thread we provide a nabto_init() method. It is called by the main program after initializing the TCP/IP stack and either setting a static IP address or obtaining a dynamic IP address from a DHCP server.

void nabto_init(struct netif *netif)
{
  sys_thread_new("Nabto", nabto_thread, netif, DEFAULT_THREAD_STACKSIZE, NABTO_THREAD_PRIO);
}

The actual handling of received Nabto messages from the client is implemented in the application_event() function. The handler uses the message format used in the default HTML Device Driver, provided in the Nabto portal. In this demo the LCD display can be switched on and off by the client. For more information on how to create your own HTML DD, please refer to TEN024 Writing a uNabto HTML client.

application_event_result application_event(application_request* appreq,
                                           unabto_query_request* r_b,
                                           unabto_query_response* w_b)
{
  switch (appreq->queryId) {
  case 1: {
    // <query name="light_write.json" description="Turn light on and off" id="1">
    // <request>
    // <parameter name="light_id" type="uint8"/>
    // <parameter name="light_on" type="uint8"/>
    // </request>
    // <response>
    // <parameter name="light_state" type="uint8"/>
    // </response>
    // </query>

    uint8_t light_id;
    uint8_t light_on;

    // Read parameters in request
    if (!unabto_query_read_uint8(r_b, &light_id))
      return AER_REQ_TOO_SMALL;
    if (!unabto_query_read_uint8(r_b, &light_on))
      return AER_REQ_TOO_SMALL;

    // Set display according to request
    display_state = light_on;
    if (display_state)
      BSP_LCD_DisplayOn();
    else
      BSP_LCD_DisplayOff();

    // Write back display state
    if (!unabto_query_write_uint8(w_b, display_state))
      return AER_REQ_RSP_TOO_LARGE;

    return AER_REQ_RESPONSE_READY;
  }
  case 2: {
    // <query name="light_read.json" description="Read light status" id="2">
    // <request>
    // <parameter name="light_id" type="uint8"/>
    // </request>
    // <response>
    // <parameter name="light_state" type="uint8"/>
    // </response>
    // </query>

    uint8_t light_id;

    // Read parameters in request
    if (!unabto_query_read_uint8(r_b, &light_id))
      return AER_REQ_TOO_SMALL;

    // Write back led state
    if (!unabto_query_write_uint8(w_b, display_state))
      return AER_REQ_RSP_TOO_LARGE;

    return AER_REQ_RESPONSE_READY;
  }
  }
  return AER_REQ_INV_QUERY_ID;
}

Hands-On!

Enough theory. Let’s try out the demo! It is available as System Workbench for STM32 (SW4STM32) project here on GitHub. Simply follow the instructions in the README.

The board should now print out the Nabto log on the LCD screen, like on the picture in the beginning of the article.

When entering you device ID into your browser or Nabto App, you can see the uNabto Demo client. Using the light switch you can now turn the LCD Display on and off from everywhere!

stm32-demo-screenshot