diff options
author | Trygve Laugstøl <trygvis@inamo.no> | 2018-04-26 19:02:41 +0200 |
---|---|---|
committer | Trygve Laugstøl <trygvis@inamo.no> | 2018-04-26 19:02:41 +0200 |
commit | 09be8a0d1b07dc55a55fea52365c774398658d7d (patch) | |
tree | 3eb8fcd1540b64256cb445cc8c8dbd1e5582a0ae | |
parent | 129a22667006ec4f7ebca9c9d5b8e4d492103304 (diff) | |
download | iot-workshop-09be8a0d1b07dc55a55fea52365c774398658d7d.tar.gz iot-workshop-09be8a0d1b07dc55a55fea52365c774398658d7d.tar.bz2 iot-workshop-09be8a0d1b07dc55a55fea52365c774398658d7d.tar.xz iot-workshop-09be8a0d1b07dc55a55fea52365c774398658d7d.zip |
wip
-rw-r--r-- | assignments/Makefile | 10 | ||||
-rw-r--r-- | assignments/README.md | 3 | ||||
-rw-r--r-- | assignments/README.pdf | bin | 112702 -> 113254 bytes | |||
-rw-r--r-- | assignments/blink-a-led/blink-a-led.md | 12 | ||||
-rw-r--r-- | assignments/blink-a-led/blink-a-led.pdf | bin | 703496 -> 722602 bytes | |||
-rw-r--r-- | assignments/mqtt/mqtt.md | 44 | ||||
-rw-r--r-- | assignments/mqtt/mqtt.pdf | bin | 0 -> 105234 bytes | |||
-rw-r--r-- | slides/Makefile | 3 | ||||
-rw-r--r-- | slides/toc.md | 25 | ||||
-rw-r--r-- | slides/what-is-iot-reveal.html | 213 | ||||
-rw-r--r-- | slides/what-is-iot-slides.pdf | bin | 181891 -> 314263 bytes | |||
-rw-r--r-- | slides/what-is-iot-slides.tex | 157 | ||||
-rw-r--r-- | slides/what-is-iot-text.pdf | bin | 689296 -> 331141 bytes | |||
-rw-r--r-- | slides/what-is-iot.md | 100 |
14 files changed, 493 insertions, 74 deletions
diff --git a/assignments/Makefile b/assignments/Makefile index 24208f2..864864e 100644 --- a/assignments/Makefile +++ b/assignments/Makefile @@ -1,13 +1,17 @@ -AS=blink-a-led +AS=blink-a-led mqtt PDFS=$(foreach A,$(AS),$(A)/$(A).pdf) all: README.pdf $(PDFS) README.pdf: README.md -$(eval $(foreach A,$(AS),$(A)/$(A).pdf: $(A)/$(A).md)) +define A_PATTERN +$(1)/$(1).pdf: $(1)/$(1).md +endef +$(eval $(foreach A,$(AS),$(call $(A_PATTERN),$(A)))) %.pdf: %.md - cd $(dir $<); pandoc $(notdir $<) -o $(notdir $@) + @echo pandoc $< + @cd $(dir $<); pandoc $(notdir $<) -o $(notdir $@) #$(patsubst )/%,%,$<) -o $(patsubst $(DIR)/%,%,$@) diff --git a/assignments/README.md b/assignments/README.md index b420798..363ce15 100644 --- a/assignments/README.md +++ b/assignments/README.md @@ -1,5 +1,7 @@ # Assignment preparations +# Drivers + ## Install Arduino IDE Download and install from https://www.arduino.cc/en/Main/Software. The @@ -20,6 +22,7 @@ which should include "NodeMCU 1.0 (ESP-12E Module)". * PubSubClient * Time * TimeAlarms +* WifiManager ## Install Python 3 diff --git a/assignments/README.pdf b/assignments/README.pdf Binary files differindex a65c448..51f6f0b 100644 --- a/assignments/README.pdf +++ b/assignments/README.pdf diff --git a/assignments/blink-a-led/blink-a-led.md b/assignments/blink-a-led/blink-a-led.md index f4b3fa1..e7fb5d8 100644 --- a/assignments/blink-a-led/blink-a-led.md +++ b/assignments/blink-a-led/blink-a-led.md @@ -1,13 +1,19 @@ # Assignment: Blink a led - ## Goal 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. + +Create a new sketch with *File* -> *New* and compile it with *ctrl-R*. + ## Step 1 -Create this schematic: +Wire up this schematic on the bread board: ![](schematic/assignment-1_schem.pdf) @@ -23,14 +29,12 @@ Implement `setup()` and `loop()`. In `setup()` configure the LED pin and blink t Use these functions: ~~~ .c++ - Serial.begin(115200); Serial.println(string); pinMode(pin, mode); digitalWrite(pin, state); // HIGH or LOW delay(); - ~~~ ## Tips diff --git a/assignments/blink-a-led/blink-a-led.pdf b/assignments/blink-a-led/blink-a-led.pdf Binary files differindex c963e79..6456260 100644 --- a/assignments/blink-a-led/blink-a-led.pdf +++ b/assignments/blink-a-led/blink-a-led.pdf diff --git a/assignments/mqtt/mqtt.md b/assignments/mqtt/mqtt.md new file mode 100644 index 0000000..e89e88c --- /dev/null +++ b/assignments/mqtt/mqtt.md @@ -0,0 +1,44 @@ +# Assignment: MQTT + +## Goal + +Get aquainted with MQTT. + +## Steps + +1. Connect to the Wi-Fi network + * Use `WiFi.localIP()` + +1. Connect to MQTT broker +1. Publish temperature +1. Implement last will to indicate online status +1. Implement subscription to reconfigure device + 1. Change temperature report interval + +## Tips + +To generate a client id make something with `ESP.getChipId()`{.cpp} + +Creating a `String` from a number: + +* `String(123) => "123"`{.cpp} +* Hex formatted: `String(0x123abc, HEX) => "123abc"`{.cpp} + +Some APIs require "plain C strings" aka a `char *`{.cpp}. They can be converted with `String::c_str()`: + +~~~.c++ +char *cStr = myString.c_str(); +~~~ + +## Bonus + +**1:** Print the heap at regular intervals. + +**2:** Implement min, max and average temperature over configured interval. + +Suggested parameters: + +* Sample interval: 2 seconds +* Publish interval: 10 seconds + +**3:** Make sure the values are calculated even if we're reconnecting to the Wi-Fi or MQTT server. diff --git a/assignments/mqtt/mqtt.pdf b/assignments/mqtt/mqtt.pdf Binary files differnew file mode 100644 index 0000000..aa797bf --- /dev/null +++ b/assignments/mqtt/mqtt.pdf diff --git a/slides/Makefile b/slides/Makefile index 846caa0..d6a5a26 100644 --- a/slides/Makefile +++ b/slides/Makefile @@ -7,7 +7,8 @@ HTMLS=$(P)-reveal.html ifeq (1,$(QUICK)) PP_DEFS+=QUICK PDF_ENGINE = pdflatex -PANDOC_ARGS += --no-highlight +#PANDOC_ARGS += --no-highlight +PANDOC_ARGS += --highlight-style=pygments else PDF_ENGINE = xelatex PANDOC_ARGS += --highlight-style=pygments diff --git a/slides/toc.md b/slides/toc.md index e01e58b..8c07c8b 100644 --- a/slides/toc.md +++ b/slides/toc.md @@ -3,10 +3,13 @@ * IoT is just a concept * What is an IoT Device? * What is an IoT Device? - * Typical IoT chips - Bluetooth 4/5 - * Typical IoT chips - Wi-Fi + * IoT Devices - Bluetooth 4/5 chips + * IoT Devices - LoRA +### Modules +### Chips + * IoT Devices - NB-IoT + * IoT Devices - Wi-Fi * ESP8266 details - Power usage - * ESP8266 details - Arduino * Going back to basics * What is the internet again? * OSI model @@ -21,7 +24,15 @@ * Details: IP * Lecture: ESP8266 * NodeMCU hardware + * NodeMCU hardware * ESP8266 software layers + * ESP8266 + Arduino + * Arduino IDE + * Arduino code structure + * Arduino file structure + * Generic Arduino APIs + * ESP Arduino APIs + * ESP Arduino APIs * Lecture: MQTT * MQTT * MQTT - The protocol @@ -34,8 +45,6 @@ * MQTT - Patterns * MQTT - Implementations * MQTT Cloud Connectors -* Assignments - * Assignment 1: Blink a led - * Assignment 2: Connect to Wi-Fi - * Assignment 3: Connect to MQTT broker - * Assignment 4: Network play time + * MQTT on Arduino + * MQTT on Arduino + * Assignment: Network play time diff --git a/slides/what-is-iot-reveal.html b/slides/what-is-iot-reveal.html index a2f7d9e..0d73619 100644 --- a/slides/what-is-iot-reveal.html +++ b/slides/what-is-iot-reveal.html @@ -15,6 +15,71 @@ span.underline{text-decoration: underline;} div.column{display: inline-block; vertical-align: top; width: 50%;} </style> + <style type="text/css"> +a.sourceLine { display: inline-block; line-height: 1.25; } +a.sourceLine { pointer-events: none; color: inherit; text-decoration: inherit; } +a.sourceLine:empty { height: 1.2em; position: absolute; } +.sourceCode { overflow: visible; } +code.sourceCode { white-space: pre; position: relative; } +div.sourceCode { margin: 1em 0; } +pre.sourceCode { margin: 0; } +@media screen { +div.sourceCode { overflow: auto; } +} +@media print { +code.sourceCode { white-space: pre-wrap; } +a.sourceLine { text-indent: -1em; padding-left: 1em; } +} +pre.numberSource a.sourceLine + { position: relative; } +pre.numberSource a.sourceLine:empty + { position: absolute; } +pre.numberSource a.sourceLine::before + { content: attr(data-line-number); + position: absolute; left: -5em; text-align: right; vertical-align: baseline; + border: none; pointer-events: all; + -webkit-touch-callout: none; -webkit-user-select: none; + -khtml-user-select: none; -moz-user-select: none; + -ms-user-select: none; user-select: none; + padding: 0 4px; width: 4em; + color: #aaaaaa; + } +pre.numberSource { margin-left: 3em; border-left: 1px solid #aaaaaa; padding-left: 4px; } +div.sourceCode + { } +@media screen { +a.sourceLine::before { text-decoration: underline; } +} +code span.al { color: #ff0000; font-weight: bold; } /* Alert */ +code span.an { color: #60a0b0; font-weight: bold; font-style: italic; } /* Annotation */ +code span.at { color: #7d9029; } /* Attribute */ +code span.bn { color: #40a070; } /* BaseN */ +code span.bu { } /* BuiltIn */ +code span.cf { color: #007020; font-weight: bold; } /* ControlFlow */ +code span.ch { color: #4070a0; } /* Char */ +code span.cn { color: #880000; } /* Constant */ +code span.co { color: #60a0b0; font-style: italic; } /* Comment */ +code span.cv { color: #60a0b0; font-weight: bold; font-style: italic; } /* CommentVar */ +code span.do { color: #ba2121; font-style: italic; } /* Documentation */ +code span.dt { color: #902000; } /* DataType */ +code span.dv { color: #40a070; } /* DecVal */ +code span.er { color: #ff0000; font-weight: bold; } /* Error */ +code span.ex { } /* Extension */ +code span.fl { color: #40a070; } /* Float */ +code span.fu { color: #06287e; } /* Function */ +code span.im { } /* Import */ +code span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Information */ +code span.kw { color: #007020; font-weight: bold; } /* Keyword */ +code span.op { color: #666666; } /* Operator */ +code span.ot { color: #007020; } /* Other */ +code span.pp { color: #bc7a00; } /* Preprocessor */ +code span.sc { color: #4070a0; } /* SpecialChar */ +code span.ss { color: #bb6688; } /* SpecialString */ +code span.st { color: #4070a0; } /* String */ +code span.va { color: #19177c; } /* Variable */ +code span.vs { color: #4070a0; } /* VerbatimString */ +code span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */ + </style> <link rel="stylesheet" href="./bower_components/reveal.js/css/theme/black.css" id="theme"> <!-- Printing and PDF exports --> <script> @@ -40,16 +105,7 @@ <p class="author">Trygve Laugstøl <trygvis@trygvis.io></p> </section> -<section><section id="what-is-iot" class="title-slide slide level1"><h1>What is IoT</h1></section><section id="wat-png" class="slide level2"> -<h2>wat png</h2> -<p><img data-src="/home/trygvis/Dokumenter/Fritzing/bins/Untitled%20Sketch_bb.png" /></p> -</section><section id="wat-pdf" class="slide level2"> -<h2>wat pdf</h2> -<p><embed data-src="/home/trygvis/Dokumenter/Fritzing/bins/Untitled%20Sketch_bb.pdf" /></p> -</section><section id="wat-svg" class="slide level2"> -<h2>wat svg</h2> -<p><img data-src="/home/trygvis/Dokumenter/Fritzing/bins/Untitled%20Sketch_bb.svg" /></p> -</section><section id="what-is-iot-1" class="slide level2"> +<section><section id="what-is-iot" class="title-slide slide level1"><h1>What is IoT</h1></section><section id="what-is-iot-1" class="slide level2"> <h2>What is IoT</h2> <ul> <li>Not “a computer connected to the internet” @@ -97,6 +153,11 @@ </ul></li> </ul> <aside class="notes"> +<p>Might not have:</p> +<ul> +<li>RTC</li> +</ul> +<p>Extra features:</p> <ul> <li>IR</li> <li>UART</li> @@ -310,9 +371,6 @@ <aside class="notes"> <p>Datasheet page 18</p> </aside> -</section><section id="esp8266-details---arduino" class="slide level2"> -<h2>ESP8266 details - Arduino</h2> -<p>https://github.com/esp8266/Arduino</p> </section></section> <section><section id="going-back-to-basics" class="title-slide slide level1"><h1>Going back to basics</h1></section><section id="what-is-the-internet-again" class="slide level2"> <h2>What is the internet again?</h2> @@ -409,6 +467,91 @@ </section><section id="esp8266-software-layers" class="slide level2"> <h2>ESP8266 software layers</h2> +</section><section id="esp8266-arduino" class="slide level2"> +<h2>ESP8266 + Arduino</h2> +<ul> +<li>Standard Arduino IDE</li> +<li>ESP8266 Arduino core +<ul> +<li>https://github.com/esp8266/Arduino</li> +</ul></li> +</ul> +</section><section id="arduino-ide" class="slide level2"> +<h2>Arduino IDE</h2> +<p><img data-src="images/arduino-ide.png" /></p> +</section><section id="arduino-code-structure" class="slide level2"> +<h2>Arduino code structure</h2> +<div class="sourceCode" id="cb1"><pre class="sourceCode .c++"><code class="sourceCode cpp"><a class="sourceLine" id="cb1-1" data-line-number="1"><span class="dt">void</span> setup() {</a> +<a class="sourceLine" id="cb1-2" data-line-number="2"> <span class="co">// Called once</span></a> +<a class="sourceLine" id="cb1-3" data-line-number="3">}</a> +<a class="sourceLine" id="cb1-4" data-line-number="4"></a> +<a class="sourceLine" id="cb1-5" data-line-number="5"><span class="dt">void</span> loop() {</a> +<a class="sourceLine" id="cb1-6" data-line-number="6"> <span class="co">// Called repeatedly</span></a> +<a class="sourceLine" id="cb1-7" data-line-number="7">}</a></code></pre></div> +<aside class="notes"> +<p>MCU programming is often structured into:</p> +<ul> +<li>Configure +<ul> +<li>CPU</li> +<li>GPIO ports</li> +<li>MCU’s peripherals</li> +<li>The rest of the board</li> +<li>Configure application and callbacks.</li> +</ul></li> +<li>Sleep</li> +</ul> +<p>Arduino chooses to run the cpu at 100% instead of the sleep step..</p> +</aside> +</section><section id="arduino-file-structure" class="slide level2"> +<h2>Arduino file structure</h2> +<pre><code>foo/ + foo.ino + config.h</code></pre> +<aside class="notes"> +<p><code>foo.ino</code> must always be in a <code>foo</code> directory.</p> +<p>config.h is created by “new tab”.</p> +</aside> +</section><section id="generic-arduino-apis" class="slide level2"> +<h2>Generic Arduino APIs</h2> +<div class="sourceCode" id="cb3"><pre class="sourceCode cpp"><code class="sourceCode cpp"><a class="sourceLine" id="cb3-1" data-line-number="1"><span class="co">// Pin: D0, D1, etc.</span></a> +<a class="sourceLine" id="cb3-2" data-line-number="2"><span class="co">// Mode: OUTPUT, INPUT, INPUT_PULLUP</span></a> +<a class="sourceLine" id="cb3-3" data-line-number="3"><span class="dt">void</span> pinMode(<span class="dt">uint8_t</span> pin, <span class="dt">uint8_t</span> mode);</a> +<a class="sourceLine" id="cb3-4" data-line-number="4"></a> +<a class="sourceLine" id="cb3-5" data-line-number="5"><span class="co">// State: HIGH, LOW, true/false, 1/0</span></a> +<a class="sourceLine" id="cb3-6" data-line-number="6"><span class="dt">void</span> digitalWrite(<span class="dt">uint8_t</span> pin, <span class="dt">uint8_t</span> state);</a> +<a class="sourceLine" id="cb3-7" data-line-number="7"><span class="dt">int</span> digitalRead(<span class="dt">uint8_t</span> pin);</a> +<a class="sourceLine" id="cb3-8" data-line-number="8"></a> +<a class="sourceLine" id="cb3-9" data-line-number="9"><span class="dt">unsigned</span> <span class="dt">long</span> now millis();</a> +<a class="sourceLine" id="cb3-10" data-line-number="10"><span class="dt">unsigned</span> <span class="dt">long</span> now micros();</a></code></pre></div> +</section><section id="esp-arduino-apis" class="slide level2"> +<h2>ESP Arduino APIs</h2> +<div class="sourceCode" id="cb4"><pre class="sourceCode cpp"><code class="sourceCode cpp"><a class="sourceLine" id="cb4-1" data-line-number="1"><span class="kw">class</span> {</a> +<a class="sourceLine" id="cb4-2" data-line-number="2"> <span class="dt">void</span> restart();</a> +<a class="sourceLine" id="cb4-3" data-line-number="3"> <span class="dt">uint32_t</span> getFreeHeap();</a> +<a class="sourceLine" id="cb4-4" data-line-number="4"> <span class="dt">uint32_t</span> getChipId();</a> +<a class="sourceLine" id="cb4-5" data-line-number="5">} ESP;</a></code></pre></div> +<p>// Usage ESP.restart();</p> +</section><section id="esp-arduino-apis-1" class="slide level2"> +<h2>ESP Arduino APIs</h2> +<div class="sourceCode" id="cb5"><pre class="sourceCode cpp"><code class="sourceCode cpp"><a class="sourceLine" id="cb5-1" data-line-number="1"><span class="kw">class</span> {</a> +<a class="sourceLine" id="cb5-2" data-line-number="2"> String macAddress();</a> +<a class="sourceLine" id="cb5-3" data-line-number="3"></a> +<a class="sourceLine" id="cb5-4" data-line-number="4"> <span class="dt">wl_status_t</span> status();</a> +<a class="sourceLine" id="cb5-5" data-line-number="5"> <span class="dt">int32_t</span> RSSI();</a> +<a class="sourceLine" id="cb5-6" data-line-number="6"></a> +<a class="sourceLine" id="cb5-7" data-line-number="7"> IPAddress localIP();</a> +<a class="sourceLine" id="cb5-8" data-line-number="8"> IPAddress subnetMask();</a> +<a class="sourceLine" id="cb5-9" data-line-number="9"> IPAddress gatewayIP();</a> +<a class="sourceLine" id="cb5-10" data-line-number="10"> IPAddress dnsIP(<span class="dt">uint8_t</span> dns_no = <span class="dv">0</span>);</a> +<a class="sourceLine" id="cb5-11" data-line-number="11">} WiFi;</a> +<a class="sourceLine" id="cb5-12" data-line-number="12"></a> +<a class="sourceLine" id="cb5-13" data-line-number="13"><span class="co">// Usage:</span></a> +<a class="sourceLine" id="cb5-14" data-line-number="14"></a> +<a class="sourceLine" id="cb5-15" data-line-number="15">Serial.println(WiFi.localIP().toString());</a></code></pre></div> +<aside class="notes"> +<p>http://arduino-esp8266.readthedocs.io/en/latest/libraries.html</p> +</aside> </section></section> <section><section id="lecture-mqtt" class="title-slide slide level1"><h1>Lecture: MQTT</h1></section><section id="mqtt" class="slide level2"> <h2>MQTT</h2> @@ -625,15 +768,41 @@ <li>Generic bridges</li> </ul> </aside> -</section></section> -<section><section id="assignments" class="title-slide slide level1"><h1>Assignments</h1></section><section id="assignment-1-blink-a-led" class="slide level2"> -<h2>Assignment 1: Blink a led</h2> -</section><section id="assignment-2-connect-to-wi-fi" class="slide level2"> -<h2>Assignment 2: Connect to Wi-Fi</h2> -</section><section id="assignment-3-connect-to-mqtt-broker" class="slide level2"> -<h2>Assignment 3: Connect to MQTT broker</h2> -</section><section id="assignment-4-network-play-time" class="slide level2"> -<h2>Assignment 4: Network play time</h2> +</section><section id="mqtt-on-arduino" class="slide level2"> +<h2>MQTT on Arduino</h2> +<p>PubSubClient is our MQTT client implementation.</p> +<div class="sourceCode" id="cb6"><pre class="sourceCode cpp"><code class="sourceCode cpp"><a class="sourceLine" id="cb6-1" data-line-number="1">WiFiClient wifiClient;</a> +<a class="sourceLine" id="cb6-2" data-line-number="2">PubSubClient mqtt(wifiClient);</a> +<a class="sourceLine" id="cb6-3" data-line-number="3"></a> +<a class="sourceLine" id="cb6-4" data-line-number="4"><span class="dt">void</span> callback(<span class="dt">char</span>* topic,</a> +<a class="sourceLine" id="cb6-5" data-line-number="5"> byte* payload,</a> +<a class="sourceLine" id="cb6-6" data-line-number="6"> <span class="dt">unsigned</span> <span class="dt">int</span> length);</a> +<a class="sourceLine" id="cb6-7" data-line-number="7"></a> +<a class="sourceLine" id="cb6-8" data-line-number="8"><span class="dt">void</span> setup() {</a> +<a class="sourceLine" id="cb6-9" data-line-number="9"> <span class="co">// Configure WiFi</span></a> +<a class="sourceLine" id="cb6-10" data-line-number="10"> mqtt.setServer(mqtt_server, <span class="dv">1883</span>);</a> +<a class="sourceLine" id="cb6-11" data-line-number="11"> mqtt.setCallback(callback);</a> +<a class="sourceLine" id="cb6-12" data-line-number="12">}</a></code></pre></div> +</section><section id="mqtt-on-arduino-1" class="slide level2"> +<h2>MQTT on Arduino</h2> +<div class="sourceCode" id="cb7"><pre class="sourceCode cpp"><code class="sourceCode cpp"><a class="sourceLine" id="cb7-1" data-line-number="1"><span class="dt">void</span> loop() {</a> +<a class="sourceLine" id="cb7-2" data-line-number="2"> <span class="cf">if</span> (!mqtt.connected())</a> +<a class="sourceLine" id="cb7-3" data-line-number="3"> reconnect();</a> +<a class="sourceLine" id="cb7-4" data-line-number="4"> <span class="cf">else</span></a> +<a class="sourceLine" id="cb7-5" data-line-number="5"> mqtt.loop();</a> +<a class="sourceLine" id="cb7-6" data-line-number="6"> <span class="co">// Do work</span></a> +<a class="sourceLine" id="cb7-7" data-line-number="7">}</a> +<a class="sourceLine" id="cb7-8" data-line-number="8"></a> +<a class="sourceLine" id="cb7-9" data-line-number="9"><span class="dt">void</span> reconnect() {</a> +<a class="sourceLine" id="cb7-10" data-line-number="10"> <span class="cf">while</span> (!mqtt.<span class="fu">connect</span>(client_id));</a> +<a class="sourceLine" id="cb7-11" data-line-number="11"></a> +<a class="sourceLine" id="cb7-12" data-line-number="12"> mqtt.subscribe(topic_pattern);</a> +<a class="sourceLine" id="cb7-13" data-line-number="13">}</a></code></pre></div> +<aside class="notes"> +<p>This is blocking!</p> +</aside> +</section><section id="assignment-network-play-time" class="slide level2"> +<h2>Assignment: Network play time</h2> <ul> <li><p>Measure round trip time/latency. Measure UDP, TCP. Measure when the packet size is greater than the MTU</p></li> <li><p>Notice variations in RTT</p></li> diff --git a/slides/what-is-iot-slides.pdf b/slides/what-is-iot-slides.pdf Binary files differindex 49b1b5e..52c729b 100644 --- a/slides/what-is-iot-slides.pdf +++ b/slides/what-is-iot-slides.pdf diff --git a/slides/what-is-iot-slides.tex b/slides/what-is-iot-slides.tex index 582922b..8755756 100644 --- a/slides/what-is-iot-slides.tex +++ b/slides/what-is-iot-slides.tex @@ -502,15 +502,17 @@ maximum value is 64k, 65536.} \begin{frame}[fragile]{Arduino code structure} \protect\hypertarget{arduino-code-structure}{} -\begin{verbatim} -void setup() { - // Called once -} - -void loop() { - // Called repeatedly -} -\end{verbatim} +\begin{Shaded} +\begin{Highlighting}[] +\DataTypeTok{void}\NormalTok{ setup() \{} + \CommentTok{// Called once} +\NormalTok{\}} + +\DataTypeTok{void}\NormalTok{ loop() \{} + \CommentTok{// Called repeatedly} +\NormalTok{\}} +\end{Highlighting} +\end{Shaded} \note{MCU programming is often structured into: @@ -558,15 +560,64 @@ config.h is created by “new tab”.} \begin{frame}[fragile]{Generic Arduino APIs} \protect\hypertarget{generic-arduino-apis}{} -// Pin: D0, D1, etc. // Mode: OUTPUT, INPUT, INPUT\_PULLUP +\begin{Shaded} +\begin{Highlighting}[] +\CommentTok{// Pin: D0, D1, etc.} +\CommentTok{// Mode: OUTPUT, INPUT, INPUT_PULLUP} +\DataTypeTok{void}\NormalTok{ pinMode(}\DataTypeTok{uint8_t}\NormalTok{ pin, }\DataTypeTok{uint8_t}\NormalTok{ mode);} -\begin{verbatim} -pinMode(pin, mode); +\CommentTok{// State: HIGH, LOW, true/false, 1/0} +\DataTypeTok{void}\NormalTok{ digitalWrite(}\DataTypeTok{uint8_t}\NormalTok{ pin, }\DataTypeTok{uint8_t}\NormalTok{ state);} +\DataTypeTok{int}\NormalTok{ digitalRead(}\DataTypeTok{uint8_t}\NormalTok{ pin);} -digitalWrite(pin, state); +\DataTypeTok{unsigned} \DataTypeTok{long}\NormalTok{ now millis();} +\DataTypeTok{unsigned} \DataTypeTok{long}\NormalTok{ now micros();} +\end{Highlighting} +\end{Shaded} -state = digitalRead(pin); -\end{verbatim} +\end{frame} + +\begin{frame}[fragile]{ESP Arduino APIs} +\protect\hypertarget{esp-arduino-apis}{} + +\begin{Shaded} +\begin{Highlighting}[] +\KeywordTok{class}\NormalTok{ \{} + \DataTypeTok{void}\NormalTok{ restart();} + \DataTypeTok{uint32_t}\NormalTok{ getFreeHeap();} + \DataTypeTok{uint32_t}\NormalTok{ getChipId();} +\NormalTok{\} ESP;} +\end{Highlighting} +\end{Shaded} + +// Usage ESP.restart(); + +\end{frame} + +\begin{frame}[fragile]{ESP Arduino APIs} +\protect\hypertarget{esp-arduino-apis-1}{} + +\begin{Shaded} +\begin{Highlighting}[] +\KeywordTok{class}\NormalTok{ \{} +\NormalTok{ String macAddress();} + + \DataTypeTok{wl_status_t}\NormalTok{ status();} + \DataTypeTok{int32_t}\NormalTok{ RSSI();} + +\NormalTok{ IPAddress localIP();} +\NormalTok{ IPAddress subnetMask();} +\NormalTok{ IPAddress gatewayIP();} +\NormalTok{ IPAddress dnsIP(}\DataTypeTok{uint8_t}\NormalTok{ dns_no = }\DecValTok{0}\NormalTok{);} +\NormalTok{\} WiFi;} + +\CommentTok{// Usage:} + +\NormalTok{Serial.println(WiFi.localIP().toString());} +\end{Highlighting} +\end{Shaded} + +\note{http://arduino-esp8266.readthedocs.io/en/latest/libraries.html} \end{frame} @@ -998,26 +1049,82 @@ releases at the same time.} \end{frame} -\hypertarget{assignments}{% -\section{Assignments}\label{assignments}} +\begin{frame}[fragile]{MQTT on Arduino} +\protect\hypertarget{mqtt-on-arduino}{} + +PubSubClient is our MQTT client implementation. -\begin{frame}{Assignment 1: Blink a led} -\protect\hypertarget{assignment-1-blink-a-led}{} +\begin{Shaded} +\begin{Highlighting}[] +\NormalTok{WiFiClient wifiClient;} +\NormalTok{PubSubClient mqtt(wifiClient);} + +\DataTypeTok{void}\NormalTok{ callback(}\DataTypeTok{char}\NormalTok{* topic,} +\NormalTok{ byte* payload,} + \DataTypeTok{unsigned} \DataTypeTok{int}\NormalTok{ length);} + +\DataTypeTok{void}\NormalTok{ setup() \{} + \CommentTok{// Configure WiFi} +\NormalTok{ mqtt.setServer(mqtt_server, }\DecValTok{1883}\NormalTok{);} +\NormalTok{ mqtt.setCallback(callback);} +\NormalTok{\}} +\end{Highlighting} +\end{Shaded} + +\end{frame} + +\begin{frame}[fragile]{MQTT on Arduino} +\protect\hypertarget{mqtt-on-arduino-1}{} + +\begin{Shaded} +\begin{Highlighting}[] +\DataTypeTok{void}\NormalTok{ loop() \{} + \ControlFlowTok{if}\NormalTok{ (!mqtt.connected())} +\NormalTok{ reconnect();} + \ControlFlowTok{else} +\NormalTok{ mqtt.loop();} + \CommentTok{// Do work} +\NormalTok{\}} + +\DataTypeTok{void}\NormalTok{ reconnect() \{} + \ControlFlowTok{while}\NormalTok{ (!mqtt.}\FunctionTok{connect}\NormalTok{(client_id));} + +\NormalTok{ mqtt.subscribe(topic_pattern);} +\NormalTok{\}} +\end{Highlighting} +\end{Shaded} + +\note{This is blocking!} \end{frame} -\begin{frame}{Assignment 2: Connect to Wi-Fi} -\protect\hypertarget{assignment-2-connect-to-wi-fi}{} +\begin{frame}{Assignment: MQTT} +\protect\hypertarget{assignment-mqtt}{} \end{frame} -\begin{frame}{Assignment 3: Connect to MQTT broker} -\protect\hypertarget{assignment-3-connect-to-mqtt-broker}{} +\hypertarget{assignments}{% +\section{Assignments}\label{assignments}} + +\begin{frame}{Assignment: Arduino} +\protect\hypertarget{assignment-arduino}{} + +\begin{itemize} +\tightlist +\item + Hello world on serial console +\item + Blink a led +\item + Read the temperature every second, print to serial console +\item + Print available heap +\end{itemize} \end{frame} -\begin{frame}{Assignment 4: Network play time} -\protect\hypertarget{assignment-4-network-play-time}{} +\begin{frame}{Assignment: Network play time} +\protect\hypertarget{assignment-network-play-time}{} \begin{itemize} \item diff --git a/slides/what-is-iot-text.pdf b/slides/what-is-iot-text.pdf Binary files differindex 6d02221..e1c80ad 100644 --- a/slides/what-is-iot-text.pdf +++ b/slides/what-is-iot-text.pdf diff --git a/slides/what-is-iot.md b/slides/what-is-iot.md index ef11ca3..c3a74eb 100644 --- a/slides/what-is-iot.md +++ b/slides/what-is-iot.md @@ -376,17 +376,58 @@ 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++ -pinMode(pin, mode); +class { + void restart(); + uint32_t getFreeHeap(); + uint32_t getChipId(); +} ESP; +~~~ + +// Usage +ESP.restart(); -digitalWrite(pin, state); +## ESP Arduino APIs + +~~~c++ +class { + String macAddress(); -state = digitalRead(pin); + 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 + +::: + # Lecture: MQTT ## MQTT @@ -396,13 +437,17 @@ state = digitalRead(pin); ::: notes -MQTT is *the* standard for IoT applications (and lots of other useful stuff to). Using HTTP is just silly. +MQTT is *the* standard for IoT applications (and lots of other useful +stuff to). Using HTTP is just silly. Supports SSL, and requires TCP. -Has UDP-like semantics with "fire and forget" but on a higher level (the message always have to be delivered and ACKed by the broker, not it's final recipient. +Has UDP-like semantics with "fire and forget" but on a higher level +(the message always have to be delivered and ACKed by the broker, not +it's final recipient. -Version 3.1.1 er den som gjelder, V 3.1 er rar, de andre finnes ikke (før standardisering). +Version 3.1.1 er den som gjelder, V 3.1 er rar, de andre finnes ikke +(før standardisering). ::: @@ -600,15 +645,48 @@ In between are: ::: -# Assignments +## MQTT on Arduino -## Assignment 1: Blink a led +PubSubClient is our MQTT client implementation. -## Assignment 2: Connect to Wi-Fi +~~~c++ +WiFiClient wifiClient; +PubSubClient mqtt(wifiClient); + +void callback(char* topic, + byte* payload, + unsigned int length); -## Assignment 3: Connect to MQTT broker +void setup() { + // Configure WiFi + mqtt.setServer(mqtt_server, 1883); + mqtt.setCallback(callback); +} +~~~ + +## MQTT on Arduino + +~~~c++ +void loop() { + if (!mqtt.connected()) + reconnect(); + else + mqtt.loop(); + // Do work +} + +void reconnect() { + while (!mqtt.connect(client_id)); + + mqtt.subscribe(topic_pattern); +} +~~~ + +::: notes +This is blocking! +::: -## Assignment 4: Network play time +## Assignment: Network play time * Measure round trip time/latency. Measure UDP, TCP. Measure when the packet size is greater than the MTU |