Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Diff: mesh_led_control_example.cpp
- Revision:
- 52:27692043e962
- Child:
- 54:34cbb2c2155c
diff -r de6c96c52689 -r 27692043e962 mesh_led_control_example.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/mesh_led_control_example.cpp Wed Sep 20 12:17:51 2017 +0100
@@ -0,0 +1,206 @@
+/*
+ * Copyright (c) 2016 ARM Limited. All rights reserved.
+ * SPDX-License-Identifier: Apache-2.0
+ * Licensed under the Apache License, Version 2.0 (the License); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "mbed.h"
+#include "nanostack/socket_api.h"
+#include "mesh_led_control_example.h"
+#include "common_functions.h"
+#include "ip6string.h"
+#include "mbed-trace/mbed_trace.h"
+
+static void init_socket();
+static void handle_socket();
+static void receive();
+static void my_button_isr();
+static void send_message();
+static void blink();
+static void update_state(uint8_t state);
+static void handle_message(char* msg);
+
+// mesh local multicast to all nodes
+#define multicast_addr_str "ff03::1"
+#define TRACE_GROUP "example"
+#define UDP_PORT 1234
+#define MESSAGE_WAIT_TIMEOUT (30.0)
+#define MASTER_GROUP 0
+#define MY_GROUP 1
+
+DigitalOut led_1(MBED_CONF_APP_LED, 1);
+InterruptIn my_button(MBED_CONF_APP_BUTTON);
+DigitalOut output(D3, 1);
+Timeout messageTimeout;
+
+NetworkInterface * network_if;
+UDPSocket* my_socket;
+// queue for sending messages from button press.
+EventQueue queue;
+// for LED blinking
+Ticker ticker;
+
+uint8_t multi_cast_addr[16] = {0};
+uint8_t receive_buffer[20];
+// how many hops the multicast message can go
+static const int16_t multicast_hops = 10;
+bool button_status = 0;
+
+void start_mesh_led_control_example(NetworkInterface * interface){
+ tr_debug("start_mesh_led_control_example()");
+ MBED_ASSERT(MBED_CONF_APP_LED != NC);
+ MBED_ASSERT(MBED_CONF_APP_BUTTON != NC);
+
+ network_if = interface;
+ stoip6(multicast_addr_str, strlen(multicast_addr_str), multi_cast_addr);
+ init_socket();
+}
+
+static void messageTimeoutCallback()
+{
+ send_message();
+}
+
+static void blink() {
+ led_1 = !led_1;
+}
+
+void start_blinking() {
+ ticker.attach(blink, 1.0);
+}
+
+void cancel_blinking() {
+ ticker.detach();
+ led_1=1;
+}
+
+static void send_message() {
+ tr_debug("send msg %d", button_status);
+
+ char buf[20];
+ int length;
+
+ /**
+ * Multicast control message is a NUL terminated string of semicolon separated
+ * <field identifier>:<value> pairs.
+ *
+ * Light control message format:
+ * t:lights;g:<group_id>;s:<1|0>;\0
+ */
+ length = snprintf(buf, sizeof(buf), "t:lights;g:%03d;s:%s;", MY_GROUP, (button_status ? "1" : "0")) + 1;
+ MBED_ASSERT(length > 0);
+ tr_debug("Sending lightcontrol message, %d bytes: %s", length, buf);
+ SocketAddress send_sockAddr(multi_cast_addr, NSAPI_IPv6, UDP_PORT);
+ my_socket->sendto(send_sockAddr, buf, 20);
+ //After message is sent, it is received from the network
+}
+
+// As this comes from isr, we cannot use printing or network functions directly from here.
+static void my_button_isr() {
+ button_status = !button_status;
+ queue.call(send_message);
+}
+
+static void update_state(uint8_t state) {
+ if (state == 1) {
+ tr_debug("Turning led on\n");
+ led_1 = 0;
+ button_status=1;
+ output = 0;
+ }
+ else {
+ tr_debug("Turning led off\n");
+ led_1 = 1;
+ button_status=0;
+ output = 1;
+ }
+}
+
+static void handle_message(char* msg) {
+ // Check if this is lights message
+ uint8_t state=button_status;
+ uint16_t group=0xffff;
+
+ if (strstr(msg, "t:lights;") == NULL) {
+ return;
+ }
+
+ if (strstr(msg, "s:1;") != NULL) {
+ state = 1;
+ }
+ else if (strstr(msg, "s:0;") != NULL) {
+ state = 0;
+ }
+
+ // 0==master, 1==default group
+ char *msg_ptr = strstr(msg, "g:");
+ if (msg_ptr) {
+ char *ptr;
+ group = strtol(msg_ptr, &ptr, 10);
+ }
+
+ // in this example we only use one group
+ if (group==MASTER_GROUP || group==MY_GROUP) {
+ update_state(state);
+ }
+}
+
+static void receive() {
+ // Read data from the socket
+ SocketAddress source_addr;
+ memset(receive_buffer, 0, sizeof(receive_buffer));
+ bool something_in_socket=true;
+ // read all messages
+ while (something_in_socket) {
+ int length = my_socket->recvfrom(&source_addr, receive_buffer, sizeof(receive_buffer) - 1);
+ if (length > 0) {
+ int timeout_value = MESSAGE_WAIT_TIMEOUT;
+ tr_debug("Packet from %s\n", source_addr.get_ip_address());
+ timeout_value += rand() % 30;
+ tr_debug("Advertisiment after %d seconds", timeout_value);
+ messageTimeout.detach();
+ messageTimeout.attach(&messageTimeoutCallback, timeout_value);
+ // Handle command - "on", "off"
+ handle_message((char*)receive_buffer);
+ }
+ else if (length!=NSAPI_ERROR_WOULD_BLOCK) {
+ tr_error("Error happened when receiving %d\n", length);
+ something_in_socket=false;
+ }
+ else {
+ // there was nothing to read.
+ something_in_socket=false;
+ }
+ }
+}
+
+static void handle_socket() {
+ // call-back might come from ISR
+ queue.call(receive);
+}
+
+static void init_socket()
+{
+ my_socket = new UDPSocket(network_if);
+ my_socket->set_blocking(false);
+ my_socket->bind(UDP_PORT);
+ my_socket->setsockopt(SOCKET_IPPROTO_IPV6, SOCKET_IPV6_MULTICAST_HOPS, &multicast_hops, sizeof(multicast_hops));
+ if (MBED_CONF_APP_BUTTON != NC) {
+ my_button.fall(&my_button_isr);
+ my_button.mode(PullUp);
+ }
+ //let's register the call-back function.
+ //If something happens in socket (packets in or out), the call-back is called.
+ my_socket->sigio(callback(handle_socket));
+ // dispatch forever
+ queue.dispatch();
+}