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
- }
1
+ {
2
+ "targets" : {
3
+ "esp32" : false ,
4
+ "esp32c2" : false ,
5
+ "esp32c3" : false ,
6
+ "esp32s2" : false ,
7
+ "esp32s3" : false
8
+ }
9
+ }
0 commit comments