<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Project Lab</title>
	<atom:link href="https://nootropicdesign.com/projectlab/feed/" rel="self" type="application/rss+xml" />
	<link>https://nootropicdesign.com/projectlab</link>
	<description>Interesting projects I&#039;ve done</description>
	<lastBuildDate>Thu, 21 Aug 2025 11:33:17 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.8.5</generator>
	<item>
		<title>Swarm vs. Iridium For Satellite IoT</title>
		<link>https://nootropicdesign.com/projectlab/2022/07/30/swarm-vs-iridium-for-satellite-iot/</link>
					<comments>https://nootropicdesign.com/projectlab/2022/07/30/swarm-vs-iridium-for-satellite-iot/#comments</comments>
		
		<dc:creator><![CDATA[Michael]]></dc:creator>
		<pubDate>Sat, 30 Jul 2022 19:59:48 +0000</pubDate>
				<category><![CDATA[IoT]]></category>
		<category><![CDATA[Radio]]></category>
		<category><![CDATA[Satellite]]></category>
		<category><![CDATA[Space]]></category>
		<guid isPermaLink="false">https://nootropicdesign.com/projectlab/?p=2636</guid>

					<description><![CDATA[Using Satellite for IoT If you are involved in building Internet of Things solutions for industry, you are probably familiar with radio technologies that connect IoT sensors to the Internet: WiFi, cellular, LoRa, etc. What about satellite connectivity? Wifi or cellular connectivity may not be available where you need to deploy a solution. Perhaps you [&#8230;]]]></description>
										<content:encoded><![CDATA[<h3>Using Satellite for IoT</h3>
<p>If you are involved in building Internet of Things solutions for industry, you are probably familiar with radio technologies that connect IoT sensors to the Internet: WiFi, cellular, LoRa, etc. What about satellite connectivity? Wifi or cellular connectivity may not be available where you need to deploy a solution. Perhaps you are monitoring sensors on an ocean vessel or a remote oil well. With many aspiring entrants in the satellite IoT space (no pun intended), it&#8217;s time to get serious about comparing not only the costs, but how these systems actually perform.</p>
<p>Using satellite connectivity is becoming a more viable option as new solutions like <a href="https://swarm.space" rel="noopener noreferrer" target="_blank">Swarm</a> come to market. This article compares Swarm&#8217;s offering to the well-established <a href="https://www.iridium.com/services/iridium-sbd/" rel="noopener noreferrer" target="_blank">Iridium Short Burst Data (SBD) service</a>. This isn&#8217;t just a comparison of the features and costs &#8212; I&#8217;ve run experiments with Swarm and Iridium modems to compare the latency and performance of each system so that you can make decisions based on actual data. By just looking at the sizes of the satellites, we can see that this is a David vs. Goliath story!</p>
<p><div id="attachment_2638" style="width: 1034px" class="wp-caption alignleft"><a href="https://nootropicdesign.com/projectlab/wp-content/uploads/2022/07/swarm_vs_iridium_size.jpg"><img fetchpriority="high" decoding="async" aria-describedby="caption-attachment-2638" src="https://nootropicdesign.com/projectlab/wp-content/uploads/2022/07/swarm_vs_iridium_size.jpg" alt="" width="1024" height="447" class="size-full wp-image-2638" srcset="https://nootropicdesign.com/projectlab/wp-content/uploads/2022/07/swarm_vs_iridium_size.jpg 1024w, https://nootropicdesign.com/projectlab/wp-content/uploads/2022/07/swarm_vs_iridium_size-980x428.jpg 980w, https://nootropicdesign.com/projectlab/wp-content/uploads/2022/07/swarm_vs_iridium_size-480x210.jpg 480w" sizes="(min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) and (max-width: 980px) 980px, (min-width: 981px) 1024px, 100vw" /></a><p id="caption-attachment-2638" class="wp-caption-text">Swarm and Iridium satellites</p></div><br />
<br clear="all"/></p>
<p>I know you are probably wondering about costs, right? The Costs section below gives the cost details, but the quick summary is that Swarm is cheaper than Iridium both in terms of CapEx and OpEx. That&#8217;s capital expenditures and operation expenses for you non-CFOs. But cost is not the only concern, so you might find the cost differences immaterial given the actual operational characteristics that you need. So let&#8217;s get into how these two satellite IoT solutions actually work and how I measured their capabilities.</p>
<h3>Swarm</h3>
<p>Swarm Technologies (acquired by SpaceX in 2021) has launched (as of this writing) approximately 175 small &#8220;SpaceBEE&#8221; satellites about the size of a piece of bread. They are about 2.8cm thick, so more like Texas toast. <a href="https://celestrak.org/NORAD/elements/table.php?GROUP=swarm" rel="noopener noreferrer" target="_blank">According to CelesTrak</a>, they are near polar orbits (I think they are sun-synchronous orbits) providing coverage at all latitudes and are in several orbital planes at a variety of LEO altitudes. Here&#8217;s a snapshot of the orbits using a tool that I made to help me see where things are. Swarm also provides a <a href="https://kube.tools.swarm.space/pass-checker/" rel="noopener noreferrer" target="_blank">pass checker tool</a> which probably takes into account which satellites are actually operational.</p>
<p><div id="attachment_2632" style="width: 1034px" class="wp-caption alignleft"><a href="https://nootropicdesign.com/projectlab/wp-content/uploads/2022/07/swarm_orbits.png"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-2632" src="https://nootropicdesign.com/projectlab/wp-content/uploads/2022/07/swarm_orbits-1024x809.png" alt="" width="1024" height="809" class="size-large wp-image-2632" srcset="https://nootropicdesign.com/projectlab/wp-content/uploads/2022/07/swarm_orbits-1024x809.png 1024w, https://nootropicdesign.com/projectlab/wp-content/uploads/2022/07/swarm_orbits-980x774.png 980w, https://nootropicdesign.com/projectlab/wp-content/uploads/2022/07/swarm_orbits-480x379.png 480w" sizes="auto, (min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) and (max-width: 980px) 980px, (min-width: 981px) 1024px, 100vw" /></a><p id="caption-attachment-2632" class="wp-caption-text">Swarm constellation &#8212; note separation between orbital planes</p></div><br />
<br clear="all"/></p>
<p>To communicate with the Swarm satellite network, I bought the Swarm evaluation kit in fall of 2021. It came with a tripod, solar panel, antenna, and circuit board with the Swarm modem and all required power management circuitry. It came with a <a href="https://feathers2.io/" rel="noopener noreferrer" target="_blank">FeatherS2 development board</a> with pre-loaded firmware for communicating with the modem. The FeatherS2 has an Adafruit OLED display. This is a very nice kit that has everything you need to start communicating right away.</p>
<p><div id="attachment_2640" style="width: 1034px" class="wp-caption alignleft"><a href="https://nootropicdesign.com/projectlab/wp-content/uploads/2022/07/swarm_eval_kit.jpg"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-2640" src="https://nootropicdesign.com/projectlab/wp-content/uploads/2022/07/swarm_eval_kit-1024x454.jpg" alt="" width="1024" height="454" class="size-large wp-image-2640" srcset="https://nootropicdesign.com/projectlab/wp-content/uploads/2022/07/swarm_eval_kit-980x434.jpg 980w, https://nootropicdesign.com/projectlab/wp-content/uploads/2022/07/swarm_eval_kit-480x213.jpg 480w" sizes="auto, (min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) and (max-width: 980px) 980px, (min-width: 981px) 1024px, 100vw" /></a><p id="caption-attachment-2640" class="wp-caption-text">Swarm evaluation kit</p></div><br />
<br clear="all"/></p>
<p>Note that this version of the eval kit has their first generation &#8220;Tile&#8221; modem, which has been superseded by their new M138 modem. I don&#8217;t know if the performance of the new modem is better, but as we will see, the ability to send messages has much more to do with satellite coverage than the modem hardware. It&#8217;s obvious in the orbit image above that there are significant gaps in coverage between orbital planes, and this has a huge effect on the time it takes to successfully deliver a message.</p>
<p>The goal of the experiments is to measure how long it takes to deliver messages from the modem to the Internet. Sending messages using the Swarm modem is easy. As a developer, you just send NMEA-like sentences over a serial connection to the modem. Messages are queued in the modem until the modem can successfully uplink it to a passing Swarm satellite. The modem can hold up to 1000 messages that it will continually try to uplink, so as a developer, it&#8217;s like a fire-and-forget approach. Nice.</p>
<p>Whichever Swarm satellite received the message will downlink the message to a ground station. Messages that have been delivered to Earth show up on the online site <a href="https://bumblebee.hive.swarm.space/" rel="noopener noreferrer" target="_blank">Swarm Hive</a>. Hive can also deliver the message to your own infrastructure using a webhook (I had my messages delivered to a Node-RED endpoint). This article is not going to get into all the code details of how I performed the experiments, but the source code is linked in the Resources section below.</p>
<p>In order to assess the characteristics of the network, there are two things we want to measure: the time it takes for a message to be received by a satellite and the time it takes to be downlinked to a ground station and made available in the Hive. </p>
<pre>
time to uplink + time to downlink and deliver = total time
</pre>
<p>Measuring these is a bit tricky. After handing a message to the modem using the <span style="font-family:monospace">$TD</span> command, the modem responds with a unique identifier for that message. Eventually when the message is uplinked, the modem provides an unsolicited message <span style="font-family:monospace">$TD SENT</span> with the unique identifier. My firmware keeps track of how long this process took and saves all of the information in a .csv file on the FeatherS2 filesystem. On the receiving side, I deployed a Node-RED endpoint to serve as a webhook to which the Hive could deliver my messages. The problem is that the delivered message does not contain the unique identifier known to the modem, so there is no way to correlate what the modem knows with what the Hive knows. To solve this, I included my own unique identifier in the payload of the message. This way I could match up the uplink measurements performed on the FeatherS2 code with the received messages in my Node-RED code.</p>
<p>I ran my experiement to send a message every 15 minutes for 8 hours. For each message I was able to determine how long it took for the modem to uplink it to a satellite, and then how long it took for that satellite to deliver the message to my Internet endpoint. The detailed results are in the Experimental Results section below. In summary, Swarm messages can take up to several hours to be uplinked if your ground station is under a gap in the orbital planes. Sometimes there were a dozen messages queued up in the modem. But eventually, when there are satellites overhead, the messages will get uplinked, sometimes 5 at a time. Once uplinked, the downlink/delivery time is usually pretty short.</p>
<p>It&#8217;s worth noting that messages will not necessarily be uplinked in the order they were sent, so &#8220;queue&#8221; is not the right word for what the modem is doing. I also observed several cases where the modem reported the uplink of a message <em>after</em> the message had already been delivered to Earth. Sometimes this happened several <em>hours</em> after terrestrial delivery. I don&#8217;t know if that&#8217;s a bug or if it&#8217;s just a design characteristic of the way the network acknowledges receipt of a message to the modem. I have omitted those few anomalies from the statistics below.</p>
<p>Bottom line? Swarm makes it easy to send messages from an embedded microcontroller IoT solution. The messages may get uplinked and delivered right away if you are lucky, or you may wait several hours. But they do get delivered! In all of my experimentation I have never lost a message.</p>
<h3>Iridium</h3>
<p>Iridium is the decades-old 800 pound gorilla in the commercial space communications industry. Literally, their Iridium NEXT satellites weigh significantly more than 800 pounds each (a lot more). This doesn&#8217;t mean that their satellites are old and obsolete. The current generation is quite new, and don&#8217;t forget that these satellites are used for satellite telephone conversations. Iridium satellites communicate with one another using microwave links with nearby satellites in order to create a real-time communication link capable of maintaining a telephone conversation. That&#8217;s nothing short of incredible, in my opinion. IoT messages should be a piece of cake, and from what I can tell, it is. The Iridium constellation is 66 satellites in polar orbits at the somewhat high altitude of 781 km giving them global coverage.</p>
<p><div id="attachment_2633" style="width: 1034px" class="wp-caption alignleft"><a href="https://nootropicdesign.com/projectlab/wp-content/uploads/2022/07/iridium_orbits.png"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-2633" src="https://nootropicdesign.com/projectlab/wp-content/uploads/2022/07/iridium_orbits-1024x826.png" alt="" width="1024" height="826" class="size-large wp-image-2633" srcset="https://nootropicdesign.com/projectlab/wp-content/uploads/2022/07/iridium_orbits-1024x826.png 1024w, https://nootropicdesign.com/projectlab/wp-content/uploads/2022/07/iridium_orbits-980x790.png 980w, https://nootropicdesign.com/projectlab/wp-content/uploads/2022/07/iridium_orbits-480x387.png 480w" sizes="auto, (min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) and (max-width: 980px) 980px, (min-width: 981px) 1024px, 100vw" /></a><p id="caption-attachment-2633" class="wp-caption-text">Iridium constellation provides full coverage</p></div><br />
<br clear="all"/></p>
<p>For IoT using small messages, Iridium offers the Small Data Burst (SBD) service. I&#8217;m using the Ground Control (formerly Rock Seven Communications) <a href="https://www.groundcontrol.com/us/product/rockblock-9603-compact-plug-and-play-satellite-transmitter/" rel="noopener noreferrer" target="_blank">RockBLOCK 9603 modem</a>. You can also <a href="https://www.sparkfun.com/products/14498" rel="noopener noreferrer" target="_blank">buy it from SparkFun</a>.</p>
<p>For my experiments I used a simple development board that I had built for a project called <a href="https://nootropicdesign.com/projectlab/2019/09/21/arduino-satellite-communication/" rel="noopener noreferrer" target="_blank">Iridium satellite communication</a>. It incorporates the modem with a GPS receiver because the Iridium modem does not have integrated GPS like the Swarm modem. GPS is important for knowing what time it is, not where we are.</p>
<p><div id="attachment_2409" style="width: 1034px" class="wp-caption alignleft"><a href="https://nootropicdesign.com/projectlab/wp-content/uploads/2019/09/IridiumExperimenter.jpg"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-2409" src="https://nootropicdesign.com/projectlab/wp-content/uploads/2019/09/IridiumExperimenter-1024x693.jpg" alt="" width="1024" height="693" class="size-large wp-image-2409" srcset="https://nootropicdesign.com/projectlab/wp-content/uploads/2019/09/IridiumExperimenter-1024x693.jpg 1024w, https://nootropicdesign.com/projectlab/wp-content/uploads/2019/09/IridiumExperimenter-980x663.jpg 980w, https://nootropicdesign.com/projectlab/wp-content/uploads/2019/09/IridiumExperimenter-480x325.jpg 480w" sizes="auto, (min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) and (max-width: 980px) 980px, (min-width: 981px) 1024px, 100vw" /></a><p id="caption-attachment-2409" class="wp-caption-text">Simple Iridium development board</p></div><br />
<br clear="all"/></p>
<p>Here is my ground station. The dev board is in a plastic box in case it rains. I&#8217;m using an external antenna (also available from SparkFun), and power is provided by a large battery with solar charger.</p>
<p><div id="attachment_2631" style="width: 1034px" class="wp-caption alignleft"><a href="https://nootropicdesign.com/projectlab/wp-content/uploads/2022/07/iridium_ground_station.jpg"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-2631" src="https://nootropicdesign.com/projectlab/wp-content/uploads/2022/07/iridium_ground_station-1024x703.jpg" alt="" width="1024" height="703" class="size-large wp-image-2631" srcset="https://nootropicdesign.com/projectlab/wp-content/uploads/2022/07/iridium_ground_station-1024x703.jpg 1024w, https://nootropicdesign.com/projectlab/wp-content/uploads/2022/07/iridium_ground_station-980x673.jpg 980w, https://nootropicdesign.com/projectlab/wp-content/uploads/2022/07/iridium_ground_station-480x330.jpg 480w" sizes="auto, (min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) and (max-width: 980px) 980px, (min-width: 981px) 1024px, 100vw" /></a><p id="caption-attachment-2631" class="wp-caption-text">Iridium ground station</p></div><br />
<br clear="all"/></p>
<p>Just as I did with Swarm, I ran the experiement for 8 hours, sending a message every 15 minutes. Using the Iridium modem is quite different than Swarm, though. The Iridium modem can only handle one message at a time, so there&#8217;s no fire-and-forget model. The embedded software on the microcontroller needs to interact with the modem to wait for the successful uplink and cannot send any other messages until the uplink succeeds, times out, or is canceled. From a development perspective, it&#8217;s much more hands-on, but luckily there is an excellent Arduino library, <a href="https://github.com/mikalhart/IridiumSBD" rel="noopener noreferrer" target="_blank">Mikal Hart&#8217;s Iridium SBD library</a>, that makes this as painless as possible.</p>
<p>After successful uplink, the message will be downlinked to an Iridium ground station somewhere &#8212; possibly being passed between other Iridium satellites! &#8212; and delivered to the Ground Control online management console similar to Swarm&#8217;s Hive site. Ground Control will also deliver the message to a webhook, so I am also having the data sent to a Node-RED endpoint for analysis. </p>
<p>Measurement of the uplink time and downlink time is easier with Iridium than with Swarm. The data delivered to the management console and my webhook tells me when the message was received by an Iridium satellite. I know when I sent the message because I include a timestamp in the payload itself. So at the Internet endpoint, I know when I attempted to send the message, when it was actually received by a satellite, and when it was delivered to Earth. Full results are below, but the bottom line is that Iridium&#8217;s global coverage and microwave interconnects provides fast and predictable delivery of IoT messages. Sometimes it takes 10 minutes, but usually only a few minutes, and sometimes almost instantly.</p>
<h3>Experimental Results</h3>
<p>Ok, it&#8217;s finally time to review the results. Below are tables showing the minimum, maximum and average measured times for the uplink, downlink, and total latency. You can see clearly that Swarm messages can take hours to deliver (one took almost 2 hours). If Swarm satellites are overhead, though, it can only take a couple of minutes. On average, over an 8 hour experiment sending a message every 15 minutes, Swarm delivered the messages in 39 minutes, 44 seconds.<br />
&nbsp;</p>
<table style="height: 200px; border-style: solid; width: 560px;" border="1" width="560">
<caption>Swarm message delivery statistics</caption>
<tbody>
<tr style="height: 45px;">
<td style="width: 200px; height: 45px;"></td>
<td style="width: 110px; height: 45px;">min</td>
<td style="width: 110px; height: 45px;">max</td>
<td style="width: 110px; height: 45px;">average</td>
</tr>
<tr style="height: 45px;">
<td style="width: 200px; height: 45px;">time to uplink</td>
<td style="width: 110px; height: 45px;">00:00:30</td>
<td style="width: 110px; height: 45px;">01:56:45</td>
<td style="width: 110px; height: 45px;">00:32:47</td>
</tr>
<tr style="height: 45px;">
<td style="width: 200px; height: 45px;">time to downlink</td>
<td style="width: 110px; height: 45px;">00:00:07</td>
<td style="width: 110px; height: 45px;">00:35:22</td>
<td style="width: 110px; height: 45px;">00:07:31</td>
</tr>
<tr style="height: 45px;">
<td style="width: 200.734px; height: 45px;">total time</td>
<td style="width: 110.391px; height: 45px;"><span style="color: #ff7700;"><strong>00:02:32</strong></span></td>
<td style="width: 110.391px; height: 45px;"><span style="color: #ff7700;"><strong>01:58:37</strong></span></td>
<td style="width: 110.484px; height: 45px;"><span style="color: #ff7700;"><strong>00:39:44</strong></span></td>
</tr>
</tbody>
</table>
<p>&nbsp;<br />
Iridium, on the other hand, is much faster. It can take up to 15 minutes for an uplink to succeed, but on average only takes 3:11. Once uplinked, the Iridium network delivers messages to the ground very quickly with an average of only 12 seconds! Remember that Iridium satellites can talk to one another, so this can really speed things up. Average end-to-end delivery time for Iridium was only 3 minutes, 22 seconds.<br />
&nbsp;</p>
<table style="height: 200px; border-style: solid; width: 560px;" border="1" width="560">
<caption>Iridium message delivery statistics</caption>
<tbody>
<tr style="height: 45px;">
<td style="width: 200px; height: 45px;"></td>
<td style="width: 110px; height: 45px;">min</td>
<td style="width: 110px; height: 45px;">max</td>
<td style="width: 110px; height: 45px;">average</td>
</tr>
<tr style="height: 45px;">
<td style="width: 200px; height: 45px;">time to uplink</td>
<td style="width: 110px; height: 45px;">00:00:04</td>
<td style="width: 110px; height: 45px;">00:15:47</td>
<td style="width: 110px; height: 45px;">00:03:11</td>
</tr>
<tr style="height: 45px;">
<td style="width: 200px; height: 45px;">time to downlink</td>
<td style="width: 110px; height: 45px;">00:00:05</td>
<td style="width: 110px; height: 45px;">00:01:06</td>
<td style="width: 110px; height: 45px;">00:00:12</td>
</tr>
<tr style="height: 45px;">
<td style="width: 200px; height: 45px;">total time</td>
<td style="width: 110px; height: 45px;"><span style="color: #ff7700;"><strong>00:00:10</strong></span></td>
<td style="width: 110px; height: 45px;"><span style="color: #ff7700;"><strong>00:15:53</strong></span></td>
<td style="width: 110px; height: 45px;"><span style="color: #ff7700;"><strong>00:03:22</strong></span></td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<h3>Costs</h3>
<p>How much does all this cost? First let&#8217;s talk about hardware (CapEx). I bought the $500 Swarm evaluation kit, but for an actual IoT deployment, the newer Swarm M138 modem on a breakout board is <a href="https://www.sparkfun.com/products/19236" rel="noopener noreferrer" target="_blank">available from SparkFun for $150</a>, including an antenna and ground plane. An Iridium ROCKBlock modem module can also be bought from <a href="https://www.sparkfun.com/products/14498" rel="noopener noreferrer" target="_blank">SparkFun for $267</a>. If you want the external antenna, that will cost another $70. Overall, an Iridium hardware solution will cost you more. </p>
<p>Also note that since Iridium uses a much higher frequency (1626 MHz), it can get by with a patch antenna or the small GPS-like antenna. The Swarm system uses lower frequencies: downlink 137-138 MHz / uplink 148-149.95 MHz. This requires a larger antenna which is 8 inches or 20cm and a square 8&#215;8 inch ground plane. That will affect the size of your deployed package.</p>
<p>Operational costs are also much lower for Swarm than Iridium. For a $60/year subscription, you can send 750 messages per month, or about 24 per day. That&#8217;s a lot of messages. For my Iridium integration, I am using Ground Control (formerly Rock Seven) which is a British company. Their pricing is in GBP, but I&#8217;ll convert to USD for comparison. There is a monthly &#8220;line rental&#8221; fee for about $15 per device. Messages are paid for with &#8220;credits&#8221; which cost about $0.15 per credit. A message of 50 bytes or less uses one credit. Longer messages will use 2 credits.</p>
<p>To compare apples to apples, let&#8217;s say we wanted to send 750 messages per month for one year with Iridium + Ground Control. First line rental would be $15 x 12 = $180. At 15 cents per message, we would spend $1350 for credits, for a yearly total of $1530. Swarm would cost $60 for the same amount of messaging. That&#8217;s a big difference. But that&#8217;s assuming you are using all of your alloted message capacity with Swarm, and you may not need to send nearly that many messages. So, it really depends on how many messages you need to send. The fewer it is, the less difference there is between both solutions.</p>
<p>Does this cost difference really matter? If you are a hobbyist, yes, money matters. But what if you are a large company using IoT to monitor assets in the field? Maybe your infrastructure is worth millions of dollars. A few thousand dollars here and there for monitoring may not matter at all. But if you are a company deploying thousands of devices? Then Swarm will probably be cheaper. As always, &#8220;it depends&#8221;.</p>
<h3>Summary</h3>
<p>Both Swarm and Iridum can be used to create satellite-connected IoT solutions. Swarm is easy to use and lower cost, but the latency for message delivery is significantly longer, potentially several hours. This might be fine for your application.</p>
<p>Iridium is more expensive, but offers much lower latency delivery of messages and can generally be integrated into a smaller hardware package. If you need to monitor expensive infrastructure and want to know about problems as soon as possible, Iridium might be for you. If there is a leak or a fire or anything that needs attention, you&#8217;ll want to know in a few minutes, not a few hours. </p>
<p>As is usually the case in engineering, there is no one-size-fits-all answer and as an IoT professional you have some things to consider. I hope this article and the actual experimental results presented is useful. With the rapid proliferation of commercial space ventures, the coming years will bring many new options to the satellite IoT solution space, and we will be watching closely and experimenting as much as we can!</p>
<p><em>nootropic design, LLC provides custom electronics and IoT solutions for industry.</em><br />
<em>You can contact us at nootropicdesign [at] gmail.com</em></p>
<h3>Resources</h3>
<p><a href="https://swarm.space" rel="noopener noreferrer" target="_blank">Swarm</a></p>
<p><a href="https://www.sparkfun.com/products/19236" rel="noopener noreferrer" target="_blank">SparkFun: Satellite Transceiver Breakout &#8211; Swarm M138</a></p>
<p><a href="https://www.groundcontrol.com" rel="noopener noreferrer" target="_blank">Ground Control</a></p>
<p><a href="https://www.sparkfun.com/products/14498" rel="noopener noreferrer" target="_blank">SparkFun: Iridium ROCKBlock 9603N &#8211; Iridium SatComm Module</a></p>
<p><a href="https://github.com/mikalhart/IridiumSBD" rel="noopener noreferrer" target="_blank">Iridium SBD library for Arduino</a></p>
<p><a href="https://github.com/sparkfun/SparkFun_Swarm_Satellite_Arduino_Library" rel="noopener noreferrer" target="_blank">Swarm Satellite Arduino Library</a></p>
<p><a href="https://github.com/nootropicdesign/swarm-vs-iridium" rel="noopener noreferrer" target="_blank">GitHub repository</a> containing the source code used to perform the experiements. This is provided for reference only and is not intended to help you replicate the experiements. There is significant setup required on the Swarm Hive and Ground Control management console sites, and I deployed Node-RED endpoints as webhooks to receive messages. Much of the analysis was manual file manipulation and was not automated.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://nootropicdesign.com/projectlab/2022/07/30/swarm-vs-iridium-for-satellite-iot/feed/</wfw:commentRss>
			<slash:comments>7</slash:comments>
		
		
			</item>
		<item>
		<title>Laser Show Motor Controller</title>
		<link>https://nootropicdesign.com/projectlab/2020/04/17/laser-show-motor-controller/</link>
					<comments>https://nootropicdesign.com/projectlab/2020/04/17/laser-show-motor-controller/#respond</comments>
		
		<dc:creator><![CDATA[Michael]]></dc:creator>
		<pubDate>Fri, 17 Apr 2020 14:16:18 +0000</pubDate>
				<category><![CDATA[Arduino]]></category>
		<category><![CDATA[Art]]></category>
		<guid isPermaLink="false">https://nootropicdesign.com/projectlab/?p=2576</guid>

					<description><![CDATA[Here&#8217;s a fun idea I had while quarantined during the 2020 pandemic. I have a bunch of these cheap laser modules that can easily be driven from an Arduino with 5V, and they only draw 20mA of current. I also have a handful of cheap vibration motors. What happens when you mount vibration motors on [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>Here&#8217;s a fun idea I had while quarantined during the 2020 pandemic. I have a bunch of these cheap laser modules that can easily be driven from an Arduino with 5V, and they only draw 20mA of current. I also have a handful of cheap vibration motors. What happens when you mount vibration motors on a laser? Well, it turns out you can make a cool laser show!</p>
<p><iframe loading="lazy" title="Laser Show Motor Controller" width="1080" height="608" src="https://www.youtube.com/embed/LamcX1Kpm8c?feature=oembed" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe><br />
<br clear="all"/></p>
<p>Here&#8217;s what I used:</p>
<ul>
<li>Arduino</li>
<li>SN754410 quad half H-bridge chip</li>
<li>laser module from AliExpress</li>
<li>2 cell phone vibration motors from AliExpress</li>
<li>4 10K pots to control motor speeds, laser PWM duty cycle, and laser PWM frequency</li>
</ul>
<p><a href="https://nootropicdesign.com/projectlab/wp-content/uploads/2020/04/laserShowMotorController.jpg"><img loading="lazy" decoding="async" class="alignleft size-large wp-image-2573" src="https://nootropicdesign.com/projectlab/wp-content/uploads/2020/04/laserShowMotorController-1024x768.jpg" alt="" width="1024" height="768" srcset="https://nootropicdesign.com/projectlab/wp-content/uploads/2020/04/laserShowMotorController-980x735.jpg 980w, https://nootropicdesign.com/projectlab/wp-content/uploads/2020/04/laserShowMotorController-480x360.jpg 480w" sizes="auto, (min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) and (max-width: 980px) 980px, (min-width: 981px) 1024px, 100vw" /></a><br />
<br clear="all" /></p>
<p>The motors are mounted perpendicular to one another, and when you change the speed of the motors, the vibrations cause the laser to oscillate in chaotic patterns. They look a lot like <a href="https://en.wikipedia.org/wiki/Lissajous_curve" rel="noopener noreferrer" target="_blank">Lissajous figures</a> you see on an oscilloscope. This makes sense, of course, because the motors cause periodic oscillations along different axes. There are also pots to control the PWM duty cycle and PWM frequency. This leads to even more interesting visualizations.</p>
<p><a href="https://nootropicdesign.com/projectlab/wp-content/uploads/2020/04/laserShowMotorController_top.jpg"><img loading="lazy" decoding="async" src="https://nootropicdesign.com/projectlab/wp-content/uploads/2020/04/laserShowMotorController_top-1024x768.jpg" alt="" width="1024" height="768" class="alignleft size-large wp-image-2574" srcset="https://nootropicdesign.com/projectlab/wp-content/uploads/2020/04/laserShowMotorController_top-980x735.jpg 980w, https://nootropicdesign.com/projectlab/wp-content/uploads/2020/04/laserShowMotorController_top-480x360.jpg 480w" sizes="auto, (min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) and (max-width: 980px) 980px, (min-width: 981px) 1024px, 100vw" /></a><br />
<br clear="all" /></p>
<p>I made the circuit on an Arduino shield prototyping board. I didn&#8217;t say it was pretty.</p>
<p><a href="https://nootropicdesign.com/projectlab/wp-content/uploads/2020/04/laserShowMotorController_bottom.jpg"><img loading="lazy" decoding="async" src="https://nootropicdesign.com/projectlab/wp-content/uploads/2020/04/laserShowMotorController_bottom-1024x768.jpg" alt="" width="1024" height="768" class="alignleft size-large wp-image-2575" srcset="https://nootropicdesign.com/projectlab/wp-content/uploads/2020/04/laserShowMotorController_bottom-980x735.jpg 980w, https://nootropicdesign.com/projectlab/wp-content/uploads/2020/04/laserShowMotorController_bottom-480x360.jpg 480w" sizes="auto, (min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) and (max-width: 980px) 980px, (min-width: 981px) 1024px, 100vw" /></a><br />
<br clear="all" /></p>
<p><a href="https://github.com/nootropicdesign/laser-show-motor-controller" rel="noopener noreferrer" target="_blank">The code is on GitHub</a>, and here is the schematic so you can build it yourself with the things you have lying around. Have fun!</p>
<p><a href="https://nootropicdesign.com/projectlab/wp-content/uploads/2020/04/laserShowMotorController_schematic.png"><img loading="lazy" decoding="async" src="https://nootropicdesign.com/projectlab/wp-content/uploads/2020/04/laserShowMotorController_schematic-1024x764.png" alt="" width="1024" height="764" class="alignleft size-large wp-image-2572" srcset="https://nootropicdesign.com/projectlab/wp-content/uploads/2020/04/laserShowMotorController_schematic-980x731.png 980w, https://nootropicdesign.com/projectlab/wp-content/uploads/2020/04/laserShowMotorController_schematic-480x358.png 480w" sizes="auto, (min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) and (max-width: 980px) 980px, (min-width: 981px) 1024px, 100vw" /></a><br />
<br clear="all" /></p>
]]></content:encoded>
					
					<wfw:commentRss>https://nootropicdesign.com/projectlab/2020/04/17/laser-show-motor-controller/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Iridium Satellite Signal Monitoring</title>
		<link>https://nootropicdesign.com/projectlab/2019/12/27/iridium-signal-monitoring/</link>
					<comments>https://nootropicdesign.com/projectlab/2019/12/27/iridium-signal-monitoring/#comments</comments>
		
		<dc:creator><![CDATA[Michael]]></dc:creator>
		<pubDate>Fri, 27 Dec 2019 20:45:18 +0000</pubDate>
				<category><![CDATA[ESP8266]]></category>
		<category><![CDATA[IoT]]></category>
		<category><![CDATA[Radio]]></category>
		<category><![CDATA[Satellite]]></category>
		<category><![CDATA[Space]]></category>
		<guid isPermaLink="false">https://nootropicdesign.com/projectlab/?p=2539</guid>

					<description><![CDATA[Project source code at GitHub: iridium-signal-strength-monitor In a previous article, I wrote all about Iridium satellite communication for IoT projects using an Iridium modem and simple Arduino technology. However, when trying to send a message to a satellite constellation, you never know if the message will go right away or if it will take several [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>Project source code at GitHub: <a href="https://github.com/nootropicdesign/iridium-signal-strength-monitor" rel="noopener noreferrer" target="_blank">iridium-signal-strength-monitor</a></p>
<p>In a previous article, I wrote all about <a href="https://nootropicdesign.com/projectlab/2019/09/21/arduino-satellite-communication/" rel="noopener noreferrer" target="_blank">Iridium satellite communication</a> for IoT projects using an Iridium modem and simple Arduino technology. However, when trying to send a message to a satellite constellation, you never know if the message will go right away or if it will take several minutes. Sometimes there is a satellite overhead, but sometimes you will have to wait a while before one flies over you. I decided to investigate how the signal strength reported by the Iridium modem (AT+CSQ command) correlates to the <em>actual</em> positions of Iridium satellites. So I used the amazing <a href="https://cesium.com/cesiumjs/" rel="noopener noreferrer" target="_blank">CesiumJS open source JavaScript library</a> and the hardware I built in the previous project to make a great tool that shows how signal strength matches up with the satellite positions! Understanding the reception quality of satellite constellations is going to become increasingly important as companies like SpaceX roll out their low earth orbit (LEO) Internet connectivity solutions like <a href="https://www.starlink.com/" rel="noopener noreferrer" target="_blank">Starlink</a>.</p>
<p><a href="https://nootropicdesign.com/projectlab/wp-content/uploads/2019/12/iridiumSignalMonitor.png"><img loading="lazy" decoding="async" src="https://nootropicdesign.com/projectlab/wp-content/uploads/2019/12/iridiumSignalMonitor-1024x568.png" alt="" width="1024" height="568" class="alignleft size-large wp-image-2538" srcset="https://nootropicdesign.com/projectlab/wp-content/uploads/2019/12/iridiumSignalMonitor-980x544.png 980w, https://nootropicdesign.com/projectlab/wp-content/uploads/2019/12/iridiumSignalMonitor-480x266.png 480w" sizes="auto, (min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) and (max-width: 980px) 980px, (min-width: 981px) 1024px, 100vw" /></a><br />
<br clear="all"/></p>
<h3>How It All Works</h3>
<p>There&#8217;s a lot going on here, so let me explain. First, I deployed my <a href="https://nootropicdesign.com/projectlab/2019/09/21/arduino-satellite-communication/" rel="noopener noreferrer" target="_blank">simple development board that I built before</a> but this time I connected an ESP8266 to the serial line so that it could send information to the Internet. The Arduino code on the dev board uses the <a href="https://github.com/mikalhart/IridiumSBD" rel="noopener noreferrer" target="_blank">Iridium SBD library</a> to ask the modem for the &#8220;signal strength&#8221; that it has at the moment. This gives a value from 0-5. It writes this info over serial to the ESP8266 which publishes it to an MQTT topic. So basically this sits outside with the antenna pointed to the sky and asks the modem every 5 seconds what the signal strength is. The GPS module allows me to attach an accurate timestamp to the reading so that the data can be matched up with the satellite position info.</p>
<p><a href="https://nootropicdesign.com/projectlab/wp-content/uploads/2019/12/IridiumSignalMonitoringArchitecture.png"><img loading="lazy" decoding="async" src="https://nootropicdesign.com/projectlab/wp-content/uploads/2019/12/IridiumSignalMonitoringArchitecture-1024x565.png" alt="" width="1024" height="565" class="alignleft size-large wp-image-2548" srcset="https://nootropicdesign.com/projectlab/wp-content/uploads/2019/12/IridiumSignalMonitoringArchitecture-1024x565.png 1024w, https://nootropicdesign.com/projectlab/wp-content/uploads/2019/12/IridiumSignalMonitoringArchitecture-980x540.png 980w, https://nootropicdesign.com/projectlab/wp-content/uploads/2019/12/IridiumSignalMonitoringArchitecture-480x265.png 480w" sizes="auto, (min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) and (max-width: 980px) 980px, (min-width: 981px) 1024px, 100vw" /></a><br />
<br clear="all"/></p>
<p>On the software side, I wrote a web tool using <a href="https://cesium.com/cesiumjs/" rel="noopener noreferrer" target="_blank">CesiumJS</a> that displays the orbits of all the Iridium satellites. It calculates the orbits from the <a href="http://celestrak.com/NORAD/elements/iridium-NEXT.txt" rel="noopener noreferrer" target="_blank">Iridium two-line element sets (TLEs) from Celestrak</a>. CesiumJS is a great way to visualize orbits and show the positions of satellites in realtime. You can zoom in, pan and tilt the globe, OMG it&#8217;s just gorgeous. The web client is served up from a simple NodeJS server that also subscribes to the MQTT topic to get the signal strength data as the hardware publishes it. The server sends the data up a websocket to the web client.</p>
<p>In addition to showing the realtime satellite positions and predicted orbits, the web tool also:</p>
<ul>
<li>displays the current signal strength as 5 bars, just like your phone</li>
<li>calculates the closest satellite to the ground station and renders a green line to it</li>
<li>displays the footprint of each satellite. You can change the elevation angle using a slider. When set to zero, the footprint represents visibility to the horizon. I have found that setting this to 25 degrees gives a more accurate depiction of the satellite&#8217;s communication range. That is, my hardware can &#8220;hear&#8221; the satellite if it is at least 25 degrees above the horizon.</li>
<li>plots the signal strength vs. the distance to the closest satellite on a scatter plot. This should show that higher signal readings are correlated with shorter distances to the closest satellite.</li>
</ul>
<h3>Results</h3>
<p>Well, does it work? Does the signal strength reported by the modem correspond to the actual proximity of an Iridium satellite? Yes, it does! It&#8217;s not perfect, but this is RF, so one should not expect perfectly predictable measurements. There are all kinds of factors at play in RF propagation. But generally speaking, I measure zero bars when there are no satellites overhead, and measure a stronger and stronger signal as a satellite approaches. The scatter plot that is built up over time definitely shows that strong signals (vertical axis) are associated with smaller distance to the closest satellite (horizontal axis).</p>
<p><a href="https://nootropicdesign.com/projectlab/wp-content/uploads/2019/12/iridiumSignalStrengthScatterPlot.png"><img loading="lazy" decoding="async" src="https://nootropicdesign.com/projectlab/wp-content/uploads/2019/12/iridiumSignalStrengthScatterPlot.png" alt="" width="629" height="312" class="alignleft size-full wp-image-2537" srcset="https://nootropicdesign.com/projectlab/wp-content/uploads/2019/12/iridiumSignalStrengthScatterPlot.png 629w, https://nootropicdesign.com/projectlab/wp-content/uploads/2019/12/iridiumSignalStrengthScatterPlot-480x238.png 480w" sizes="auto, (min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) 629px, 100vw" /></a><br />
<br clear="all"/></p>
<p>This video shows the experiment in action. The great thing about building a CesiumJS model is the ability to have all the data stored in a time series that you can play back at different speeds and even play it backward. Since satellites move slowly, it&#8217;s very helpful to back up in time and play the sequence forward at higher speeds. And it looks beautiful, too!</p>
<p><iframe loading="lazy" title="Iridium Satellite Signal Strength Monitoring" width="1080" height="608" src="https://www.youtube.com/embed/gkn1H7h44vU?feature=oembed" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe><br />
<br clear="all"/></p>
<h3>Software</h3>
<p>You can try this yourself if you have an Iridium modem like the RockBLOCK 9603 modem. Or you can use the CesiumJS orbit visualization for your own projects. GitHub repo: <a href="https://github.com/nootropicdesign/iridium-signal-strength-monitor" rel="noopener noreferrer" target="_blank">iridium-signal-strength-monitor</a></p>
<p>Even if you don&#8217;t have the hardware to measure signal strength, you can use the the CesiumJS web application to show the realtime positions of Iridium satellites.</p>
<p>Here are some things you will need to change in the software if you want to do this project:</p>
<p>In the code for the ESP8266 <span class="code">MQTTWiFiGateway.ino</span>:</p>
<pre class="codeblock">
const char* mqtt_server = "your_mqtt_server";
const char* mqtt_username = "mqtt_user";
const char* mqtt_password = "mqtt_password";
</pre>
<p>For the webserver and CesiumJS web application, set your MQTT server and credentials in <span class="code">server.js</span>:</p>
<pre class="codeblock">
var options = {
    host: 'your_mqtt_server',
    port: 1883,
    username: 'mqtt_user',
    password: 'mqtt_password'
}
</pre>
<p>You will need to <a href="https://cesium.com/ion/signup" rel="noopener noreferrer" target="_blank">get a Cesium Ion access token</a>. It&#8217;s free.<br />
Set your Cesium Ion access token in <span class="code">app.js</span>:</p>
<pre class="codeblock">
Cesium.Ion.defaultAccessToken = 'YOUR_CESIUM_ION_ACCESS_TOKEN';
</pre>
<p>To use the MapBox dark imagery like I did, you&#8217;ll need to <a href="https://docs.mapbox.com/help/how-mapbox-works/access-tokens/" rel="noopener noreferrer" target="_blank">get a MapBox access token</a>. Also set in <span class="code">app.js</span>:</p>
<pre class="codeblock">
imageryProvider : new Cesium.MapboxImageryProvider({
    mapId: 'mapbox.dark',
    accessToken: 'YOUR_MAPBOX_ACCESS_TOKEN'
})
</pre>
<p>Installation and startup:</p>
<pre class="codeblock">
cd webserver
npm install
npm start
</pre>
]]></content:encoded>
					
					<wfw:commentRss>https://nootropicdesign.com/projectlab/2019/12/27/iridium-signal-monitoring/feed/</wfw:commentRss>
			<slash:comments>8</slash:comments>
		
		
			</item>
		<item>
		<title>Automated Weather Satellite Ground Station</title>
		<link>https://nootropicdesign.com/projectlab/2019/11/08/weather-satellite-ground-station/</link>
					<comments>https://nootropicdesign.com/projectlab/2019/11/08/weather-satellite-ground-station/#comments</comments>
		
		<dc:creator><![CDATA[Michael]]></dc:creator>
		<pubDate>Fri, 08 Nov 2019 14:12:56 +0000</pubDate>
				<category><![CDATA[Radio]]></category>
		<category><![CDATA[Satellite]]></category>
		<category><![CDATA[Space]]></category>
		<guid isPermaLink="false">https://nootropicdesign.com/projectlab/?p=2461</guid>

					<description><![CDATA[UPDATE: All NOAA APT satellites (NOAA-18, NOAA-19, NOAA-15) were decommissioned in 2025. NOAA-15 was decommissioned and stopped transmitting imagery at 15:28 UTC on August 19. You can see my very last received images on my site. Project source code at GitHub: wx-ground-station This project will show you how to create a fully automated ground station [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>UPDATE: All NOAA APT satellites (NOAA-18, NOAA-19, NOAA-15) were decommissioned in 2025. NOAA-15 was decommissioned and stopped transmitting imagery at 15:28 UTC on August 19. <a href="https://nootropicdesign.com/wx/" rel="noopener noreferrer" target="_blank">You can see my very last received images on my site.</a></p>
<p>Project source code at GitHub: <a href="https://github.com/nootropicdesign/wx-ground-station" rel="noopener noreferrer" target="_blank">wx-ground-station</a></p>
<p><a href="https://nootropicdesign.com/projectlab/wp-content/uploads/2019/11/wx-ground-station_images.jpg"><img loading="lazy" decoding="async" src="https://nootropicdesign.com/projectlab/wp-content/uploads/2019/11/wx-ground-station_images.jpg" alt="" width="1002" height="871" class="alignleft size-full wp-image-2527" srcset="https://nootropicdesign.com/projectlab/wp-content/uploads/2019/11/wx-ground-station_images.jpg 1002w, https://nootropicdesign.com/projectlab/wp-content/uploads/2019/11/wx-ground-station_images-980x852.jpg 980w, https://nootropicdesign.com/projectlab/wp-content/uploads/2019/11/wx-ground-station_images-480x417.jpg 480w" sizes="auto, (min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) and (max-width: 980px) 980px, (min-width: 981px) 1002px, 100vw" /></a><br />
<br clear="all"/></p>
<p>This project will show you how to create a fully automated ground station that will receive and decode NOAA weather satellite images and upload them to your own website served from an Amazon AWS S3 bucket. With this project you don&#8217;t need your own server or have to run your own website infrastructure. <a href="https://nootropicdesign.com/wx/" rel="noopener noreferrer" target="_blank">Have a look at my AWS site that is updated automatically all day long</a>. </p>
<p>Oh, you want a site like this, too? Full of images you decoded from space? Then let&#8217;s get started, my friend.</p>
<p>Here&#8217;s what you&#8217;ll need:</p>
<ul>
<li>a modern Raspberry Pi (version 3 or 4), probably with Wi-Fi since it may be deployed outdoors. I used a RPi 3 model B. I have heard that a RPi Zero may not be powerful enough.</li>
<li>an RTL-SDR dongle. I recommend the <a href="https://www.rtl-sdr.com/buy-rtl-sdr-dvb-t-dongles/" rel="noopener noreferrer" target="_blank">RTL-SDR V3 dongle</a> from the excellent <a href="https://www.rtl-sdr.com" rel="noopener noreferrer" target="_blank">RTL-SDR.COM blog</a>.</li>
<li>an AWS account for hosting images and web content in an <a href="https://aws.amazon.com/s3/" rel="noopener noreferrer" target="_blank">Amazon S3</a> bucket. You can sign up for the free tier for a year, and it&#8217;s still cheap after that.</li>
<li>a simple dipole antenna with elements 21 inches (53.4 cm) long and that can be adjusted to have a 120 degree angle between the elements. <a href="http://lna4all.blogspot.com/2017/02/diy-137-mhz-wx-sat-v-dipole-antenna.html" rel="noopener noreferrer" target="_blank">Here&#8217;s a great article on design</a> or you can just buy <a href="https://www.rtl-sdr.com/product/rtl-sdr-blog-multipurpose-dipole-antenna-kit/" rel="noopener noreferrer" target="_blank">this dipole kit</a>, also from the RTL-SDR.COM blog.</li>
<li>coaxial cable to go from your antenna to Raspberry Pi + RTL-SDR dongle. The dipole antenna kit comes with 3m of RG174 coax, but I used 10 feet of RG58 coax.</li>
</ul>
<p>This is a very long article with lots of steps, so take your time &#8212; I won&#8217;t be able to help everyone debug all their issues. I won&#8217;t go into the details of using a Raspberry Pi for the first time &#8212; this project assumes you know your way around the Pi and are comfortable with installing software on it. If you have never used AWS before, I suggest you set up an account and get familiar with what S3 is.</p>
<p></p>
<h4>Weather Satellites and RTL-SDR</h4>
<p>This probably isn&#8217;t the first you&#8217;ve read about using a software defined radio (SDR) to receive weather satellite images. This type of project has been documented before. Sometimes the emphasis is on software defined radio hardware and techniques, sometimes it&#8217;s about antenna design, or maybe the article is written by a real weather enthusiast who always use the abbreviation &#8220;wx&#8221; for weather. I&#8217;m not an expert in any of these areas, but the idea of receiving images directly from weather satellites as they fly overhead has intrigued me for many years. This has all gotten a lot easier with RTL-SDR dongles, more powerful Raspberry Pi computers and simpler antenna designs that get the job done. I gave this project a try recently using <a href="https://www.instructables.com/id/Raspberry-Pi-NOAA-Weather-Satellite-Receiver/" rel="noopener noreferrer" target="_blank">this well-written Instructables</a> article, a totally hacked-together antenna I made, and a very old rtl-sdr dongle:</p>
<p><a href="https://nootropicdesign.com/projectlab/wp-content/uploads/2019/11/first_wx_antenna.jpg"><img loading="lazy" decoding="async" src="https://nootropicdesign.com/projectlab/wp-content/uploads/2019/11/first_wx_antenna-1024x656.jpg" alt="" width="1024" height="656" class="alignleft size-large wp-image-2471" srcset="https://nootropicdesign.com/projectlab/wp-content/uploads/2019/11/first_wx_antenna-1024x656.jpg 1024w, https://nootropicdesign.com/projectlab/wp-content/uploads/2019/11/first_wx_antenna-980x628.jpg 980w, https://nootropicdesign.com/projectlab/wp-content/uploads/2019/11/first_wx_antenna-480x308.jpg 480w" sizes="auto, (min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) and (max-width: 980px) 980px, (min-width: 981px) 1024px, 100vw" /></a><br />
<br clear="all"/></p>
<p>and on my <em>very first attempt</em>, I decoded this image from NOAA19 as it passed over my area:</p>
<p><a href="https://nootropicdesign.com/projectlab/wp-content/uploads/2019/11/first_NOAA_image.png"><img loading="lazy" decoding="async" src="https://nootropicdesign.com/projectlab/wp-content/uploads/2019/11/first_NOAA_image-1024x510.png" alt="" width="1024" height="510" class="alignleft size-large wp-image-2470" srcset="https://nootropicdesign.com/projectlab/wp-content/uploads/2019/11/first_NOAA_image-1024x510.png 1024w, https://nootropicdesign.com/projectlab/wp-content/uploads/2019/11/first_NOAA_image-980x488.png 980w, https://nootropicdesign.com/projectlab/wp-content/uploads/2019/11/first_NOAA_image-480x239.png 480w" sizes="auto, (min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) and (max-width: 980px) 980px, (min-width: 981px) 1024px, 100vw" /></a><br />
<br clear="all"/></p>
<p>From that moment, I was hooked. I played around with different antennas and such, but found it tedious to always copy the images from my outdoor Raspberry Pi to my computer so I could look at them. I resolved to automate the uploading of images to an S3 bucket and to improve upon the scripts from the Instructables article. This is the overall solution:</p>
<p><a href="https://nootropicdesign.com/projectlab/wp-content/uploads/2019/11/wx-ground-station-architecture.png"><img loading="lazy" decoding="async" src="https://nootropicdesign.com/projectlab/wp-content/uploads/2019/11/wx-ground-station-architecture-1024x617.png" alt="" width="1024" height="617" class="alignleft size-large wp-image-2532" srcset="https://nootropicdesign.com/projectlab/wp-content/uploads/2019/11/wx-ground-station-architecture-1024x617.png 1024w, https://nootropicdesign.com/projectlab/wp-content/uploads/2019/11/wx-ground-station-architecture-980x590.png 980w, https://nootropicdesign.com/projectlab/wp-content/uploads/2019/11/wx-ground-station-architecture-480x289.png 480w" sizes="auto, (min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) and (max-width: 980px) 980px, (min-width: 981px) 1024px, 100vw" /></a><br />
<br clear="all"/></p>
<p></p>
<h3>Amazon AWS Setup</h3>
<p>Your ground station website functionality will be completely in client-side JavaScript. It will use the AWS JavaScript SDK to make API calls to S3. The scripts that run on the Raspberry Pi also use some Node.js scripts to upload to S3. There are a lot of steps to get everything set up:</p>
<p></p>
<h4>AWS SDK Credentials</h4>
<p>The scripts that run on the Raspberry Pi use some Node.js scripts and the AWS JavaScript SDK to upload to S3. You need to get your credentials. These two articles show you how to get your credentials and store them for Node.js access:<br />
<a href="https://docs.aws.amazon.com/en_pv/sdk-for-javascript/v2/developer-guide/getting-your-credentials.html" rel="noopener noreferrer" target="_blank">Getting your credentials</a><br />
<a href="https://docs.aws.amazon.com/en_pv/sdk-for-javascript/v2/developer-guide/loading-node-credentials-shared.html" rel="noopener noreferrer" target="_blank">Loading Credentials in Node.js from the Shared Credentials File</a></p>
<p>Your credentials file on the Raspberry Pi <span class="code">~/.aws/credentials</span> will look like this:</p>
<pre class="codeblock">
[default]
aws_access_key_id = YOUR_ACCESS_KEY_ID
aws_secret_access_key = YOUR_SECRET_ACCESS_KEY
</pre>
<p>Also set the default region where your S3 bucket will reside in <span class="code">~/.aws/config</span>. For example:</p>
<pre class="codeblock">
[default]
output = json
region = us-west-2
</pre>
<p></p>
<h4>Create an S3 Bucket</h4>
<p>Now create an S3 bucket for public website hosting. I&#8217;m using the bucket name <span class="code">nootropicdesign.wx</span> for mine. The instructions are in this article:<br />
<a href="https://docs.aws.amazon.com/en_pv/AmazonS3/latest/dev/HostingWebsiteOnS3Setup.html" rel="noopener noreferrer" target="_blank">Setting up a Static Website</a></p>
<p>At this point you should be able to load a simple web site from your new bucket. You might want to upload a simple <span class="code">index.html</span> file and try to load it in your browser with <span class="code">http://BUCKETNAME.s3-website-REGION.amazonaws.com/</span>.</p>
<pre class="codeblock">
&lt;!doctype html&gt;
&lt;html&gt;
  &lt;head&gt;&lt;title&gt;S3 test&lt;/title&gt;&lt;/head&gt;
  &lt;body&gt;Hello from S3&lt;/body&gt;
&lt;/html&gt;
</pre>
<p></p>
<h4>Create an Identity Pool in Cognito</h4>
<p>To give public users the ability to access your S3 bucket using the AWS SDK, you need to set up an identity pool and create a policy allowing them read access to your bucket. This is done using Amazon Cognito. A good guide for granting public access to your bucket is <a href="https://docs.aws.amazon.com/en_pv/sdk-for-javascript/v2/developer-guide/s3-example-photos-view.html" rel="noopener noreferrer" target="_blank">described in this article that shows how to serve images from an S3 bucket</a> (just like we are). It&#8217;s somewhat confusing to follow the steps, so take your time.</p>
<p>Step 1: <a href="https://docs.aws.amazon.com/en_pv/sdk-for-javascript/v2/developer-guide/getting-started-browser#getting-started-browser-create-identity-pool" rel="noopener noreferrer" target="_blank">create an Amazon Cognito identity pool</a> called &#8220;<span class="code">wx image users</span>&#8221; and enable access to unauthenticated identities. Be sure to select the region in the upper right of the page that matches the region where your S3 bucket was created! Make note of the role name for unauthorized users, e.g. &#8220;<span class="code">Cognito_wximageusersUnauth_Role</span>&#8220;.</p>
<p>Step 2: on the Sample Code page, select JavaScript from the Platform list. Save this code somewhere, because we need to add it to the web content later. It looks something like this:</p>
<pre class="codeblock">
// Initialize the Amazon Cognito credentials provider
AWS.config.region = 'us-west-2'; // Region
AWS.config.credentials = new AWS.CognitoIdentityCredentials({
  IdentityPoolId: 'us-west-2:1d02ae39-3a06-497e-b63c-799a070dd09d',
});
</pre>
<p>Step 3: Add a Policy to the Created IAM Role. In <a href="https://console.aws.amazon.com/iam/" rel="noopener noreferrer" target="_blank">IAM console</a>, choose <span class="code">Policies</span>. Click <span class="code">Create Policy</span>, then click the JSON tab and add this, substituting BUCKET_NAME with your bucket name.</p>
<pre class="codeblock">
{
   "Version": "2012-10-17",
   "Statement": [
      {
         "Effect": "Allow",
         "Action": [
            "s3:ListBucket"
         ],
         "Resource": [
            "arn:aws:s3:::BUCKET_NAME"
         ]
      }
   ]
}
</pre>
<p>Click <span class="code">Review policy</span> and give your policy a name, like <span class="code">wxImagePolicy</span>.</p>
<p>In IAM console, click <span class="code">Roles</span>, then choose the unauthenticated user role previously created when the identity pool was created (e.g. <span class="code">Cognito_wximageusersUnauth_Role</span>). Click <span class="code">Attach Policies</span>. From the <span class="code">Filter policies</span> menu, select <span class="code">Customer managed</span>. This will show the policy you created above. Select it and click <span class="code">Attach policy</span>. </p>
<p>Step 4. Set CORS configuration on the S3 bucket. In the S3 console for your bucket, select <span class="code">Permissions</span>, then <span class="code">CORS configuration</span>.</p>
<pre class="codeblock">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;CORSConfiguration xmlns=&quot;http://s3.amazonaws.com/doc/2006-03-01/&quot;&gt;
    &lt;CORSRule&gt;
        &lt;AllowedOrigin&gt;*&lt;/AllowedOrigin&gt;
        &lt;AllowedMethod&gt;GET&lt;/AllowedMethod&gt;
        &lt;AllowedMethod&gt;HEAD&lt;/AllowedMethod&gt;
        &lt;AllowedHeader&gt;*&lt;/AllowedHeader&gt;
    &lt;/CORSRule&gt;
&lt;/CORSConfiguration&gt;
</pre>
<p></p>
<h3>Raspberry Pi Setup</h3>
<p>Most of these instructions are from steps are from steps 2 and 3 of the <a href="https://www.instructables.com/id/Raspberry-Pi-NOAA-Weather-Satellite-Receiver/" rel="noopener noreferrer" target="_blank">Instructables</a> article I mentioned earlier.</p>
<p></p>
<h4>Install Required Packages</h4>
<p>First, make sure your Raspberry Pi is up to date:</p>
<pre class="codeblock">
sudo apt-get update
sudo apt-get upgrade
sudo reboot
</pre>
<p>Then install a set of of required packages. </p>
<pre class="codeblock">
sudo apt-get install libusb-1.0
sudo apt-get install cmake
sudo apt-get install sox
sudo apt-get install at
sudo apt-get install predict
</pre>
<p>I used Node.js in some of the scripting, so if you don&#8217;t have <span class="code">node</span> and <span class="code">npm</span> installed, you&#8217;ll need to do that. In depth details <a href="https://github.com/nodesource/distributions/#deb" rel="noopener noreferrer" target="_blank">are here</a>, and I easily installed with:</p>
<pre class="codeblock">
curl -sL https://deb.nodesource.com/setup_10.x | sudo -E bash -
sudo apt-get install -y nodejs
</pre>
<p>Using your favorite editor as root (e.g. <span class="code">sudo vi</span>), create a file <span class="code">/etc/modprobe.d/no-rtl.conf</span> and add these contents:</p>
<pre class="codeblock">
blacklist dvb_usb_rtl28xxu
blacklist rtl2832
blacklist rtl2830
</pre>
<p></p>
<h4>Build rtl-sdr</h4>
<p>Even if you have rtl-sdr already built and installed, it&#8217;s important to use the version in the GitHub repo <a href="https://github.com/keenerd/rtl-sdr" rel="noopener noreferrer" target="_blank">keenerd/rtl-sdr</a>, as this version&#8217;s <span class="code">rtl_fm</span> command can create the WAV file header needed to decode the data with <span class="code">sox</span>.</p>
<pre class="codeblock">
cd ~
git clone https://github.com/keenerd/rtl-sdr.git
cd rtl-sdr/
mkdir build
cd build
cmake ../ -DINSTALL_UDEV_RULES=ON
make
sudo make install
sudo ldconfig
cd ~
sudo cp ./rtl-sdr/rtl-sdr.rules /etc/udev/rules.d/
sudo reboot
</pre>
<p></p>
<h4>Install and Configure wxtoimg</h4>
<p>The program <span class="code">wxtoimg</span> is what does the heavy lifting in this project. It decodes the audio files received by the RTL-SDR receiver and converts the data to images. The original author of wxtoimg has abandoned the project, but it is mirrored at <a href="https://wxtoimgrestored.xyz/" rel="noopener noreferrer" target="_blank"><span class="code">wxtoimgrestored.xyz</span></a>.</p>
<pre class="codeblock">
wget https://wxtoimgrestored.xyz/beta/wxtoimg-armhf-2.11.2-beta.deb
sudo dpkg -i wxtoimg-armhf-2.11.2-beta.deb
</pre>
<p>Now run <span class="code">wxtoimg</span> once to accept the license agreement.</p>
<pre class="codeblock">
wxtoimg
</pre>
<p>Create a file <span class="code">~/.wxtoimgrc</span> with the location of your base station. As usual, negative latitude is southern hemisphere, and negative longitude is western hemisphere. Here&#8217;s my location in Minnesota, USA.</p>
<pre class="codeblock">
Latitude: 45.0468
Longitude: -93.4747
Altitude: 315
</pre>
<p>The program <span class="code">predict</span> is used by the automated scripts to predict weather satellite orbits. Run <span class="code">predict</span> to bring up the main menu:</p>
<pre class="codeblock">
                                      
                           --== PREDICT  v2.2.3 ==--         
                     Released by John A. Magliacane, KD2BD   
                                    May 2006                 
                                                             


                            --==[ Main Menu ]==--


 [P]: Predict Satellite Passes          [I]: Program Information
 [V]: Predict Visible Passes            [G]: Edit Ground Station Information
 [S]: Solar Illumination Predictions    [D]: Display Satellite Orbital Data
 [L]: Lunar Predictions                 [U]: Update Sat Elements From File
 [O]: Solar Predictions                 [E]: Manually Edit Orbital Elements
 [T]: Single Satellite Tracking Mode    [B]: Edit Transponder Database
 [M]: Multi-Satellite Tracking Mode     [Q]: Exit PREDICT
</pre>
<p>Select option &#8216;G&#8217; from the menu to set your ground station location:</p>
<pre class="codeblock">

                *  Ground Station Location Editing Utility  *



                        Station Callsign  : KD0WUV
                        Station Latitude  : 45.0468 [DegN]
                        Station Longitude : 93.4747 [DegW]
                        Station Altitude  : 315 [m]



            Enter the callsign or identifier of your ground station
</pre>
<p>You can enter whatever you want for the callsign (I used my amateur radio callsign). When entering the longitude, note that positive numbers are for the western hemisphere and negative numbers are for the eastern hemisphere. This is opposite convention, so make sure you get this right or you&#8217;ll be listening when there&#8217;s no satellite overhead!</p>
<p></p>
<h4>Get the Automation Scripts and Configure</h4>
<p>I&#8217;ve completely refactored the scripts originally posted in the Instructables article and added Node.js scripts for creating thumbnail images and uploading all images to S3. The git repo can be cloned anywhere on your Raspberry Pi. The <span class="code">configure.sh</span> script sets the installation directory in the scripts and schedules a cron job to run the satellite pass scheduler job at midnight every night.</p>
<pre class="codeblock">
git clone https://github.com/nootropicdesign/wx-ground-station.git
cd wx-ground-station
sh configure.sh
cd aws-s3
npm install
</pre>
<p>In the file <span class="code">aws-s3/upload-wx-images.js</span> set REGION, BUCKET, and LOCATION to the correct values. This Node.js script prepares the images for upload by creating thumbnail images, printing some metadata on the images, and creating a JSON metadata file for each image capture. The LOCATION string will be printed on the images that you capture. Here are my values just for reference.</p>
<pre class="codeblock">
var REGION = "us-west-2";
var BUCKET = "nootropicdesign.wx";
var LOCATION = "nootropic design ground station, Plymouth, Minnesota, USA  45.0468, -93.4747";
</pre>
<p>Also set the REGION and BUCKET correctly in the files <span class="code">aws-s3/upload-upcoming-passes.js</span> and <span class="code">aws-s3/remove-wx-images.js</span>. Plug in your own values:</p>
<pre class="codeblock">
var REGION = "us-west-2";
var BUCKET = "nootropicdesign.wx";
</pre>
<p>Now we need to make some changes to the web content. The web interface uses <a href="https://mapbox.com" rel="noopener noreferrer" target="_blank">Mapbox</a> to draw the live maps of the next upcoming satellite pass. You&#8217;ll need to <a href="https://account.mapbox.com/auth/signup/" rel="noopener noreferrer" target="_blank">create an account at Mapbox</a> to get an access token. Their free tier lets you load 50,000 maps/month, so you are not likely to have any real costs. When logged into Mapbox, get your account token from <a href="https://account.mapbox.com" rel="noopener noreferrer" target="_blank">https://account.mapbox.com/</a>.</p>
<p>Now in the file <span class="code">website/wx-ground-station.js</span>, set your bucket name, AWS region, AWS credentials (the Cognito identity pool info you saved above), Mapbox token, and your ground station info. Some of my values are shown here for reference.</p>
<pre class="codeblock">
var bucketName = 'nootropicdesign.wx';
AWS.config.region = 'us-west-2'; // Region
AWS.config.credentials = new AWS.CognitoIdentityCredentials({
    IdentityPoolId: 'us-west-2:1d02ae39-30a6-497e-b066-795f070de089'
});

// Create a mapbox.com account and get access token
const MAP_BOX_ACCESS_TOKEN = 'YOUR_MAPBOX_TOKEN';
const GROUND_STATION_LAT =  45.0468;
const GROUND_STATION_LON = -93.4747;
const GROUND_STATION_NAME = 'my ground station';
</pre>
<p></p>
<h4>Upload the Web Content to S3</h4>
<p>Upload the the contents of the <span class="code">website</span> directory to your S3 bucket using the S3 console. Since you probably edited the files on your Raspberry Pi, you might need to copy them to your computer where you are accessing AWS using a browser. Whatever the case, these files need to be uploaded to the top level of your bucket. IMPORTANT: be sure to grant public access to the files when you upload them!</p>
<pre class="codeblock">
index.html
wx-ground-station.js
tle.js
logo.png
</pre>
<p>Of course, you can replace <span class="code">logo.png</span> with your own, or just remove the <span class="code">&lt;img&gt;</span> tag from <span class="code">index.html</span>.</p>
<p></p>
<h4>Test Everything Out</h4>
<p>Now that everything is configured, let&#8217;s run the scheduling script to schedule recording of upcoming satellite passes. This way you can have a look today instead of waiting until they get scheduled at midnight. This step will also upload a JSON file with the upcoming passes info to your website.</p>
<pre class="codeblock">
cd wx-ground-station
./schedule_all.sh
</pre>
<p>You can now visit your AWS S3 website endpoint at </p>
<pre class="codeblock">
http://BUCKETNAME.s3-website-REGION.amazonaws.com/
</pre>
<p>Once again, mine is here: <a href="http://nootropicdesign.wx.s3-website-us-west-2.amazonaws.com/" rel="noopener noreferrer" target="_blank">http://nootropicdesign.wx.s3-website-us-west-2.amazonaws.com/</a></p>
<p>Even though you don&#8217;t have any images captured, you should be able to see the next upcoming pass. The next thing to do is make sure the scripts work correctly to record the audio file, process it into images, and upload to your bucket. You can watch the logs in the <span class="code">wx-ground-station/logs</span> to debug any errors. </p>
<p>The <span class="code">wxtoimg</span> enhancements that are displayed depends on what sensors were active when the images were captured. If sensors 3 and 4 were active (usually at night), then the thermal enhancement will be shown. Otherwise a multispectral analysis enhancement will be shown.</p>
<p>Not all images you capture will be good. I feel lucky if even half of my satellite passes produce recognizable images. You can clean up bad ones by using the script <span class="code">aws-s3/remove-wx-images</span> on the Raspberry Pi. Just provide the key to the particular capture as an argument to remove all the images and the metadata from the S3 bucket.</p>
<pre class="codeblock">
node aws-s3/remove-wx-images NOAA19-20191108-162650
</pre>
<p>Hopefully in the next few hours you&#8217;ll be able to see some images uploaded, depending on when satellites are scheduled to fly over. You may get up to 12 passes per day, usually 2 for each of the NOAA satellites in the morning, then 2 more for each of them in the evening. Let us know if this project worked for you!</p>
<p></p>
<h3>Fine Tuning</h3>
<p>The script <span class="code">receive_and_process_satellite.sh</span> uses the <span class="code">rtl_fm</span> command to read the signal from the RTL-SDR receiver. The <span class="code">-p</span> argument sets the PPM error correction. I have mine set to 0, but you may want to adjust. See <a href="https://davidnelson.me/?p=371" rel="noopener noreferrer" target="_blank">this article for details</a>.</p>
<p>I have also installed a low noise amplifier (LNA) to improve my reception (results are mixed). My LNA can be powered with a bias tee circuit and controlled with the <span class="code">rtl_biast</span> command. If you are using an LNA like this, you can install rtl_biast <a href="https://www.rtl-sdr.com/rtl-sdr-blog-v-3-dongles-user-guide/" rel="noopener noreferrer" target="_blank">as documented here</a> and uncomment the <span class="code">rtl_biast</span> lines in <span class="code">receive_and_process_satellite.sh</span> which turn the LNA on and off.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://nootropicdesign.com/projectlab/2019/11/08/weather-satellite-ground-station/feed/</wfw:commentRss>
			<slash:comments>86</slash:comments>
		
		
			</item>
		<item>
		<title>Iridium Satellite Communication with Arduino</title>
		<link>https://nootropicdesign.com/projectlab/2019/09/21/arduino-satellite-communication/</link>
					<comments>https://nootropicdesign.com/projectlab/2019/09/21/arduino-satellite-communication/#comments</comments>
		
		<dc:creator><![CDATA[Michael]]></dc:creator>
		<pubDate>Sat, 21 Sep 2019 20:19:39 +0000</pubDate>
				<category><![CDATA[Arduino]]></category>
		<category><![CDATA[GPS]]></category>
		<category><![CDATA[IoT]]></category>
		<category><![CDATA[Satellite]]></category>
		<guid isPermaLink="false">https://nootropicdesign.com/projectlab/?p=2396</guid>

					<description><![CDATA[Note: Rock7 Communications is now Ground Control When deploying a microcontroller-based IoT solution or just doing experiments gathering data in the field, you often need a way to get the data back to your home base or to the cloud somehow. You&#8217;ve probably used WiFi, maybe dabbled with cellular solutions, but what about satellite communication? [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>Note: Rock7 Communications is now <a href="https://www.groundcontrol.com" rel="noopener noreferrer" target="_blank">Ground Control</a></p>
<p>When deploying a microcontroller-based IoT solution or just doing experiments gathering data in the field, you often need a way to get the data back to your home base or to the cloud somehow. You&#8217;ve probably used WiFi, maybe dabbled with cellular solutions, but what about satellite communication? Sometimes satellite is the only option if you are in a remote area. Transmitting data via satellite has been possible for quite some time using a satellite modem like the <a href="https://www.groundcontrol.com/us/product/rockblock-9603-compact-plug-and-play-satellite-transmitter/" rel="noopener noreferrer" target="_blank">RockBLOCK 9603 from Ground Control (previously Rock Seven Communications)</a>. I recently used this technology to build a solution for a customer, and it was SO FUN I wanted to write up something about it because there&#8217;s not very much info out there.</p>
<p>Here is the basic architecture of the solution. Data is transmitted to one of the 66 Iridium satellites and then downlinked to Rock Seven where it will then be sent over the Internet to your server via HTTP or even email. I&#8217;m using a <a href="https://nodered.org/" rel="noopener noreferrer" target="_blank">Node-RED</a> server as the destination endpoint.</p>
<p><a href="https://nootropicdesign.com/projectlab/wp-content/uploads/2019/09/Iridium_architecture.png"><img loading="lazy" decoding="async" src="https://nootropicdesign.com/projectlab/wp-content/uploads/2019/09/Iridium_architecture.png" alt="" width="921" height="505" class="alignleft size-full wp-image-2444" srcset="https://nootropicdesign.com/projectlab/wp-content/uploads/2019/09/Iridium_architecture.png 921w, https://nootropicdesign.com/projectlab/wp-content/uploads/2019/09/Iridium_architecture-480x263.png 480w" sizes="auto, (min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) 921px, 100vw" /></a><br />
<br clear="all"/></p>
<p><iframe loading="lazy" title="Iridium Satellite Communication for Arduino" width="1080" height="608" src="https://www.youtube.com/embed/saBkM5mh7Lw?feature=oembed"  allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe><br />
<br clear="all"/><br />
One barrier is cost: the <a href="https://www.sparkfun.com/products/14498" rel="noopener noreferrer" target="_blank">RockBLOCK 9603 costs $250</a>, you&#8217;ll pay a monthly fee to keep the modem activated, and each message costs money. I&#8217;ll give more details on cost later, but if you have a mission critical system that needs to be monitored or controlled in a remote area, it can be easy to justify the costs. From a development perspective, the good news is that there is an <a href="https://github.com/mikalhart/IridiumSBD" rel="noopener noreferrer" target="_blank">excellent Arduino library called IridiumSBD</a> that makes it very easy to send Iridium short burst data messages (<a href="http://arduiniana.org/libraries/iridiumsbd/" rel="noopener noreferrer" target="_blank">full documentation here</a>). You will also want to keep in mind that messages need to be short (few hundred bytes at most) and that sending a message can take several minutes. We&#8217;re not streaming video with this stuff.<br />
<br clear="all"/></p>
<h3>Hardware</h3>
<p>After I learned this technology, I decided to make a simple development board to make it easier to deal with the wiring and make it more portable. The RockBLOCK modem has a 10-pin Molex &#8220;PicoBlade&#8221; connector (Molex part number 15134-1001), but it was fairly easy to solder to the board. I used a SAMD21 microcontroller (the <a href="https://www.sparkfun.com/products/13664" rel="noopener noreferrer" target="_blank">SparkFun SAMD21 mini breakout board</a> is a great choice) because it is more powerful than a simple Arduino Uno and it has more hardware serial interfaces. I need one serial interface for a GPS module and one for the satellite modem. You might want one for serial communication to some other device, too! It&#8217;s good to have lots of hardware serial interfaces. I have grown tired of using software serial, as it can introduce problems and I don&#8217;t have time for that.</p>
<p><a href="https://nootropicdesign.com/projectlab/wp-content/uploads/2019/09/IridiumExperimenter.jpg"><img loading="lazy" decoding="async" src="https://nootropicdesign.com/projectlab/wp-content/uploads/2019/09/IridiumExperimenter-1024x693.jpg" alt="" width="1024" height="693" class="alignleft size-large wp-image-2409" srcset="https://nootropicdesign.com/projectlab/wp-content/uploads/2019/09/IridiumExperimenter-1024x693.jpg 1024w, https://nootropicdesign.com/projectlab/wp-content/uploads/2019/09/IridiumExperimenter-980x663.jpg 980w, https://nootropicdesign.com/projectlab/wp-content/uploads/2019/09/IridiumExperimenter-480x325.jpg 480w" sizes="auto, (min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) and (max-width: 980px) 980px, (min-width: 981px) 1024px, 100vw" /></a><br />
<br clear="all"/></p>
<p>The board also has an <a href="https://www.adafruit.com/product/746" rel="noopener noreferrer" target="_blank">Adafruit GPS breakout board</a> for plug-n-play GPS. I just put female headers on the board so I can redeploy the SAMD21 and GPS boards in other solutions someday. I also added an SSD1306 OLED display for output and a few LEDs with 220 ohm resistors, along with some buttons and a 10K pot for input. These are just generic parts. The Eagle design files are in the <a href="https://github.com/nootropicdesign/iridium-satellite-comm" rel="noopener noreferrer" target="_blank">project GitHub repository</a>.<br />
<br clear="all"/></p>
<h3>Rock Seven Account</h3>
<p>To use the modem, it has to be registered with Rock Seven Communications. You have to pay a monthly line rental fee to keep it active on the network, and you have to buy credits that are used up as you send messages. Rock Seven is a British company, so all the prices are in GBP. Line rental <a href="https://www.xe.com/currencyconverter/convert/?Amount=12&#038;From=GBP&#038;To=USD" rel="noopener noreferrer" target="_blank">costs £12 per month (click for conversion to U.S. dollars)</a>, and 100 credits <a href="https://www.xe.com/currencyconverter/convert/?Amount=13&#038;From=GBP&#038;To=USD" rel="noopener noreferrer" target="_blank">costs £13</a>. It costs one credit for every 50 bytes in a message. A message sent from a modem can be up to 340 bytes, and that would cost you 7 credits. As a system designer, I was highly motivated to keep my messages under 50 bytes!</p>
<p>You also use your Rock Seven account to tell Rock Seven what to do with the messages when they get them from the Iridium constellation. This is called a &#8220;delivery group&#8221;. I&#8217;m having Rock Seven do an HTTP POST to my Node-RED server. Note that there doesn&#8217;t seem to be any security; I can&#8217;t specify a username and password for my server, so &#8220;security by obscurity&#8221; is the simple approach. That&#8217;s why I&#8217;m not showing you my AWS server name in this image. All the info you need about the <a href="https://docs.rockblock.rock7.com/docs/integration-with-application" rel="noopener noreferrer" target="_blank">integration between Rock Seven and your application can be found here</a>.</p>
<p><a href="https://nootropicdesign.com/projectlab/wp-content/uploads/2019/09/RockSevenDeliveryGroup.png"><img loading="lazy" decoding="async" src="https://nootropicdesign.com/projectlab/wp-content/uploads/2019/09/RockSevenDeliveryGroup.png" alt="" width="830" height="205" class="alignleft size-full wp-image-2426" srcset="https://nootropicdesign.com/projectlab/wp-content/uploads/2019/09/RockSevenDeliveryGroup.png 830w, https://nootropicdesign.com/projectlab/wp-content/uploads/2019/09/RockSevenDeliveryGroup-480x119.png 480w" sizes="auto, (min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) 830px, 100vw" /></a><br />
<br clear="all"/><br />
<br clear="all"/></p>
<h3>Communication Experiments</h3>
<p>For my experimentation I use an external antenna but the default configuration is to use a built-in patch antenna which works fine. You will need a clear view of the sky &#8212; satellite communication typically won&#8217;t work indoors (although I have successfully sent messages from indoors very near a window). For power, I&#8217;m using a portable 5V supply.</p>
<p><a href="https://nootropicdesign.com/projectlab/wp-content/uploads/2019/09/outdoor_setup.jpg"><img loading="lazy" decoding="async" src="https://nootropicdesign.com/projectlab/wp-content/uploads/2019/09/outdoor_setup-1024x503.jpg" alt="" width="1024" height="503" class="alignleft size-large wp-image-2412" srcset="https://nootropicdesign.com/projectlab/wp-content/uploads/2019/09/outdoor_setup-1024x503.jpg 1024w, https://nootropicdesign.com/projectlab/wp-content/uploads/2019/09/outdoor_setup-980x481.jpg 980w, https://nootropicdesign.com/projectlab/wp-content/uploads/2019/09/outdoor_setup-480x236.jpg 480w" sizes="auto, (min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) and (max-width: 980px) 980px, (min-width: 981px) 1024px, 100vw" /></a><br />
<br clear="all"/></p>
<p>My Arduino program just lets you input a number from 1-100 using a potentiometer to show how data can be transmitted. I&#8217;m also transmitting the GPS coordinates and the time of the sensor reading. Keep in mind that sending a message can take several minutes. The IridiumSBD library can call a callback function you specify so you can do things during the long transmission time, like control an LED and print output. Once you tell the library to send a message, it will keep trying to contact an Iridium satellite, as it may take a while for one of the 66 satellites to fly over your area. The default timeout in the library is 5 minutes. If my program fails to send the message in 5 minutes, the red LED comes on. If successful, the green LED is lit.</p>
<p><a href="https://nootropicdesign.com/projectlab/wp-content/uploads/2019/09/success.jpg"><img loading="lazy" decoding="async" src="https://nootropicdesign.com/projectlab/wp-content/uploads/2019/09/success-1024x692.jpg" alt="" width="1024" height="692" class="alignleft size-large wp-image-2418" srcset="https://nootropicdesign.com/projectlab/wp-content/uploads/2019/09/success-1024x692.jpg 1024w, https://nootropicdesign.com/projectlab/wp-content/uploads/2019/09/success-980x662.jpg 980w, https://nootropicdesign.com/projectlab/wp-content/uploads/2019/09/success-480x324.jpg 480w" sizes="auto, (min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) and (max-width: 980px) 980px, (min-width: 981px) 1024px, 100vw" /></a><br />
<br clear="all"/></p>
<p>The payload of my message to the satellite is 16 bytes: 6 bytes for the timestamp (year, month, day, hour, minute, second), 4 bytes each for latitude and longitude, and two bytes for the data value. The Rock Seven management console lets you see the messages received by Rock Seven and forwarded to your destination server. The payload is sent as hexadecimal, so my 16 byte message is actually sent as 32 HEX characters to my server.</p>
<p><a href="https://nootropicdesign.com/projectlab/wp-content/uploads/2019/09/RockSeven.png"><img loading="lazy" decoding="async" src="https://nootropicdesign.com/projectlab/wp-content/uploads/2019/09/RockSeven-1024x430.png" alt="" width="1024" height="430" class="alignleft size-large wp-image-2413" srcset="https://nootropicdesign.com/projectlab/wp-content/uploads/2019/09/RockSeven-980x411.png 980w, https://nootropicdesign.com/projectlab/wp-content/uploads/2019/09/RockSeven-480x201.png 480w" sizes="auto, (min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) and (max-width: 980px) 980px, (min-width: 981px) 1024px, 100vw" /></a><br />
<br clear="all"/><br />
<br clear="all"/></p>
<h3>Processing Messages</h3>
<p>After receiving the data over the Internet from Rock Seven, you can do whatever you want with it. I am processing the messages with a Node-RED server and displaying the received value on a web dashboard.</p>
<p><a href="https://nootropicdesign.com/projectlab/wp-content/uploads/2019/09/Iridium_dashboard_data.png"><img loading="lazy" decoding="async" src="https://nootropicdesign.com/projectlab/wp-content/uploads/2019/09/Iridium_dashboard_data.png" alt="" width="869" height="382" class="alignleft size-full wp-image-2437" srcset="https://nootropicdesign.com/projectlab/wp-content/uploads/2019/09/Iridium_dashboard_data.png 869w, https://nootropicdesign.com/projectlab/wp-content/uploads/2019/09/Iridium_dashboard_data-480x211.png 480w" sizes="auto, (min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) 869px, 100vw" /></a><br />
<br clear="all"/></p>
<p>Along with the payload, Rock Seven delivers metadata, including the time at which the satellite received the message. I compare this to the time that the microncrontroller started sending the message so we know how long the process really took. In this case, it took 3 minutes and 48 seconds to successfully transmit to a satellite. The data also provides an <em>approximate</em> GPS location where it thinks your modem is. This is the <a href="https://en.wikipedia.org/wiki/Circular_error_probable" rel="noopener noreferrer" target="_blank">CEP</a> parameter in the metadata. This can be off by several kilometers, so if you are interested in actual location, you will need to use a real GPS module, like I am.</p>
<p><a href="https://nootropicdesign.com/projectlab/wp-content/uploads/2019/09/Node-RED_flow.png"><img loading="lazy" decoding="async" src="https://nootropicdesign.com/projectlab/wp-content/uploads/2019/09/Node-RED_flow-1024x587.png" alt="" width="1024" height="587" class="alignleft size-large wp-image-2395" srcset="https://nootropicdesign.com/projectlab/wp-content/uploads/2019/09/Node-RED_flow-1024x587.png 1024w, https://nootropicdesign.com/projectlab/wp-content/uploads/2019/09/Node-RED_flow-980x562.png 980w, https://nootropicdesign.com/projectlab/wp-content/uploads/2019/09/Node-RED_flow-480x275.png 480w" sizes="auto, (min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) and (max-width: 980px) 980px, (min-width: 981px) 1024px, 100vw" /></a><br />
<br clear="all"/></p>
<p>Here is the JavaScript code in the function node &#8220;parse data&#8221;. The decoded data is passed along to the dashboard display widgets.</p>
<pre class="codeblockscroll">
var data = msg.payload.data;

var p = 0;
var year = parseInt(data.substr(p,2), 16);
p += 2;
var month = parseInt(data.substr(p,2), 16);
p += 2;
var day = parseInt(data.substr(p,2), 16);
p += 2;
var hour = parseInt(data.substr(p,2), 16);
p += 2;
var minute = parseInt(data.substr(p,2), 16);
p += 2;
var second = parseInt(data.substr(p,2), 16);
p += 2;

var latString = data.substr(p,8);
var lat = parseInt(latString, 16);
// can be negative, so check for sign bit
if (lat & 0x80000000) {
    lat = lat - 0x100000000;
}
lat = lat / 10000000.0;
p += 8;

var lonString = data.substr(p,8);
var lon = parseInt(lonString, 16);
// can be negative, so check for sign bit
if (lon & 0x80000000) {
    lon = lon - 0x100000000;
}
lon = lon / 10000000.0;
p += 8;


var valueString = data.substr(p,4);
var value = parseInt(valueString, 16);


// time that the message was created and ready to send
var msgTime = new Date(year+2000, month-1, day, hour, minute, second);
msg.payload.message_time = msgTime;

// time that the message was actually successfully transmitted to satellite
var txTime =  new Date("20" + msg.payload.transmit_time);
msg.payload.transmit_time = txTime;

var txMilliseconds = txTime.getTime() - msgTime.getTime();

var txMinutes = Math.floor(txMilliseconds / 60000);
var txSeconds = (txMilliseconds % 60000) / 1000;
var txTimeString = txMinutes + ":" + txSeconds;
msg.payload.txTime_ms = txMilliseconds;
msg.payload.txTime = txTimeString;

msg.payload.decoded_data = {
   year: year,
   month: month,
   day: day,
   hour: hour,
   minute: minute,
   second: second,
   lat: lat,
   lon: lon,
   value: value
}
return msg;
</pre>
<p><br clear="all"/></p>
<h3>Resources</h3>
<p><a href="https://github.com/nootropicdesign/iridium-satellite-comm" rel="noopener noreferrer" target="_blank">GitHub repo with the code used in this project and the board design files</a></p>
<p><a href="https://docs.rockblock.rock7.com/docs" rel="noopener noreferrer" target="_blank">RockBLOCK 9603 modem documentation</a></p>
<p><a href="https://github.com/mikalhart/IridiumSBD" rel="noopener noreferrer" target="_blank">GitHub repo for IridiumSBD library</a></p>
<p><a href="http://arduiniana.org/libraries/iridiumsbd/" rel="noopener noreferrer" target="_blank">Detailed documentation for IridiumSBD library</a></p>
<h3>Going Further</h3>
<p>There are some things I haven&#8217;t tried yet. A satellite modem can actually receive messages from your server via Rock Seven. I also think it is important to design a security solution. A shared secret between the modem and Internet application may be sufficient, but deploying secrets to IoT devices has its own complexity. I could send a security token to the modem securely because sending a message to a modem requires Rock Seven credentials. The modem could then present the security token in each message, and the endpoint processor could require it. I think this would be reasonably secure, but the security token would take up valuable bytes in each message.</p>
<h3>Summary</h3>
<p>Using a Rock Seven Iridium modem is a lot of fun and it can be an important part of an IoT solution when you don&#8217;t have other connectivity options. It&#8217;s not cheap, you need a clear view of the sky, and it can take several minutes to send a short message. But if you can design a solution within those constraints like I have, it&#8217;s completely viable. And special thanks to Mikal Hart for writing the awesome Iridium SBD library!</p>
]]></content:encoded>
					
					<wfw:commentRss>https://nootropicdesign.com/projectlab/2019/09/21/arduino-satellite-communication/feed/</wfw:commentRss>
			<slash:comments>25</slash:comments>
		
		
			</item>
		<item>
		<title>Arduino Audio Hacker Realtime Voice Changer</title>
		<link>https://nootropicdesign.com/projectlab/2019/09/07/arduino-realtime-voice-changer/</link>
					<comments>https://nootropicdesign.com/projectlab/2019/09/07/arduino-realtime-voice-changer/#comments</comments>
		
		<dc:creator><![CDATA[Michael]]></dc:creator>
		<pubDate>Sat, 07 Sep 2019 16:56:47 +0000</pubDate>
				<category><![CDATA[Arduino]]></category>
		<category><![CDATA[Audio]]></category>
		<guid isPermaLink="false">https://nootropicdesign.com/projectlab/?p=2390</guid>

					<description><![CDATA[Here&#8217;s another fun but simple project using the Audio Hacker shield for Arduino. This is a realtime voice changer, which is an improvement upon the original voice changer example I provided with the Audio Hacker library. This project uses a technique called granular synthesis to change the pitch of the input. Granular synthesis is rather complex, [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>Here&#8217;s another fun but simple project using the <a href="https://nootropicdesign.com/audio-hacker/" target="_blank" rel="noopener noreferrer">Audio Hacker shield for Arduino.</a> This is a realtime voice changer, which is an improvement upon the <a href="https://nootropicdesign.com/projectlab/2013/07/05/voice-changer/">original voice changer example</a> I provided with the <a href="https://github.com/nootropicdesign/audio-hacker">Audio Hacker library</a>.</p>
<p><iframe loading="lazy" title="Arduino Realtime Voice Changer" width="1080" height="608" src="https://www.youtube.com/embed/fy28FCZDGVk?feature=oembed" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe></p>
<p>This project uses a technique called <a href="http://en.wikipedia.org/wiki/Granular_synthesis" target="_blank" rel="noopener noreferrer">granular synthesis</a> to change the pitch of the input. Granular synthesis is rather complex, but it involves dividing the sample up into small fragments called “grains”. When playing back a sample, if we want the pitch higher, we play the grain at a higher speed, but we play it over and over again until it takes the same amount of time as the grain played at original speed. Likewise, to lower pitch, we play each grain at a slower speed, but move onto the next grain sooner so that the overall sample has the same duration.</p>
<p>This realtime voice changer only lowers pitch. Raising pitch would require a lag to record something and play snippits of it faster. Lowering the pitch is accomplished by recording the input and then simultaneously playing it slower. That is, the &#8220;play head&#8221; moves slower than the &#8220;record head&#8221;. Occasionally, the play head needs to skip ahead over some of the input and catch up to the record head. This way, the playback takes the same amount of time as the recording, making it seem realtime. It is realtime, we are just playing only part of what was input (slowly) and skipping the rest so that the overall time is the same.</p>
<p>The example is in the Audio Hacker Library examples folder so you can load it into the Arduino IDE with</p>
<pre>File-&gt;Examples-&gt;Audio Hacker-&gt;RealtimeVoiceChanger</pre>
<p>As always, get the Audio Hacker library from GitHub: <a href="https://github.com/nootropicdesign/audio-hacker">https://github.com/nootropicdesign/audio-hacker</a></p>
]]></content:encoded>
					
					<wfw:commentRss>https://nootropicdesign.com/projectlab/2019/09/07/arduino-realtime-voice-changer/feed/</wfw:commentRss>
			<slash:comments>39</slash:comments>
		
		
			</item>
		<item>
		<title>Arduino Audio Hacker Realtime Reverser</title>
		<link>https://nootropicdesign.com/projectlab/2019/09/07/audio-hacker-realtime-reverser/</link>
					<comments>https://nootropicdesign.com/projectlab/2019/09/07/audio-hacker-realtime-reverser/#respond</comments>
		
		<dc:creator><![CDATA[Michael]]></dc:creator>
		<pubDate>Sat, 07 Sep 2019 14:31:50 +0000</pubDate>
				<category><![CDATA[Arduino]]></category>
		<category><![CDATA[Audio]]></category>
		<category><![CDATA[Video]]></category>
		<guid isPermaLink="false">https://nootropicdesign.com/projectlab/?p=2382</guid>

					<description><![CDATA[Here&#8217;s a fun project using the Audio Hacker shield for Arduino &#8211; a realtime audio reverser! This program records the audio input to the Audio Hacker&#8217;s memory but plays it back in reverse. The &#8220;play head&#8221; jumps ahead a bit, then plays recorded audio backwards, then jumps ahead to the next snippet, plays it backward, [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>Here&#8217;s a fun project using the <a href="https://nootropicdesign.com/audio-hacker/" target="_blank" rel="noopener noreferrer">Audio Hacker shield for Arduino</a> &#8211; a realtime audio reverser! This program records the audio input to the Audio Hacker&#8217;s memory but plays it back in reverse. The &#8220;play head&#8221; jumps ahead a bit, then plays recorded audio backwards, then jumps ahead to the next snippet, plays it backward, and so on. There is a bit of lag between the input signal and reversed output, but this is unavoidable: we have to record something before playing it backward. There&#8217;s no way to play something backward in perfect realtime. This audio snippets are about a half-second long, so the lag is pretty small.</p>
<p>It&#8217;s great to hook up to a TV signal and just reverse all the audio. Using this effect, spoken English sounds like Russian to me!</p>
<p><iframe loading="lazy" title="Arduino Audio Hacker Realtime Reverser" width="1080" height="608" src="https://www.youtube.com/embed/3cQ1ZIUgE8E?feature=oembed" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe></p>
<p>&nbsp;</p>
<p>The example is in the Audio Hacker Library examples folder so you can load it into the Arduino IDE with</p>
<pre>File-&gt;Examples-&gt;Audio Hacker-&gt;RealtimeReverser</pre>
<p>As always, get the Audio Hacker library from GitHub: <a href="https://github.com/nootropicdesign/audio-hacker">https://github.com/nootropicdesign/audio-hacker</a></p>
<p>&nbsp;</p>
]]></content:encoded>
					
					<wfw:commentRss>https://nootropicdesign.com/projectlab/2019/09/07/audio-hacker-realtime-reverser/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Arduino Shield for CAT M1 and NB-IoT Modems</title>
		<link>https://nootropicdesign.com/projectlab/2019/04/21/arduino-shield-for-cat-m1-and-nb-iot-modems/</link>
					<comments>https://nootropicdesign.com/projectlab/2019/04/21/arduino-shield-for-cat-m1-and-nb-iot-modems/#comments</comments>
		
		<dc:creator><![CDATA[Michael]]></dc:creator>
		<pubDate>Sun, 21 Apr 2019 16:15:05 +0000</pubDate>
				<category><![CDATA[Cellular]]></category>
		<category><![CDATA[IoT]]></category>
		<guid isPermaLink="false">https://nootropicdesign.com/projectlab/?p=2057</guid>

					<description><![CDATA[LTE CAT M1 (sometimes called LTE-M) and NB-IoT are both exciting new cellular technologies targeting IoT applications. While there are many modems being built with this new technology, there are not many choices for hobbyists. There are a few Arduino shields and breakout boards based on the SIMCOM SIM7000 modem, and a few with u-blox [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>LTE CAT M1 (sometimes called LTE-M) and NB-IoT are both exciting new cellular technologies targeting IoT applications. While there are many modems being built with this new technology, there are not many choices for hobbyists. There are a few Arduino shields and breakout boards based on the SIMCOM SIM7000 modem, and a few with u-blox SARA modems.</p>
<p><a href="https://nimbelink.com/embedded-modems/" rel="noopener noreferrer" target="_blank">Nimbelink</a> is a cellular technology provider that takes the unique approach of offering a variety of different modems as interchangeable modules. No matter what the actual cellular modem is, the 20-pin Nimbelink Skywire modules with the familiar &#8220;XBEE&#8221; footprint all have the same pinout and electrical characteristics. The interchangeable nature of these modem modules allows product designers to future-proof their products, allowing new modules to be plugged in later. Another huge benefit is that the Nimbelink modules are already certified on their respective cellular networks (Verizon, AT&#038;T, etc.) so you don&#8217;t have to. </p>
<p>Nimbelink has a development kit for use by product developers, but it&#8217;s rather expensive. I wanted to try out a Nimbelink CAT M1 modem without the dev kit, and since there are so many hobbyists using Arduinos out there, I wanted to provide a nice Arduino library for the modem. I chose the Nimbelink module based on the Sequans Monarch CAT M1 modem and got to work designing an Arduino shield to hold it.</p>
<p><div id="attachment_2060" style="width: 1034px" class="wp-caption alignleft"><a href="https://nootropicdesign.com/projectlab/wp-content/uploads/2019/04/SkywireShield1.jpg"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-2060" src="https://nootropicdesign.com/projectlab/wp-content/uploads/2019/04/SkywireShield1-1024x768.jpg" alt="" width="1024" height="768" class="size-large wp-image-2060" srcset="https://nootropicdesign.com/projectlab/wp-content/uploads/2019/04/SkywireShield1-1024x768.jpg 1024w, https://nootropicdesign.com/projectlab/wp-content/uploads/2019/04/SkywireShield1-300x225.jpg 300w, https://nootropicdesign.com/projectlab/wp-content/uploads/2019/04/SkywireShield1-768x576.jpg 768w, https://nootropicdesign.com/projectlab/wp-content/uploads/2019/04/SkywireShield1.jpg 2000w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a><p id="caption-attachment-2060" class="wp-caption-text">Skywire Shield with Nimbelink Skywire module with Sequans Monarch CAT M1 modem</p></div><br />
<br clear="all"/></p>
<h3>Hardware Design</h3>
<p>The shield is quite simple, and really just provides an appropriate switch-mode power supply for the modem. The input power for the shield can be 5-12V, and provides a stable 3.8V at up to 1.7A to the modem. I used a <a href="http://www.ti.com/product/TPS5402" rel="noopener noreferrer" target="_blank">TI TPS5402</a> for this. Jumper settings allow you to connect the modem&#8217;s UART to the Arduino hardware UART on pins 0 and 1 or to software serial on digital pins 2 and 3. I typically use software serial at 19200 so that I can use the Arduino serial interface for debugging. The buttons labeled &#8220;Func 1&#8221; and &#8220;Func 2&#8221; are connected to digital pins 4 and 5.</p>
<h3>Software Interface</h3>
<p>What about actually using the modem in software? Every modem has its own AT command set, and although there are similarities, a developer must know the details of the modem they are using. Luckily, the excellent <a href="https://github.com/vshymanskyy/TinyGSM">TinyGSM</a> Arduino library provides an <a href="https://www.arduino.cc/en/Reference/ClientConstructor">Arduino Client interface</a> for a variety of underlying modems. The Arduino Client interface is widely used by networking libraries to abstract away the underlying hardware. That is, when you code to the Client API, it doesn&#8217;t matter if the hardware underneath is an Ethernet shield, an ESP8266, a cellular modem, or whatever. Examples of libraries that code to this interface and therefore work with many kinds of hardware are <a href="https://github.com/arduino-libraries/ArduinoHttpClient" rel="noopener noreferrer" target="_blank">ArduinoHttpClient</a> for web clients and <a href="https://github.com/knolleary/pubsubclient" rel="noopener noreferrer" target="_blank">PubSubClient</a> for MQTT clients. Even HTTPS and MQTT over TLS work! Security is important.</p>
<p>TinyGSM did not have an implementation for the Sequans modem, so I wrote one. It&#8217;s in <a href="https://github.com/nootropicdesign/TinyGSM" rel="noopener noreferrer" target="_blank">my forked repo of TinyGSM</a> (it has not been merged into the parent yet). To use the TinyGSM examples with the Nimbelink module with a Sequans modem, simply add this to your source code:</p>
<pre class="codeblock">
#define TINY_GSM_MODEM_SEQUANS_MONARCH
</pre>
<p>I also bought a Nimbelink module with the Quectel BG96 CAT M1 and NB-IoT modem on it. Luckily, TinyGSM already has an Client interface implementation for this modem. After plugging it into my shield and simply changing my HTTP and MQTT test clients to use this modem, everything just worked! That is, I was able to change the modem to a different manufacturer (and completely different AT command set) and make my code work with a one line change: </p>
<pre class="codeblock">
#define TINY_GSM_MODEM_BG96
</pre>
<p><div id="attachment_2061" style="width: 650px" class="wp-caption alignleft"><a href="https://nootropicdesign.com/projectlab/wp-content/uploads/2019/04/SkywireShield2.jpg"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-2061" src="https://nootropicdesign.com/projectlab/wp-content/uploads/2019/04/SkywireShield2-sm.jpg" alt="" width="640" height="480" class="size-full wp-image-2061" srcset="https://nootropicdesign.com/projectlab/wp-content/uploads/2019/04/SkywireShield2-sm.jpg 640w, https://nootropicdesign.com/projectlab/wp-content/uploads/2019/04/SkywireShield2-sm-300x225.jpg 300w" sizes="auto, (max-width: 640px) 100vw, 640px" /></a><p id="caption-attachment-2061" class="wp-caption-text">Skywire Shield with Nimbelink Skywire module with Quectel BG96 CAT M1/NB-IoT modem</p></div><br />
</a><br clear="all"/></p>
<p>So the lesson here is that with thoughtful design of software and hardware abstractions, one can achieve a lot of flexibility. </p>
<ul>
<li>the Arduino Client interface defines a standard software API for network clients so that an implementation for any hardware can be written and expose its functions through this same interface</li>
<li>useful libraries like ArduinoHttpClient and PubSubClient code to this interface so that HTTP and MQTT are easily used with lots of hardware</li>
<li>and finally, Nimbelink has defined a standard Skywire module pinout so that it&#8217;s easy to swap out the hardware
</ul>
<p>This is all getting pretty easy, right?! I hope you agree.</p>
<p>I haven&#8217;t decided if I&#8217;ll make this shield available as a product because there has to be some real demand for that to be worth it. <a href="https://nootropicdesign.com/store/contact-us/" rel="noopener noreferrer" target="_blank">Let me know if you are interested</a> in an easy way to get started with modern cellular technology using Nimbelink modules.</p>
<p>Schematic and board design files at GitHub: <a href="https://github.com/nootropicdesign/skywire-cat-m1-modem-shield" rel="noopener noreferrer" target="_blank">skywire-cat-m1-modem-shield</a><br />
Arduino library for controlling the Sequans Monarch and Quectel BG96 modems: <a href="https://github.com/nootropicdesign/TinyGSM" rel="noopener noreferrer" target="_blank">TinyGSM</a></p>
]]></content:encoded>
					
					<wfw:commentRss>https://nootropicdesign.com/projectlab/2019/04/21/arduino-shield-for-cat-m1-and-nb-iot-modems/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
	</channel>
</rss>
