This application is the simplest one to utilize our mesh networking stack. It just joins your device to the unsecure 6LoWPAN-ND network. The canonical source for this example lives at https://github.com/ARMmbed/mbed-os-example-mesh-minimal

Example mesh application for Mbed OS

With this application, you can use our mesh networking stack. This application joins your device to the unsecure 6LoWPAN-ND network.

Setup

Building with Mbed CLI

If you'd like to use Mbed CLI to build this offline, then you should refer to the Mbed CLI documentation. The instructions here relate to using the Mbed Online Compiler

  1. Click `Import this application` button.
  2. Change the channel settings: See the file `mbed_app.json` for an example of defining an IEEE 802.15.4 channel to use.
  3. Compile the application

A binary is generated at the end of the build process.

Connect the RF shield to the board

By default, we are using the Atmel AT86RF233, which you can purchase. Place the shield on top of your board, and power it on.

Program the target

Drag and drop the binary to the target to program the application.

Update the firmware of the border router.

You can read the instructions on updating the firmware of your board working as 6LoWPAN border router here.

Please remember to connect the Ethernet cable between the border router and your router. Then, power up the board.

Testing

As soon as both the border router and the target are up and running, you can verify the correct behavior. Open a serial console, and see the IP address obtained by the device.

Note: This application uses a baud rate of 115200.

Quote:

connected. IP = 2001:db8:a0b:12f0::1

You can use this IP address to ping from your PC and verify that the connection is working correctly.

Changing the radio driver (optional)

To run a 6LoWPAN-ND network, you need a working RF driver for Nanostack. This example uses the Atmel AT86RF233 by default.

To change the RF driver:

  1. Uninstall the Atmel RF driver.
  2. Install the new driver. (For example, for the FRDM-CR20A radio shield based on the MCR20A device.)
  3. Recompile your application.
Committer:
mbed_official
Date:
Mon Aug 19 14:00:33 2019 +0100
Revision:
128:e7faff9c9fd9
Parent:
120:fe68bb7d2462
Child:
133:9266a0884a45
Merge branch 'mbed-os-5.13'

