nRF5 SDK for Thread and Zigbee v4.1.0
Thread Google Cloud Platform CoAP Example

Table of Contents

This information applies to the following SoCs: nRF52833 and nRF52840.

This example demonstrates the interaction between the development kit and the Google Cloud Platform. The nRF52 node uses the built-in OpenThread CoAP protocol (with optional DTLS security).

The application uses the temperature sensor to measure the current temperature and uses the internal counter that can be altered between 15 and 30 (which corresponds to the Celsius degree range). The node sends the temperature with the counter value each time the assigned buttons are pressed and with each TEMP_MEASUREMENT_INTERVAL, by default 5000 ms. Additionally, these buttons decrease and increase the counter value, respectively.

Another functionality is reading and applying the LED configuration from the cloud. This functionality is bound to Button 1. The example implements an optional CLI interface that you can use to communicate with the nodes through the serial port and configure them manually.

Figure 1: Thread Google IoT CoAP communication architecture.

Required initial configuration

This example is based on the Thread Border Router and Thread NCP/RCP Example. For proper operation, you must set up Nordic's Thread Border Router to provide Internet connectivity to the Thread network.

To verify that Thread Border Router is booted up correctly and is providing Internet access, go to Border Router test connectivity to test the connectivity to a public Google DNS server (64:ff9b::808:808).

After the Thread Border Router is set up, configure the cloud and the node to ensure they communicate. Once configured, each CoAP packet sent to the cloud will contain a JSON Web Token (JWT) that acts as signature and confirms the identity of the device. For this configuration to work, you must embed the following data in the JWT:

With this information embedded, you will obtain the current unix time, which is used for JWT generation. You must also embed the private key used to sign the message, while the complementary public key must be uploded to the cloud to make the authentication possible. See the following subsections for more details.

Setting up the cloud

For a device to be able to connect, it must first be registered with the Cloud IoT Core: you must add the device to a collection (the registry) and define some essential properties. You can configure the cloud side by using the Google Cloud Shell as described later in this document.

The Cloud IoT Core uses public key (or asymmetric) authentication:

