You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: content/arduino-cloud/01.getting-started/02.technical-reference/iot-cloud-tech-ref.md
+63-16Lines changed: 63 additions & 16 deletions
Original file line number
Diff line number
Diff line change
@@ -308,42 +308,89 @@ One or more **Things** can be added to a **Dashboard**, with all or some of thei
308
308
309
309

310
310
311
-
***You can read more about [Dashboards & Widgets]().***
311
+
***You can read more about [Dashboards & Widgets](/arduino-cloud/getting-started/dashboard-widgets).***
312
312
313
313
## Recommended Code Practices
314
314
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:
***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
316
334
317
335
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.
318
336
319
337
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.
320
338
321
339
Let's see how to blink a LED. The traditional way involves the `delay()` function:
322
340
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
+
```
331
351
332
352
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.
333
353
334
354
This can be rewritten in a non-blocking way as follows:
335
355
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
+
```
341
363
342
364
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.
343
365
344
366
For a more complex and commented example, you can have a look at the [BlinkWithoutDelay example](/built-in-examples/digital/BlinkWithoutDelay).
345
367
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:
Serial.println("Failed to initialize MKR ENV shield!");
388
+
while (1);
389
+
}
390
+
```
391
+
392
+
393
+
### Avoid Blocking Serial Communication
347
394
348
395
`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.
0 commit comments