From 3c04ab07f66f279b0a346b91c6b4a131acb1d156 Mon Sep 17 00:00:00 2001 From: Trygve Laugstøl Date: Thu, 14 Jun 2018 11:57:29 +0200 Subject: wip --- assignments/blink-a-led/blink-a-led.md | 26 +- assignments/blink-a-led/blink-a-led.pdf | Bin 722602 -> 731445 bytes assignments/mqtt-with-button/mqtt-with-button.md | 50 +-- assignments/mqtt-with-button/mqtt-with-button.pdf | Bin 841066 -> 857213 bytes slides/connected-arduino-slides.pdf | Bin 293791 -> 287191 bytes slides/connected-arduino-text.pdf | Bin 298798 -> 287028 bytes slides/connected-arduino.md | 449 ++++++++-------------- slides/toc.md | 43 +-- 8 files changed, 220 insertions(+), 348 deletions(-) diff --git a/assignments/blink-a-led/blink-a-led.md b/assignments/blink-a-led/blink-a-led.md index a08bc4e..72bbb9c 100644 --- a/assignments/blink-a-led/blink-a-led.md +++ b/assignments/blink-a-led/blink-a-led.md @@ -6,10 +6,19 @@ Check that your local environment is working properly. ## Configure the Arduino IDE -Under *Tools* -> *Board* make sure that "NodeMCU 1.0 (ESP-12E Module)" -is available and selected. +1. Make sure the "ESP8266" core is installed. If it is not installed + follow the installation instructions: -Create a new sketch with *File* -> *New* and compile it with *ctrl-R*. + [https://github.com/esp8266/Arduino#installing-with-boards-manager](https://github.com/esp8266/Arduino#installing-with-boards-manager) + +1. Under *Tools* -> *Board* make sure that "NodeMCU 1.0 (ESP-12E + Module)" is available and selected. + +1. Select the correct serial port: *Tools -> Port*. + +1. Select the highest upload speed: *Tools -> Upload Speed*. + +1. Create a new sketch with *File* -> *New* and compile it with *ctrl-R*. ## Step 1 @@ -24,7 +33,7 @@ orientation is not important, but the LED's orientation is important. ## Step 2 -Implement `setup()` and `loop()`. In `setup()` configure the LED pin and blink the LED in `loop()`. +Implement `setup()` and `loop()`: In `setup()` configure the LED pin and blink the LED in `loop()`. Use these functions: @@ -32,9 +41,14 @@ Use these functions: Serial.begin(115200); Serial.println(string); +// Pin is D1/D2/D.. +// mode is INPUT or OUTPUT pinMode(pin, mode); -digitalWrite(pin, state); // HIGH or LOW -delay(); + +// HIGH or LOW +digitalWrite(pin, state); + +delay(ms); ~~~ ## Tips diff --git a/assignments/blink-a-led/blink-a-led.pdf b/assignments/blink-a-led/blink-a-led.pdf index da370c4..655f964 100644 Binary files a/assignments/blink-a-led/blink-a-led.pdf and b/assignments/blink-a-led/blink-a-led.pdf differ diff --git a/assignments/mqtt-with-button/mqtt-with-button.md b/assignments/mqtt-with-button/mqtt-with-button.md index c825615..30defc8 100644 --- a/assignments/mqtt-with-button/mqtt-with-button.md +++ b/assignments/mqtt-with-button/mqtt-with-button.md @@ -6,6 +6,11 @@ * Publish a message when a button is pressed. * Subscribe to a topic to control the LED +## Preparation + +* Install the *PubSubClient* library. Use the library manager under + *Sketch -> Include library -> Library Manager* to install it. + ## Step 1 Wire up this schematic on the bread board: @@ -16,10 +21,8 @@ Wire up this schematic on the bread board: # Step 2 -* Tip: change upload speed to max. - -* Read button in `loop()`. If the button's state changes, print a - message. +* Read button's value inside `loop()`. If the button's state changes, + print a message. *Note:* reading the button in a busy loop is not really a best practice as it uses lots of energy. Instead use the `attachInterrupt`. @@ -29,34 +32,35 @@ practice as it uses lots of energy. Instead use the `attachInterrupt`. * Connect to the Wi-Fi network * Connect to MQTT broker +See the slides for example code. + # Step 4 -* Publish a message on button press on the topic +* Create a subscription for `ndc/$device-id/#` with HiveMQ's web ui: + http://www.hivemq.com/demos/websocket-client/ +* Publish a message when the button is pressed on the topic `ndc/$device-id/button` # Step 5 (Bonus) -Subscripe to a topic and do something with the led. - -* Subscribe to the topic you're publishing to. - -* Subscribe to the topic `ndc/$device-id/led`. - -* Use the value to for example turn the LED on/off, or change the - LED's blinking pattern. +*Feel free to be creative here.* -## Tips +The other useful half of MQTT is subscribing to topics and reacting to +messages. Here are some example things you can do: -To generate a client id make something with `ESP.getChipId()`{.cpp} +* Subscribe to the topic you're publishing to and change the state of + the LED when the button is pressed. This will give you a very + complicated and brittle way of toggling a LED. -Creating a `String` from a number: +* In `loop` blink the led. Subscribe to another topic (for example + `ndc/$device-id/frequency`), and use the value as a way to control + the blink rate. -* `String(123) => "123"`{.cpp} -* Hex formatted: `String(0x123abc, HEX) => "123abc"`{.cpp} +# Step 6 (Strech goal) -Some APIs require "plain C strings" aka a `char *`{.cpp}. They can be -converted with `String::c_str()`: +Use a last will message to indicate if the device is online or not. -~~~.c++ -char *cStr = myString.c_str(); -~~~ +* When connecting, include a last will message with topic + `ndc/$device-id/online` and payload `0`. +* After a successfull connection, publish a similar message with the + payload `1`. Observe what happens when you unplug the device. diff --git a/assignments/mqtt-with-button/mqtt-with-button.pdf b/assignments/mqtt-with-button/mqtt-with-button.pdf index 8fcccf7..ccb511e 100644 Binary files a/assignments/mqtt-with-button/mqtt-with-button.pdf and b/assignments/mqtt-with-button/mqtt-with-button.pdf differ diff --git a/slides/connected-arduino-slides.pdf b/slides/connected-arduino-slides.pdf index cc258eb..7849f9a 100644 Binary files a/slides/connected-arduino-slides.pdf and b/slides/connected-arduino-slides.pdf differ diff --git a/slides/connected-arduino-text.pdf b/slides/connected-arduino-text.pdf index 6882209..3ad5987 100644 Binary files a/slides/connected-arduino-text.pdf and b/slides/connected-arduino-text.pdf differ diff --git a/slides/connected-arduino.md b/slides/connected-arduino.md index 16f93d4..512f8cb 100644 --- a/slides/connected-arduino.md +++ b/slides/connected-arduino.md @@ -16,167 +16,10 @@ header-includes: --- -# NodeMCU - -!comment(aka NodeMCU aka ESP-12) - -## NodeMCU hardware - -!ifndef(QUICK)( -![](images/NodeMCU-–-Board-de-desarrollo-con-módulo-ESP8266-WiFi-y-Lua-4.jpg) -) - -## NodeMCU hardware - -!ifndef(QUICK)( -\begin{center} -!include(images/nodemcu.pgf) -\end{center} -) - -## ESP8266 software layers - -!ifndef(QUICK)( -\begin{center} -!include(images/esp+arduino-sdks.pgf) -\end{center} -) - -## ESP8266 + Arduino - -* Standard Arduino IDE -* ESP8266 Arduino core - * https://github.com/esp8266/Arduino - -## Arduino IDE - -!ifndef(QUICK)( -![](images/arduino-ide.png) -) - -## Arduino code structure - -~~~ .c++ -void setup() { - // Called once -} - -void loop() { - // Called repeatedly -} -~~~ - -::: notes - -MCU programming is often structured into: - -* Configure - * CPU - * GPIO ports - * MCU's peripherals - * The rest of the board - * Configure application and callbacks. -* Sleep - -Arduino chooses to run the cpu at 100% instead of the sleep step.. - -::: - -## Arduino file structure - - foo/ - foo.ino - config.h - -::: notes - -`foo.ino` must always be in a `foo` directory. - -config.h is created by "new tab". - -::: - -## Generic Arduino APIs - -~~~c++ -// Pin: D0, D1, etc. -// Mode: OUTPUT, INPUT, INPUT_PULLUP -void pinMode(uint8_t pin, uint8_t mode); - -// State: HIGH, LOW, true/false, 1/0 -void digitalWrite(uint8_t pin, uint8_t state); -int digitalRead(uint8_t pin); - -unsigned long now millis(); -unsigned long now micros(); -~~~ - -## ESP Arduino APIs - -~~~c++ -class { - void restart(); - uint32_t getFreeHeap(); - uint32_t getChipId(); - - ... -} ESP; - -// Usage -ESP.restart(); -~~~ - -## ESP - -~~~c++ -// Top of file -#include - -// In setup() -WiFi.mode(WIFI_STA); -WiFi.begin(ssid, password); - -while (WiFi.status() != WL_CONNECTED) { - delay(500); - Serial.print("."); -} - -Serial.println(""); -Serial.println("WiFi connected"); -Serial.println("IP address: "); -Serial.println(WiFi.localIP()); -~~~ - -## ESP Arduino APIs - -~~~c++ -class { - String macAddress(); - - wl_status_t status(); - int32_t RSSI(); - - IPAddress localIP(); - IPAddress subnetMask(); - IPAddress gatewayIP(); - IPAddress dnsIP(uint8_t dns_no = 0); - - ... -} WiFi; - -// Usage: - -Serial.println(WiFi.localIP().toString()); -~~~ - -::: notes - -http://arduino-esp8266.readthedocs.io/en/latest/libraries.html - -::: - # What is IoT +!comment +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ## What is IoT * Not "a computer connected to the internet" @@ -205,6 +48,7 @@ As for their definition. What differentiates a computer from an IoT device? ::: +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ## What is an IoT Device? @@ -213,6 +57,10 @@ What differentiates a computer from an IoT device? * CPU * Network bandwidth and/or latency * Storage +* Has connectivity + +!comment +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Has connectivity * Bluetooth * Wi-Fi @@ -220,6 +68,7 @@ What differentiates a computer from an IoT device? * LTE Cat-M * LoRa * Proprietary radio +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ::: notes @@ -260,7 +109,26 @@ single company. LoRa chips are just trancievers, an MCU with LoRa stack is required. ::: -## ESP8266 details - Power usage +## ESP8266 Specifications + ++-------------+-----------------------------+ +| CPU | Tensilica Xtensa L106 | ++-------------+-----------------------------+ +| Frequency | 80MHz (160MHz possible | ++-------------+-----------------------------+ +| RAM | 32 kB instruction RAM | +| | 80 kB user RAM | +| | 16 kB system RAM | ++-------------+-----------------------------+ +| Flash | None, integrated SPI driver | ++-------------+-----------------------------+ +| Peripherals | 16 x GPIO | +| | I²C, SPI, I²S, UART | +| | 10 bit ADC | +| | Wi-Fi | ++-------------+-----------------------------+ + +## ESP8266 Power usage +--------------------------+----------------+ | State | Current usage | @@ -282,6 +150,61 @@ Datasheet page 18 ::: +# NodeMCU + +!comment(aka NodeMCU aka ESP-12) + +## NodeMCU hardware + +!ifndef(QUICK)( +\begin{center} +!include(images/nodemcu.pgf) +\end{center} +) + +## NodeMCU hardware + +!ifndef(QUICK)( +![](images/NodeMCU-–-Board-de-desarrollo-con-módulo-ESP8266-WiFi-y-Lua-4.jpg) +) + +## ESP8266 software layers + +!ifndef(QUICK)( +\begin{center} +!include(images/esp+arduino-sdks.pgf) +\end{center} +) + +## ESP8266 + Arduino + +* Standard Arduino IDE +* ESP8266 Arduino core + * https://github.com/esp8266/Arduino + +## Arduino IDE + +!ifndef(QUICK)( +![](images/arduino-ide.png) +) + +## Generic Arduino APIs + +~~~c++ +// Pin: D0, D1, etc. +// Mode: OUTPUT, INPUT, INPUT_PULLUP +// State: HIGH, LOW, 1/0 + +void pinMode(pin, mode); +void digitalWrite(pin, state); +int digitalRead(pin); + +unsigned long now = millis(); +unsigned long now = micros(); +~~~ + +# Assignment: `blink-a-led` + # Lecture: MQTT ## MQTT @@ -313,7 +236,7 @@ Version 3.1.1 er den som gjelder, V 3.1 er rar, de andre finnes ikke \end{center} ) -## MQTT Topic +## MQTT Example The temperature sensor: @@ -343,41 +266,6 @@ Commands can be: ::: -## MQTT - Implementations - -* Mosquitto -* Eclipse Paho -* RabbitMQ -* ActiveMQ - -::: notes - -RabbitMQ has a separate connector that must be installed -Not sure about ActiveMQ but it is at least a part of the project so it is releases at the same time. - -::: - -## MQTT Cloud Connectors - -* Cloud - * Amazon IoT - * Google Cloud IoT - * Microsoft Azure IoT - * CloudMQTT (at Heroku) - -* DIY - * ThingMQ - * HiveMQ - -::: notes - -In between are: - -* self hosted -* Generic bridges - -::: - ## MQTT - The protocol Agents have one of two roles: @@ -392,8 +280,8 @@ Agents have one of two roles: * Keeps subscriptions * Manages client * Timeouts and disconnects - * *(last) will* - * Persistence of retained messages + * *last will* + * Persistence of *retained* messages ::: notes @@ -418,76 +306,68 @@ Push vs pull, central applications can push to clients * `foo/bar/?` * `foo/#` -## MQTT - The protocol - Retained message - -Message is kept by the server even after disconnect - -* `CONNECT` -* `PUBLISH` - * `RETAIN` - * `$app/$device/temperature` - * `22.3` -* `DISCONNECT` - -Later on: - -* `SUBSCRIBE` - * `$app/#/temperature` -* `PUBLISH` - * `$app/$device/temperature` - * `22.3` - -::: notes +## ESP Arduino APIs -The last PUBLISH is an incoming message +~~~c++ +class { + void restart(); + uint32_t getFreeHeap(); + uint32_t getChipId(); -::: + ... +} ESP; -## MQTT - The protocol - Will message +// Usage +ESP.restart(); +~~~ -Message sent when you disconnect +## Connecting to a Wi-Fi -Client #1: +~~~c++ +#include -1. `CONNECT` - * `WILL TOPIC: $app/$device/online` - * `WILL PAYLOAD: 0` -1. `PUBLISH` - * `$app/$device/online` - * `1` -1. `DISCONNECT` +void setup() { + WiFi.mode(WIFI_STA); + WiFi.begin("NDC2018", NULL); -Broker + while (WiFi.status() != WL_CONNECTED) { + delay(500); + Serial.print("."); + } -1. *To all subscribers* `PUBLISH` - * `$app/$device/online` - * `0` + Serial.println(""); + Serial.println("WiFi connected"); + Serial.println("IP address: "); + Serial.println(WiFi.localIP()); +} +~~~ ## MQTT on Arduino PubSubClient is our MQTT client implementation. +Preparing to publish messages: + ~~~c++ +#include #include WiFiClient wifiClient; PubSubClient mqtt(wifiClient); -void callback(char* topic, - byte* payload, - unsigned int length); +String deviceId = "esp-" + String(ESP.getChipId(), HEX); void setup() { - // Configure WiFi - mqtt.setServer(mqtt_server, 1883); - mqtt.setCallback(callback); + // ... + mqtt.setServer("broker.hivemq.com", 1883); } ~~~ ## MQTT on Arduino ~~~c++ -void loop() { +void loop() +{ if (!mqtt.connected()) { reconnect(); } @@ -497,71 +377,52 @@ void loop() { // Do work } +~~~ -void reconnect() { +## MQTT on Arduino + +~~~c++ +void reconnect() +{ do { Serial.println("Connecting to MQTT"); delay(1000); - } while (!mqtt.connect(client_id)); - Serial.println("Connected to MQTT server"); + } while (!mqtt.connect(clientId.c_str())); - // Subscribe to any topics you need - mqtt.subscribe(topic_pattern); + Serial.println("Connected to MQTT server"); } ~~~ -::: notes -This is blocking! -::: - -## Assignment - -* `mqtt` - -## MQTT topic architecture - -The central application is split: - -* An aggregating agent: - * `myapp/#/temperature` - * `myapp/#/humidity` -* Emailing agent - * `myapp/$device-id/altert` - -* Publishes on: - * `myapp/$device-id/command` - -## MQTT topic architecture - -!ifndef(QUICK)( -\begin{center} -!include(images/mqtt-example-architecture.pgf) -\end{center} -) - -## MQTT topic architecture - -!ifndef(QUICK)( -\begin{center} -!include(images/mqtt-example-architecture2.pgf) -\end{center} -) - -## MQTT - Patterns - -* Combining MQTT and HTTP -* Using web sockets transport +## MQTT on Arduino -## Assignment +~~~c++ +void sendMessage() +{ + String topic = "ndc/" + deviceId + "/led"; + mqtt.publish(topic.c_str(), "1"); +} +~~~ -* `mqtt2` +## MQTT on Arduino -## Assignment +Preparing for subscriptions: -* `mqtt3` +~~~c++ +void setup() { + ... + mqtt.setCallback(callback); +} -::: notes +void callback(char* topic, + byte* payload, + unsigned int length) { +} -discussion: how to connect these two devices? +void reconnect() { + ... + // Subscribe to any topics you need + mqtt.subscribe(topic_pattern); +} +~~~ -::: +# Assignment: `mqtt-with-button` diff --git a/slides/toc.md b/slides/toc.md index 227f00a..d137e28 100644 --- a/slides/toc.md +++ b/slides/toc.md @@ -1,40 +1,33 @@ +* What is IoT + * What is IoT + * IoT is just a concept + * What is an IoT Device? + * What is an IoT Device? + * IoT Devices - Example chips + * ESP8266 Specifications + * ESP8266 Power usage * NodeMCU * NodeMCU hardware * NodeMCU hardware * ESP8266 software layers * ESP8266 + Arduino * Arduino IDE - * Arduino code structure - * Arduino file structure * Generic Arduino APIs - * ESP Arduino APIs - * ESP -#include - * ESP Arduino APIs -* What is IoT - * What is IoT - * IoT is just a concept - * What is an IoT Device? - * What is an IoT Device? - * IoT Devices - Example chips - * ESP8266 details - Power usage +* Assignment: `blink-a-led` * Lecture: MQTT * MQTT * Device and application architecture with MQTT - * MQTT Topic - * MQTT - Implementations - * MQTT Cloud Connectors + * MQTT Example * MQTT - The protocol * MQTT - The protocol - MQTT Topic - * MQTT - The protocol - Retained message - * MQTT - The protocol - Will message + * ESP Arduino APIs + * Connecting to a Wi-Fi +#include * MQTT on Arduino +#include #include * MQTT on Arduino - * Assignment - * MQTT topic architecture - * MQTT topic architecture - * MQTT topic architecture - * MQTT - Patterns - * Assignment - * Assignment + * MQTT on Arduino + * MQTT on Arduino + * MQTT on Arduino +* Assignment: `mqtt-with-button` -- cgit v1.2.3