* mbed-os-5.13:
Updating mbed-os to mbed-os-5.13.3 (#275)
Update mesh_minimal_startup.py
Updating mbed-os to mbed-os-5.13.2 (#274)

.
Commit copied from https://github.com/ARMmbed/mbed-os-example-mesh-minimal

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mbed_official 52:27692043e962 1 /*
mbed_official 52:27692043e962 2 * Copyright (c) 2016 ARM Limited. All rights reserved.
mbed_official 52:27692043e962 3 * SPDX-License-Identifier: Apache-2.0
mbed_official 52:27692043e962 4 * Licensed under the Apache License, Version 2.0 (the License); you may
mbed_official 52:27692043e962 5 * not use this file except in compliance with the License.
mbed_official 52:27692043e962 6 * You may obtain a copy of the License at
mbed_official 52:27692043e962 7 *
mbed_official 52:27692043e962 8 * http://www.apache.org/licenses/LICENSE-2.0
mbed_official 52:27692043e962 9 *
mbed_official 52:27692043e962 10 * Unless required by applicable law or agreed to in writing, software
mbed_official 52:27692043e962 11 * distributed under the License is distributed on an AS IS BASIS, WITHOUT
mbed_official 52:27692043e962 12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
mbed_official 52:27692043e962 13 * See the License for the specific language governing permissions and
mbed_official 52:27692043e962 14 * limitations under the License.
mbed_official 52:27692043e962 15 */
mbed_official 52:27692043e962 16 #include "mbed.h"
mbed_official 52:27692043e962 17 #include "nanostack/socket_api.h"
mbed_official 52:27692043e962 18 #include "mesh_led_control_example.h"
mbed_official 52:27692043e962 19 #include "common_functions.h"
mbed_official 52:27692043e962 20 #include "ip6string.h"
mbed_official 52:27692043e962 21 #include "mbed-trace/mbed_trace.h"
mbed_official 52:27692043e962 22
mbed_official 52:27692043e962 23 static void init_socket();
mbed_official 52:27692043e962 24 static void handle_socket();
mbed_official 52:27692043e962 25 static void receive();
mbed_official 52:27692043e962 26 static void my_button_isr();
mbed_official 52:27692043e962 27 static void send_message();
mbed_official 52:27692043e962 28 static void blink();
mbed_official 52:27692043e962 29 static void update_state(uint8_t state);
mbed_official 52:27692043e962 30 static void handle_message(char* msg);
mbed_official 52:27692043e962 31
mbed_official 59:3e1533ffb4f5 32 #define multicast_addr_str "ff15::810a:64d1"
mbed_official 52:27692043e962 33 #define TRACE_GROUP "example"
mbed_official 52:27692043e962 34 #define UDP_PORT 1234
mbed_official 52:27692043e962 35 #define MESSAGE_WAIT_TIMEOUT (30.0)
mbed_official 52:27692043e962 36 #define MASTER_GROUP 0
mbed_official 52:27692043e962 37 #define MY_GROUP 1
mbed_official 52:27692043e962 38
mbed_official 52:27692043e962 39 DigitalOut led_1(MBED_CONF_APP_LED, 1);
mbed_official 52:27692043e962 40 InterruptIn my_button(MBED_CONF_APP_BUTTON);
mbed_official 120:fe68bb7d2462 41 DigitalOut output(MBED_CONF_APP_RELAY_CONTROL, 1);
mbed_official 52:27692043e962 42
mbed_official 52:27692043e962 43 NetworkInterface * network_if;
mbed_official 52:27692043e962 44 UDPSocket* my_socket;
mbed_official 52:27692043e962 45 // queue for sending messages from button press.
mbed_official 52:27692043e962 46 EventQueue queue;
mbed_official 52:27692043e962 47 // for LED blinking
mbed_official 52:27692043e962 48 Ticker ticker;
mbed_official 66:30f2c1317e6d 49 // Handle for delayed message send
mbed_official 66:30f2c1317e6d 50 int queue_handle = 0;
mbed_official 52:27692043e962 51
mbed_official 52:27692043e962 52 uint8_t multi_cast_addr[16] = {0};
mbed_official 52:27692043e962 53 uint8_t receive_buffer[20];
mbed_official 52:27692043e962 54 // how many hops the multicast message can go
mbed_official 52:27692043e962 55 static const int16_t multicast_hops = 10;
mbed_official 52:27692043e962 56 bool button_status = 0;
mbed_official 52:27692043e962 57
mbed_official 52:27692043e962 58 void start_mesh_led_control_example(NetworkInterface * interface){
mbed_official 52:27692043e962 59 tr_debug("start_mesh_led_control_example()");
mbed_official 52:27692043e962 60 MBED_ASSERT(MBED_CONF_APP_LED != NC);
mbed_official 52:27692043e962 61 MBED_ASSERT(MBED_CONF_APP_BUTTON != NC);
mbed_official 52:27692043e962 62
mbed_official 52:27692043e962 63 network_if = interface;
mbed_official 52:27692043e962 64 stoip6(multicast_addr_str, strlen(multicast_addr_str), multi_cast_addr);
mbed_official 52:27692043e962 65 init_socket();
mbed_official 52:27692043e962 66 }
mbed_official 52:27692043e962 67
mbed_official 52:27692043e962 68 static void blink() {
mbed_official 52:27692043e962 69 led_1 = !led_1;
mbed_official 52:27692043e962 70 }
mbed_official 52:27692043e962 71
mbed_official 52:27692043e962 72 void start_blinking() {
mbed_official 52:27692043e962 73 ticker.attach(blink, 1.0);
mbed_official 52:27692043e962 74 }
mbed_official 52:27692043e962 75
mbed_official 52:27692043e962 76 void cancel_blinking() {
mbed_official 52:27692043e962 77 ticker.detach();
mbed_official 52:27692043e962 78 led_1=1;
mbed_official 52:27692043e962 79 }
mbed_official 52:27692043e962 80
mbed_official 52:27692043e962 81 static void send_message() {
mbed_official 52:27692043e962 82 tr_debug("send msg %d", button_status);
mbed_official 52:27692043e962 83
mbed_official 52:27692043e962 84 char buf[20];
mbed_official 52:27692043e962 85 int length;
mbed_official 52:27692043e962 86
mbed_official 52:27692043e962 87 /**
mbed_official 52:27692043e962 88 * Multicast control message is a NUL terminated string of semicolon separated
mbed_official 52:27692043e962 89 * <field identifier>:<value> pairs.
mbed_official 52:27692043e962 90 *
mbed_official 52:27692043e962 91 * Light control message format:
mbed_official 52:27692043e962 92 * t:lights;g:<group_id>;s:<1|0>;\0
mbed_official 52:27692043e962 93 */
mbed_official 52:27692043e962 94 length = snprintf(buf, sizeof(buf), "t:lights;g:%03d;s:%s;", MY_GROUP, (button_status ? "1" : "0")) + 1;
mbed_official 52:27692043e962 95 MBED_ASSERT(length > 0);
mbed_official 52:27692043e962 96 tr_debug("Sending lightcontrol message, %d bytes: %s", length, buf);
mbed_official 52:27692043e962 97 SocketAddress send_sockAddr(multi_cast_addr, NSAPI_IPv6, UDP_PORT);
mbed_official 52:27692043e962 98 my_socket->sendto(send_sockAddr, buf, 20);
mbed_official 52:27692043e962 99 //After message is sent, it is received from the network
mbed_official 52:27692043e962 100 }
mbed_official 52:27692043e962 101
mbed_official 52:27692043e962 102 // As this comes from isr, we cannot use printing or network functions directly from here.
mbed_official 52:27692043e962 103 static void my_button_isr() {
mbed_official 52:27692043e962 104 button_status = !button_status;
mbed_official 52:27692043e962 105 queue.call(send_message);
mbed_official 52:27692043e962 106 }
mbed_official 52:27692043e962 107
mbed_official 52:27692043e962 108 static void update_state(uint8_t state) {
mbed_official 52:27692043e962 109 if (state == 1) {
mbed_official 52:27692043e962 110 tr_debug("Turning led on\n");
mbed_official 52:27692043e962 111 led_1 = 0;
mbed_official 52:27692043e962 112 button_status=1;
mbed_official 52:27692043e962 113 output = 0;
mbed_official 52:27692043e962 114 }
mbed_official 52:27692043e962 115 else {
mbed_official 52:27692043e962 116 tr_debug("Turning led off\n");
mbed_official 52:27692043e962 117 led_1 = 1;
mbed_official 52:27692043e962 118 button_status=0;
mbed_official 52:27692043e962 119 output = 1;
mbed_official 52:27692043e962 120 }
mbed_official 52:27692043e962 121 }
mbed_official 52:27692043e962 122
mbed_official 52:27692043e962 123 static void handle_message(char* msg) {
mbed_official 52:27692043e962 124 // Check if this is lights message
mbed_official 52:27692043e962 125 uint8_t state=button_status;
mbed_official 52:27692043e962 126 uint16_t group=0xffff;
mbed_official 52:27692043e962 127
mbed_official 52:27692043e962 128 if (strstr(msg, "t:lights;") == NULL) {
mbed_official 52:27692043e962 129 return;
mbed_official 52:27692043e962 130 }
mbed_official 52:27692043e962 131
mbed_official 52:27692043e962 132 if (strstr(msg, "s:1;") != NULL) {
mbed_official 52:27692043e962 133 state = 1;
mbed_official 52:27692043e962 134 }
mbed_official 52:27692043e962 135 else if (strstr(msg, "s:0;") != NULL) {
mbed_official 52:27692043e962 136 state = 0;
mbed_official 52:27692043e962 137 }
mbed_official 52:27692043e962 138
mbed_official 52:27692043e962 139 // 0==master, 1==default group
mbed_official 52:27692043e962 140 char *msg_ptr = strstr(msg, "g:");
mbed_official 52:27692043e962 141 if (msg_ptr) {
mbed_official 52:27692043e962 142 char *ptr;
mbed_official 52:27692043e962 143 group = strtol(msg_ptr, &ptr, 10);
mbed_official 52:27692043e962 144 }
mbed_official 52:27692043e962 145
mbed_official 52:27692043e962 146 // in this example we only use one group
mbed_official 52:27692043e962 147 if (group==MASTER_GROUP || group==MY_GROUP) {
mbed_official 52:27692043e962 148 update_state(state);
mbed_official 52:27692043e962 149 }
mbed_official 52:27692043e962 150 }
mbed_official 52:27692043e962 151
mbed_official 52:27692043e962 152 static void receive() {
mbed_official 52:27692043e962 153 // Read data from the socket
mbed_official 52:27692043e962 154 SocketAddress source_addr;
mbed_official 52:27692043e962 155 memset(receive_buffer, 0, sizeof(receive_buffer));
mbed_official 52:27692043e962 156 bool something_in_socket=true;
mbed_official 52:27692043e962 157 // read all messages
mbed_official 52:27692043e962 158 while (something_in_socket) {
mbed_official 52:27692043e962 159 int length = my_socket->recvfrom(&source_addr, receive_buffer, sizeof(receive_buffer) - 1);
mbed_official 52:27692043e962 160 if (length > 0) {
mbed_official 52:27692043e962 161 int timeout_value = MESSAGE_WAIT_TIMEOUT;
mbed_official 52:27692043e962 162 tr_debug("Packet from %s\n", source_addr.get_ip_address());
mbed_official 52:27692043e962 163 timeout_value += rand() % 30;
mbed_official 52:27692043e962 164 tr_debug("Advertisiment after %d seconds", timeout_value);
mbed_official 66:30f2c1317e6d 165 queue.cancel(queue_handle);
mbed_official 66:30f2c1317e6d 166 queue_handle = queue.call_in((timeout_value * 1000), send_message);
mbed_official 52:27692043e962 167 // Handle command - "on", "off"
mbed_official 52:27692043e962 168 handle_message((char*)receive_buffer);
mbed_official 52:27692043e962 169 }
mbed_official 52:27692043e962 170 else if (length!=NSAPI_ERROR_WOULD_BLOCK) {
mbed_official 52:27692043e962 171 tr_error("Error happened when receiving %d\n", length);
mbed_official 52:27692043e962 172 something_in_socket=false;
mbed_official 52:27692043e962 173 }
mbed_official 52:27692043e962 174 else {
mbed_official 52:27692043e962 175 // there was nothing to read.
mbed_official 52:27692043e962 176 something_in_socket=false;
mbed_official 52:27692043e962 177 }
mbed_official 59:3e1533ffb4f5 178 }
mbed_official 52:27692043e962 179 }
mbed_official 52:27692043e962 180
mbed_official 52:27692043e962 181 static void handle_socket() {
mbed_official 52:27692043e962 182 // call-back might come from ISR
mbed_official 52:27692043e962 183 queue.call(receive);
mbed_official 52:27692043e962 184 }
mbed_official 52:27692043e962 185
mbed_official 52:27692043e962 186 static void init_socket()
mbed_official 52:27692043e962 187 {
mbed_official 116:b2f0131722a0 188 my_socket = new UDPSocket();
mbed_official 116:b2f0131722a0 189 my_socket->open(network_if);
mbed_official 52:27692043e962 190 my_socket->set_blocking(false);
mbed_official 59:3e1533ffb4f5 191 my_socket->bind(UDP_PORT);
mbed_official 52:27692043e962 192 my_socket->setsockopt(SOCKET_IPPROTO_IPV6, SOCKET_IPV6_MULTICAST_HOPS, &multicast_hops, sizeof(multicast_hops));
mbed_official 59:3e1533ffb4f5 193
mbed_official 59:3e1533ffb4f5 194 ns_ipv6_mreq_t mreq;
mbed_official 59:3e1533ffb4f5 195 memcpy(mreq.ipv6mr_multiaddr, multi_cast_addr, 16);
mbed_official 59:3e1533ffb4f5 196 mreq.ipv6mr_interface = 0;
mbed_official 59:3e1533ffb4f5 197
mbed_official 59:3e1533ffb4f5 198 my_socket->setsockopt(SOCKET_IPPROTO_IPV6, SOCKET_IPV6_JOIN_GROUP, &mreq, sizeof mreq);
mbed_official 59:3e1533ffb4f5 199
mbed_official 52:27692043e962 200 if (MBED_CONF_APP_BUTTON != NC) {
mbed_official 52:27692043e962 201 my_button.fall(&my_button_isr);
mbed_official 90:0d8804fe2ce2 202 my_button.mode(MBED_CONF_APP_BUTTON_MODE);
mbed_official 52:27692043e962 203 }
mbed_official 52:27692043e962 204 //let's register the call-back function.
mbed_official 52:27692043e962 205 //If something happens in socket (packets in or out), the call-back is called.
mbed_official 52:27692043e962 206 my_socket->sigio(callback(handle_socket));
mbed_official 52:27692043e962 207 // dispatch forever
mbed_official 52:27692043e962 208 queue.dispatch();
mbed_official 52:27692043e962 209 }