To set up the cloud:

  1. Generate an ES256 key pair with the Eliptic Curve algorithm by running the following commands on your development PC:
    openssl ecparam -genkey -name prime256v1 -noout -out ec_private.pem
    openssl ec -in ec_private.pem -pubout -out ec_public.pem
    These commands create the following public/private key pair:
    • ec_private.pem: The private key that must be securely stored on the device. It is used to sign the authentication JWT.
    • ec_public.pem: The public key that must be stored in Cloud IoT Core. It is used to verify the signature of the authentication JWT.
  2. Open the Google Cloud Platform Console webpage.
  3. Click the console logo in the right upper corner of the Google Cloud Platform panel. This activates the Google Cloud Shell, needed to configure the cloud side.
  4. Enter the following commands:
    git clone
    cd community/tutorials/cloud-iot-coap-proxy
    gcloud services enable
    gcloud pubsub topics create coap-events
    gcloud iot registries create coap-demo --region us-central1 --event-notification-config topic=coap-events
    gcloud compute instances create-with-container coap-proxy-demo \
    --tags=coap --container-image$GOOGLE_CLOUD_PROJECT/coap-proxy \
    --zone us-central1-a \
    gcloud compute firewall-rules create allow-coap --action=ALLOW \
    --rules=udp:5683 --source-ranges= --target-tags=coap
    gcloud compute firewall-rules create allow-coaps --action=ALLOW \
    --rules=udp:5684 --source-ranges= --target-tags=coap
  5. Upload the ec_public.pem file generated previously to your home directory by clicking three dots symbol in the Google Cloud Shell.
  6. Create a device by running the following command:
    gcloud iot devices create --registry=coap-demo --region=us-central1 \
    --public-key path=~/ec_public.pem,type=es256-pem some_device_id
  7. Create a Firestone database in the native mode using the panel on the left side.
  8. Create the following resource hierachy in the Firestone database:
    • Collection with name collection_id.
    • Document with name document_id.
    • Two integer fields: temp, counter.
      If you choose different values, these changes must be reflected in the script below.
  9. Create a Google Cloud Function:
    • Trigger Cloud Pub/Sub
    • Topic coap-events
    • Language Python 3.7
    • Script content:
      import base64
      import json
      from import firestore
      def hello_pubsub(event, context):
      """Triggered from a message on a Cloud Pub/Sub topic.
      event (dict): Event payload.
      context ( Metadata for the event.
      pubsub_message = base64.b64decode(event['data']).decode('utf-8')
      x_dict = json.loads(pubsub_message)
      db = firestore.Client()
      doc_ref = db.collection(u'collection_id').document(u'document_id')
      u'temp': x_dict["temp"],
      u'counter': x_dict["counter"]
    • Edit requirements.txt.
      # Function dependencies, for example:
      # package>=version
  10. Obtain the gateway IPv4 address by running the following command:
    gcloud compute instances describe coap-proxy-demo --zone us-central1-a --format="value(networkInterfaces.accessConfigs[0].natIP)"
  11. Embed the obtained gateway IPv4 address in the GCP_COAP_IOT_CORE_SERVER_ADDRESS define in the thread\\examples\\cloud\\google_iot_coap\\main.c file.
    • For example, the address translates to the following hexadecimal values: 0x23, 0xc3, 0xb8, 0x5b. This results in the following define value:
      #define GCP_COAP_IOT_CORE_SERVER_ADDRESS "64:ff9b::23c3:b85b"
  12. Obtain the project ID by running the following command:
  13. Embed the project ID in the GCP_COAP_IOT_CORE_PROJECT_ID define in the main.c file.
    The remaining GCP CoAP defines are set to default. If you altered any of the commands above, you might need to adjust more define parameters in the main.c file.
  14. Fill the GCP_COAP_IOT_CORE_DEVICE_KEY define in the thread\\examples\\cloud\\google_iot_coap\\main.c file.
    #define GCP_COAP_IOT_CORE_DEVICE_ID "some_device_id"
    "-----BEGIN EC PRIVATE KEY-----\r\n" \
    "-----END EC PRIVATE KEY-----\r\n"

Enabling the secure communication with DTLS

To enable the secure communication with Datagram Transport Layer Security (DTLS), you must enable a DTLS session between the Thread device and Google IoT Cloud:

  1. Locate the following lines in the main.c file of the example:
    #define GCP_COAP_SECURE_PSK_SECRET "some_secret"
    #define GCP_COAP_SECURE_PSK_IDENTITY "my_identity"
  2. Edit the GCP_COAP_SECURE_ENABLED from 0 to 1 and provide the correct values for PSK and PSK Identity below it.


You can find the source code and the makefile in the following folder: <InstallFolder>\examples\thread\cloud\google_iot_coap.

LED assignments

The client uses LED assignments as described in Thread BSP LED and button reference for the following LEDs:

Button assignments

The client uses the following button assignments:


To test this example, you need the same hardware as for Thread Border Router.

Testing the temperature sensor

All capital strings in the URLs need to be replaced with the values present in the main.c.

To test the temperature sensor:

  1. Open The Firestone Database and choose your device.
  2. Turn on the OpenThread Border Router.
  3. Turn on the Thread device and wait few seconds to make sure that device has joined the Thread network.
  4. Observe the LED status:
    • LED1 blinking: Device is joining the network.
    • LED1 solid: Device joined the network.
  5. Press Button 3 to decrease the simulated counter value.
  6. Observe the data received in the Firestore database. Replace some_device_id with the value defined in the main.c.
  7. Press Button 4 to increase the simulated counter value.
  8. Observe the data received in the Firestore database. Replace some_device_id with the value defined in the main.c.
To verify that two nodes have joined the same network and your device communicates with Google IoT Cloud, you can use the nRF Sniffer for 802.15.4 project to sniff Thread packets. To decrypt them correctly, set up Wireshark according to steps 4-8 in Configuring Wireshark for Thread.

Testing reading and applying the LED configuration from the cloud

To test reading and applying the LED configuration from the cloud:

  1. Complete all the steps in Testing the temperature sensor.
  2. Navigate to the Device webpage:
  3. Change the LED configuration in the IoT Core device settings.
    The device accepts only the following strings:
    • "LED1"
    • "LED2"
    • "LED3"
    • "LED4"
  4. Press Button 1 to obtain the configuration of the device.
  5. Observe that only the configured LED is turned on.

Documentation feedback | Developer Zone | Subscribe | Updated