Skip to content

Commit 02c4341

Browse files
committed
Merge branch 'OpenThread' of https://github.com/SuGlider/arduino-esp32 into OpenThread
2 parents 43331c0 + c363ddb commit 02c4341

File tree

14 files changed

+1047
-362
lines changed

14 files changed

+1047
-362
lines changed

Diff for: libraries/OpenThread/README.md

-2
Original file line numberDiff line numberDiff line change
@@ -70,5 +70,3 @@ extern OpenThreadCLI OThreadCLI;
7070
- `setTxBufferSize(size_t tx_queue_len)`: Sets the transmit buffer size (default is 256 bytes).
7171
- `setRxBufferSize(size_t rx_queue_len)`: Sets the receive buffer size (default is 1024 bytes).
7272
- `write(uint8_t)`, `available()`, `read()`, `peek()`, `flush()`: Standard Stream methods implementation for OpenThread CLI object.
73-
74-

Diff for: libraries/OpenThread/examples/COAP/coap_lamp/ci.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,4 @@
66
"esp32s2": false,
77
"esp32s3": false
88
}
9-
}
9+
}

Diff for: libraries/OpenThread/examples/COAP/coap_lamp/coap_lamp.ino

+17-28
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,25 @@
11
#include "OThreadCLI.h"
22
#include "OThreadCLI_Util.h"
33

4-
#define OT_CHANNEL "24"
5-
#define OT_NETWORK_KEY "00112233445566778899aabbccddeeff"
6-
#define OT_MCAST_ADDR "ff05::abcd"
4+
#define OT_CHANNEL "24"
5+
#define OT_NETWORK_KEY "00112233445566778899aabbccddeeff"
6+
#define OT_MCAST_ADDR "ff05::abcd"
77
#define OT_COAP_RESOURCE_NAME "Lamp"
88

99
const char *otSetupLeader[] = {
1010
// clear/disable all
11-
"coap", "stop",
12-
"thread", "stop",
13-
"ifconfig", "down",
14-
"dataset", "clear",
11+
"coap", "stop", "thread", "stop", "ifconfig", "down", "dataset", "clear",
1512
// set dataset
16-
"dataset", "init new",
17-
"dataset channel", OT_CHANNEL,
18-
"dataset networkkey", OT_NETWORK_KEY,
19-
"dataset", "commit active",
13+
"dataset", "init new", "dataset channel", OT_CHANNEL, "dataset networkkey", OT_NETWORK_KEY, "dataset", "commit active",
2014
// network start
21-
"ifconfig", "up",
22-
"thread", "start"
15+
"ifconfig", "up", "thread", "start"
2316
};
2417

2518
const char *otCoapLamp[] = {
2619
// create a multicast IPv6 Address for this device
2720
"ipmaddr add", OT_MCAST_ADDR,
2821
// start and create a CoAP resource
29-
"coap", "start",
30-
"coap resource", OT_COAP_RESOURCE_NAME,
31-
"coap set", "0"
22+
"coap", "start", "coap resource", OT_COAP_RESOURCE_NAME, "coap set", "0"
3223
};
3324

