My LoRaWAN Signal Mapping MSc summer project. This is a copy of the actual repository with personal information removed.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

203 lines
14 KiB

  1. <!DOCTYPE html>
  2. <html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang="">
  3. <head>
  4. <meta charset="utf-8" />
  5. <meta name="generator" content="pandoc" />
  6. <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
  7. <title>LoRaWAN Signal Mapping - User Manual</title>
  8. <style type="text/css">
  9. code{white-space: pre-wrap;}
  10. span.smallcaps{font-variant: small-caps;}
  11. span.underline{text-decoration: underline;}
  12. div.column{display: inline-block; vertical-align: top; width: 50%;}
  13. </style>
  14. <style type="text/css">
  15. a.sourceLine { display: inline-block; line-height: 1.25; }
  16. a.sourceLine { pointer-events: none; color: inherit; text-decoration: inherit; }
  17. a.sourceLine:empty { height: 1.2em; }
  18. .sourceCode { overflow: visible; }
  19. code.sourceCode { white-space: pre; position: relative; }
  20. div.sourceCode { margin: 1em 0; }
  21. pre.sourceCode { margin: 0; }
  22. @media screen {
  23. div.sourceCode { overflow: auto; }
  24. }
  25. @media print {
  26. code.sourceCode { white-space: pre-wrap; }
  27. a.sourceLine { text-indent: -1em; padding-left: 1em; }
  28. }
  29. pre.numberSource a.sourceLine
  30. { position: relative; left: -4em; }
  31. pre.numberSource a.sourceLine::before
  32. { content: attr(title);
  33. position: relative; left: -1em; text-align: right; vertical-align: baseline;
  34. border: none; pointer-events: all; display: inline-block;
  35. -webkit-touch-callout: none; -webkit-user-select: none;
  36. -khtml-user-select: none; -moz-user-select: none;
  37. -ms-user-select: none; user-select: none;
  38. padding: 0 4px; width: 4em;
  39. color: #aaaaaa;
  40. }
  41. pre.numberSource { margin-left: 3em; border-left: 1px solid #aaaaaa; padding-left: 4px; }
  42. div.sourceCode
  43. { }
  44. @media screen {
  45. a.sourceLine::before { text-decoration: underline; }
  46. }
  47. code span.al { color: #ff0000; font-weight: bold; } /* Alert */
  48. code span.an { color: #60a0b0; font-weight: bold; font-style: italic; } /* Annotation */
  49. code span.at { color: #7d9029; } /* Attribute */
  50. code span.bn { color: #40a070; } /* BaseN */
  51. code span.bu { } /* BuiltIn */
  52. code span.cf { color: #007020; font-weight: bold; } /* ControlFlow */
  53. code span.ch { color: #4070a0; } /* Char */
  54. code span.cn { color: #880000; } /* Constant */
  55. code span.co { color: #60a0b0; font-style: italic; } /* Comment */
  56. code span.cv { color: #60a0b0; font-weight: bold; font-style: italic; } /* CommentVar */
  57. code span.do { color: #ba2121; font-style: italic; } /* Documentation */
  58. code span.dt { color: #902000; } /* DataType */
  59. code span.dv { color: #40a070; } /* DecVal */
  60. code span.er { color: #ff0000; font-weight: bold; } /* Error */
  61. code span.ex { } /* Extension */
  62. code span.fl { color: #40a070; } /* Float */
  63. code span.fu { color: #06287e; } /* Function */
  64. code span.im { } /* Import */
  65. code span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Information */
  66. code span.kw { color: #007020; font-weight: bold; } /* Keyword */
  67. code span.op { color: #666666; } /* Operator */
  68. code span.ot { color: #007020; } /* Other */
  69. code span.pp { color: #bc7a00; } /* Preprocessor */
  70. code span.sc { color: #4070a0; } /* SpecialChar */
  71. code span.ss { color: #bb6688; } /* SpecialString */
  72. code span.st { color: #4070a0; } /* String */
  73. code span.va { color: #19177c; } /* Variable */
  74. code span.vs { color: #4070a0; } /* VerbatimString */
  75. code span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
  76. </style>
  77. </head>
  78. <body>
  79. <header>
  80. <h1 class="title">LoRaWAN Signal Mapping - User Manual</h1>
  81. </header>
  82. <h1 id="msc-summer-project">Msc-Summer-Project</h1>
  83. <blockquote>
  84. <p>My Msc Summer Project</p>
  85. </blockquote>
  86. <p>This repository contains my Masters-level summer project. The title is <em>LoRaWAN Signal Mapping</em>. The software contained here provides a complete system for mapping and visualising the signal coverage of <a href="https://thethingsnetwork.org/">The Things Network</a>.</p>
  87. <h2 id="structure">Structure</h2>
  88. <p>The system is split up into 2 primary parts:</p>
  89. <ol type="1">
  90. <li>An Arduino program that collects the data.</li>
  91. <li>A Node.js program that stores and analyses the data</li>
  92. </ol>
  93. <p>It’s best explained with the aid of a diagram or two:</p>
  94. <p><img src="images/Manual%20Diagrams-Workflow.png" /></p>
  95. <p>The above flowchart describes the workflow when using the system:</p>
  96. <ol type="1">
  97. <li>First, the IoT device is turned on and the TTN Listener is launched.</li>
  98. <li>Then, the IoT device is taken around the target area that needs mapping. This can be done by anyone - the device does not require operation beyond turning it on and off once provisioned.</li>
  99. <li>Once the device has been carried around the target area, the <code>DATA.TSV</code> file on the IoT device’s microSD card is copied off and placed on the server.</li>
  100. <li>The server data processor is then run to fold the data into the database.</li>
  101. <li>The AI trainer is now run on the collected data</li>
  102. <li>The data is displayed in a web browser, with the help of a web server</li>
  103. </ol>
  104. <p>The flow of data during use can be shown using a diagram:</p>
  105. <p><img src="images/Manual%20Diagrams-Data%20Flow.png" /></p>
  106. <h2 id="system-requirements">System requirements</h2>
  107. <p>This software has a number of requirements in order to function properly:</p>
  108. <ul>
  109. <li>A Linux-based server (<em>Ubuntu Server LTS</em> is recommended), with the following installed:
  110. <ul>
  111. <li>Node.js v10+ with npm 6+ - see <a href="https://github.com/nodesource/distributions">this website</a> for instructions on how to install a recent version of Node.js (for the various application server stuff)</li>
  112. <li>Git (for cloning the code repository)</li>
  113. <li><code>awk</code> (for text processing by the build script)</li>
  114. <li>Bash v4+ (for the build script)</li>
  115. <li>PHP (for the temporary test web server; not otherwise used any static web server will do)</li>
  116. </ul></li>
  117. <li>Arduino IDE (for programming the IoT device)</li>
  118. <li>Git (for cloning the code repository)</li>
  119. <li></li>
  120. </ul>
  121. <h2 id="getting-started">Getting Started</h2>
  122. <h3 id="step-0-initial-setup">Step 0: Initial setup</h3>
  123. <p>Before doing anything, clone this git repository to both the server (for the TTN listener etc.) and your local machine (for programming the IoT device):</p>
  124. <div class="sourceCode" id="cb1"><pre class="sourceCode bash"><code class="sourceCode bash"><a class="sourceLine" id="cb1-1" title="1"><span class="fu">git</span> clone https://git.starbeamrainbowlabs.com/sbrl/Msc-Summer-Project.git</a></code></pre></div>
  125. <p><em>If you have somehow obtained a static copy of the code (e.g. through the University’s marking system), then skip the above and use that instead.</em></p>
  126. <p>Next, <code>cd</code> to the root of the repository and then run the setup task of the build script:</p>
  127. <div class="sourceCode" id="cb2"><pre class="sourceCode bash"><code class="sourceCode bash"><a class="sourceLine" id="cb2-1" title="1"><span class="ex">./build</span> setup</a></code></pre></div>
  128. <p>On Windows, this should be run in <em>Git Bash</em> (accessible from the start menu when <em>Git</em> is installed - don’t forget to <code>cd</code> to the root of the repository).</p>
  129. <h3 id="step-1-build-a-device">Step 1: Build a device</h3>
  130. <p>First, a device must be built and provisioned. See <code>HARDWARE.md</code> in this repository for detailed instructions on how to do this.</p>
  131. <p>Once built, copy <code>iot/main/settings.custom.cpp.example</code> to <code>iot/main/settings.custom.cpp</code> and follow the instructions fill in the fields there. To do this, you’ll need to register the device using ABP (Activation By Personalisation) on <em>The Things Network</em>. <a href="https://www.thethingsnetwork.org/docs/devices/registration.html">This guide</a> tells you how to do this.</p>
  132. <p>It is suggested that the following Bash one-liner be used to generate a new encryption key in the right formats:</p>
  133. <div class="sourceCode" id="cb3"><pre class="sourceCode bash"><code class="sourceCode bash"><a class="sourceLine" id="cb3-1" title="1"><span class="fu">head</span> -c16 /dev/urandom <span class="kw">|</span> <span class="fu">od</span> -tx1 <span class="kw">|</span> <span class="fu">awk</span> <span class="st">&#39;{ gsub(/^0+\s+/, &quot;&quot;, $0); toml=$0; gsub(/\s+/, &quot;&quot;, toml); print(&quot;settings.toml format: &quot; toml); arduino=toupper($0); gsub(/\s+/, &quot;, 0x&quot;, arduino); print(&quot;settings.custom.cpp format: 0x&quot; arduino); exit }&#39;</span></a></code></pre></div>
  134. <p><em>(Paste it into a terminal and hit enter)</em></p>
  135. <p>Then, review <code>iot/main/settings.h</code> to make sure it matches your setup (e.g. all the pin numbers are correct)</p>
  136. <p>Next, copy the folders in <code>iot/libraries</code> to your Arduino IDE libraries folder.</p>
  137. <p>Finally, open <code>iot/main/main.ino</code> in the Arduino IDE and program the IoT device itself.</p>
  138. <h3 id="step-2-the-things-network-setup">Step 2: The Things Network Setup</h3>
  139. <p><em>This step should be completed on the server.</em></p>
  140. <p>Once a device has been constructed, running the <em>The Things Network</em> listener is next. This requires giving the system the <em>The Things Network</em> credentials.</p>
  141. <p>Edit the file called <code>settings.toml</code> in the root of this repository (or create it if it doesn’t exist), and make sure it contains the following:</p>
  142. <pre class="toml"><code>[ttn]
  143. app_id = &quot;{APPLICATION_ID}&quot;
  144. access_key = &quot;{TTN_ACCESS_ID}&quot;
  145. encryption_key = &quot;{ENCRYPTION_KEY_FROM_STEP_1}&quot;
  146. port = 8883
  147. tls = true
  148. devices = [ &quot;{DEVICE_NAME_FROM_TTN}&quot; ]</code></pre>
  149. <p>The <code>app_id</code> and <code>access_key</code> can be obtained from <em>The Things Network Console</em>:</p>
  150. <p><img src="images/TTN-Main.png" /></p>
  151. <p>The device name can be obtained from step #1, when you registered the device with <em>The Things Network</em>. Alternatively, if the device is already registered, it can be obtained from the device list if you click the “X registered devices” text.</p>
  152. <p>With <code>settings.toml</code> filled in, you can now start TTN Listener:</p>
  153. <div class="sourceCode" id="cb5"><pre class="sourceCode bash"><code class="sourceCode bash"><a class="sourceLine" id="cb5-1" title="1"><span class="ex">./build</span> ttn-listener</a></code></pre></div>
  154. <p>….it will display an error message if you forgot a value.</p>
  155. <p>Now that the TTN listener is running, the IoT device can be carried around and data collected.</p>
  156. <h3 id="step-3-processing-the-data">Step 3: Processing the data</h3>
  157. <p><em>This step should be completed on the server.</em></p>
  158. <p>Once data has been collected by the IoT device, it can then be processed by the Node.js server application.</p>
  159. <p>Copy the <code>DATA.TSV</code> file from the IoT device’s microSD card to the root of the repository on the server. It is suggested that <code>scp</code> (Linux) or <a href="https://winscp.net/">WinSCP</a> be used to do this.</p>
  160. <p>Next, fold <code>DATA.TSV</code> into the database like so:</p>
  161. <div class="sourceCode" id="cb6"><pre class="sourceCode bash"><code class="sourceCode bash"><a class="sourceLine" id="cb6-1" title="1"><span class="ex">./build</span> process-data</a></code></pre></div>
  162. <p>Then, train the AIs on the collected data like this:</p>
  163. <div class="sourceCode" id="cb7"><pre class="sourceCode bash"><code class="sourceCode bash"><a class="sourceLine" id="cb7-1" title="1"><span class="ex">./build</span> train-ai</a></code></pre></div>
  164. <p>The architecture of the neural networks trained can be customised by editing <code>settings.toml</code>. Check <code>server/settings.default.toml</code> for a guide on the different options available.</p>
  165. <h3 id="step-4-viewing-the-ai-output">Step 4: Viewing the AI output</h3>
  166. <p>With the AIs trained, the browser-based web interface can be used to display the output as a map. Any static web server will do, but the build script has one built-in (if PHP is installed) for convenience:</p>
  167. <div class="sourceCode" id="cb8"><pre class="sourceCode bash"><code class="sourceCode bash"><a class="sourceLine" id="cb8-1" title="1"><span class="ex">./build</span> server</a></code></pre></div>
  168. <p>If an alternative server is to be used, it should serve the <code>app/</code> directory that can be found in the root of this repository.</p>
  169. <h2 id="credits">Credits</h2>
  170. <ul>
  171. <li>Build Engine: <a href="https://gitlab.com/sbrl/lantern-build-engine">Lantern Build Engine</a> (written by me; proof available upon request)</li>
  172. </ul>
  173. <h3 id="iot-device">IoT Device</h3>
  174. <ul>
  175. <li>Random number generation: <a href="https://github.com/taoyuan/Entropy">Entropy</a></li>
  176. <li>LoRa Modem Driver: <a href="https://github.com/matthijskooijman/arduino-lmic">LMiC</a></li>
  177. <li>MicroSD card access: <a href="https://github.com/greiman/SdFat">SdFat</a></li>
  178. <li>GPS Decoder: <a href="https://github.com/mikalhart/TinyGPS">TinyGPS</a></li>
  179. <li>Free memory analyser: <a href="https://github.com/mpflaga/Arduino-MemoryFree/">Arduino-MemoryFree</a></li>
  180. </ul>
  181. <h3 id="node.js-server">Node.js Server</h3>
  182. <ul>
  183. <li>AI: <a href="https://www.npmjs.com/package/brain.js">Brain.js</a></li>
  184. <li>Database access: <a href="https://github.com/JoshuaWise/better-sqlite3/">better-sqlite3</a></li>
  185. <li>Encryption: <a href="https://www.npmjs.com/package/aes-js">aes-js</a></li>
  186. <li>The Things Network Access: <a href="https://github.com/mqttjs/async-mqtt">async-mqtt</a></li>
  187. <li>Dependency Injection: <a href="https://www.npmjs.com/package/awilix">Awilix</a></li>
  188. </ul>
  189. <h3 id="web-interface">Web Interface</h3>
  190. <ul>
  191. <li>Mapping Library: <a href="https://leafletjs.com/">Leaflet</a></li>
  192. <li><a href="https://github.com/SamHerbert/SVG-Loaders">Loading Animation</a></li>
  193. <li>Packaging system: <a href="https://rollupjs.org/">Rollup</a></li>
  194. </ul>
  195. <h2 id="useful-links">Useful Links</h2>
  196. <ul>
  197. <li>Entropy extraction from the watchdog timer vs the internal clock: https://github.com/taoyuan/Entropy</li>
  198. </ul>
  199. </body>
  200. </html>