mirror of
https://github.com/lupyuen/lupyuen.github.io.git
synced 2025-01-13 09:08:30 +08:00
1155 lines
No EOL
72 KiB
HTML
1155 lines
No EOL
72 KiB
HTML
<!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: That’s 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 didn’t
|
||
we use 4G LTE with NB-IoT? It’s 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 don’t 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">Let’s 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">Don’t feel obligated to
|
||
continue any conversation. It’s your right to listen as much or as little as you want. You’re 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">That’s 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
|
||
there’s 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 don’t 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">Isn’t 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>? That’s 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. What’s 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 don’t
|
||
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. Let’s 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 don’t require any acknowledgement from the CoAP Server.
|
||
So it’s 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 we’re 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>. What’s <code class="dm jo jp jq jr b">device</code>? We’ll
|
||
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 doesn’t 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. We’ll 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). We’ll 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 computer’s 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 computer’s 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 computer’s 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 computer’s 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: What’s 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">{"status":"created"}</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 that’s 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">That’s 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
|
||
it’s 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>. That’s 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 I’ll allow you to send CoAP messages to my (personal, paid, non-sponsored) account at
|
||
thethings.io… because there’s 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 Developer’s 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">What’s 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 we’ll 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 we’ll 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">I’m 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 I’m 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
|
||
I’ll 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 & BC95-G & 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 & 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 & 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 & BC95-G & 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 & BC95-G & 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 & 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 & 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 & 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 you’re 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)
|
||
--> |