Skip to content

Commit d2526f9

Browse files
authored
Merge pull request #700 from arduino/karlsoderby/iotc-cheat-sheet-fix
[MKC-778] Add WDT, I2C best practices for IoTC
2 parents 8060880 + e4d28d7 commit d2526f9

File tree

1 file changed

+63
-16
lines changed

1 file changed

+63
-16
lines changed

content/arduino-cloud/01.getting-started/02.technical-reference/iot-cloud-tech-ref.md

Lines changed: 63 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -308,42 +308,89 @@ One or more **Things** can be added to a **Dashboard**, with all or some of thei
308308

309309
![Create widgets from a Thing](./images/create-widget-from-thing.png)
310310

311-
***You can read more about [Dashboards & Widgets]().***
311+
***You can read more about [Dashboards & Widgets](/arduino-cloud/getting-started/dashboard-widgets).***
312312

313313
## Recommended Code Practices
314314

315-
### Avoid blocking commands within the loop()
315+
This section highlights some important aspects of writing code with regard to the implementations in the [ArduinoIoTCloud](https://github.com/arduino-libraries/ArduinoIoTCloud).
316+
317+
### Watchdog Timer (WDT)
318+
319+
All IoT Cloud sketches use a **Watchdog Timer (WDT)** by default. The WDT can be used to automatically recover from hardware faults or unrecoverable software errors.
320+
321+
A WDT is essentially a countdown timer, whereas it starts counting from a set value, and upon reaching zero, it resets the board. To prevent it from reaching zero, we continuously call it from the `loop()`, using the `ArduinoCloud.update()` function.
322+
323+
This is why, it is very important to not use any long blocking code in your sketch. For example, using a long `delay()` inside the `loop()` is **strongly discouraged**, as the WDT can reach zero and reset the board.
324+
325+
The WDT can however be disabled inside of the `setup()` function, by adding the `false` parameter:
326+
327+
```arduino
328+
ArduinoCloud.begin(ArduinoIoTPreferredConnection, false).
329+
```
330+
331+
***You can view the source code of this implementation [here](https://github.com/arduino-libraries/ArduinoIoTCloud/tree/master/src/utility/watchdog).***
332+
333+
### Alternatives to Delays
316334

317335
The `loop()` function includes the `ArduinoCloud.update();` call, which sends data to the cloud and receives updates. In order to get the best responsiveness in your cloud-connected projects, the `loop()` function should run as fast as possible. This means that no blocking commands should be used inside, and you should prefer a non-blocking programming approach whenever possible.
318336

319337
A common **blocking pattern** is the use of the `delay()` function which stops the execution of the function for the given time. We strongly advise to **get rid of this function** and achieve the same behavior in a non-blocking way with the `millis()` function as described below.
320338

321339
Let's see how to blink a LED. The traditional way involves the `delay()` function:
322340

323-
void loop() {
324-
ArduinoCloud.update();
325-
326-
digitalWrite(LED_BUILTIN, HIGH);
327-
delay(1000);
328-
digitalWrite(LED_BUILTIN, LOW);
329-
delay(1000);
330-
}
341+
```arduino
342+
void loop() {
343+
ArduinoCloud.update();
344+
345+
digitalWrite(LED_BUILTIN, HIGH);
346+
delay(1000);
347+
digitalWrite(LED_BUILTIN, LOW);
348+
delay(1000);
349+
}
350+
```
331351

332352
This works, but it will cause a delay of at least two seconds between one execution of `ArduinoCloud.update()` and the next one, thus causing bad performance of the cloud communication.
333353

334354
This can be rewritten in a non-blocking way as follows:
335355

336-
void loop() {
337-
ArduinoCloud.update();
338-
339-
digitalWrite(LED_PIN, (millis() % 2000) < 1000);
340-
}
356+
```arduino
357+
void loop() {
358+
ArduinoCloud.update();
359+
360+
digitalWrite(LED_PIN, (millis() % 2000) < 1000);
361+
}
362+
```
341363

342364
How does this work? It gets the current execution time provided by `millis()` and divides it by 2 seconds. If the remainder is smaller than one second it will turn the LED on, and if it's greater it will turn the LED off.
343365

344366
For a more complex and commented example, you can have a look at the [BlinkWithoutDelay example](/built-in-examples/digital/BlinkWithoutDelay).
345367

346-
### Avoid waiting for Serial Monitor to initialize connection
368+
### I2C Usage
369+
370+
Components connected via I²C (including the sensors onboard the [MKR IoT Carrier](https://store.arduino.cc/products/arduino-mkr-iot-carrier)) uses the same bus as the **ECCX08** cryptochip. As the crypto chip is an essential part of establishing a connection to the IoT Cloud (it contains the credentials), it is important that other I²C peripherals are initialized after the connection has been made.
371+
372+
For example, if you are initializing a library such as [Arduino_MKRENV](https://www.arduino.cc/reference/en/libraries/arduino_mkrenv), your `setup()` should be implemented as:
373+
374+
```arduino
375+
void setup() {
376+
Serial.begin(9600);
377+
delay(1500);
378+
379+
initProperties();
380+
381+
ArduinoCloud.begin(ArduinoIoTPreferredConnection);
382+
setDebugMessageLevel(2);
383+
ArduinoCloud.printDebugInfo();
384+
385+
//initializing the Arduino_MKRENV library
386+
if (!ENV.begin()) {
387+
Serial.println("Failed to initialize MKR ENV shield!");
388+
while (1);
389+
}
390+
```
391+
392+
393+
### Avoid Blocking Serial Communication
347394

348395
`while(!Serial) {}` loops endlessly until the Serial Monitor is opened. This is a useful practice in cases where you want to see all debug output from the start of the sketch execution. However, when building IoT systems using **`while(!Serial){}` can hinder our project from running autonomously**, stopping the board from connecting to the network and IoT Cloud before manually opening the Serial Monitor. Therefore, it is recommended to consider removing the `while(!Serial){}` loop if it's not necessary.
349396

0 commit comments

Comments
 (0)