lupyuen.org/articles/get-started-with-nb-iot-and-quectel-modules.html

1155 lines
No EOL
72 KiB
HTML
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!doctype html>
<html lang="en">
<head>
<link rel="stylesheet" type="text/css" href="/_static/css/banner-styles.css?v=bsmaklHF" />
<link rel="stylesheet" type="text/css" href="/_static/css/iconochive.css?v=qtvMKcIJ" />
<link rel="canonical" href="https://lupyuen.org/articles/get-started-with-nb-iot-and-quectel-modules.html" />
<!-- End Wayback Rewrite JS Include -->
<title data-rh="true">Get Started with NB-IoT and Quectel modules - Lup Yuen Lee 李立源 - Medium</title>
<meta data-rh="true" charset="utf-8" />
<meta data-rh="true" name="viewport" content="width=device-width,minimum-scale=1,initial-scale=1" />
<meta data-rh="true" name="theme-color" content="#000000" />
<meta data-rh="true" property="og:type" content="article" />
<meta data-rh="true" property="article:published_time" content="2019-08-17T17:13:24.259Z" />
<meta data-rh="true" name="title" content="Get Started with NB-IoT and Quectel modules - Lup Yuen Lee 李立源 - Medium" />
<meta data-rh="true" property="og:title" content="Get Started with NB-IoT and Quectel modules" />
<meta data-rh="true" property="twitter:title" content="Get Started with NB-IoT and Quectel modules" />
<meta data-rh="true" name="description"
content="Send a real CoAP message to thethings.io over NB-IoT to visualise your sensor data" />
<meta data-rh="true" property="og:description"
content="Send a real CoAP message to thethings.io over NB-IoT to visualise your sensor data" />
<meta data-rh="true" property="twitter:description"
content="Send a real CoAP message to thethings.io over NB-IoT to visualise your sensor data" />
<meta data-rh="true" name="twitter:card" content="summary_large_image" />
<meta data-rh="true" name="twitter:creator" content="@MisterTechBlog" />
<meta data-rh="true" name="author" content="Lup Yuen Lee 李立源" />
<meta data-rh="true" name="robots" content="index,follow" />
<meta data-rh="true" name="referrer" content="unsafe-url" />
<meta data-rh="true" name="twitter:label1" value="Reading time" />
<meta data-rh="true" name="twitter:data1" value="14 min read" />
<meta property="og:image"
content="https://lupyuen.github.io/images/legacy2/c1.png">
<!-- Begin scripts/rustdoc-header.html: Header for Custom Markdown files processed by rustdoc, like chip8.md -->
<link rel="alternate" type="application/rss+xml" title="RSS Feed for lupyuen" href="/rss.xml" />
<link rel="stylesheet" type="text/css" href="../normalize.css">
<link rel="stylesheet" type="text/css" href="../rustdoc.css" id="mainThemeStyle">
<link rel="stylesheet" type="text/css" href="../light.css" id="themeStyle">
<link rel="stylesheet" type="text/css" href="../prism.css">
<script src="../storage.js"></script><noscript>
<link rel="stylesheet" href="../noscript.css"></noscript>
<link rel="shortcut icon" href="../favicon.ico">
<style type="text/css">
#crate-search {
background-image: url("../down-arrow.svg");
}
a {
color: #77d;
}
</style>
<!-- End scripts/rustdoc-header.html -->
</head>
<body>
<div id="root">
<div class="a b c">
<article>
<section class="cj ck cl cm ak cn ce n co"></section><span class="r"></span>
<div>
<div class="cp u cq cr cs ct"></div>
<section class="cu cv cw cx cy">
<div class="cz ak">
<div class="figure da cz ak paragraph-image">
<p><img src="https://lupyuen.github.io/images/legacy2/c1.png" /></p>
</div>
</div>
<div class="n p">
<div class="ac ae af ag ah ds aj ak">
<div>
<div id="af66" class="dt du dv bk dw b dx dy dz ea eb ec ed">
<h1 class="dw b dx ee dv">Get Started with NB-IoT and Quectel modules</h1>
</div>
<div class="ef">
<div class="n eg eh ei ej">
<div class="o n">
<div><a rel="noopener"
href="https://lupyuen.github.io">
<div class="dd ek el">
<div class="bs n em o p cp en eo ep eq er ct"></div>
</div>
</a></div>
<div class="et ak r">
<div class="n">
<div style="flex:1"><span class="bj b bk bl bm bn r dv q">
<div class="eu n o ev"><span class="bj ew ex bl di ey ez fa fb fc dv"><a
class="at au av aw ax ay az ba bb bc fd bf bg bh bi" rel="noopener"
href="https://lupyuen.github.io">Lup
Yuen Lee 李立源</a></span>
</div>
</span></div>
</div><span class="bj b bk bl bm bn r bo bp"><span class="bj ew ex bl di ey ez fa fb fc bo">
<div><a class="at au av aw ax ay az ba bb bc fd bf bg bh bi" rel="noopener"
href="https://lupyuen.github.io/articles/get-started-with-nb-iot-and-quectel-modules">
15 Jul 2019</a> <!-- -->·
<!-- -->
<!-- -->14
<!-- --> min read
</div>
</span></span>
</div>
</div>
</div>
</div>
</div>
<blockquote class="gc gd ge">
<p id="692d" class="gf gg dv gh gi b gj gk gl gm gn go gp gq gr gs gt">The year is 2029. Humans are
populating the Moon, starting at <a class="at cg gu gv gw gx" target="_blank" rel="noopener"
href="https://lupyuen.github.io/articles/create-your-iot-gadget-with-apache-mynewt-and-stm32-blue-pill">Moon
Base One</a>. Two Moon Base Operators are about to commit a grave mistake in the crop garden of
beautiful red tomatoes…</p>
</blockquote>
<div class="figure gz ha hb hc hd cz dr he cd hf hg hh hi hj ba hk hl hm hn ho hp paragraph-image">
<p><img src="https://lupyuen.github.io/images/legacy2/c2.png" /></p>
<figcaption class="bo ex hr hs ht cn cl cm hu hv bj ew"><p><em>Tomato Crop on Moon Base One</em></p></figcaption>
</div>
<blockquote class="gc gd ge">
<p id="5e72" class="gf gg dv gh gi b gj gk gl gm gn go gp gq gr gs gt">Operator 1: Are we all set to
power on 1,000 new temperature sensors today?</p>
<p id="e845" class="gf gg dv gh gi b gj gk gl gm gn go gp gq gr gs gt">Operator 2: All set! We already
have 1,000 existing temperature sensors. Doubling the sensors should be a piece of cake!</p>
<p id="61e6" class="gf gg dv gh gi b gj gk gl gm gn go gp gq gr gs gt">Operator 1: OK powering on
1,000 new sensors… Wait we got an error… CONNECTION REFUSED… MQTT SERVER TOO BUSY</p>
<p id="5127" class="gf gg dv gh gi b gj gk gl gm gn go gp gq gr gs gt">Operator 2: Thats odd… These
sensors are just connecting to the MQTT server over the 8G mobile network, sending a short sensor
data message periodically while keeping the connection alive. What could have gone wrong?</p>
<p id="989e" class="gf gg dv gh gi b gj gk gl gm gn go gp gq gr gs gt">Operator 1: WHAT??? Why didnt
we use 4G LTE with NB-IoT? Its connectionless and can handle more sensors!</p>
<p id="f759" class="gf gg dv gh gi b gj gk gl gm gn go gp gq gr gs gt">Operator 2: But the message
delivery is not guaranteed with NB-IoT! Then again, maybe we dont really need to receive every
single sensor message…</p>
<p id="fe51" class="gf gg dv gh gi b gj gk gl gm gn go gp gq gr gs gt">Operator 1: ALL our temperature
sensors are DISCONNECTED! Fans are speeding up and blowing HOT AIR at our crops! Our fresh tomatoes
are getting AIR FRIED!!! NOOOOOOO…</p>
</blockquote>
<p id="d81c" class="gf gg dv bk gi b gj gk gl gm gn go gp gq gr gs gt">Lets face it — NB-IoT is hard!
But we may not realise that NB-IoT (or <a
href="https://en.wikipedia.org/wiki/Narrowband_IoT"
class="at cg gu gv gw gx" target="_blank" rel="noopener nofollow">Narrowband Internet of
Things</a>)<strong class="gi hw"> </strong>is hard because it requires a <em class="gh">mindset
change</em></p>
<p id="27a2" class="gf gg dv bk gi b gj gk gl gm gn go gp gq gr gs gt">When phones were created, they
were meant to <strong class="gi hw">connect people to other people</strong> so that we could talk.
Today our 4G LTE networks still carry over the same <strong class="gi hw">Connection-Oriented</strong>
concepts but introduces a new twist: A new <strong class="gi hw">Connectionless</strong> method called
<a href="https://en.wikipedia.org/wiki/Narrowband_IoT"
class="at cg gu gv gw gx" target="_blank" rel="noopener nofollow">NB-IoT</a></p>
<blockquote class="gc gd ge">
<p id="0a29" class="gf gg dv gh gi b gj gk gl gm gn go gp gq gr gs gt">NB-IoT focuses specifically on
<strong class="gi hw">indoor coverage, low cost, long battery life, and high connection
density</strong>. NB-IoT uses a subset of the LTE standard, but limits the bandwidth to a single
narrow-band of 200kHz.</p>
</blockquote>
<p id="42ab" class="gf gg dv bk gi b gj gk gl gm gn go gp gq gr gs gt">In this article we shall learn…
</p>
<p id="e9dd" class="gf gg dv bk gi b gj gk gl gm gn go gp gq gr gs gt">1⃣ How NB-IoT networks operate
the <strong class="gi hw">Connectionless way with UDP and CoAP protocols</strong></p>
<p id="ff0c" class="gf gg dv bk gi b gj gk gl gm gn go gp gq gr gs gt">2⃣ How to use a <a
href="https://www.quectel.com/product/bc68.htm"
class="at cg gu gv gw gx" target="_blank" rel="noopener nofollow"><strong class="gi hw">Quectel
evaluation board</strong></a> to send a CoAP message to the <strong class="gi hw">CoAP server
hosted at thethings.io</strong></p>
<p id="c7c5" class="gf gg dv bk gi b gj gk gl gm gn go gp gq gr gs gt">3⃣ How to <strong
class="gi hw">visualise the sensor data transmitted</strong> to thethings.io</p>
<p id="4bb1" class="gf gg dv bk gi b gj gk gl gm gn go gp gq gr gs gt">Many thanks to <a
href="https://www.starhub.com/" class="at cg gu gv gw gx"
target="_blank" rel="noopener nofollow"><strong class="gi hw">StarHub</strong></a> for providing the
Quectel evaluation board and the NB-IoT SIM for the purpose of IoT Education! This generous gesture by
StarHub will surely benefit many IoT makers around the world.</p>
</div>
</div>
<div class="cz ak">
<div class="figure gz ha hb hc hd cz ak paragraph-image">
<p><img src="https://lupyuen.github.io/images/legacy2/h0.png" /></p>
</div>
</div>
<div class="n p">
<div class="ac ae af ag ah ds aj ak">
<h1 id="8b75" class="hy hz dv bk bj ia ib ic id ie if ig ih ii ij ik il">Are You Connected? Or
Connectionless?</h1>
<p id="7954" class="gf gg dv bk gi b gj im gl in gn io gp ip gr iq gt">How do we achieve <em
class="gh">“low cost, long battery life, and high connection density”</em> with NB-IoT? Next time
you attend a party, try this…</p>
<blockquote class="gc gd ge">
<p id="2fc9" class="gf gg dv gh gi b gj gk gl gm gn go gp gq gr gs gt">Mingle around as many people as
you can. Listen to what EVERYONE has to say.</p>
<p id="9abd" class="gf gg dv gh gi b gj gk gl gm gn go gp gq gr gs gt">When a conversation gets
boring, just move away without saying anything.</p>
<p id="8bc3" class="gf gg dv gh gi b gj gk gl gm gn go gp gq gr gs gt">Dont feel obligated to
continue any conversation. Its your right to listen as much or as little as you want. Youre NOT
committed to stay CONNECTED to any person at the party.</p>
<p id="b402" class="gf gg dv gh gi b gj gk gl gm gn go gp gq gr gs gt">Yes your friends will find you
strangely anti-social. You will miss out on some great stories from your friends, but then again,
they are probably repeating the same old stories.</p>
<p id="1bf5" class="gf gg dv gh gi b gj gk gl gm gn go gp gq gr gs gt">BUT you will <strong
class="gi hw">learn lots more, from more people</strong>. And feel <strong class="gi hw">less
drained</strong>.</p>
<p id="afd5" class="gf gg dv gh gi b gj gk gl gm gn go gp gq gr gs gt">Thats the better way… the
CONNECTIONLESS way!</p>
</blockquote>
</div>
</div>
<div class="cz">
<div class="n p">
<div class="ir is it iu iv iw ag ix ah iy aj ak">
<div class="figure gz ha hb hc hd cz ja jb paragraph-image">
<p><img src="https://lupyuen.github.io/images/legacy2/c3.png" /></p>
</div>
</div>
</div>
</div>
<div class="n p">
<div class="ac ae af ag ah ds aj ak">
<p id="738c" class="gf gg dv bk gi b gj gk gl gm gn go gp gq gr gs gt">We have been using <a
href="https://en.wikipedia.org/wiki/Transmission_Control_Protocol"
class="at cg gu gv gw gx" target="_blank" rel="noopener nofollow">TCP (Transmission Control
Protocol)</a> since the beginning of the internet to connect our gadgets (<a
href="https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol"
class="at cg gu gv gw gx" target="_blank" rel="noopener nofollow">HTTP</a> and <a
href="https://en.wikipedia.org/wiki/MQTT"
class="at cg gu gv gw gx" target="_blank" rel="noopener nofollow">MQTT</a> are two popular protocols
based on TCP). However <strong class="gi hw">TCP is Connection-Oriented </strong>— when two devices
are connected via TCP, they need to <strong class="gi hw">stay connected… or they will be
penalised</strong>.</p>
<p id="9281" class="gf gg dv bk gi b gj gk gl gm gn go gp gq gr gs gt">If any packets are dropped (due
to poor network coverage or congestion) or delayed, both devices will need to <a
href="https://en.wikipedia.org/wiki/Transmission_Control_Protocol#Flow_control"
class="at cg gu gv gw gx" target="_blank" rel="noopener nofollow">resynchronise their TCP
windows</a> by retransmitting their packets. Which may lead to severe problems like the MQTT Server
congestion on Moon Base One!</p>
</div>
</div>
<div class="cz ak">
<div class="figure gz ha hb hc hd cz ak paragraph-image">
<p><img src="https://lupyuen.github.io/images/legacy2/h0.png" /></p>
</div>
</div>
<div class="n p">
<div class="ac ae af ag ah ds aj ak">
<h1 id="c802" class="hy hz dv bk bj ia ib ic id ie if ig ih ii ij ik il">The Connectionless Way: Change
TCP to UDP</h1>
<p id="935e" class="gf gg dv bk gi b gj im gl in gn io gp ip gr iq gt">In a Connectionless Network
theres no commitment to stay connected to any device:<strong class="gi hw"> Just transmit or receive
a message. And move on</strong>. (Like our Connectionless Party!)</p>
</div>
</div>
<div class="cz">
<div class="n p">
<div class="ir is it iu iv iw ag ix ah iy aj ak">
<div class="figure gz ha hb hc hd cz ja jb paragraph-image">
<p><img src="https://lupyuen.github.io/images/legacy2/c4.png" /></p>
</div>
</div>
</div>
</div>
<div class="n p">
<div class="ac ae af ag ah ds aj ak">
<p id="5214" class="gf gg dv bk gi b gj gk gl gm gn go gp gq gr gs gt">Instead of establishing a TCP
connection, we transmit a <a
href="https://en.wikipedia.org/wiki/User_Datagram_Protocol"
class="at cg gu gv gw gx" target="_blank" rel="noopener nofollow">UDP (User Datagram Protocol)</a>
packet <strong class="gi hw">without</strong> <strong class="gi hw">waiting for the
acknowledgement</strong>. But because they are Connectionless, <strong class="gi hw">UDP packets do
not enjoy guaranteed delivery</strong>.</p>
<p id="1146" class="gf gg dv bk gi b gj gk gl gm gn go gp gq gr gs gt">Most UDP packets are delivered
properly, but if any packets are dropped (due to poor network coverage or congestion),<strong
class="gi hw"> UDP devices dont attempt to resynchronise and retransmit the lost packets.</strong>
</p>
<p id="8940" class="gf gg dv bk gi b gj gk gl gm gn go gp gq gr gs gt"><em class="gh">Isnt it a serious
problem when packets disappear in our IoT network?</em> Well, do we really need to receive every
single sensor reading? Instead of suffering a server failure or network congestion like Moon Base One,
could we <em class="gh">compromise by dropping a couple of sensor messages</em>? Thats how we achieve
<strong class="gi hw">High Connection Density</strong> in NB-IoT!</p>
<p id="6b31" class="gf gg dv bk gi b gj gk gl gm gn go gp gq gr gs gt">When we go Connectionless, our
gadgets become a lot <strong class="gi hw">simpler to build</strong>… no messy <a
href="https://en.wikipedia.org/wiki/Sliding_window_protocol"
class="at cg gu gv gw gx" target="_blank" rel="noopener nofollow">sliding window protocols</a> and
waiting forever! Thus our NB-IoT gadgets are <strong class="gi hw">Low Cost</strong>, and enjoy
<strong class="gi hw">Long Battery Life!</strong></p>
<blockquote class="gc gd ge">
<p id="0e49" class="gf gg dv gh gi b gj gk gl gm gn go gp gq gr gs gt"><em class="bk">💎</em> Many
other things are switching to the simpler Connectionless way… <em class="bk">1</em> <a
href="https://en.wikipedia.org/wiki/HTTP/3"
class="at cg gu gv gw gx" target="_blank" rel="noopener nofollow">HTTP version 3</a> will switch
from TCP to a UDP protocol named <a
href="https://en.wikipedia.org/wiki/QUIC"
class="at cg gu gv gw gx" target="_blank" rel="noopener nofollow">QUIC</a>. Because it just works
better on lossy mobile networks. <em class="bk">2</em> YouTube and many video streaming services
are already running on <a
href="https://en.wikipedia.org/wiki/Real_Time_Streaming_Protocol"
class="at cg gu gv gw gx" target="_blank" rel="noopener nofollow">RTSP</a> based on UDP. It allows
video quality to be negotiated in real time based on network conditions. <em class="bk">3</em> <a
href="https://technology.riotgames.com/news/fixing-internet-real-time-applications-part-i"
class="at cg gu gv gw gx" target="_blank" rel="noopener nofollow">Most massively multiplayer games
already use UDP</a> to achieve lower latency.</p>
</blockquote>
</div>
</div>
<div class="cz ak">
<div class="figure gz ha hb hc hd cz ak paragraph-image">
<p><img src="https://lupyuen.github.io/images/legacy2/h0.png" /></p>
</div>
</div>
<div class="cz">
<div class="n p">
<div class="ir is it iu iv iw ag ix ah iy aj ak">
<div class="figure jf jg jh ji jj cz ja jb paragraph-image">
<p><img src="https://lupyuen.github.io/images/legacy2/c5.png" /></p>
</div>
</div>
</div>
</div>
<div class="n p">
<div class="ac ae af ag ah ds aj ak">
<h1 id="abb9" class="hy hz dv bk bj ia ib ic id ie if ig ih ii ij ik il">Hello CoAP!</h1>
<p id="0914" class="gf gg dv bk gi b gj im gl in gn io gp ip gr iq gt">In the<strong class="gi hw">
Connection-Oriented Universe</strong>, we have the <strong class="gi hw">MQTT</strong> protocol for
transmitting TCP sensor messages to the IoT Server. Whats the equivalent for the <strong
class="gi hw">Connectionless Universe</strong> that will allow us to transmit UDP sensor messages?
</p>
<p id="a4ec" class="gf gg dv bk gi b gj gk gl gm gn go gp gq gr gs gt"><em class="gh">Answer</em>: <a
href="https://en.wikipedia.org/wiki/Constrained_Application_Protocol"
class="at cg gu gv gw gx" target="_blank" rel="noopener nofollow"><strong class="gi hw">Constrained
Application Protocol, or CoAP</strong></a></p>
<p id="c063" class="gf gg dv bk gi b gj gk gl gm gn go gp gq gr gs gt">Why <em
class="gh">“Constrained”</em>? Because CoAP was designed for low-power microcontrollers that dont
have easy access to power (like the crop sensors on Moon Base One). And CoAP requires little
bandwidth… <strong class="gi hw">120 bytes</strong> is all we need to send a sensor message to a CoAP
server (like thethings.io)… Perfect for NB-IoT!</p>
<div class="figure gz ha hb hc hd cz dr he cd hf hg hh hi hj ba hk hl hm hn ho hp paragraph-image">
<p><img src="https://lupyuen.github.io/images/legacy2/c6.png" /></p>
<figcaption class="bo ex hr hs ht cn cl cm hu hv bj ew"><p><em></em>Google Sheet for encoding CoAP messages. From
<a href="https://docs.google.com/spreadsheets/d/1k72R9CWKxu8_AsQURA3iOtTTlE08Qks0gFcuBJZtTqo/edit?usp=sharing"
class="at cg gu gv gw gx" target="_blank"
rel="noopener nofollow">https://docs.google.com/spreadsheets/d/1k72R9CWKxu8_AsQURA3iOtTTlE08Qks0gFcuBJZtTqo/edit?usp=sharing</a>
</em></p></figcaption>
</div>
<p id="deb3" class="gf gg dv bk gi b gj gk gl gm gn go gp gq gr gs gt">I have prepared a <a
href="https://docs.google.com/spreadsheets/d/1k72R9CWKxu8_AsQURA3iOtTTlE08Qks0gFcuBJZtTqo/edit?usp=sharing"
class="at cg gu gv gw gx" target="_blank" rel="noopener nofollow">Google Sheet</a> that shows how a
CoAP message is encoded for sending sensor data. Lets look at the three parts of a CoAP message…</p>
<p id="9a7a" class="gf gg dv bk gi b gj gk gl gm gn go gp gq gr gs gt"><strong class="gi hw">0⃣ CoAP
Preamble</strong></p>
<p id="796d" class="gf gg dv bk gi b gj gk gl gm gn go gp gq gr gs gt"><strong class="gi hw">1⃣ CoAP
Options</strong></p>
<p id="e957" class="gf gg dv bk gi b gj gk gl gm gn go gp gq gr gs gt"><strong class="gi hw">2⃣ CoAP
Payload</strong></p>
</div>
</div>
<div class="cz ak">
<div class="figure gz ha hb hc hd cz ak paragraph-image">
<p><img src="https://lupyuen.github.io/images/legacy2/h0.png" /></p>
</div>
<div class="figure da cz ak paragraph-image">
<p><img src="https://lupyuen.github.io/images/legacy2/c7.png" /></p>
<figcaption class="bo ex hr hs ht cn cl cm hu hv bj ew"><p><em>CoAP Preamble. From <a
href="https://docs.google.com/spreadsheets/d/1k72R9CWKxu8_AsQURA3iOtTTlE08Qks0gFcuBJZtTqo/edit?usp=sharing"
class="at cg gu gv gw gx" target="_blank"
rel="noopener nofollow">https://docs.google.com/spreadsheets/d/1k72R9CWKxu8_AsQURA3iOtTTlE08Qks0gFcuBJZtTqo/edit?usp=sharing</a>
</em></p></figcaption>
</div>
</div>
<div class="n p">
<div class="ac ae af ag ah ds aj ak">
<h1 id="249e" class="hy hz dv bk bj ia ib ic id ie if ig ih ii ij ik il">[0] CoAP Preamble</h1>
<p id="9bed" class="gf gg dv bk gi b gj im gl in gn io gp ip gr iq gt">The Preamble appears at the start
of every CoAP message. The important parts are…</p>
<p id="4d8f" class="gf gg dv bk gi b gj gk gl gm gn go gp gq gr gs gt">▶️ <strong class="gi hw">Message
Type</strong>: <code class="dm jo jp jq jr b">NON</code> is the recommended Message Type. <code
class="dm jo jp jq jr b">NON</code> messages dont require any acknowledgement from the CoAP Server.
So its highly efficient for transmitting sensor data and keeps the device firmware simple. If
acknowledgement is desired (think very carefully!), select <code class="dm jo jp jq jr b">CON</code>
as the Message Type.</p>
<p id="9c4b" class="gf gg dv bk gi b gj gk gl gm gn go gp gq gr gs gt">▶️ <strong class="gi hw">Method
Code</strong>: <code class="dm jo jp jq jr b">POST</code>will transmit sensor data to thethings.io.
<code class="dm jo jp jq jr b">GET</code> will fetch the last transmitted sensor value. Yes, CoAP
follows the same conventions as HTTP and REST.</p>
</div>
</div>
<div class="cz ak">
<div class="figure gz ha hb hc hd cz ak paragraph-image">
<p><img src="https://lupyuen.github.io/images/legacy2/h0.png" /></p>
</div>
<div class="figure da cz ak paragraph-image">
<p><img src="https://lupyuen.github.io/images/legacy2/c8.png" /></p>
<figcaption class="bo ex hr hs ht cn cl cm hu hv bj ew"><p><em>CoAP Options. From <a
href="https://docs.google.com/spreadsheets/d/1k72R9CWKxu8_AsQURA3iOtTTlE08Qks0gFcuBJZtTqo/edit?usp=sharing"
class="at cg gu gv gw gx" target="_blank"
rel="noopener nofollow">https://docs.google.com/spreadsheets/d/1k72R9CWKxu8_AsQURA3iOtTTlE08Qks0gFcuBJZtTqo/edit?usp=sharing</a>
</em></p></figcaption>
</div>
</div>
<div class="n p">
<div class="ac ae af ag ah ds aj ak">
<h1 id="9083" class="hy hz dv bk bj ia ib ic id ie if ig ih ii ij ik il">[1] CoAP Options</h1>
<p id="e986" class="gf gg dv bk gi b gj im gl in gn io gp ip gr iq gt">After the Preamble, the Options
section appears next. The Options will remind you of HTTP Headers…</p>
<p id="0cb7" class="gf gg dv bk gi b gj gk gl gm gn go gp gq gr gs gt">▶️ <strong class="gi hw">URI
Path</strong>: This is similar to the URL for HTTP requests. For thethings.io, each Thing is
identified by a URI like…</p>
<p id="ade0" class="gf gg dv bk gi b gj gk gl gm gn go gp gq gr gs gt"><code
class="dm jo jp jq jr b">v2/things/IVRiBCcR6HPp_CcZIFfOZFxz_izni5xc_KO-kgSA2Y8</code></p>
<p id="d11d" class="gf gg dv bk gi b gj gk gl gm gn go gp gq gr gs gt">The last gibberish part (<code
class="dm jo jp jq jr b">IVRi…</code>) is the Thing Token in thethings.io. More about that later.
</p>
<p id="0626" class="gf gg dv bk gi b gj gk gl gm gn go gp gq gr gs gt">▶️ <strong class="gi hw">Content
Format</strong>: Here we tell the CoAP Server that our sensor data (the payload) is in JSON format
</p>
<p id="c2ab" class="gf gg dv bk gi b gj gk gl gm gn go gp gq gr gs gt">▶️ <strong
class="gi hw">Accept</strong>: Here we tell the CoAP Server that the response from the server should
also be in JSON format (if were expecting a response)</p>
<p id="30c8" class="gf gg dv bk gi b gj gk gl gm gn go gp gq gr gs gt">Note that Content Format and
Accept fields each require only 1 byte <code class="dm jo jp jq jr b">32</code> to specify the value
<code class="dm jo jp jq jr b">application/json</code>. Constrained and highly-efficient indeed!</p>
</div>
</div>
<div class="cz ak">
<div class="figure gz ha hb hc hd cz ak paragraph-image">
<p><img src="https://lupyuen.github.io/images/legacy2/h0.png" /></p>
</div>
<div class="figure da cz ak paragraph-image">
<p><img src="https://lupyuen.github.io/images/legacy2/c9.png" /></p>
<figcaption class="bo ex hr hs ht cn cl cm hu hv bj ew"><p><em>CoAP Payload. From <a
href="https://docs.google.com/spreadsheets/d/1k72R9CWKxu8_AsQURA3iOtTTlE08Qks0gFcuBJZtTqo/edit?usp=sharing"
class="at cg gu gv gw gx" target="_blank"
rel="noopener nofollow">https://docs.google.com/spreadsheets/d/1k72R9CWKxu8_AsQURA3iOtTTlE08Qks0gFcuBJZtTqo/edit?usp=sharing</a>
</em></p></figcaption>
</div>
</div>
<div class="n p">
<div class="ac ae af ag ah ds aj ak">
<h1 id="7df5" class="hy hz dv bk bj ia ib ic id ie if ig ih ii ij ik il">[2] CoAP Payload</h1>
<p id="1cd2" class="gf gg dv bk gi b gj im gl in gn io gp ip gr iq gt">Finally we have the Payload,
which contains the sensor data. Here we use a JSON document to encode the sensor values <code
class="dm jo jp jq jr b">device=4BUXIW6W, <br/>tmp=28.1</code></p>
<div class="figure gz ha hb hc hd cz">
<p><script src="https://gist.github.com/lupyuen/db777a7c61f58e0e88967affceb0ea67.js"></script></p>
</div>
<p id="5369" class="gf gg dv bk gi b gj gk gl gm gn go gp gq gr gs gt">thethings.io requires the device
to transmit sensor values in the above format: an array of <code
class="dm jo jp jq jr b">values</code>, with <code class="dm jo jp jq jr b">key</code> and <code
class="dm jo jp jq jr b">value</code> in each entry.</p>
<p id="18f6" class="gf gg dv bk gi b gj gk gl gm gn go gp gq gr gs gt">thethings.io will look up the
Thing that we have specified in the URI Options (<code class="dm jo jp jq jr b">IVRi…</code>) and set
the temperature <code class="dm jo jp jq jr b">tmp</code> to <code
class="dm jo jp jq jr b">28.1</code>. Whats <code class="dm jo jp jq jr b">device</code>? Well
find out in a while.</p>
<p id="aae7" class="gf gg dv bk gi b gj gk gl gm gn go gp gq gr gs gt"><em class="gh">How do we know
where the Options end and where the Payload starts</em>? Easy — just look for the <strong
class="gi hw">End Of Options Marker </strong><code
class="dm jo jp jq jr b"><strong class="gi hw">FF</strong></code>. The CoAP format is so simple that
it doesnt need any fields to indicate the sizes of the Options and the Payload!</p>
</div>
</div>
<div class="cz ak">
<div class="figure gz ha hb hc hd cz ak paragraph-image">
<p><img src="https://lupyuen.github.io/images/legacy2/c10.png" /></p>
<figcaption class="bo ex hr hs ht cn cl cm hu hv bj ew"><p><em>Encoded CoAP message. From <a
href="https://docs.google.com/spreadsheets/d/1k72R9CWKxu8_AsQURA3iOtTTlE08Qks0gFcuBJZtTqo/edit?usp=sharing"
class="at cg gu gv gw gx" target="_blank"
rel="noopener nofollow">https://docs.google.com/spreadsheets/d/1k72R9CWKxu8_AsQURA3iOtTTlE08Qks0gFcuBJZtTqo/edit?usp=sharing</a>
</em></p></figcaption>
</div>
</div>
<div class="n p">
<div class="ac ae af ag ah ds aj ak">
<p id="1d69" class="gf gg dv bk gi b gj gk gl gm gn go gp gq gr gs gt">In under 150 bytes we have
created a UDP message that our device may transmit over NB-IoT to update the sensor data for our Thing
at thethings.io. Well learn next how to send this packet with a simple AT command.</p>
<p id="9c6b" class="gf gg dv bk gi b gj gk gl gm gn go gp gq gr gs gt">For more details on CoAP, check
the <a href="https://tools.ietf.org/html/rfc7252"
class="at cg gu gv gw gx" target="_blank" rel="noopener nofollow">CoAP specifications (RFC7252)</a>
</p>
</div>
</div>
<div class="cz ak">
<div class="figure gz ha hb hc hd cz ak paragraph-image">
<p><img src="https://lupyuen.github.io/images/legacy2/h0.png" /></p>
</div>
</div>
<div class="n p">
<div class="ac ae af ag ah ds aj ak">
<h1 id="0206" class="hy hz dv bk bj ia ib ic id ie if ig ih ii ij ik il">Connect the Quectel Evaluation
Board</h1>
<div class="figure gz ha hb hc hd cz dr he cd hf hg hh hi hj ba hk hl hm hn ho hp paragraph-image">
<p><img src="https://lupyuen.github.io/images/legacy2/c11.jpeg" /></p>
<figcaption class="bo ex hr hs ht cn cl cm hu hv bj ew"><p><em>Insert the NB-IoT SIM</em></p></figcaption>
</div>
<p id="d429" class="gf gg dv bk gi b gj gk gl gm gn go gp gq gr gs gt">For this tutorial, <a
href="https://www.starhub.com/" class="at cg gu gv gw gx"
target="_blank" rel="noopener nofollow">StarHub</a> has kindly provided me a <strong
class="gi hw">Quectel BC68-TE-B Evaluation Board</strong> (which contains the <a
href="https://www.quectel.com/product/bc68.htm"
class="at cg gu gv gw gx" target="_blank" rel="noopener nofollow">Quectel BC68 module</a>). The
board is pin-compatible with Arduino Uno.</p>
<p id="4b3c" class="gf gg dv bk gi b gj gk gl gm gn go gp gq gr gs gt">Quectel makes NB-IoT modules for
various regions worldwide so your Quectel board may be slightly different, but the instructions below
should be similar.</p>
<p id="dcfd" class="gf gg dv bk gi b gj gk gl gm gn go gp gq gr gs gt"><strong class="gi hw"><em
class="gh">Remember: Always connect the antenna before powering up the board!</em></strong></p>
<p id="61cf" class="gf gg dv bk gi b gj gk gl gm gn go gp gq gr gs gt">Insert the <strong
class="gi hw">NB-IoT SIM</strong> into the slot provided (at lower right). Well use a <strong
class="gi hw">USB-To-UART Adapter</strong> to connect our computer to the Quectel board.</p>
</div>
</div>
<div class="cz ak">
<div class="figure gz ha hb hc hd cz ak paragraph-image">
<p><img src="https://lupyuen.github.io/images/legacy2/c12.png" /></p>
<figcaption class="bo ex hr hs ht cn cl cm hu hv bj ew"><p><em>Top row of pins: TX, RX</em></p></figcaption>
</div>
</div>
<div class="n p">
<div class="ac ae af ag ah ds aj ak">
<blockquote class="jz">
<div id="4adf" class="ka kb kc bk dw b kd ke kf kg kh ki gt">
<p class="dw b kj kk bo"><strong class="az">Top Row</strong></p>
</div>
</blockquote>
<p id="fd73" class="gf gg dv bk gi b gj kl gl km gn kn gp ko gr kp gt">1<strong
class="gi hw">TX</strong>: Connect to the Transmit Pin of your computers UART Port. (MOSI means
Master Out, Slave In)</p>
<p id="9295" class="gf gg dv bk gi b gj gk gl gm gn go gp gq gr gs gt">2<strong
class="gi hw">RX</strong>: Connect to the Receive Pin of your computers UART Port. (MISO means
Master In, Slave Out)</p>
</div>
</div>
<div class="cz ak">
<div class="figure gz ha hb hc hd cz ak paragraph-image">
<p><img src="https://lupyuen.github.io/images/legacy2/h0.png" /></p>
</div>
<div class="figure da cz ak paragraph-image">
<p><img src="https://lupyuen.github.io/images/legacy2/c13.png" /></p>
<figcaption class="bo ex hr hs ht cn cl cm hu hv bj ew"><p><em>Bottom row of pins: 5V and GND (two of them).
The SIM slot is at the right.</em></p></figcaption>
</div>
</div>
<div class="n p">
<div class="ac ae af ag ah ds aj ak">
<blockquote class="jz">
<div id="219e" class="ka kb kc bk dw b kd ke kf kg kh ki gt">
<p class="dw b kj kk bo">Bottom Row</p>
</div>
</blockquote>
<p id="ff9b" class="gf gg dv bk gi b gj kl gl km gn kn gp ko gr kp gt">1<strong
class="gi hw">5V</strong>: Connect to the 5V power supply of your computers UART Port</p>
<p id="fe62" class="gf gg dv bk gi b gj gk gl gm gn go gp gq gr gs gt">2<strong
class="gi hw">GND</strong>: Connect both pins together with a jumper cable. Connect one of the GND
pins to the GND pin of your computers UART Port</p>
<p id="e07b" class="gf gg dv bk gi b gj gk gl gm gn go gp gq gr gs gt">3<strong class="gi hw">Main
UART To MCU</strong>: Push switch J302 to the left position so that the Quectel module connected to
the TX/RX pins instead of the USB port. The USB port did not respond when I connected it to my MacBook
Pro, so I decided to use the TX/RX pins instead.</p>
<p id="16e5" class="gf gg dv bk gi b gj gk gl gm gn go gp gq gr gs gt">If you have a Bus Pirate, connect
the pins as shown in the above photos.</p>
</div>
</div>
<div class="cz ak">
<div class="figure gz ha hb hc hd cz ak paragraph-image">
<p><img src="https://lupyuen.github.io/images/legacy2/h0.png" /></p>
</div>
<div class="figure da cz ak paragraph-image">
<p><img src="https://lupyuen.github.io/images/legacy2/c14.png" /></p>
<figcaption class="bo ex hr hs ht cn cl cm hu hv bj ew"><p><em>AT Commands used for transmitting CoAP messages
</em></p></figcaption>
</div>
</div>
<div class="n p">
<div class="ac ae af ag ah ds aj ak">
<h1 id="6adc" class="hy hz dv bk bj ia ib ic id ie if ig ih ii ij ik il">Transmit CoAP message to
thethings.io</h1>
<p id="5658" class="gf gg dv bk gi b gj im gl in gn io gp ip gr iq gt">On your computer, open a terminal
emulator (like <code
class="dm jo jp jq jr b"><a href="https://www.putty.org/" class="at cg gu gv gw gx" target="_blank" rel="noopener nofollow">putty</a></code>).
Connect to the UART port at <strong class="gi hw">9600 bps, 8 data bits, No parity bit, 1 stop
bit.</strong></p>
<p id="a94a" class="gf gg dv bk gi b gj gk gl gm gn go gp gq gr gs gt">When entering the AT commands
below, make sure that your terminal emulator sends CR (Ctrl-M or <code
class="dm jo jp jq jr b">0x0d</code>) and LF (Ctrl-J or <code class="dm jo jp jq jr b">0x0a</code>)
at the end of the line.</p>
<blockquote class="jz">
<div id="ea0f" class="ka kb kc bk dw b kd ke kf kg kh ki gt">
<p class="dw b kj kk bo">[0] Prepare to transmit</p>
</div>
</blockquote>
<p id="a426" class="gf gg dv bk gi b gj kl gl km gn kn gp ko gr kp gt">First we reboot the Quectel
module to start from a fresh, clean state…</p>
<div class="figure gz ha hb hc hd cz">
<p><script src="https://gist.github.com/lupyuen/4dbb83e0a1bf66d86fe7202221669230.js"></script></p>
</div>
<blockquote class="jz">
<div id="1863" class="ka kb kc bk dw b kd ke kf kg kh ki gt">
<p class="dw b kj kk bo">[1] Attach to network</p>
</div>
</blockquote>
<p id="5597" class="gf gg dv bk gi b gj kl gl km gn kn gp ko gr kp gt">After rebooting, we specify the
network settings and attach to the NB-IoT network…</p>
<div class="figure gz ha hb hc hd cz">
<p><script src="https://gist.github.com/lupyuen/9cfcb692dd1291f88685470690b2283c.js"></script></p>
</div>
<blockquote class="jz">
<div id="9f7c" class="ka kb kc bk dw b kd ke kf kg kh ki gt">
<p class="dw b kj kk bo">[2] Transmit message</p>
</div>
</blockquote>
<p id="8b7b" class="gf gg dv bk gi b gj kl gl km gn kn gp ko gr kp gt">We are now ready to transmit. For
the specific AT command for transmitting our message, look in the <a
href="https://docs.google.com/spreadsheets/d/1k72R9CWKxu8_AsQURA3iOtTTlE08Qks0gFcuBJZtTqo/edit?usp=sharing"
class="at cg gu gv gw gx" target="_blank" rel="noopener nofollow">CoAP Message Encoder Google
Sheet</a>.</p>
<div class="figure gz ha hb hc hd cz">
<p><script src="https://gist.github.com/lupyuen/117e29d796603b9a0ea616daa563ae56.js"></script></p>
</div>
<blockquote class="jz">
<div id="2939" class="ka kb kc bk dw b kd ke kf kg kh ki gt">
<p class="dw b kj kk bo">[3] Receive response</p>
</div>
</blockquote>
<p id="9445" class="gf gg dv bk gi b gj kl gl km gn kn gp ko gr kp gt">The CoAP Server at thethings.io
returns a response to our message…</p>
<div class="figure gz ha hb hc hd cz">
<p><script src="https://gist.github.com/lupyuen/2ae1dffae48c37d415d4e0ab80e90981.js"></script></p>
</div>
<p id="e0fb" class="gf gg dv bk gi b gj gk gl gm gn go gp gq gr gs gt">We may use Wireshark to decode
the above server response (which is another CoAP message)…</p>
<pre
class="gz ha hb hc hd ks kt ku"><span id="600f" class="kv hz dv bk jr b ex kw kx r ky">58 41 00 01 00 00 16 4A 27 2A E2 39 C1<br/>32 FF 7B 22 73 74 61 74 75 73 22 3A 22<br/>63 72 65 61 74 65 64 22 7D</span></pre>
<p id="4181" class="gf gg dv bk gi b gj gk gl gm gn go gp gq gr gs gt">See the section <em
class="gh">“Advanced Topic: Whats Inside The CoAP Message?”</em> in <a class="at cg gu gv gw gx"
target="_blank" rel="noopener"
href="https://lupyuen.github.io/articles/connect-stm32-blue-pill-to-esp8266-with-apache-mynewt"><em
class="gh">“Connect STM32 Blue Pill to ESP8266 with Apache Mynewt”</em></a><em class="gh">.
</em>Insert a space between each byte before decoding with Wireshark. The decoded response from
thethings.io should read…</p>
<pre
class="gz ha hb hc hd ks kt ku"><span id="93bb" class="kv hz dv bk jr b ex kw kx r ky">{&quot;status&quot;:&quot;created&quot;}</span></pre>
<p id="9ee6" class="gf gg dv bk gi b gj gk gl gm gn go gp gq gr gs gt">Which means that the Thing State
has been successfully updated in thethings.io.</p>
<blockquote class="jz">
<div id="636d" class="ka kb kc bk dw b kd ke kf kg kh ki gt">
<p class="dw b kj kk bo">[4] Diagnostics</p>
</div>
</blockquote>
<p id="3d82" class="gf gg dv bk gi b gj kl gl km gn kn gp ko gr kp gt">Here are some AT commands useful
for troubleshooting…</p>
<div class="figure gz ha hb hc hd cz">
<p><script src="https://gist.github.com/lupyuen/ef51005c6c965f6a21d496ad24eacc51.js"></script></p>
</div>
</div>
</div>
<div class="cz ak">
<div class="figure jf jg jh ji jj cz ak paragraph-image">
<p><img src="https://lupyuen.github.io/images/legacy2/h0.png" /></p>
</div>
</div>
<div class="n p">
<div class="ac ae af ag ah ds aj ak">
<h1 id="5b08" class="hy hz dv bk bj ia ib ic id ie if ig ih ii ij ik il">Has thethings.io received our
sensor data?</h1>
<p id="ec01" class="gf gg dv bk gi b gj im gl in gn io gp ip gr iq gt">How do we check if the sensor
data <code class="dm jo jp jq jr b">tmp=28.1</code> was actually received by thethings.io? Easy peasy
— just open the <a
href="https://docs.google.com/spreadsheets/d/1k72R9CWKxu8_AsQURA3iOtTTlE08Qks0gFcuBJZtTqo/edit?usp=sharing"
class="at cg gu gv gw gx" target="_blank" rel="noopener nofollow">CoAP Message Encoder Google
Sheet</a> and click the URL there…</p>
</div>
</div>
<div class="cz ak">
<div class="figure gz ha hb hc hd cz ak paragraph-image">
<p><img src="https://lupyuen.github.io/images/legacy2/c15.png" /></p>
<figcaption class="bo ex hr hs ht cn cl cm hu hv bj ew"><p><em>URL in the CoAP Message Encoder Google Sheet: <a
href="https://docs.google.com/spreadsheets/d/1k72R9CWKxu8_AsQURA3iOtTTlE08Qks0gFcuBJZtTqo/edit?usp=sharing"
class="at cg gu gv gw gx" target="_blank"
rel="noopener nofollow">https://docs.google.com/spreadsheets/d/1k72R9CWKxu8_AsQURA3iOtTTlE08Qks0gFcuBJZtTqo/edit?usp=sharing</a>
</em></p></figcaption>
</div>
</div>
<div class="n p">
<div class="ac ae af ag ah ds aj ak">
<p id="4906" class="gf gg dv bk gi b gj gk gl gm gn go gp gq gr gs gt">The temperature data <code
class="dm jo jp jq jr b">tmp</code> appears in a web page like this (it refreshes every 10 seconds)…
</p>
<div class="figure gz ha hb hc hd cz dr he cd hf hg hh hi hj ba hk hl hm hn ho hp paragraph-image">
<p><img src="https://lupyuen.github.io/images/legacy2/c16.png" /></p>
<figcaption class="bo ex hr hs ht cn cl cm hu hv bj ew"><p><em>Display of temperature sensor data at my
Google Cloud AppEngine website</em></p></figcaption>
</div>
<p id="cbde" class="gf gg dv bk gi b gj gk gl gm gn go gp gq gr gs gt"><em class="gh">Whoa how did the
sensor data get posted on a public website thats outside thethings.io?</em></p>
<p id="bac1" class="gf gg dv bk gi b gj gk gl gm gn go gp gq gr gs gt">Thats my demo server hosted at
Google Cloud running AppEngine Go. Lemme explain what just happened…</p>
<div class="figure gz ha hb hc hd cz cl cm paragraph-image">
<p><img src="https://lupyuen.github.io/images/legacy2/h0.png" /></p>
</div>
<p id="2c70" class="gf gg dv bk gi b gj gk gl gm gn go gp gq gr gs gt">1⃣ When we pasted the AT command
from the Google Sheet, it transmits the sensor data to thethings.io using this Thing Token…</p>
<div class="figure gz ha hb hc hd cz cl cm paragraph-image">
<p><img src="https://lupyuen.github.io/images/legacy2/c17.png" /></p>
<figcaption class="bo ex hr hs ht cn cl cm hu hv bj ew"><p><em>Thing Token for thethings.io</em></p></figcaption>
</div>
<p id="b118" class="gf gg dv bk gi b gj gk gl gm gn go gp gq gr gs gt">2⃣ This Thing Token refers to a
specific Thing in my thethings.io account. What sensor data are we sending to the Thing?</p>
<div class="figure gz ha hb hc hd cz cl cm paragraph-image">
<p><img src="https://lupyuen.github.io/images/legacy2/c18.png" /></p>
<figcaption class="bo ex hr hs ht cn cl cm hu hv bj ew"><p><em>Sensor data transmitted to thethings.io
</em></p></figcaption>
</div>
<p id="0906" class="gf gg dv bk gi b gj gk gl gm gn go gp gq gr gs gt">3⃣ We are sending the
temperature data plus a <code class="dm jo jp jq jr b">device</code> field. <code
class="dm jo jp jq jr b">device</code> is a random ID generated by the Google Sheet. When my CoAP
Server at thethings.io receives the <code class="dm jo jp jq jr b">device</code> and <code
class="dm jo jp jq jr b">tmp</code> fields, it pushes the two values to my Google Cloud server. (Yes
its possible with thethings.io Cloud Code!)</p>
<p id="c2ee" class="gf gg dv bk gi b gj gk gl gm gn go gp gq gr gs gt">4⃣ Then when you click the URL
in the Google Sheet…</p>
<pre
class="gz ha hb hc hd ks kt ku"><span id="4c7a" class="kv hz dv bk jr b ex kw kx r ky">https://blue-pill-geolocate.appspot.com/?device=4BUXIW6W</span></pre>
<p id="7b5e" class="gf gg dv bk gi b gj gk gl gm gn go gp gq gr gs gt">The <code
class="dm jo jp jq jr b">device</code> ID appears inside the URL, so my Google Cloud server renders
the value of <code class="dm jo jp jq jr b">tmp</code> associated with the <code
class="dm jo jp jq jr b">device</code>. Thats the power of end-to-end IoT Integration with Quectel
modules, NB-IoT, thethings.io and Google Cloud!</p>
<p id="d1db" class="gf gg dv bk gi b gj gk gl gm gn go gp gq gr gs gt">For the purpose of NB-IoT
Education Ill allow you to send CoAP messages to my (personal, paid, non-sponsored) account at
thethings.io… because theres no better way to learn CoAP!</p>
<p id="efc2" class="gf gg dv bk gi b gj gk gl gm gn go gp gq gr gs gt">What about displaying your own
sensor data, say a different value for <code class="dm jo jp jq jr b">tmp</code>? Just make a copy of
the Google Sheet. This allocates a new <code class="dm jo jp jq jr b">device</code> ID automatically.
You may then send your sensor data to that <code class="dm jo jp jq jr b">device</code> ID and watch
the updates in my Google Cloud server. Here are the steps…</p>
</div>
</div>
<div class="cz ak">
<div class="figure gz ha hb hc hd cz ak paragraph-image">
<p><img src="https://lupyuen.github.io/images/legacy2/h0.png" /></p>
</div>
</div>
<div class="n p">
<div class="ac ae af ag ah ds aj ak">
<h1 id="cd59" class="hy hz dv bk bj ia ib ic id ie if ig ih ii ij ik il">Transmit and visualise your own
sensor data</h1>
<p id="7ac0" class="gf gg dv bk gi b gj im gl in gn io gp ip gr iq gt">Follow these steps to transmit
and visualise your own values for <code class="dm jo jp jq jr b">tmp</code></p>
<p id="c8d2" class="gf gg dv bk gi b gj gk gl gm gn go gp gq gr gs gt">1⃣ Open the <a
href="https://docs.google.com/spreadsheets/d/1k72R9CWKxu8_AsQURA3iOtTTlE08Qks0gFcuBJZtTqo/edit?usp=sharing"
class="at cg gu gv gw gx" target="_blank" rel="noopener nofollow">CoAP Message Encoder Google
Sheet</a></p>
<p id="a067" class="gf gg dv bk gi b gj gk gl gm gn go gp gq gr gs gt">2⃣ Click File → Make A Copy</p>
<p id="669e" class="gf gg dv bk gi b gj gk gl gm gn go gp gq gr gs gt">3⃣ This creates a copy of the
Google Sheet with a new random <code class="dm jo jp jq jr b">device</code> ID and new URL</p>
<p id="80c3" class="gf gg dv bk gi b gj gk gl gm gn go gp gq gr gs gt">4⃣ Change the value of <code
class="dm jo jp jq jr b">tmp</code></p>
<p id="5475" class="gf gg dv bk gi b gj gk gl gm gn go gp gq gr gs gt">5⃣ Use the updated AT command to
send the sensor data</p>
<p id="2289" class="gf gg dv bk gi b gj gk gl gm gn go gp gq gr gs gt">6⃣ Click the URL to view the
updated sensor data.</p>
<p id="199f" class="gf gg dv bk gi b gj gk gl gm gn go gp gq gr gs gt">The web page refreshes every 10
seconds, so you may send another AT command to update the <code class="dm jo jp jq jr b">tmp</code>
value and the web page will show the new value in 10 seconds</p>
<blockquote class="gc gd ge">
<p id="64f0" class="gf gg dv gh gi b gj gk gl gm gn go gp gq gr gs gt"><em class="bk">💎</em> If you
wish to create your own free account for thethings.io, check the steps in the section “Configuring
the CoAP Server at thethings.io” in <a class="at cg gu gv gw gx" target="_blank" rel="noopener"
href="https://lupyuen.github.io/articles/build-your-iot-sensor-network-stm32-blue-pill-nrf24l01-esp8266-apache-mynewt-thethings-io">this
article</a>. Copy your Thing Token to the <code class="dm jo jp jq jr b">Uri-Path3</code> field.
This updates the AT command in the Google Sheet.</p>
<p id="23e5" class="gf gg dv gh gi b gj gk gl gm gn go gp gq gr gs gt">Open the Developers Console in
thethings.io. Updates to the Thing State triggered by CoAP messages will be shown here.</p>
<p id="4b22" class="gf gg dv gh gi b gj gk gl gm gn go gp gq gr gs gt">You will not longer be able to
view the sensor data on my Google Cloud server, but you may follow the instructions in the above
article to view your sensor data in thethings.io dashboards. The integration with Google Cloud is
explained in the same article.</p>
</blockquote>
</div>
</div>
<div class="cz">
<div class="n p">
<div class="ir is it iu iv iw ag ix ah iy aj ak">
<div class="figure gz ha hb hc hd cz ja jb paragraph-image">
<p><img src="https://lupyuen.github.io/images/legacy2/c19.png" /></p>
<figcaption class="bo ex hr hs ht cn cl cm hu hv bj ew"><p><em>thethings.io Dashboard with Raw Temperature
“t” and Computed Temperature “tmp”</em></p></figcaption>
</div>
</div>
</div>
</div>
<div class="cz ak">
<div class="figure jf jg jh ji jj cz ak paragraph-image">
<p><img src="https://lupyuen.github.io/images/legacy2/h0.png" /></p>
</div>
</div>
<div class="n p">
<div class="ac ae af ag ah ds aj ak">
<h1 id="a06e" class="hy hz dv bk bj ia ib ic id ie if ig ih ii ij ik il">Whats Next?</h1>
<p id="0b06" class="gf gg dv bk gi b gj im gl in gn io gp ip gr iq gt">In this article we covered the
basics of Quectel modules. We have transmitted CoAP messages over NB-IoT to thethings.io for capturing
and visualising sensor data.</p>
<p id="ba03" class="gf gg dv bk gi b gj gk gl gm gn go gp gq gr gs gt">In the next article well learn
to automate this — by using a <strong class="gi hw">real microcontroller (</strong><a
href="http://wiki.stm32duino.com/index.php?title=Blue_Pill"
class="at cg gu gv gw gx" target="_blank" rel="noopener nofollow"><strong class="gi hw">STM32 Blue
Pill</strong></a><strong class="gi hw">) with a real temperature sensor</strong>, connected to the
Quectel module. And well look at the open-source libraries for encoding CoAP messages. The next
article is here…</p>
<div class="lj lk ll lm ln lo"><a rel="noopener"
href="https://lupyuen.github.io/articles/connect-stm32-blue-pill-to-nb-iot-with-quectel-bc95-g-and-apache-mynewt">
<section class="lr cl cm ak ce n ar ls lt lu lv lw lx ly lz ma mb mc md me mf mg">
<div class="mh n co p mi mj">
<h2 class="bj ia mk bl dv">
<div class="di lp ez fa lq fc">Connect STM32 Blue Pill to NB-IoT with Quectel BC95-G and
Apache Mynewt</div>
</h2>
</div>
<div class="mn r">
<div class="mo r mp mq mr mn ms mt mu"></div>
</div>
</section>
</a></div>
<p id="2acd" class="gf gg dv bk gi b gj gk gl gm gn go gp gq gr gs gt">The Rust version of that article
is here…</p>
<div class="lj lk ll lm ln lo"><a rel="noopener"
href="https://lupyuen.github.io/articles/rust-rocks-nb-iot-stm32-blue-pill-with-quectel-bc95-g-on-apache-mynewt">
<section class="lr cl cm ak ce n ar ls lt lu lv lw lx ly lz ma mb mc md me mf mg">
<div class="mh n co p mi mj">
<h2 class="bj ia mk bl dv">
<div class="di lp ez fa lq fc">Rust Rocks NB-IoT! STM32 Blue Pill with Quectel BC95-G on
Apache Mynewt</div>
</h2>
</div>
<div class="mn r">
<div class="mv r mp mq mr mn ms mt mu"></div>
</div>
</section>
</a></div>
<p id="cdd5" class="gf gg dv bk gi b gj gk gl gm gn go gp gq gr gs gt">The code in the article is based
on an earlier article…</p>
<div class="lj lk ll lm ln lo"><a rel="noopener"
href="https://lupyuen.github.io/articles/build-your-iot-sensor-network-stm32-blue-pill-nrf24l01-esp8266-apache-mynewt-thethings-io">
<section class="lr cl cm ak ce n ar ls lt lu lv lw lx ly lz ma mb mc md me mf mg">
<div class="mh n co p mi mj">
<h2 class="bj ia mk bl dv">
<div class="di lp ez fa lq fc">Build Your IoT Sensor Network — STM32 Blue Pill + nRF24L01 +
ESP8266 + Apache Mynewt + thethings.io</div>
</h2>
</div>
<div class="mn r">
<div class="mw r mp mq mr mn ms mt mu"></div>
</div>
</section>
</a></div>
<p id="2370" class="gf gg dv bk gi b gj gk gl gm gn go gp gq gr gs gt">Im also exploring <a
class="at cg gu gv gw gx" target="_blank" rel="noopener"
href="https://lupyuen.github.io/articles/visual-embedded-rust-programming-with-visual-studio-code"><strong
class="gi hw">Visual Embedded Rust Programming for NB-IoT</strong></a>. So that you can
drag-and-drop sensors and network modules to create an NB-IoT microcontroller program really easily…
</p>
<div class="lj lk ll lm ln lo"><a rel="noopener"
href="https://lupyuen.github.io/articles/visual-embedded-rust-programming-with-visual-studio-code">
<section class="lr cl cm ak ce n ar ls lt lu lv lw lx ly lz ma mb mc md me mf mg">
<div class="mh n co p mi mj">
<h2 class="bj ia mk bl dv">
<div class="di lp ez fa lq fc">Visual Embedded Rust Programming with Visual Studio Code</div>
</h2>
</div>
<div class="mn r">
<div class="mx r mp mq mr mn ms mt mu"></div>
</div>
</section>
</a></div>
<p id="4cc4" class="gf gg dv bk gi b gj gk gl gm gn go gp gq gr gs gt">As Im writing this, <a
href="https://docs.google.com/document/d/1V96zQc8PbxuxEwsdd3wzEb7SxpDhbSsOOP6faiFPfzo/edit"
class="at cg gu gv gw gx" target="_blank" rel="noopener nofollow">my new Quectel breakout boards and
dev kits</a> are flying over from Taobao.com to Singapore. Stay tuned!</p>
</div>
</div>
<div class="cz ak">
<div class="figure gz ha hb hc hd cz ak paragraph-image">
<p><img src="https://lupyuen.github.io/images/legacy2/c20.png" /></p>
<figcaption class="bo ex hr hs ht cn cl cm hu hv bj ew"><p><em>New Quectel breakout boards and dev kits that
Ill be featuring in the next article</em></p></figcaption>
</div>
<div class="figure da cz ak paragraph-image">
<p><img src="https://lupyuen.github.io/images/legacy2/c21.png" /></p>
<figcaption class="bo ex hr hs ht cn cl cm hu hv bj ew"><p><em>Visual NB-IoT programming in progress
</em></p></figcaption>
</div>
<div class="figure da cz ak paragraph-image">
<p><img src="https://lupyuen.github.io/images/legacy2/h0.png" /></p>
</div>
</div>
<div class="n p">
<div class="ac ae af ag ah ds aj ak">
<h1 id="adde" class="hy hz dv bk bj ia ib ic id ie if ig ih ii ij ik il">References</h1>
<p id="a2a8" class="gf gg dv bk gi b gj im gl in gn io gp ip gr iq gt">The following Quectel documents
were very useful for understanding the AT commands. Download them from (free registration required)
<code
class="dm jo jp jq jr b"><a href="https://www.quectel.com/support/downloadb/TechnicalDocuments.htm" class="at cg gu gv gw gx" target="_blank" rel="noopener nofollow">https://www.quectel.com/support/downloadb/TechnicalDocuments.htm</a></code>
</p>
<ol class="">
<li id="c7a5" class="gf gg dv bk gi b gj gk gl gm gn go gp gq gr gs gt na nb nc"><strong
class="gi hw"><em class="gh">Quectel BC68-TE-B User Guide V1.1</em></strong>: Details of the
Quectel BC68 Evaluation Board</li>
<li id="04a8" class="gf gg dv bk gi b gj nd gl ne gn nf gp ng gr nh gt na nb nc"><strong
class="gi hw"><em class="gh">Quectel BC68 Hardware Design V1.3</em></strong>: Details of the BC68
pins</li>
<li id="cf7f" class="gf gg dv bk gi b gj nd gl ne gn nf gp ng gr nh gt na nb nc"><strong
class="gi hw"><em class="gh">Quectel BC95 &amp; BC95-G &amp; BC68 Application Design Guide
V1.1</em></strong>: Designing applications for BC68</li>
<li id="de25" class="gf gg dv bk gi b gj nd gl ne gn nf gp ng gr nh gt na nb nc"><strong
class="gi hw"><em class="gh">Quectel BC95-G &amp; BC68 AT Commands Manual V1.4</em></strong>: AT
commands</li>
<li id="bdf0" class="gf gg dv bk gi b gj nd gl ne gn nf gp ng gr nh gt na nb nc"><strong
class="gi hw"><em class="gh">Quectel BC95-G &amp; BC68 CoAP Application Note V1.0</em></strong>:
AT commands for CoAP. Unfortunately I was not able to use the AT commands here to transmit the
payload correctly (the transmitted payload was always empty). So I decided to encode the CoAP
messages myself.</li>
</ol>
<p id="c10a" class="gf gg dv bk gi b gj gk gl gm gn go gp gq gr gs gt">Other documents available from
the Quectel website…</p>
<ol class="">
<li id="1bfb" class="gf gg dv bk gi b gj gk gl gm gn go gp gq gr gs gt na nb nc"><em
class="gh">Quectel BC95 &amp; BC95-G &amp; BC68 RAI Application Note V1.0</em></li>
<li id="394e" class="gf gg dv bk gi b gj nd gl ne gn nf gp ng gr nh gt na nb nc"><em
class="gh">Quectel BC95 &amp; BC95-G &amp; BC68 Low Power Design Guide V1.1</em></li>
<li id="2a84" class="gf gg dv bk gi b gj nd gl ne gn nf gp ng gr nh gt na nb nc"><em
class="gh">Quectel BC68 &amp; M66 Compatible Design V1.0</em></li>
<li id="eefc" class="gf gg dv bk gi b gj nd gl ne gn nf gp ng gr nh gt na nb nc"><em
class="gh">Quectel BC95-G &amp; BC68 UEMonitor User Guide V1.0</em></li>
<li id="816a" class="gf gg dv bk gi b gj nd gl ne gn nf gp ng gr nh gt na nb nc"><em
class="gh">Quectel BC95-G &amp; BC68 Firmware Upgrade User Guide V1.1</em></li>
</ol>
<p id="5559" class="gf gg dv bk gi b gj gk gl gm gn go gp gq gr gs gt">Benchmarks of CoAP vs MQTT
performance…</p>
<p id="262a" class="gf gg dv bk gi b gj gk gl gm gn go gp gq gr gs gt"><a
href="https://www.researchgate.net/publication/329820943_Impact_of_CoAP_and_MQTT_on_NB-IoT_system_performance"
class="at cg gu gv gw gx" target="_blank" rel="noopener nofollow"><em class="gh">Impact of CoAP and
MQTT on NB-IoT System Performance</em></a></p>
<p id="9897" class="gf gg dv bk gi b gj gk gl gm gn go gp gq gr gs gt">If youre in Singapore…</p>
<ol class="">
<li id="99e5" class="gf gg dv bk gi b gj gk gl gm gn go gp gq gr gs gt na nb nc"><a
href="https://www.imda.gov.sg/-/media/imda/files/regulation-licensing-and-consultations/frameworks-and-policies/spectrum-management-and-coordination/spectrummgmthb.pdf?la=en"
class="at cg gu gv gw gx" target="_blank" rel="noopener nofollow"><em class="gh">IMDA Spectrum
Management Handbook</em></a><em class="gh"> </em><br />Includes Spectrum Assignment for Cellular
Systems, e.g. Band 8</li>
<li id="86c7" class="gf gg dv bk gi b gj nd gl ne gn nf gp ng gr nh gt na nb nc"><a
href="https://www.imda.gov.sg/-/media/imda/files/regulation-licensing-and-consultations/ict-standards/telecommunication-standards/radio-comms/imda-ts-iot.pdf?la=en"
class="at cg gu gv gw gx" target="_blank" rel="noopener nofollow"><em class="gh">IMDA
Telecommunications Standards Advisory Committee (TSAC) — Technical Specification — Internet of
Things</em></a><em class="gh"> </em><br />Includes operating frequencies for each NB-IoT
operator</li>
</ol>
</div>
</div>
</section>
</div>
</article>
</div>
</div>
<ul>
<li>
<p><a href="https://github.com/sponsors/lupyuen">Sponsor me a coffee</a></p>
</li>
<li>
<p><a href="https://lupyuen.github.io">Check out my articles</a></p>
</li>
<li>
<p><a href="https://lupyuen.github.io/rss.xml">RSS Feed</a></p>
</li>
</ul>
</body>
</html>
<!--
FILE ARCHIVED ON 19:40:58 Dec 04, 2019 AND RETRIEVED FROM THE
INTERNET ARCHIVE ON 01:29:37 Feb 23, 2021.
JAVASCRIPT APPENDED BY WAYBACK MACHINE, COPYRIGHT INTERNET ARCHIVE.
ALL OTHER CONTENT MAY ALSO BE PROTECTED BY COPYRIGHT (17 U.S.C.
SECTION 108(a)(3)).
-->
<!--
playback timings (ms):
load_resource: 154.903
esindex: 0.011
RedisCDXSource: 10.328
exclusion.robots.policy: 0.265
captures_list: 317.887
PetaboxLoader3.resolve: 87.672
LoadShardBlock: 274.985 (3)
exclusion.robots: 0.275
PetaboxLoader3.datanode: 90.501 (4)
CDXLines.iter: 28.648 (3)
-->