3425
bool otDeviceSetup(const char **otSetupCmds, uint8_t nCmds1, const char **otCoapCmds, uint8_t nCmds2, ot_device_role_t expectedRole) {
@@ -47,7 +38,7 @@ bool otDeviceSetup(const char **otSetupCmds, uint8_t nCmds1, const char **otCoap
4738
}
4839
Serial.println("OpenThread started.\r\nWaiting for activating correct Device Role.");
4940
// wait for the expected Device Role to start
50-
uint8_t tries = 24; // 24 x 2.5 sec = 1 min
41+
uint8_t tries = 24; // 24 x 2.5 sec = 1 min
5142
while (tries && otGetDeviceRole() != expectedRole) {
5243
Serial.print(".");
5344
delay(2500);
@@ -72,22 +63,20 @@ bool otDeviceSetup(const char **otSetupCmds, uint8_t nCmds1, const char **otCoap
7263
}
7364
Serial.println("OpenThread setup done. Node is ready.");
7465
// all fine! LED goes Green
75-
neopixelWrite(RGB_BUILTIN, 0, 64, 8); // GREEN ... Lamp is ready!
66+
neopixelWrite(RGB_BUILTIN, 0, 64, 8); // GREEN ... Lamp is ready!
7667
return true;
7768
}
7869

7970
void setupNode() {
8071
// tries to set the Thread Network node and only returns when succeded
8172
bool startedCorrectly = false;
8273
while (!startedCorrectly) {
83-
startedCorrectly |= otDeviceSetup(otSetupLeader, sizeof(otSetupLeader) / sizeof(char *) / 2,
84-
otCoapLamp, sizeof(otCoapLamp) / sizeof(char *) / 2,
85-
OT_ROLE_LEADER);
74+
startedCorrectly |=
75+
otDeviceSetup(otSetupLeader, sizeof(otSetupLeader) / sizeof(char *) / 2, otCoapLamp, sizeof(otCoapLamp) / sizeof(char *) / 2, OT_ROLE_LEADER);
8676
if (!startedCorrectly) {
8777
Serial.println("Setup Failed...\r\nTrying again...");
8878
}
8979
}
90-
9180
}
9281

9382
// this function is used by the Lamp mode to listen for CoAP frames from the Switch Node
@@ -107,16 +96,16 @@ void otCOAPListen() {
10796
log_i("CoAP PUT [%s]\r\n", payload == '0' ? "OFF" : "ON");
10897
if (payload == '0') {
10998
for (int16_t c = 248; c > 16; c -= 8) {
110-
neopixelWrite(RGB_BUILTIN, c, c, c); // ramp down
99+
neopixelWrite(RGB_BUILTIN, c, c, c); // ramp down
111100
delay(5);
112101
}
113-
neopixelWrite(RGB_BUILTIN, 0, 0, 0); // Lamp Off
102+
neopixelWrite(RGB_BUILTIN, 0, 0, 0); // Lamp Off
114103
} else {
115104
for (int16_t c = 16; c < 248; c += 8) {
116-
neopixelWrite(RGB_BUILTIN, c, c, c); // ramp up
105+
neopixelWrite(RGB_BUILTIN, c, c, c); // ramp up
117106
delay(5);
118107
}
119-
neopixelWrite(RGB_BUILTIN, 255, 255, 255); // Lamp On
108+
neopixelWrite(RGB_BUILTIN, 255, 255, 255); // Lamp On
120109
}
121110
}
122111
}
@@ -126,8 +115,8 @@ void setup() {
126115
Serial.begin(115200);
127116
// LED starts RED, indicating not connected to Thread network.
128117
neopixelWrite(RGB_BUILTIN, 64, 0, 0);
129-
OThreadCLI.begin(false); // No AutoStart is necessary
130-
OThreadCLI.setTimeout(250); // waits 250ms for the OpenThread CLI response
118+
OThreadCLI.begin(false); // No AutoStart is necessary
119+
OThreadCLI.setTimeout(250); // waits 250ms for the OpenThread CLI response
131120
setupNode();
132121
// LED goes Green when all is ready and Red when failed.
133122
}
+160-9
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,160 @@
1-
{
2-
"targets": {
3-
"esp32": false,
4-
"esp32c2": false,
5-
"esp32c3": false,
6-
"esp32s2": false,
7-
"esp32s3": false
8-
}
9-
}
1+
#include "OThreadCLI.h"
2+
#include "OThreadCLI_Util.h"
3+
4+
#define USER_BUTTON 9 // C6/H2 Boot button
5+
#define OT_CHANNEL "24"
6+
#define OT_NETWORK_KEY "00112233445566778899aabbccddeeff"
7+
#define OT_MCAST_ADDR "ff05::abcd"
8+
#define OT_COAP_RESOURCE_NAME "Lamp"
9+
10+
const char *otSetupChild[] = {
11+
// clear/disable all
12+
"coap", "stop", "thread", "stop", "ifconfig", "down", "dataset", "clear",
13+
// set dataset
14+
"dataset channel", OT_CHANNEL, "dataset networkkey", OT_NETWORK_KEY, "dataset", "commit active",
15+
// network start
16+
"ifconfig", "up", "thread", "start"
17+
};
18+
19+
const char *otCoapSwitch[] = {
20+
// start and create a CoAP resource
21+
"coap",
22+
"start",
23+
};
24+
25+
bool otDeviceSetup(
26+
const char **otSetupCmds, uint8_t nCmds1, const char **otCoapCmds, uint8_t nCmds2, ot_device_role_t expectedRole1, ot_device_role_t expectedRole2
27+
) {
28+
Serial.println("Starting OpenThread.");
29+
Serial.println("Running as Switch - use the BOOT button to toggle the other C6/H2 as a Lamp");
30+
uint8_t i;
31+
for (i = 0; i < nCmds1; i++) {
32+
if (!otExecCommand(otSetupCmds[i * 2], otSetupCmds[i * 2 + 1])) {
33+
break;
34+
}
35+
}
36+
if (i != nCmds1) {
37+
log_e("Sorry, OpenThread Network setup failed!");
38+
neopixelWrite(RGB_BUILTIN, 255, 0, 0); // RED ... failed!
39+
return false;
40+
}
41+
Serial.println("OpenThread started.\r\nWaiting for activating correct Device Role.");
42+
// wait for the expected Device Role to start
43+
uint8_t tries = 24; // 24 x 2.5 sec = 1 min
44+
while (tries && otGetDeviceRole() != expectedRole1 && otGetDeviceRole() != expectedRole2) {
45+
Serial.print(".");
46+
delay(2500);
47+
tries--;
48+
}
49+
Serial.println();
50+
if (!tries) {
51+
log_e("Sorry, Device Role failed by timeout! Current Role: %s.", otGetStringDeviceRole());
52+
neopixelWrite(RGB_BUILTIN, 255, 0, 0); // RED ... failed!
53+
return false;
54+
}
55+
Serial.printf("Device is %s.\r\n", otGetStringDeviceRole());
56+
for (i = 0; i < nCmds2; i++) {
57+
if (!otExecCommand(otCoapCmds[i * 2], otCoapCmds[i * 2 + 1])) {
58+
break;
59+
}
60+
}
61+
if (i != nCmds2) {
62+
log_e("Sorry, OpenThread CoAP setup failed!");
63+
neopixelWrite(RGB_BUILTIN, 255, 0, 0); // RED ... failed!
64+
return false;
65+
}
66+
Serial.println("OpenThread setup done. Node is ready.");
67+
// all fine! LED goes and stays Blue
68+
neopixelWrite(RGB_BUILTIN, 0, 0, 64); // BLUE ... Swtich is ready!
69+
return true;
70+
}
71+
72+
void setupNode() {
73+
// tries to set the Thread Network node and only returns when succeded
74+
bool startedCorrectly = false;
75+
while (!startedCorrectly) {
76+
startedCorrectly |= otDeviceSetup(
77+
otSetupChild, sizeof(otSetupChild) / sizeof(char *) / 2, otCoapSwitch, sizeof(otCoapSwitch) / sizeof(char *) / 2, OT_ROLE_CHILD, OT_ROLE_ROUTER
78+
);
79+
if (!startedCorrectly) {
80+
Serial.println("Setup Failed...\r\nTrying again...");
81+
}
82+
}
83+
}
84+
85+
// Sends the CoAP frame to the Lamp node
86+
bool otCoapPUT(bool lampState) {
87+
bool gotDone = false, gotConfirmation = false;
88+
String coapMsg = "coap put ";
89+
coapMsg += OT_MCAST_ADDR;
90+
coapMsg += " ";
91+
coapMsg += OT_COAP_RESOURCE_NAME;
92+
coapMsg += " con 0";
93+
94+
// final command is "coap put ff05::abcd Lamp con 1" or "coap put ff05::abcd Lamp con 0"
95+
if (lampState) {
96+
coapMsg[coapMsg.length() - 1] = '1';
97+
}
98+
OThreadCLI.println(coapMsg.c_str());
99+
log_d("Send CLI CMD:[%s]", coapMsg.c_str());
100+
101+
char cliResp[256];
102+
// waits for the CoAP confirmation and Done message for about 1.25 seconds
103+
// timeout is based on Stream::setTimeout()
104+
// Example of the expected confirmation response: "coap response from fdae:3289:1783:5c3f:fd84:c714:7e83:6122"
105+
uint8_t tries = 5;
106+
*cliResp = '\0';
107+
while (tries && !(gotDone && gotConfirmation)) {
108+
size_t len = OThreadCLI.readBytesUntil('\n', cliResp, sizeof(cliResp));
109+
cliResp[len - 1] = '\0';
110+
log_d("Try[%d]::MSG[%s]", tries, cliResp);
111+
if (strlen(cliResp)) {
112+
if (!strncmp(cliResp, "coap response from", 18)) {
113+
gotConfirmation = true;
114+
}
115+
if (!strncmp(cliResp, "Done", 4)) {
116+
gotDone = true;
117+
}
118+
}
119+
tries--;
120+
}
121+
if (gotDone && gotConfirmation) {
122+
return true;
123+
}
124+
return false;
125+
}
126+
127+
// this fucntion is used by the Switch mode to check the BOOT Button and send the user action to the Lamp node
128+
void checkUserButton() {
129+
static long unsigned int lastPress = 0;
130+
const long unsigned int debounceTime = 500;
131+
static bool lastLampState = true; // first button press will turn the Lamp OFF from inital Green
132+
133+
pinMode(USER_BUTTON, INPUT_PULLUP); // C6/H2 User Button
134+
if (millis() > lastPress + debounceTime && digitalRead(USER_BUTTON) == LOW) {
135+
lastLampState = !lastLampState;
136+
if (!otCoapPUT(lastLampState)) { // failed: Lamp Node is not responding due to be off or unreachable
137+
// timeout from the CoAP PUT message... restart the node.
138+
neopixelWrite(RGB_BUILTIN, 255, 0, 0); // RED ... something failed!
139+
Serial.println("Reseting the Node as Switch... wait.");
140+
// start over...
141+
setupNode();
142+
}
143+
lastPress = millis();
144+
}
145+
}
146+
147+
void setup() {
148+
Serial.begin(115200);
149+
// LED starts RED, indicating not connected to Thread network.
150+
neopixelWrite(RGB_BUILTIN, 64, 0, 0);
151+
OThreadCLI.begin(false); // No AutoStart is necessary
152+
OThreadCLI.setTimeout(250); // waits 250ms for the OpenThread CLI response
153+
setupNode();
154+
// LED goes and keeps Blue when all is ready and Red when failed.
155+
}
156+
157+
void loop() {
158+
checkUserButton();
159+
delay(10);
160+
}

0 commit comments

Comments
 (0)