<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Particle</title>
    <description>The latest articles on Forem by Particle (@particle).</description>
    <link>https://forem.com/particle</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Forganization%2Fprofile_image%2F533%2Faded66c5-c446-4cfb-95fa-c58d49f3c2d0.png</url>
      <title>Forem: Particle</title>
      <link>https://forem.com/particle</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/particle"/>
    <language>en</language>
    <item>
      <title>Learn about mesh networking by building this swarm of Particle-powered robots</title>
      <dc:creator>Brandon Satrom</dc:creator>
      <pubDate>Mon, 08 Jul 2019 20:32:15 +0000</pubDate>
      <link>https://forem.com/particle/learn-about-mesh-networking-by-building-this-swarm-of-particle-powered-robots-4c2j</link>
      <guid>https://forem.com/particle/learn-about-mesh-networking-by-building-this-swarm-of-particle-powered-robots-4c2j</guid>
      <description>&lt;p&gt;Hacking a toy is a fun form of electronics exploration. It’s a great way learn how real-world products are designed and built, and tinker without worrying about rendering expensive electronics useless in the pursuit of knowledge. Inexpensive consumer electronics are a fantastic platform for learning, exploration, and even building new, innovative solutions.&lt;/p&gt;

&lt;p&gt;Remote-controlled (RC) vehicles are a common target for makers, and cars with the “Thunder Tumbler” name provide a cheap, accessible platform for RC car hacking. The Tumbler has been hacked a number of times before, but I don’t think it’s ever been used in a mesh network. That is, until now. Using a couple of Tumblers that you can find online or in stores like CVS, and a few of Particle’s new, mesh-ready hardware, I created a swarmbot network of Tumblers that move in synchronized fashion at my every command!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; This post originally appeared in &lt;em&gt;Make: Magazine, volume 68&lt;/em&gt; and online &lt;a href="https://makezine.com/projects/diy-swarmbots/"&gt;here&lt;/a&gt;. It is reprinted here with the author’s permission. |&lt;/p&gt;

&lt;h2&gt;
  
  
  Materials needed
&lt;/h2&gt;

&lt;p&gt;For this project, you’ll need the following items:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;(2-3) “Thunder Tumbler” RC Cars, available at many chain drug stores or online — here in the states both &lt;a href="https://www.walgreens.com/store/c/thunder-tumbler-radio-control-360-degree-rally-car/ID=prod6090850-product"&gt;Walgreens&lt;/a&gt; and &lt;a href="https://www.cvs.com/shop/blue-hat-thunder-tumbler-radio-control-rally-car-prodid-458767"&gt;CVS&lt;/a&gt; carry these cars. Note there are multiple versions of this product, but I’ll cover how you can handle these subtle variations.&lt;/li&gt;
&lt;li&gt;(1) &lt;a href="https://store.particle.io/products/argon-kit"&gt;Particle Argon&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;(3) &lt;a href="https://store.particle.io/products/xenon-kit"&gt;Particle Xenons&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;(3) breadboards — included with the Argon and Xenon kits&lt;/li&gt;
&lt;li&gt;Assorted jumper wires for connecting each Xenon to the RC Car’s PCB&lt;/li&gt;
&lt;li&gt;A multimeter for inspecting IC pin functions (as the pinout may vary from one cheap RC car to the next)&lt;/li&gt;
&lt;li&gt;Soldering iron and solder&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How does mesh networking work?
&lt;/h2&gt;

&lt;p&gt;Most connected solutions tend to rely on Wi-Fi or cellular for connectivity. This typically means that each connected device maintains a direct connection to the Internet. While this is useful for connecting to the cloud for data storage or processing, some connected solutions need to be able to operate on a local network, with other devices, regardless of whether a connection to the Internet exists.&lt;/p&gt;

&lt;p&gt;Mesh networking solutions enable these scenarios by allowing developers to create local networks of connected devices. The bulk of the network consists of endpoints that sense or actuate, and repeaters that help increase the size and reliability of the mesh by passing messages between devices. In addition, a small number of devices — often just one — serve as gateways to maintain a connection to the Internet. Critically, these local networks of devices can still communicate with one another when the connection to the network disappears. The &lt;a href="https://store.particle.io/"&gt;Argon, Boron, and Xenon&lt;/a&gt; — all 3rd generation Particle devices — provide built-in mesh-networking capabilities.&lt;/p&gt;

&lt;p&gt;For this build, I used mesh to create a network of RC cars, each controlled by a Particle Xenon. All of the Xenon RC cars are endpoints, and are connected to a mesh network with a single Particle Argon as the gateway. Once the network is established, I can use local network messaging to send low-latency commands to nodes on the network and make my RC cars dance.&lt;/p&gt;

&lt;p&gt;First, however, I needed to hack the off-the-shelf Tumblers to Particle-power them!&lt;/p&gt;

&lt;h2&gt;
  
  
  Hacking the Thunder Tumbler
&lt;/h2&gt;

&lt;p&gt;The first step of this process is hacking the RC car to add a Xenon. Regardless of the brand or style of RC car you’re using, the objective is to crack open the car to reveal the PCB inside, determine how the device sends commands to the motors to rotate the wheels, and connect pins from the Xenon to the corresponding motor driver pins on the car. Because these cars are inexpensive, you should expect to find some variation, even among those with the “Thunder Tumbler” name on the box.&lt;/p&gt;

&lt;p&gt;Write-ups on Tumbler hacking can be found online going back over 9 years. That’s a lifetime in the electronics world, so be sure to test and verify the functionality of your own cars as you follow-along with the instructions below.&lt;/p&gt;

&lt;p&gt;I suggest grabbing your favorite multi-meter and measuring voltages across various pins on the RC car PCB as you make the wheels spin with the remote control. Make sure to set your car somewhere where the wheels can rotate freely so that it doesn’t get away from you during testing.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--i_Z_K0Ls--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.particle.io/wp-content/uploads/2019/07/tumbler-with-mm.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--i_Z_K0Ls--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.particle.io/wp-content/uploads/2019/07/tumbler-with-mm.jpg" alt="Image of an R/C car and my multimeter."&gt;&lt;/a&gt;R/C Tumbler with my trusty multimeter. Since these cars are inexpensive, a multimeter comes in handy to reverse engineer the IC pinouts.&lt;/p&gt;

&lt;p&gt;Remove the two screws that hold the shell of the tumbler in place. Once these are out, you can lift the shell to expose the tumbler PCB. Inside, you should see 8-10 wires that run from the the car to the PCB, and a number of through-hole and surface-mount components.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--I1696ocP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.particle.io/wp-content/uploads/2019/07/Hbridge-hacking.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--I1696ocP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.particle.io/wp-content/uploads/2019/07/Hbridge-hacking.jpg" alt="Close up image of the H-bridge motor controller from the Tumbler. Using my multimeter, I was able to determine what pins control the motor."&gt;&lt;/a&gt;The Tumbler uses a classic motor controller designed known as an H-bridge driver. By testing the pads with my multimeter, I was able to reverse engineer what combination drives the car forward and backward, plus left and right steering. Note that some Tumblers use a different pinout than mine, so you’ll want to have a meter nearby to test your car.&lt;/p&gt;

&lt;h2&gt;
  
  
  Understanding the various onboard ICs
&lt;/h2&gt;

&lt;p&gt;The small surface-mount component on the top is a remote-controller receiver chip, the RX-2B. Its pair, the TX-2B transceiver chip sits in the remote control that ships with these cars. These ICs are commonly used for RC vehicles, and I was able to find their data sheets online to determine which pins map to forward, backward, left and right commands from the remote. I also used the data sheet to establish a known ground pin, which is needed to determine which pins power the car motors and can be controlled by a Xenon.&lt;/p&gt;

&lt;p&gt;This ended up being critical because the main IC on these boards, through-hole mounted on the bottom of the car PCB, is one for which I couldn’t find a data sheet, in spite of many hours of searching. While I’m still not 100% certain of all the features on this chip, it functions primarily as an H-Bridge motor controller. Pulsing a signal into a certain pin on the IC results in a pulse out to one of the motor control pins, which makes a wheel spin forward or backwards.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--atNMGv1t--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.particle.io/wp-content/uploads/2019/07/Hbridge-hacking-2.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--atNMGv1t--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.particle.io/wp-content/uploads/2019/07/Hbridge-hacking-2.jpg" alt="Image of inserting the motor controller back into the Tumbler chassis."&gt;&lt;/a&gt;Inserting the motor controller back into the Tumbler chassis.&lt;/p&gt;

&lt;p&gt;By reverse-engineering, I was able to find that there are four pins I care about on this unknown IC: one that spins the left wheel forward, one that spins it back; one that spins the right wheel forward, and one that spins the right wheel back. I soldered one wire to the top of each of these pins, and one to a ground pin. Even though the Xenon and car are powered separately, they need to share a ground signal for everything to work, as needed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting up a mesh network
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--bhYxJyyT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.particle.io/wp-content/uploads/2019/07/Fig-E-2.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--bhYxJyyT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.particle.io/wp-content/uploads/2019/07/Fig-E-2.jpg" alt="Image of three screen shots from the mobile set up of a Particle Mesh network."&gt;&lt;/a&gt;Setting up a Particle Mesh network is a quick process with the Particle mobile app.&lt;/p&gt;

&lt;p&gt;Because this project requires a mesh network, you’ll want to set one up with one gateway (a Particle Argon or Boron) and one Xenon-based node for each RC car. If you want to program each Xenon over-the-air without having to connect each to a computer, you’ll want to set up your network in advance. You can do this from the Particle mobile app, or follow the instructions &lt;a href="http://Particle.io/start"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5YBlP4lb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.particle.io/wp-content/uploads/2019/07/Fig-E-1.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5YBlP4lb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.particle.io/wp-content/uploads/2019/07/Fig-E-1.jpg" alt="Three images from the Particle mobile app. Each shows a different stage in the mesh network setup."&gt;&lt;/a&gt;This image shows mobile flow you will go through when setting up a new Particle Mesh device.&lt;/p&gt;

&lt;h2&gt;
  
  
  Programming the tumblers
&lt;/h2&gt;

&lt;p&gt;Once you have your first Xenon claimed and ready, the next step is to write firmware for controlling the actions of each car. Since the goal is to create a small mesh of swarmbots, you’re going to create a simple sequence that moves the car forward, back, left and right. The code for this sequence can be found below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Wheel pin mappings
int leftReverse = A0;
int leftForward = A1;
int rightForward = A2;
int rightReverse = A3;

// Speed and delay variables
int speed = 85;
int turnSpeed = 255;
int forwardDelay = 1000;
int backDelay = 1000;
int turnDelay = 2000;

void setup()
{
  // Set motor pins to outputs
  pinMode(leftReverse, OUTPUT);
  pinMode(leftForward, OUTPUT);
  pinMode(rightForward, OUTPUT);
  pinMode(rightReverse, OUTPUT);

  // Make sure each motor is off
  digitalWrite(leftReverse, LOW);
  digitalWrite(leftForward, LOW);
  digitalWrite(rightForward, LOW);
  digitalWrite(rightReverse, LOW);
}

void runDemo(const char *event, const char *data)
{
  allOff();

  goForward(speed);
  delay(forwardDelay);

  goBack(speed);
  delay(backDelay);

  // Max spin to raise up on the back tires
  turnLeft(turnSpeed);
  delay(turnDelay);

  allOff();
}

void allOff()
{
  analogWrite(leftReverse, 0);
  analogWrite(leftForward, 0);
  analogWrite(rightForward, 0);
  analogWrite(rightReverse, 0);

  delay(50);
}

void goForward(int speed)
{
  allOff();

  analogWrite(rightForward, speed);
  analogWrite(leftForward, speed);
}

void goBack(int speed)
{
  allOff();

  analogWrite(rightReverse, speed);
  analogWrite(leftReverse, speed);
}

void turnLeft(int speed)
{
  allOff();

  analogWrite(rightForward, speed);
}

void turnRight(int speed)
{
  allOff();

  analogWrite(leftForward, speed);
}

void loop()
{
  // Nothing needed here. 
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;You probably noticed that the meat of the demo is &lt;code&gt;analogWrite&lt;/code&gt; commands to turn each wheel forward or backward by sending a voltage to a corresponding pin. Through testing, I determined that the cars I’m using are PWM-able, meaning that I can set a wheel pin to lower than digital HIGH (3.3 volts in the case of the Xenon) and have the wheel turn at lower speeds. Notice that I’m passing in different values for turning right or left vs forward and back. PWM enables pretty complex patterns and speeds for these inexpensive cars.&lt;/p&gt;

&lt;p&gt;With the demo code done, the final piece you need on your RC cars is a subscription to a local network message that specifies the &lt;code&gt;runDemo&lt;/code&gt; function as the handler. Particle enables local, in-mesh-network messaging between nodes on a network using a &lt;code&gt;Mesh.publish&lt;/code&gt; and &lt;code&gt;Mesh.subscribe&lt;/code&gt; API. &lt;code&gt;Mesh.publish&lt;/code&gt; sends a broadcast message (with a name and payload) to all nodes on the network. &lt;code&gt;Mesh.subscribe&lt;/code&gt;, on the other hand, listens for messages (by name) and specifies a handler to process and respond to those incoming messages.&lt;/p&gt;

&lt;p&gt;Our Xenons will use &lt;code&gt;Mesh.subscribe&lt;/code&gt; to listen for a network message, and then trigger the demo sequence.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Add to setup functionMesh.subscribe("run-demo", runDemo);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Flash the completed code to each RC car Xenon and you’re ready for the final piece: programming the gateway to coordinate the movements of the car swarm.&lt;/p&gt;

&lt;h2&gt;
  
  
  Programming the mesh gateway
&lt;/h2&gt;

&lt;p&gt;The mesh gateway is less complex than the code that runs on each Xenon, but still needs two pieces for the purposes of our demo:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;a &lt;code&gt;Mesh.publish&lt;/code&gt; call to trigger the RC car demo sequence and&lt;/li&gt;
&lt;li&gt;a way to tell the controller to fire the message to the mesh network.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;We could skip the second step by just firing the message when the gateway comes online, or regularly on a delay, but what fun would that be? Instead, we can use another Particle API Particle.function, to allow us to trigger the cars from a mobile phone.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;void setup() {
  Particle.function("runDemo", runDemo);
}

int runDemo (String command)
{
  Mesh.publish("run-demo", NULL);

  return 1;
}

void loop() {
  // Nothing needed here
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;code&gt;Particle.function&lt;/code&gt; takes a string value name of the function (used when calling that function from a mobile or web app or through the cloud) and a handler function to execute when called. That function contains our &lt;code&gt;Mesh.publish&lt;/code&gt; call, which sends a broadcast message with the name “run-demo” to all listeners (i.e. our RC cars) on the network. Once you’ve added the code above to your gateway, you’re ready to control some swarmbots!&lt;/p&gt;

&lt;h2&gt;
  
  
  Putting it all together
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--GOpG6tsV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.particle.io/wp-content/uploads/2019/07/runDemoConsole.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--GOpG6tsV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.particle.io/wp-content/uploads/2019/07/runDemoConsole.jpg" alt="Screenshot of the Particle Console."&gt;&lt;/a&gt;Once you’ve built your RC cars and have them configured in a mesh network, you’ll be able to control them from the Particle Console.&lt;/p&gt;

&lt;p&gt;Particle functions can be called from any device that has a secure connection to the &lt;a href="https://www.particle.io/device-cloud"&gt;Particle Device Cloud&lt;/a&gt;, which could be the &lt;a href="https://console.particle.io/devices"&gt;Particle Console&lt;/a&gt;, the CLI, or even your own applications. They can also be called from the Particle mobile app, which seems like a fitting place to finish this project. The Particle mobile app shows a listing of every Particle device you own. Click on your gateway, then the “Data” tab menu, and you should see a “runDemo” function. Put your Xenons in position with plenty of space, and click the function to trigger some RC swarming!&lt;/p&gt;

&lt;p&gt;The demo code above illustrated a simple, coordinated sequence of actions. But with PWM and a bit of trial and error, there are a number of cool synchronized dances you can create with mesh-networked RC cars.&lt;/p&gt;

&lt;h2&gt;
  
  
  Command your swarm!
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--xqxhDuQ3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.particle.io/wp-content/uploads/2019/07/RCdanceoff.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xqxhDuQ3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.particle.io/wp-content/uploads/2019/07/RCdanceoff.jpg" alt="Three RC Tumblers on their back wheels. The image highlights the coordinated control you'll have thanks to the mesh network."&gt;&lt;/a&gt;With the project complete, it’s time for an RC Tumbler dance party!&lt;/p&gt;

&lt;p&gt;Now that your bots are meshed, let’s turn them into real swarmbots that can communicate with each other. A common swarm scenario is the leader-follower pattern. The leader determines movements for the swarm, and communicates these directly to all followers. One example would be to control the leader with the out-of-box remote control, read pin voltages off the leader car, and send these as instructions to all followers listening for a Mesh event.&lt;/p&gt;

&lt;p&gt;To build this demo, I designated one of my three cars as a leader, and added firmware to control the fleet. Instead of writing to my motor pins, the leader simply reads the analog values sent by the remote control and sends these to listeners on the network with a &lt;code&gt;Mesh.publish&lt;/code&gt; that includes the wheel, direction and analog value to apply to follower cars.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;int32_t lastLeftRVal = 0;
int32_t lastLeftFVal = 0;
int32_t lastRightRVal = 0;
int32_t lastRightFVal = 0;

#define MIN_PIN_VAL 150
#define DRIVE_VAL 200

void setup()
{
  pinMode(leftReverse, INPUT);
  pinMode(leftForward, INPUT);
  pinMode(rightForward, INPUT);
  pinMode(rightReverse, INPUT);
}

void loop()
{
  checkPin(leftReverse, &amp;amp;lastLeftRVal, "leftR");
  checkPin(leftForward, &amp;amp;lastLeftFVal, "leftF");
  checkPin(rightReverse, &amp;amp;lastRightRVal, "rightR");
  checkPin(rightForward, &amp;amp;lastRightFVal, "rightF");
}

void checkPin(int pin, int32_t *lastVal, const char *event)
{
  int32_t pinVal = analogRead(pin) / 16;

  if (pinVal &amp;gt; MIN_PIN_VAL)
    pinVal = DRIVE_VAL;
  else
    pinVal = 0;

  if (pinVal != *lastVal &amp;amp;&amp;amp; pinVal == DRIVE_VAL)

    *lastVal = pinVal;

    Mesh.publish(event, String(DRIVE_VAL));
  } else if (pinVal == 0 &amp;amp;&amp;amp; *lastVal != 0) {
    *lastVal = 0;

    Mesh.publish(event, String(0));

}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Code for the follower robots
&lt;/h2&gt;

&lt;p&gt;On the follower side, I added firmware that listens for a Mesh event for each pin, and performs an &lt;code&gt;analogWrite&lt;/code&gt; with the passed-in value. On the cars themselves, I also removed the antenna on each board and cut the traces from the remote RX IC just to make sure that movement commands were only coming from the leader.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;void setup()
{
  pinMode(leftReverse, OUTPUT);
  pinMode(leftForward, OUTPUT);
  pinMode(rightForward, OUTPUT);
  pinMode(rightReverse, OUTPUT);

  digitalWrite(leftReverse, LOW);
  digitalWrite(leftForward, LOW);
  digitalWrite(rightForward, LOW);
  digitalWrite(rightReverse, LOW);

  Mesh.subscribe("leftR", leftR);
  Mesh.subscribe("leftF", leftF);
  Mesh.subscribe("rightR", rightR);
  Mesh.subscribe("rightF", rightF);
}

void leftR(const char *event, const char *data)
{
  move(leftReverse, data);
}

void leftF(const char *event, const char *data)
{
  move(leftForward, data);
}

void rightR(const char *event, const char *data)
{
  move(rightReverse, data);
}

void rightF(const char *event, const char *data)
{
  move(rightForward, data);
}

void move(int pin, const char *speed)
{
  int32_t speedVal = atoi(speed);

  if (speedVal &amp;gt; 16) // Filter out noise from the leader
  {
    analogWrite(pin, speedVal);
  }
  else
  {
    analogWrite(pin, 0);
  }
}

void loop() {} 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;With this simple R/C-controlled swarm as our foundation, we built a bunch more swarm sequences:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Follow the leader — basic forward and back demo with ending spin️&lt;/li&gt;
&lt;li&gt;Splinter — cars separate in three different directions and come back together&lt;/li&gt;
&lt;li&gt;Follow the leader and push — leader tells followers to stop, goes forward 2 seconds, turns around, goes back 2 seconds, then tells followers to move backward as it keeps moving forward&lt;/li&gt;
&lt;li&gt;Sentry mode — square path with right-angle turns&lt;/li&gt;
&lt;li&gt;Orbit — followers orbit a stationary leader.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can grab the complete project source code, including these more complex demos, from the repository on &lt;a href="https://github.com/particle-iot/mesh-rc-carsgithub.com/particle-iot/mesh-rc-cars"&gt;Gihub&lt;/a&gt;. I’ve also done a number of Twitch streams focused on building the demos for this project; check them out on my &lt;a href="https://www.twitch.tv/brandonsatrom"&gt;Twitch channel&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Hack It and Share It
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--nHxNAgi---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.particle.io/wp-content/uploads/2019/07/RChero.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--nHxNAgi---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.particle.io/wp-content/uploads/2019/07/RChero.jpg" alt=""&gt;&lt;/a&gt;Ready to rule the world with my new RC Tumbler swarm robots.&lt;/p&gt;

&lt;p&gt;We’d love to see makers extend and modify this project with sensors and new behaviors. You could add collision detection to the leader with a PIR or ultrasonic sensor, or even use the remote to log predefined sequences that could then be repeated automatically. And if you’ve built your own mesh-style swarmbot project, or anything else with Particle’s new hardware, we’d love to hear from you! Share with us on &lt;a href="https://twitter.com/particle"&gt;Twitter&lt;/a&gt;, &lt;a href="https://www.instagram.com/particle_iot/"&gt;Instagram&lt;/a&gt;, or in &lt;a href="https://community.particle.io/"&gt;our community of 160,000 developers&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Swarm on, makers!&lt;/p&gt;

&lt;p&gt;The post &lt;a href="https://blog.particle.io/2019/07/08/mesh-networking-swarm-robots/"&gt;Learn about mesh networking by building this swarm of Particle-powered robots&lt;/a&gt; appeared first on &lt;a href="https://blog.particle.io"&gt;Particle Blog&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>tutorial</category>
      <category>showdev</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Build this Wi-Fi thermometer for your workshop using a Gen 3 Argon and a Grove Starter Kit</title>
      <dc:creator>Jordy Moors</dc:creator>
      <pubDate>Fri, 14 Jun 2019 13:00:30 +0000</pubDate>
      <link>https://forem.com/particle/build-this-wi-fi-thermometer-for-your-workshop-using-a-gen-3-argon-and-a-grove-starter-kit-2nfl</link>
      <guid>https://forem.com/particle/build-this-wi-fi-thermometer-for-your-workshop-using-a-gen-3-argon-and-a-grove-starter-kit-2nfl</guid>
      <description>&lt;p&gt;In this tutorial, you’ll make a simple Wi-Fi thermometer using the &lt;a href="https://store.particle.io/products/argon-kit"&gt;Particle Argon&lt;/a&gt; and the &lt;a href="https://store.particle.io/products/grove-starter-kit"&gt;Grove Starter Kit for Particle Mesh&lt;/a&gt;. The goal is to measure the current temperature, display that value on a display, and an RGB LED to give a visual warning if the temperature crosses a predefined threshold. Thanks to the ease of use of the Grove system, this should be an accessible project even if you’re just starting out.&lt;/p&gt;

&lt;h2&gt;
  
  
  Required hardware
&lt;/h2&gt;

&lt;p&gt;In order to follow along with this guide, you’ll need the following items.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;(1) Particle Argon — this project assumes you’ve set up your Argon. If you’ve not done that yet, follow the instructions here before you begin this project.&lt;/li&gt;
&lt;li&gt;(1) Grove Starter Kit for Particle Mesh — the kit comes with a number of different sensors. This project will use the follow parts from the kit:

&lt;ul&gt;
&lt;li&gt;(1) Grove shield for Particle Mesh&lt;/li&gt;
&lt;li&gt;(1) temperature and humidity sensor&lt;/li&gt;
&lt;li&gt;(1) chainable RGB LED V2&lt;/li&gt;
&lt;li&gt;(1) 4-digit display&lt;/li&gt;
&lt;li&gt;(3) Grove wires&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Hardware assembly
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--QqBF2mA3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.particle.io/wp-content/uploads/2019/06/Grove-temp-blue-LED-crop-1024x768.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--QqBF2mA3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.particle.io/wp-content/uploads/2019/06/Grove-temp-blue-LED-crop-1024x768.jpg" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Assembly of the project requires zero soldering. In my build, I got a bit fancy and decided to repurpose the Grove kit box as an enclosure. I won’t cover the exact steps to build the enclosure, but will say that when you work with cardboard, measure twice and cut with several passes of your cutting tool.&lt;/p&gt;

&lt;h4&gt;
  
  
  Connect your Grove sensors
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--LLZYdOXf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.particle.io/wp-content/uploads/2019/06/Grove-temp-project-interior-crop-1024x768.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--LLZYdOXf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.particle.io/wp-content/uploads/2019/06/Grove-temp-project-interior-crop-1024x768.png" alt="I used the box from my Grove kit as an enclosure. Just add tape and a bit of patience."&gt;&lt;/a&gt;I used the box from my Grove kit as an enclosure. Just add tape and a bit of patience.&lt;/p&gt;

&lt;p&gt;The main step in this project is to connect all the sensors to the Grove FeatherWing. Building with the Grove system is quick and efficient. Plus, each of the Grove wires are notched with a small piece of plastic, so it’s physically impossible to connect the Grove cables the wrong way. Here’s a chart for the connections I used in the project.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Grove FeatherWing port&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Sensor&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;D2&lt;/td&gt;
&lt;td&gt;4-digit display&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;A2&lt;/td&gt;
&lt;td&gt;Temperature &amp;amp; Humidity sensor&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;UART&lt;/td&gt;
&lt;td&gt;RGB LED&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Finally, add your Argon to the Grove FeatherWing and seat it snuggly. That’s it, all done with the physical build. Let’s get to the code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Add code and you’ll be monitoring ambient temperature in no time
&lt;/h2&gt;

&lt;p&gt;Even though assembling the hardware was rather trivial, your project won’t do much until you add code. Luckily, flashing your Argon isn’t overly complicated either. To make things even more streamlined, you can use existing firmware libraries for the Grove sensors and actuators, so you don’t have to start from scratch. Libraries are a great method to abstract away much of the code complexity. And by using the right libraries, you’ll basically only have to tie together the functions you want to use in your project, and add your own program logic.&lt;/p&gt;

&lt;p&gt;Additionally, by clicking on &lt;a href="https://go.particle.io/shared_apps/5ce72d269c35ef001786ffc4"&gt;this link&lt;/a&gt;, you’ll be taken to the Particle Web IDE with all of the code preloaded for you. All you’ll need to do is to duplicate the project.&lt;/p&gt;

&lt;h2&gt;
  
  
  Highlights from the code
&lt;/h2&gt;

&lt;p&gt;While it’s convenient to duplicate the code and call the project done, it’s worth looking at some of the sections of the program logic to understand what’s is being run on your Argon.&lt;/p&gt;

&lt;h4&gt;
  
  
  Pre-setup: library includes and variable definitions
&lt;/h4&gt;

&lt;p&gt;At the beginning of the code, you will see &lt;code&gt;#include&lt;/code&gt; and &lt;code&gt;#define&lt;/code&gt; declarations that specify the libraries used in the project and your pin configuration that is used for each sensor.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#include "Seeed_DHT11.h"
#include "TM1637.h"
#include "Grove_ChainableLED.h"
#define DHTPIN A2     // Temp&amp;amp;Humi pin
#define CLK D2    // 4-Digit Display pins
#define DIO D3    
DHT dht(DHTPIN);    // Temp/&amp;amp;Humi object
TM1637 tm1637(CLK,DIO);    // 4-Digit Display object
ChainableLED leds(RX, TX, 1);     // LED object with respective pins
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h4&gt;
  
  
  Getting your code in order with the &lt;code&gt;Setup()&lt;/code&gt; function
&lt;/h4&gt;

&lt;p&gt;The setup function is used to initialise your libraries and configure their objects with settings that you’ll use later on in your code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;void setup()
{
tm1637.init();    // initialize Display library
tm1637.set(BRIGHTEST);    // BRIGHT_TYPICAL = 2,BRIGHT_DARKEST = 0,BRIGHTEST = 7;
tm1637.point(POINT_ON);    // Enable 'decimal' points
leds.init();    // initialize LED library
dht.begin();    // initialize DHT library
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  Understanding the main code &lt;code&gt;loop()&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;In a sketch, the &lt;code&gt;loop()&lt;/code&gt; function is run continuously. So this is the section of the code where you want to put the main program logic of your project. At a high level, &lt;code&gt;loop()&lt;/code&gt; polls data from the sensors, processes the data, and outputs it in an actionable way. Let’s dive in.&lt;/p&gt;

&lt;h4&gt;
  
  
  Measuring the temperature and humidity
&lt;/h4&gt;

&lt;p&gt;The main data for this project comes from the temperature and humidity sensor attached to &lt;code&gt;A2&lt;/code&gt;. The first thing to do is to verify that the sensor data valid. Should there be any invalid data, the code will use the &lt;code&gt;Serial.println()&lt;/code&gt; to output, “Failed to read from DHT11 sensor!” and exit the the &lt;code&gt;loop()&lt;/code&gt; function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//Read Humidity
float h = dht.getHumidity();

// Read temperature as Celsius
float t = dht.getTempCelcius();

// Read temperature as Farenheit
float f = dht.getTempFarenheit();

// Check if any reads failed
if (isnan(h) || isnan(t) || isnan(f))
{
Serial.println("Failed to read from DHT11 sensor!");
return;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h4&gt;
  
  
  Processing the temperature and humidity measurements
&lt;/h4&gt;

&lt;p&gt;If the data is valid, you’ll move on and separate the temperature data out in to individual numbers so they can be displayed on the 4-Digit display.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Separate the temperature to individual numbers to be used on the display.
int int_number = f * 100.0; // Two digits after decimal are kept. Turn the number into integer
int digits[10];             //Just in case I have 8 digits before decimal 
for (byte i=0; i&amp;lt;10; i++)
{
    digits[i]  = int_number % 10;
    if (int_number == 0) 
        break;
    int_number /= 10;
}

// display the numbers on the display
tm1637.display(0,digits[3]);
tm1637.display(1,digits[2]);
tm1637.display(2,digits[1]);
tm1637.display(3,digits[0]);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h4&gt;
  
  
  Outputting the temperature and humidity readings
&lt;/h4&gt;

&lt;p&gt;Up next, you’ll take the data you collected and push it out. Using both a serial connection as well as a &lt;code&gt;Particle.publish()&lt;/code&gt; makes sure you can read it locally and remotely, respectively.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Print the measured values over a Serial connection
Serial.print("Temp: ");
Serial.print(f);
Serial.println("*F ");
Serial.println();
Serial.println();

// Publis the temperature to the Cloud using Server Sent Events (SSE)
Particle.publish("tempF", String(f));
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h4&gt;
  
  
  Changing the RGB LED color based on the temperature
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--eeqeyPFY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.particle.io/wp-content/uploads/2019/06/Grove-temp-LED-red-crop-1024x576.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--eeqeyPFY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.particle.io/wp-content/uploads/2019/06/Grove-temp-LED-red-crop-1024x576.jpg" alt="When the temperature exceeds 75.0F, the RGB LED illuminates in red. This is handled in the logic of the loop() function."&gt;&lt;/a&gt;When the temperature exceeds 75.0F, the RGB LED illuminates in red. This is handled in the logic of the loop() function.&lt;/p&gt;

&lt;p&gt;The last bit of code is to control the color of the LED based on the current temperature. For this to work, the code uses conditional statements to evaluate if the current temperature is above or below 75F. If the temperature is above 75F, the RGB LED will turn red. If the temp is below that, the LED will illuminate blue. You can tweak the temperature thresholds simply by altering the &lt;code&gt;75.0&lt;/code&gt; in the code. Try it out for yourself. You’ll need to reflash your Argon to see your new code in action.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/ Temperature warning. Over 75F -&amp;gt; red. Under 75F -&amp;gt; Cyan.
if (f &amp;gt; 75.0){
leds.setColorRGB(0, 255, 0, 0); // red
}
if (f &amp;lt; 75.0){
leds.setColorRGB(0, 0, 0, 255); // cyan
}
delay(1000);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The last line of this snippet is not to be overlooked. The line &lt;code&gt;delay(1000)&lt;/code&gt; slows the execution of the &lt;code&gt;loop()&lt;/code&gt; function down by 1000ms. I added this so the code doesn’t exceed the &lt;code&gt;Particle.publish&lt;/code&gt; rate limit. Also, the sensor can’t read faster than 1000ms anyhow, so there’s no advantage in excluding the loop delay.&lt;/p&gt;

&lt;h4&gt;
  
  
  Know the temperature even when you’re not in the room with &lt;code&gt;Particle.publish()&lt;/code&gt;
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--rbfa6ETN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.particle.io/wp-content/uploads/2019/06/viewoftheconsole-1024x662.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--rbfa6ETN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.particle.io/wp-content/uploads/2019/06/viewoftheconsole-1024x662.png" alt="Image of the Particle Console showing the temperature data from the device."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Provided you’ve followed the instructions correctly, you should now have a working thermometer with a local display. Thanks to the &lt;code&gt;Particle.publish&lt;/code&gt; however, you can also see that temperature remotely by going to the &lt;a href="https://console.particle.io"&gt;Particle Console&lt;/a&gt; and selecting the device on the my devices tab or by checking the &lt;em&gt;Events&lt;/em&gt; tab (where you will be able to see publishes from all your devices at once).&lt;/p&gt;

&lt;h2&gt;
  
  
  Customizing this project to suite your needs
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--7fvG0lEB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.particle.io/wp-content/uploads/2019/06/Grove-temp-office-crop-1024x576.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7fvG0lEB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.particle.io/wp-content/uploads/2019/06/Grove-temp-office-crop-1024x576.jpg" alt="Particle-powered conference room temperature monitor deployed in a conference room."&gt;&lt;/a&gt;Particle-powered conference room temperature monitor deployed in a conference room.&lt;/p&gt;

&lt;p&gt;Now you’ve got your project broadcasting data to the internet, you can take that data and act upon it. For inspiration, take a look at &lt;a href="https://particle.hackster.io/"&gt;Hackster&lt;/a&gt; for some inspirational projects and ideas for how you can extend this project. For example, you could use an &lt;a href="https://ifttt.com/particle"&gt;IFTTT recipe for Particle&lt;/a&gt; to automate an email to send when the room temperature exceeds your predefined max.&lt;/p&gt;

&lt;p&gt;Be sure that however you modify this project, you share your work in the &lt;a href="https://community.particle.io/"&gt;Particle forum&lt;/a&gt; and &lt;a href="https://twitter.com/particle"&gt;tweet your project photos&lt;/a&gt; at us.&lt;/p&gt;

&lt;p&gt;The post &lt;a href="https://blog.particle.io/2019/06/14/gen3-wi-fi-thermometer/"&gt;Build this Wi-Fi thermometer for your workshop using a Gen 3 Argon and a Grove Starter Kit&lt;/a&gt; appeared first on &lt;a href="https://blog.particle.io"&gt;Particle Blog&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>tutorial</category>
      <category>iot</category>
      <category>showdev</category>
    </item>
    <item>
      <title>Exploring &amp; Understanding Our Connected World: A new contest from Particle on Hackster</title>
      <dc:creator>Joe Quinn</dc:creator>
      <pubDate>Fri, 17 May 2019 18:48:42 +0000</pubDate>
      <link>https://forem.com/particle/exploring-understanding-our-connected-world-a-new-contest-from-particle-on-hackster-1p9a</link>
      <guid>https://forem.com/particle/exploring-understanding-our-connected-world-a-new-contest-from-particle-on-hackster-1p9a</guid>
      <description>&lt;p&gt;The Internet of Things has given us a chance to explore the world around us like never before. From smart scooters on &lt;a href="https://dev.to/dcschelt/learn-how-to-build-this-cellular-asset-tracker-with-a-particle-boron-4o8l-temp-slug-6173996"&gt;city streets&lt;/a&gt; to connected devices that track weather patterns in the heart of &lt;a href="https://dev.to/particle/learn-how-scientists-are-using-connected-devices-on-4-continents-to-understand-the-impacts-of-climate-change-4kha-temp-slug-6480412"&gt;Central America&lt;/a&gt;, we’re learning more and more all over the world through the power of IoT. Now, with our 3rd generation of IoT hardware, powered by &lt;a href="https://store.particle.io/collections/mesh"&gt;Particle Mesh&lt;/a&gt;, being used far and wide, we have a chance to learn and discover even more.&lt;/p&gt;

&lt;p&gt;That’s why we’re thrilled to launch our latest contest on Hackster: &lt;a href="https://www.hackster.io/contests/particle-iot"&gt;&lt;strong&gt;Exploring &amp;amp; Understanding Our Connected World.&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Wbsrebmm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.particle.io/wp-content/uploads/2019/05/connected-1024x576.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Wbsrebmm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.particle.io/wp-content/uploads/2019/05/connected-1024x576.jpg" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Here’s all you need to know
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Scoot over to &lt;a href="https://www.hackster.io/contests/particle-iot"&gt;our contest page on Hackster&lt;/a&gt; to register and pitch your project  &lt;strong&gt;&lt;em&gt;no later than June 3, 2019&lt;/em&gt;&lt;/strong&gt; to enter for a chance to win free hardware to kick your work into gear. We’ll be awarding an &lt;a href="https://store.particle.io/products/argon-kit"&gt;Argon Kit&lt;/a&gt; to the first 50 people to register high quality projects — so don’t wait to submit!&lt;/li&gt;
&lt;li&gt;Make sure your project aligns with the contest &lt;a href="https://www.hackster.io/contests/particle-iot/rules"&gt;rules&lt;/a&gt; and uses at least one device from our &lt;a href="https://store.particle.io/collections/mesh"&gt;3rd Generation of IoT hardware&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Now it’s time to get building! Make some magic, document all of your work and get your project submitted by the completion deadline: &lt;strong&gt;July 21, 2019&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Our judges will look over the submissions and choose winners no later than  &lt;strong&gt;July 26, 2019&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Gimme the Loot
&lt;/h2&gt;

&lt;p&gt;We’ll be awarding prizes for the best projects that address issues in three distinct categories: cities, the environment, and device fleets. While you can submit your project to more than one category, you’re only able to win one prize from this contest.&lt;/p&gt;

&lt;p&gt;Speaking of winning, we’re handing out seven fantastic prizes! Drones, campaign gear, electric scooters and more.&lt;/p&gt;

&lt;p&gt;So what are you waiting for? &lt;a href="https://www.hackster.io/contests/particle-iot"&gt;Get started on your project today&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The post &lt;a href="https://blog.particle.io/2019/05/17/exploring-understanding-our-connected-world-a-new-contest-from-particle-on-hackster/"&gt;Exploring &amp;amp; Understanding Our Connected World: A new contest from Particle on Hackster&lt;/a&gt; appeared first on &lt;a href="https://blog.particle.io"&gt;Particle Blog&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>news</category>
      <category>contest</category>
      <category>gen3</category>
      <category>hackster</category>
    </item>
    <item>
      <title>Learn how-to build this cellular asset tracker with a Particle Boron</title>
      <dc:creator>Jordy Moors</dc:creator>
      <pubDate>Fri, 17 May 2019 18:00:32 +0000</pubDate>
      <link>https://forem.com/particle/learn-how-to-build-this-cellular-asset-tracker-with-a-particle-boron-519h</link>
      <guid>https://forem.com/particle/learn-how-to-build-this-cellular-asset-tracker-with-a-particle-boron-519h</guid>
      <description>&lt;p&gt;At some point in your life, you’ve probably been in a situation where you wished you could use a cellular asset tracker to help keep tabs on your stuff. Where you parked the car at a concert, the actual location of that package you ordered three weeks ago, or the whereabouts of that scooter you that’s been helping get you that last mile to work, knowing where the things you care about in life is a valuable thing.&lt;/p&gt;

&lt;p&gt;While there might be some generic solutions available, I’m going to show you how to build an all-purpose cellular asset tracker, with features that you can quikcly adapt to suit your specific needs. To build this tracker, the project uses FeatherWing accessory boards from the &lt;a href="https://www.adafruit.com/feather"&gt;Adafruit Feather system&lt;/a&gt; to allow you to easily customize the project by swapping out different sensors or actuators — no jumper-wires necessary.&lt;/p&gt;

&lt;p&gt;This project will be a relatively simple cellular asset tracking solution, but it’s a great base to customize to your needs. It starts with a &lt;a href="https://store.particle.io/products/boron-lte-kit"&gt;Particle Boron&lt;/a&gt; as the brains of the build. The Boron queries location data from an attached GPS module and displays the coordinates on a small OLED display. All three of the FeatherWing compatible devices attach together using a FeatherWing Tripler, and means zero wiring is required. And since there are hundreds of FeatherWings, you can easily expand the functionality just by swapping out a Wing and modifying your code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt; : If you’re unfamiliar with GPS and other geolocation technologies used in IoT, the &lt;a href="https://dev.to/particle/what-every-iot-engineer-needs-to-know-about-navigation-gps-dead-reckoning-cellular-wi-fi-and-ble-3k33"&gt;Ultimate Guide to Geolocation&lt;/a&gt; can help. Learn what every IoT engineer needs to know about GPS, dead reckoning, cellular, Wi-Fi, and BLE all in one place.&lt;/p&gt;

&lt;h2&gt;
  
  
  Project parts &amp;amp; tools
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--C9GTirHt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.particle.io/wp-content/uploads/2019/05/conclusion-169-crop-1024x576.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--C9GTirHt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.particle.io/wp-content/uploads/2019/05/conclusion-169-crop-1024x576.jpg" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Required parts:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://store.particle.io/products/boron-lte-kit"&gt;Particle Boron&lt;/a&gt; — this project assumes you’ve &lt;a href="https://docs.particle.io/boron/"&gt;set up your Boron&lt;/a&gt;. If you’ve not done that yet, follow the instructions here before you begin this project.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://store.particle.io/products/particle-featherwing-tripler"&gt;Particle FeatherWing Tripler&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://store.particle.io/products/adafruit-oled"&gt;Adafruit FeatherWing OLED&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.adafruit.com/product/3133"&gt;Adafruit Ultimate GPS FeatherWing&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Optional, but highly recommended parts&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.adafruit.com/product/380"&gt;CR1220 3V lithium coin cell battery&lt;/a&gt; — used with the GPS module to keep the real-time clock (RTC) powered and allow &lt;em&gt;warm starts&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.adafruit.com/product/851"&gt;SMA-to-uFL RF adapter cable&lt;/a&gt; — Most GPS antennas use an SMA connector, but most boards use smaller uFL connectors. This cable lets you connect them together.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.adafruit.com/product/960"&gt;GPS antenna&lt;/a&gt; — A bigger, more powerful antenna that will get you a better satellite fix more quickly.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Tools&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Soldering equipment is needed to connect some of the headers to the FeatherWings and Tripler board.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; You’ll most likely also want an enclosure of some kind. In this project, we’ve used a custom laser cut enclosure, but you could 3D print something, or go with an off the shelf solution just as easily. You can &lt;a href="https://github.com/moors7/Boron-asset-tracker/blob/master/2dcase.svg"&gt;download my design files here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Hardware assembly
&lt;/h2&gt;

&lt;h2&gt;
  
  
  Step 1. Soldering the headers
&lt;/h2&gt;

&lt;p&gt;Some of the FeatherWings in this project will require you to solder the header pins to the boards. To keep the headers square to the board. Place them in a spare breadboard, with the board you want to add pins to on top. This will help you’ll get proper alignment as well as it’s a lot more convenient to solder with the parts firmly in place.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Cfls_GIr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.particle.io/wp-content/uploads/2019/05/soldering-oled.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Cfls_GIr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.particle.io/wp-content/uploads/2019/05/soldering-oled.jpg" alt=""&gt;&lt;/a&gt;You’ll need to solder the headers onto the Adafruit OLED FeatherWing.&lt;/p&gt;

&lt;p&gt;The FeatherWing Tripler uses female headers, but you can use a similar trick as you used with the breadboard. Place the female headers over their respective pins on one of the other FeatherWings, and then place them in the Tripler on top to solder. That way the headers will all line up correctly, and it’s a lot easier to solder.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Attention:&lt;/strong&gt; make sure you solder the Tripler correctly, or you risk damaging your boards.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--TrBIxkIL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.particle.io/wp-content/uploads/2019/05/soldering-tripler.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--TrBIxkIL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.particle.io/wp-content/uploads/2019/05/soldering-tripler.jpg" alt=""&gt;&lt;/a&gt;Soldering the Tripler can be done without helping hands, but a steady hand is requited.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2. Assembling your FeatherWings
&lt;/h2&gt;

&lt;p&gt;With the soldering out of the way, you can move on to assembling the project. FeatherWing placement matters. In order to ensure access to the battery port on the Boron, you must place it on the right-hand side of the Tripler. In the middle comes the OLED Feather, and the GPS Wing will be on the left side.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; If you don’t use this ordering, you’ll have trouble routing the antenna and battery cables.&lt;/p&gt;

&lt;p&gt;At this point, you can carefully attach the antennas to their respective connectors — make sure you use the cellular connector on the top side — and plug in the battery to the Boron.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3. Laser-cut your enclosure or build your own
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--wkmirxrH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.particle.io/wp-content/uploads/2019/05/enclosure-crop-1024x768.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--wkmirxrH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.particle.io/wp-content/uploads/2019/05/enclosure-crop-1024x768.jpg" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you’ve made or purchased an enclosure, you can start fitting the project in there now.&lt;/p&gt;

&lt;h2&gt;
  
  
  Navigating the Boron asset tracker source code
&lt;/h2&gt;

&lt;p&gt;The code for this project is kept relatively simple, so it can easily be customized to suit your individual needs. The code makes use of the TinyGPS++ library to abstract the hard parts of dealing with GPS data and gives you easy to use functions to extract the data you need. That way, you don’t have to reinvent the wheel and go through the hassle of dealing with raw GPS data.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--RM0nKfa_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.particle.io/wp-content/uploads/2019/05/Tracker-hero.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--RM0nKfa_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.particle.io/wp-content/uploads/2019/05/Tracker-hero.jpg" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In a bird’s eye view, the code loops to see if there is GPS data available and hands it to the tinyGPS library for parsing if so. It then checks whether the data coming out is sensible. When that’s not the case, it will give an error output on the display, informing you a fix hasn’t been found. If the data does make sense, it will package it in a nice format and will display the GPS coordinates on the display. That’s also where you could make changes to the information that gets displayed.&lt;/p&gt;

&lt;p&gt;Finally, the code will publish a message to the cloud with the GPS information, which can be acted upon on that end using &lt;a href="https://docs.particle.io/tutorials/device-cloud/webhooks/"&gt;webhooks&lt;/a&gt;, or other &lt;a href="https://docs.particle.io/tutorials/device-cloud/console/#integrations"&gt;integrations&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://go.particle.io/shared_apps/5cd9a8733035ef0023871896%0A"&gt;Click here to load the code in your WebIDE&lt;/a&gt; — no extra typing required.&lt;/p&gt;

&lt;p&gt;If you’re not using the Web IDE share link, make sure to manually include the TinyGPS++ and the oled-wing-adafruit libraries.&lt;/p&gt;

&lt;h2&gt;
  
  
  Code highlights and commentary
&lt;/h2&gt;

&lt;p&gt;The code for this project is all open source, but I wanted to quickly highlight a few of the most important sections to help give you ideas for where you can modify to suit your needs. Take special note of the line numbers as I’m covering snippets of code below.&lt;/p&gt;

&lt;p&gt;The following code will run in a continuous loop, checking to see if new GPS information is available. If there is new data, it will call the &lt;code&gt;displayInfo()&lt;/code&gt; function to start processing.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;void loop()
{
    display.loop();
    while (Serial1.available() &amp;gt; 0) {
        if (gps.encode(Serial1.read())) {
            displayInfo();
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The code shown below is taken from the &lt;code&gt;displayInfo()&lt;/code&gt; function.&lt;/p&gt;

&lt;p&gt;After getting the GPS data and making sure it’s valid, the information is packed into a buffer and displayed on the OLED.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;display.clearDisplay();
display.setTextSize(2);
display.setTextColor(WHITE);
display.setCursor(0,0);
snprintf(buf, sizeof(buf), "%f", gps.location.lat());
display.println(buf);
snprintf(buf, sizeof(buf), "%f", gps.location.lng());
display.println(buf);
display.display();
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Up next, the code packages the data in new buffers so it has a nice format for output over Serial.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;snprintf(buf, sizeof(buf), "%f,%f,%f", gps.location.lat(), gps.location.lng(), gps.altitude.meters()); // Format for Serial logging
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Finally, there’s a check to see if we’re not publishing too often. If that’s not the case, then publish the data to the cloud.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if (Particle.connected()) {
    if (millis() - lastPublish &amp;gt;= PUBLISH_PERIOD) {
        lastPublish = millis();
        Particle.publish("gps", pubbuf, PRIVATE);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Visualizing your data with Ubidots
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---_ZBAwgO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.particle.io/wp-content/uploads/2019/05/ubidots-map.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---_ZBAwgO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.particle.io/wp-content/uploads/2019/05/ubidots-map.jpg" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To take this project a step further than displaying the coordinates on the OLED, you can send the data to an online platform to display it on a map. There are various services available that offer functionality like this, such as the &lt;a href="https://docs.particle.io/tutorials/integrations/google-maps/"&gt;Particle Google Maps integration&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For this tutorial, I chose to use &lt;a href="https://ubidots.com/"&gt;Ubidots&lt;/a&gt;. They offer a great service for ingesting data and plotting it on a map. Plus it’s easy to integrate. You can get the data to them by using a webhook in the Console, and a specific &lt;code&gt;Particle.publish()&lt;/code&gt; on the device.&lt;/p&gt;

&lt;p&gt;First, create an account on Ubidots. For Ubidots to accept the data as a GPS location, it will look for a specific format in the data it receives. It expects to find a JSON object containing a &lt;code&gt;lat&lt;/code&gt; and &lt;code&gt;lng&lt;/code&gt; key, with their respective values.&lt;/p&gt;

&lt;h4&gt;
  
  
  On the device:
&lt;/h4&gt;

&lt;p&gt;To get the data in the format Ubidots expects it, you’ll have to add some bits to the code. The key lines to look at here are line &lt;code&gt;71&lt;/code&gt; and &lt;code&gt;86&lt;/code&gt;, which create and fill a buffer for Ubidots.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;char pubbuf[120];
if (gps.location.isValid() &amp;amp;&amp;amp; gps.location.age() &amp;lt; MAX_GPS_AGE_MS) {
    display.clearDisplay();
    display.setTextSize(2);
    display.setTextColor(WHITE);
    display.setCursor(0,0);
    snprintf(buf, sizeof(buf), "%f", gps.location.lat());
    display.println(buf);
    snprintf(buf, sizeof(buf), "%f", gps.location.lng());
    display.println(buf);
    display.display();
    snprintf(buf, sizeof(buf), "%f,%f,%f", gps.location.lat(), gps.location.lng(), gps.altitude.meters());
    snprintf(pubbuf, sizeof(pubbuf), "{\"position\": {\"value\":1, \"context\":{\"lat\": \"%f\", \"lng\": \"%f\"}}}", gps.location.lat(), gps.location.lng());
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Create a new buffer to store the Ubidots formatted data in. Then, fill that buffer with the JSON content and the GPS data. Finally, Publish that buffer as a &lt;code&gt;Particle.publish()&lt;/code&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  In the console:
&lt;/h4&gt;

&lt;p&gt;To get the published data to Ubidots, you can use their API. To do so, you’ll have to create a &lt;a href="https://docs.particle.io/tutorials/device-cloud/webhooks/"&gt;webhook&lt;/a&gt;. Go to the &lt;a href="https://console.particle.io/integrations"&gt;Console&lt;/a&gt;, and find the integrations tab on the left. Create a new integration and select a webhook. In the top left, find and select the custom template option. Copy and paste in the following snippet.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
    "event": "gps",
    "url": "https://industrial.api.ubidots.com/api/v1.6/devices/{{{PARTICLE_DEVICE_ID}}}",
    "requestType": "POST",
    "noDefaults": false,
    "rejectUnauthorized": true,
    "headers": {
        "X-Auth-Token": "replace-this-with-your-token",
        "Content-Type": "application/json"
    },
    "body": "{{{PARTICLE_EVENT_VALUE}}}"
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Make sure to replace the highlighted &lt;code&gt;X-Auth-Token&lt;/code&gt; with your own. You can find said token by going to your Ubidots account, clicking on your profile icon and selecting API credentials.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--XoMgoYTS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.particle.io/wp-content/uploads/2019/05/ubidots-config-crop.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--XoMgoYTS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.particle.io/wp-content/uploads/2019/05/ubidots-config-crop.jpg" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After you've successfully completed each of the steps, you should now have a functioning cellular asset tracker that will display its GPS coordinates on the screen, as well as publish them to the cloud, where you can work with them in different ways to serve your purpose.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where will you take you take your asset tracker?
&lt;/h2&gt;

&lt;p&gt;Starting with this project, you can use it as the basis of a car tracking system, a geofence for your pets or kids, track shipping containers or do something as mundane as making internet connected scooters. The possibilities are certainly there and so are the basics to start from.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--GWgNhD9e--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.particle.io/wp-content/uploads/2019/05/tracker-front-on-169-crop-1024x576.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--GWgNhD9e--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.particle.io/wp-content/uploads/2019/05/tracker-front-on-169-crop-1024x576.jpg" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Take a look over at &lt;a href="https://www.hackster.io/particle"&gt;Hackster&lt;/a&gt; to get inspiration for projects you could build next. Additionally, share your thoughts and ideas on our &lt;a href="https://community.particle.io/"&gt;Particle forum&lt;/a&gt;, where you can brainstorm and get project advice. It’s also a great place to ask questions, with many of our members being eager to help out.&lt;/p&gt;

&lt;p&gt;Now go forth and track something that matters to you.&lt;/p&gt;

&lt;p&gt;The post &lt;a href="https://blog.particle.io/2019/05/17/learn-how-to-build-this-cellular-asset-tracker-with-a-particle-boron/"&gt;Learn how-to build this cellular asset tracker with a Particle Boron&lt;/a&gt; appeared first on &lt;a href="https://blog.particle.io"&gt;Particle Blog&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>showdev</category>
      <category>beginners</category>
      <category>tutorial</category>
      <category>iot</category>
    </item>
    <item>
      <title>Get up to speed with Particle Variable and Function Primitives</title>
      <dc:creator>Brandon Satrom</dc:creator>
      <pubDate>Thu, 16 May 2019 19:29:19 +0000</pubDate>
      <link>https://forem.com/particle/get-up-to-speed-with-particle-variable-and-function-primitives-18</link>
      <guid>https://forem.com/particle/get-up-to-speed-with-particle-variable-and-function-primitives-18</guid>
      <description>&lt;p&gt;IoT Projects often need to share the data they collect, or enable external systems to trigger actions. That’s the “I” in IoT, after all. To make connectivity easier, Particle provides a number of “primitives” in the built-in Device OS, including variables, functions and messaging with Particle &lt;a href="https://docs.particle.io/reference/device-os/firmware/photon/#particle-publish-"&gt;publish and subscribe&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/POHyi5xV8Mc"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;In this &lt;a href="https://www.youtube.com/watch?v=POHyi5xV8Mc"&gt;video&lt;/a&gt;, I walk through a simple project that shows you how to use the Particle Variable and Function primitives with a &lt;a href="https://store.particle.io/products/argon-kit"&gt;Particle Argon&lt;/a&gt;, and two Grove sensors from the &lt;a href="https://store.particle.io/products/grove-starter-kit"&gt;Grove Starter Kit for Particle Mesh&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;With the variable and function primitives, developers can access local device state, for instance, to retrieve the latest reading from a connected sensor, or call firmware functions to take action on the device, for instance, to turn on a light or move a servo. Because these primitives are mediated securely through the Particle Device Cloud, they can be accessed from other devices, the Particle console, or even in web and mobile applications.&lt;/p&gt;

&lt;p&gt;For other videos covering the basics of working with Particle devices, check out our &lt;a href="https://www.youtube.com/watch?v=0T5rFu-9JAI&amp;amp;list=PLIeLC6NIW2tKvC5W007j_PU-dxONK_ZXR"&gt;Particle 101 series on YouTube&lt;/a&gt;. If you have questions about using Particle variables, functions, or anything else in the Particle platform, &lt;a href="https://community.particle.io"&gt;visit us in the Particle Community&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The post &lt;a href="https://blog.particle.io/2019/05/16/get-up-to-speed-with-particle-variable-and-function-primitives/"&gt;Get up to speed with Particle Variable and Function Primitives&lt;/a&gt; appeared first on &lt;a href="https://blog.particle.io"&gt;Particle Blog&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>tutorial</category>
      <category>iot</category>
      <category>cpp</category>
      <category>embedded</category>
    </item>
    <item>
      <title>What every IoT engineer needs to know about navigation: GPS, dead reckoning, cellular, Wi-Fi, and BLE</title>
      <dc:creator>David Scheltema</dc:creator>
      <pubDate>Wed, 15 May 2019 21:18:31 +0000</pubDate>
      <link>https://forem.com/particle/what-every-iot-engineer-needs-to-know-about-navigation-gps-dead-reckoning-cellular-wi-fi-and-ble-3k33</link>
      <guid>https://forem.com/particle/what-every-iot-engineer-needs-to-know-about-navigation-gps-dead-reckoning-cellular-wi-fi-and-ble-3k33</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--q97YLPVw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/dqfmi74cwdvge945oxtb.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--q97YLPVw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/dqfmi74cwdvge945oxtb.jpg" alt="" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Personal navigation has never been easier. With numerous options from GPS and cellular to Wi-Fi and Bluetooth, it can be challenging to select the right one for your product be it micromobility scooter or a fleet of logging trucks. To understand which solution is right for you, it’s helpful to have a high-level perspective on the most popular and widespread geolocation technologies.&lt;/p&gt;

&lt;p&gt;Most geolocation solutions should start with GPS since it’s a system designed from the start to answer the question, where am I? With close to ~4-meter accuracy, it’s a no brainer to start any navigation solution here, unless of course, your use-case is underground.&lt;/p&gt;

&lt;p&gt;Unsurprisingly, no single navigation solution is right for every product use-case or fleet deployment. What works for a micromobility scooter — a combination of GPS, cellular, and Bluetooth — would be an over-engineered solution to keep track of your keys. For that, something like Bluetooth beacons are more appropriate.&lt;/p&gt;

&lt;p&gt;This guide will provide you with information about commonly radio technology used for navigation. After reading, you should be familiar with the different available technologies as well as a high-level awareness of the significant trade-offs between the options. In many cases, the best solution is a robust combination of technologies.&lt;/p&gt;

&lt;h3&gt;
  
  
  Navigation options at a glance
&lt;/h3&gt;

&lt;p&gt;Determining the right option for your geolocation needs is a balancing act between the cost of the silicon and the accuracy of the location data it provides. Battery life is not covered in this overview, however, it’s good to keep in mind that the number of times you send location data from your device to the cloud will affect your battery performance. Additionally, specific radio power performance will vary by vendor and part.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GPS&lt;/strong&gt; — The Global Positioning System (GPS) is generally the most accurate, and it can provide device location continuously. This option is moderate to high priced depending on features such as onboard RTKs. It is widely used used as the basis for any geolocation solution.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cellular&lt;/strong&gt; — Cellular geolocation uses known cell tower location to approximate where you are. Of course, cellular requires an active service plan and proximity to cellular towers. Cellular is predominately used as a supplement to GPS, as it lacks the accuracy to be an independent solution.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Wi-Fi&lt;/strong&gt; — Wi-Fi is not advisable for use-cases that move a lot, but is commonly found in smartphones and laptops as a way to supplement location data or give approximate location inside of buildings using 3rd party databases of Wi-Fi access point locations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bluetooth 5/BLE&lt;/strong&gt; — Great for small tracking devices such as key fobs and assets in a contained, small location. Typically deployments use a mobile phone in conjunction with Bluetooth beacons that broadcast location information.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting started: Weighing cost vs accuracy with GPS
&lt;/h2&gt;

&lt;p&gt;Unless your use-case is subterranean, your navigation solution should begin with GPS. Thanks to smartphones, the cost of GPS modules is lower than it’s ever been, but that means there are a lot of module options to consider for your design. A helpful way to cut through the options is by balancing between unit cost and location accuracy.&lt;/p&gt;

&lt;p&gt;As a general rule of thumb as GPS accuracy increases, so too does the cost. Inexpensive GPS modules can be purchased for under $40 and typically support UART or I2C depending on the module. More expensive, featureful GPS modules can run upwards of $200, but offer advanced capabilities like onboard RTKs. However, there’s also a bit of a middle ground. To supplement the accuracy of GPS, it’s not uncommon to see silicon vendors and product designers add additional hardware or using software to help gain higher accuracy.&lt;/p&gt;

&lt;h3&gt;
  
  
  Using cellular plus geofencing for robust geolocation
&lt;/h3&gt;

&lt;p&gt;Cellular is typically a medium for voice and data, but you can also use it to determine approximate location. Note that a cellular-only navigation system will only provide you with your location relative to the towers your cellular device is communicating with. For more in-depth information on cellular, please see our &lt;a href="https://docs.particle.io/tutorials/cellular-connectivity/introduction/"&gt;cellular guide&lt;/a&gt; in the Particle docs.&lt;/p&gt;

&lt;p&gt;Every cell tower has an identifier, and this can be looked up using Google’s &lt;a href="https://developers.google.com/maps/documentation/geolocation/intro"&gt;Geolocation API&lt;/a&gt; to find where it is on the globe. This process is fast and provides a general location, usually within 4,000 meters or a couple of miles. Of course, you need a cellular signal for this to happen.&lt;/p&gt;

&lt;p&gt;Pairing cellular connectivity with GPS-based geofencing provides a solid solution for IoT deployments that may go in and out of hard to reach places such as lumber trucks across the state of South Carolina. Particle’s customer Worthwhile combines these two technologies to provide a more robust navigation solution. Using a &lt;a href="https://store.particle.io/collections/cellular"&gt;Particle cellular solution&lt;/a&gt; their &lt;a href="https://github.com/worthwhile/geo-bound"&gt;open-source Geo-Bound software&lt;/a&gt; caches up to 2,000 GPS coordinates locally in their asset trackers memory and stores them until back in cellular range. While cellular here is not used for the navigation per se, the combinational approach of cellular plus GPS highlights a robust geolocation solution.&lt;/p&gt;

&lt;h3&gt;
  
  
  Improving GPS accuracy with IMU-based dead reckoning
&lt;/h3&gt;

&lt;p&gt;In some situations, GPS alone cannot provide a full navigation solution. Take a fleet of scooters for example. In big cities they don’t always have a clear line of sight to the sky for GPS to work efficiently — gaining a lock on satellites takes time and consumes power, both challenging in urban environments.&lt;/p&gt;

&lt;p&gt;By augmenting a GPS module with additional geolocational data and using techniques like dead reckoning — a navigation technique that uses information about your past position, speed, duration, and heading to calculate where you currently are — a fleet for scooters can still be found even if they can’t see the sky.&lt;/p&gt;

&lt;p&gt;Developers use dead reckoning to supplement GPS data and help with error correction. To cost effective achieve dead reckoning, it’s not uncommon to see prototypers add an inertial measurement unit (IMU), a specialized sensor that’s packaged in a single integrated circuit, to collect information about the heading and speed information as a supplement the available GPS coordinates.&lt;/p&gt;

&lt;p&gt;Dead reckoning works best with micromobility, specifically when tracking mobile assets around an urban area, with inexpensive non-GPS navigation devices, and it’s very accessible for DIY robotics projects.&lt;/p&gt;

&lt;p&gt;While alone, an IMU-based dead reckoning solution isn’t recommended for high-value asset tracking, supplementing a GPS with an IMU can result in a more robust geolocation solution.&lt;/p&gt;

&lt;h3&gt;
  
  
  Dead reckoning in silicon: high-end GPS modules with built-in real-time kinematic engines
&lt;/h3&gt;

&lt;p&gt;Land surveying and autopilot systems use GPS that include real-time kinematic engines (RTK) that perform dead reckoning inside the GPS module and boast centimeter accuracy. No extra ICs required. One example of such a module is the &lt;a href="https://www.u-blox.com/en/product/neo-m8p-series"&gt;ublox NEO-M8P-2&lt;/a&gt;, which SparkFun offers in a &lt;a href="https://www.sparkfun.com/products/15005"&gt;sub-$200 breakout board&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The only problem is GPS modules with RTKs is the cost. Single quantity pricing for GPS modules with integrated RTK run upwards of $200 per unit, making them too expensive for most use-cases. Unless you’re building a centimeter accurate navigation solution like surveying a building site or autonomously assisting an autopilot system, using a GPS with RTK is over-engineering your solution.&lt;/p&gt;

&lt;p&gt;As you can probably guess, due to the higher per unit cost, GPS modules with on-die RTKs are almost non-existent in micromobility markets, but more common in industries small measurements matter. For those undeterred by the unit price, Sparkfun electronics has &lt;a href="https://learn.sparkfun.com/tutorials/what-is-gps-rtk"&gt;an excellent primer on GPS with RTK&lt;/a&gt;, which also covers more advanced navigation techniques such as error correction using Radio Technical Commission for Maritime.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wi-Fi provides supplemental navigation
&lt;/h2&gt;

&lt;p&gt;Smartphones are a fantastic example of Wi-Fi supplementing other radios for geolocation. You’ve probably experienced your smartphone reminding you to turn on WI-Fi to help improve your location accuracy.&lt;/p&gt;

&lt;p&gt;Wi-Fi assisted navigation works by using special 3rd-party API service such as Google’s &lt;a href="https://developers.google.com/maps/documentation/geolocation/intro"&gt;Geolocation API&lt;/a&gt; that provides access to an enormous database of Wi-Fi access point locations. Given the scale of their enterprise and given enough data points of Wi-FI APs, the information is helpful for indoor navigation.&lt;/p&gt;

&lt;h3&gt;
  
  
  Problems with using Wi-Fi for navigation
&lt;/h3&gt;

&lt;p&gt;One enormous challenge with using Wi-Fi as a navigational aid is that as soon as you move out of range of a Wi-Fi access point, your access to the Wi-Fi location database is lost. Smartphones do a fantastic job of obscuring this limitation since they have cellular, GPS, and Wi-Fi that work seamlessly together and require near-zero user configuration.&lt;/p&gt;

&lt;p&gt;Much like cellular, it’s not uncommon to see early prototype projects attempting to combine Wi-Fi with an IMU to approximate a navigation system. These systems are architecturally similar to cellular plus IMU approach, but with one major drawback: limited range bound by Wi-Fi signal coverage. Without a Wi-Fi signal, there is no way for the device to connect to a cloud for dashboards, fleet management, or even access the geolocation APIs.&lt;/p&gt;

&lt;h3&gt;
  
  
  Don’t combine cellular and Wi-Fi to navigate unless you absolutely must
&lt;/h3&gt;

&lt;p&gt;Some might think to add cellular and have a Wi-Fi and cellular solution, however, unless you’re making a smartphone, this is not an advisable approach to navigation. Adding a second radio interface such as cellular means you effectively double your power draw, increased bill of materials cost, your software integration time and rigor, and your antenna design just got a lot more complicated. Instead, a navigation solution that combines GPS with Wi-Fi is a much more appropriate path.&lt;/p&gt;

&lt;h3&gt;
  
  
  Bluetooth navigation handles the small stuff like finding your keys
&lt;/h3&gt;

&lt;p&gt;Geolocation isn’t just about getting you from your home to office. In some use-cases, it’s about finding your misplaced keys. With a limited range of 10 meters, Bluetooth is great for helping you track down things you know are nearby but needs some help finding.&lt;/p&gt;

&lt;p&gt;Increasingly Bluetooth 5 based devices featuring ICs like the &lt;a href="https://www.nordicsemi.com/?sc_itemid=%7B2DC10BA5-A76E-40F8-836E-E2FC65803A71%7D"&gt;Nordic nRF82540&lt;/a&gt; found in all &lt;a href="https://store.particle.io/collections/mesh"&gt;Particle 3rd Gen devices&lt;/a&gt; are used for key-finding solutions. Of particular interest to designers is the improved and descriptively named Bluetooth broadcast and beacon modes. These allow for information-rich interactions between non-paired Bluetooth devices.&lt;/p&gt;

&lt;p&gt;For example, imagine a rideshare bike that could broadcast its battery state directly to the customer. No need to send data to the cloud, simply use a beacon mode to advertise to the rideshare app the charge level. For more on the use of Bluetooth in navigation, please see the Bluetooth SIG documentation here.&lt;/p&gt;

&lt;h3&gt;
  
  
  Navigating your way to the right solution for your use-case
&lt;/h3&gt;

&lt;p&gt;Ultimately, the best way to understand each of these technologies is with hands-on experience. As you’ve learned, the most reliable geolocation and navigation solutions use a robust combination of radio technologies. For your own prototyping journey using a &lt;a href="https://store.particle.io/collections/mesh"&gt;Gen 3 Particle device&lt;/a&gt; with an Adafruit &lt;a href="https://learn.adafruit.com/adafruit-ultimate-gps-featherwing"&gt;Ultimate GPS FeatherWing&lt;/a&gt; is a great place to start. From there, it’s very easy to transition to an enterprise-grade module like our &lt;a href="https://docs.particle.io/datasheets/cellular/b-series-datasheet/"&gt;B Series SoM&lt;/a&gt; for scale.&lt;/p&gt;

&lt;p&gt;For more on how Particle solutions can help with your geolocation and navigation products see our product suite overview or &lt;a href="https://www.particle.io/sales?utm_source=referral&amp;amp;utm_medium=blog&amp;amp;utm_campaign=micromobility"&gt;contact us and talk with an expert&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The post &lt;a href="https://blog.particle.io/2019/05/15/ultimate-iot-guide-to-navigation/"&gt;What every IoT engineer needs to know about navigation: GPS, dead reckoning, cellular, Wi-Fi, and BLE&lt;/a&gt; appeared first on &lt;a href="https://blog.particle.io"&gt;Particle Blog&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>connectivity</category>
      <category>iot</category>
      <category>bluetooth</category>
      <category>gps</category>
    </item>
    <item>
      <title>Professional debugging for IoT with VS Code &amp; Particle Workbench: going beyond Serial.print()</title>
      <dc:creator>Brandon Satrom</dc:creator>
      <pubDate>Fri, 03 May 2019 18:45:31 +0000</pubDate>
      <link>https://forem.com/particle/professional-debugging-for-iot-with-vs-code-particle-workbench-going-beyond-serial-print-3hc6</link>
      <guid>https://forem.com/particle/professional-debugging-for-iot-with-vs-code-particle-workbench-going-beyond-serial-print-3hc6</guid>
      <description>&lt;p&gt;I started my career in technology as a web developer back in 1999. Those halcyon days of the early web were much different than today, with no browser dev tools, not a sniff of HTML5, and JavaScript was still in its pre-AJAX infancy. But I pinned for a world where on-device debugging would be as easy as my browser dev tools.&lt;/p&gt;

&lt;p&gt;Today I pine no more, and with the recent launch of &lt;a href="https://www.particle.io/workbench/"&gt;Particle Workbench&lt;/a&gt;, I’ve finally found a tool that makes hardware device debugging as easy to use as the browser dev tools. In this post, I’ll walk through how you can do the same with your Particle devices today!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: this post covers the basics of debugging with 3rd Generation particle devices, like the Argon, Boron, and Xenon. The Particle docs have an &lt;a href="https://docs.particle.io/tutorials/developer-tools/workbench/#debugging-3rd-generation-"&gt;excellent, comprehensive guide for 3rd generation debugging&lt;/a&gt;, as well as a &lt;a href="https://docs.particle.io/tutorials/developer-tools/workbench/#debugging-2nd-generation-with-particle-debugger-"&gt;guide for debugging 2nd Generation devices (Photon, Electron)&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Brief history of my debugging experience: it’s an art
&lt;/h2&gt;

&lt;p&gt;In my early development days, the state of the art in JavaScript debugging was the &lt;code&gt;alert&lt;/code&gt; command, which would pop a UI box on ones screen with whatever value you wanted it to. Need to know the current state of a loop counter variable? &lt;code&gt;alert(i);&lt;/code&gt; Wondering what the &lt;code&gt;ADDRESS_ONE&lt;/code&gt; column looks like when retrieved from your SQL Server database? &lt;code&gt;alert(address_one)&lt;/code&gt;.&lt;/p&gt;


&lt;center&gt;&lt;p id="attachment_5178"&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--UCGCkpYn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.particle.io/wp-content/uploads/2019/05/0291g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--UCGCkpYn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.particle.io/wp-content/uploads/2019/05/0291g.png" alt="Image of a browser alert box from IE 6" width="493" height="203"&gt;&lt;/a&gt;The state of the art in debugging, circa 1999.&lt;/p&gt;&lt;/center&gt;

&lt;p&gt;Desperately trying to figure out where that heisenbug is in your new user auth flow that you swore to your boss up and down you tested thoroughly before deploying on a Friday at 4pm?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;alert(“HERE”); 

alert(“HERE 2”);

alert(“WHAT ARE WEEKENDS ANYWAY? I LIVE IN THIS CUBICLE NOW.”);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;In the years since, the state of debugging in the web has come a long way. With the advent of &lt;code&gt;console.log()&lt;/code&gt;, we got the unobtrusive replacement for the alertbox. It was a move in the right direction, but still a Crocodile Dundee-sized knife when one needed a scalpel.&lt;/p&gt;

&lt;p&gt;Then came browser developer tools, first in Firefox via Firebug, then built-in in Chrome, Firefox, IE, and Opera. Finally, web developers everywhere could set breakpoints, watches, and inspect running client-side applications like our server-focused colleagues had been doing for years.&lt;/p&gt;

&lt;h3&gt;
  
  
  Serial.print(), the alert() of embedded development
&lt;/h3&gt;

&lt;p&gt;Many years later, I got into hardware and embedded development, and I discovered that a similar trial and error debugging process dominated the field in a way not unlike the early web. There, instead of &lt;code&gt;alert()&lt;/code&gt; and &lt;code&gt;console.log()&lt;/code&gt;, the tendency was to litter ones firmware with &lt;code&gt;Serial.print()&lt;/code&gt; and &lt;code&gt;Serial.println()&lt;/code&gt; commands as a way of logging the progress and state of an embedded application.&lt;/p&gt;

&lt;p&gt;And much like my early use of &lt;code&gt;alert()&lt;/code&gt;, I found myself using &lt;code&gt;Serial.print()&lt;/code&gt; as a blunt instrument when things went awry and I had no idea where the self-induced error was to be found. Sure, professional, on-device debugging tools were available, but as a newbie in this intimidating world of hardware, I, like many others, reached for the solution that felt comfortable and familiar.&lt;/p&gt;

&lt;p&gt;With the launch of Particle Workbench, I’m happy to report that the built-in debugging capabilities are just what we firmware developers need to go beyond &lt;code&gt;Serial.print()&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Debugging with Particle Workbench: Easy like the browser dev tools
&lt;/h2&gt;

&lt;p&gt;Before getting started, you’ll need to gather a few materials, including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.particle.io/workbench/"&gt;Particle Workbench&lt;/a&gt;, a new VS Code-based IDE optimized for IoT;&lt;/li&gt;
&lt;li&gt;One 3rd Generation Particle device. I use the &lt;a href="https://store.particle.io/products/argon-kit"&gt;Argon Kit&lt;/a&gt; for this post;&lt;/li&gt;
&lt;li&gt;One &lt;a href="https://store.particle.io/products/particle-debugger"&gt;Particle Debugger&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;One USB Micro cable (included in the Argon Kit I used).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Both the Debugger and the Particle device must be connected to the same computer via USB, so make sure you have enough ports available. Connect the debugger to the debug port on your Particle device using the provided ribbon cable, and plug both into your computer. The debug port consists of ten exposed pins protected by some plastic, and you can find it next to the LiPo battery port near the top of the device.&lt;/p&gt;


&lt;center&gt;&lt;p id="attachment_5182"&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--aIKamUYA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.particle.io/wp-content/uploads/2019/05/DebuggerCable.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--aIKamUYA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.particle.io/wp-content/uploads/2019/05/DebuggerCable.png" alt="" width="600" height="600"&gt;&lt;/a&gt;The debugger cable plugs into the 10-pin JTAG port on the top left of the device.&lt;/p&gt;&lt;/center&gt;

&lt;p&gt;Once everything is connected and powered on, you’ll need to put your Particle device into Device Firmware Update (DFU) mode. In order for Workbench to facilitate on-device debugging, it needs to compile and flash a debug build of your application and the Particle Device OS firmware in a single binary. You’ll sometimes see this referred to as a “monolithic” build because this differs from the normal build process, where Device OS and your application firmware can be updated independent of one another.&lt;/p&gt;

&lt;p&gt;To put your device in DFU mode, press and hold the MODE and RESET buttons on the device. Then, release the RESET button, while continuing to hold the MODE button until the RGB LED on the device starts blinking yellow.&lt;/p&gt;


&lt;center&gt;&lt;p id="attachment_5183"&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--3bg1VcLp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://blog.particle.io/wp-content/uploads/2019/05/DFU.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--3bg1VcLp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://blog.particle.io/wp-content/uploads/2019/05/DFU.gif" alt="Gif of a Particle Argon being put into DFU mode" width="320" height="259"&gt;&lt;/a&gt;Put your device into DFU mode before starting the debug process.&lt;/p&gt;&lt;/center&gt;

&lt;p&gt;&lt;em&gt;Note: Step debugging 3rd generation devices with Mesh features enabled is currently unsupported due to requirements of the Nordic SoftDevice in the nrf52840. Devices in standalone mode, which is configurable during mobile setup, can be debugged with no issues.&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Workbench Debugging Basics
&lt;/h3&gt;

&lt;p&gt;Now that you’re setup on the hardware side, let’s start a debugging session and cover some Workbench basics. First, you’ll need to open a firmware project with Particle Workbench. I won’t cover the specifics of creating or importing projects in Workbench, so be sure to consult the &lt;a href="https://docs.particle.io/workbench/"&gt;docs&lt;/a&gt; if you need more info.&lt;/p&gt;
&lt;h4&gt;
  
  
  Starting a Debug Session
&lt;/h4&gt;

&lt;p&gt;To start a debug session, click on the Debug icon to open the debug sidebar. Then click the debug dropdown and select the “Particle Debugger (argon, boron, xenon)” option.&lt;/p&gt;


&lt;center&gt;&lt;p id="attachment_5184"&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--7NQ1sLqT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.particle.io/wp-content/uploads/2019/05/DebugMenu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7NQ1sLqT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.particle.io/wp-content/uploads/2019/05/DebugMenu.png" alt="Image of selecting the Particle Debugger from the VS Code debug meny" width="450" height="482"&gt;&lt;/a&gt;The debug sidebar icon is… a bug. Pretty easy to spot, which is more than I can say for the bugs I tend to create in my code.&lt;/p&gt;&lt;/center&gt;

&lt;p&gt;Now, get ready to wait a bit as Workbench creates a debug binary for your project. This will go much faster on repeat runs, but the first run is a good time to grab a cup of coffee, take a stretch break, or practice your &lt;a href="https://xkcd.com/303/"&gt;sword-fighting in the hallway&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Once the debug binary is built and flashed to your device, Workbench will halt and your device will power down, which you’ll see once the onboard RGB LED turns off. You’ll also see the following message in the Debug Console, which is expected.&lt;/p&gt;


&lt;center&gt;&lt;p id="attachment_5185"&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4YdV7Z7P--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.particle.io/wp-content/uploads/2019/05/DebugConsole.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4YdV7Z7P--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.particle.io/wp-content/uploads/2019/05/DebugConsole.png" alt="An Image of the debug Console in Particle Workbench" width="500" height="212"&gt;&lt;/a&gt;The message here is normal when starting a debug session&lt;/p&gt;&lt;/center&gt;

&lt;p&gt;Click the continue button to power your device back up. Once you’re breathing cyan again, you’re ready to debug!&lt;/p&gt;


&lt;center&gt;&lt;p id="attachment_5186"&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--VAqvIbDE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.particle.io/wp-content/uploads/2019/05/ContinueButton.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--VAqvIbDE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.particle.io/wp-content/uploads/2019/05/ContinueButton.png" alt="Image of the debug menu with the continue button called out in a red rectangle" width="500" height="281"&gt;&lt;/a&gt;The continue button is the play button at the left of the step debugging box.&lt;/p&gt;&lt;/center&gt;
&lt;h4&gt;
  
  
  Setting Breakpoints
&lt;/h4&gt;

&lt;p&gt;The first thing you’ll likely want to do is set some breakpoints so you can pause and inspect running code. You can set breakpoints by clicking in the gutter next to an individual line, or from the “Breakpoints” section of the debug sidebar. When a breakpoint is set, a red circle will appear next to the line on which to break.&lt;/p&gt;


&lt;center&gt;&lt;p id="attachment_5188"&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--llZ2msyG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.particle.io/wp-content/uploads/2019/05/DebugSidebar.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--llZ2msyG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.particle.io/wp-content/uploads/2019/05/DebugSidebar.png" alt="Image of a code snippet with a single line set as a breakpoint" width="600" height="357"&gt;&lt;/a&gt;Click on the gutter next to any line to set a breakpoint&lt;/p&gt;&lt;/center&gt;


&lt;center&gt;&lt;p id="attachment_5187"&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--c_dtNKZa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.particle.io/wp-content/uploads/2019/05/DebugSide.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--c_dtNKZa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.particle.io/wp-content/uploads/2019/05/DebugSide.png" alt="Image of setting a breakpoint using the sidebar" width="450" height="125"&gt;&lt;/a&gt;You can also add breakpoints in the sidebar by referencing a function by name&lt;/p&gt;&lt;/center&gt;

&lt;p&gt;It’s also possible to set breakpoints that only break code when a condition you define is met. You can set conditional breakpoints that pause execution when a condition is true, or when a hit counter is passed. In the screenshot below, I’ve set a breakpoint to pause when an Ultrasonic distance sensor reads a value less than 100 cm.&lt;/p&gt;


&lt;center&gt;&lt;p id="attachment_5190"&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6cBlP6X6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.particle.io/wp-content/uploads/2019/05/ConditionalBreakpoint.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6cBlP6X6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.particle.io/wp-content/uploads/2019/05/ConditionalBreakpoint.png" alt="Image of a conditional breakpoint" width="600" height="166"&gt;&lt;/a&gt;Use conditional breakpoints when you want to fine-tune how and when to break on a line of code.&lt;/p&gt;&lt;/center&gt;
&lt;h4&gt;
  
  
  Stepping through code
&lt;/h4&gt;

&lt;p&gt;Once a breakpoint is hit, the line in question will be highlighted in yellow. From here, you can use the Debug menu at the top of the screen to step through your code. From left to right in the image below, those buttons allow you to continue, step over the current line, step into the current line, step out of the current scope, restart the debug session (you’ll need to put the device back in DFU mode for this to work) and finally, to disconnect the session.&lt;/p&gt;


&lt;center&gt;&lt;p id="attachment_5191"&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ZpyZIIMT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.particle.io/wp-content/uploads/2019/05/DebugMenuTop.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ZpyZIIMT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.particle.io/wp-content/uploads/2019/05/DebugMenuTop.png" alt="Image of the debug menu in Particle Workbench" width="339" height="69"&gt;&lt;/a&gt;During debugging, this handy menu will appear at the top of your Workbench screen.&lt;/p&gt;&lt;/center&gt;

&lt;p&gt;Hitting continue resumes execution until the next breakpoint is hit. Most of the time, you’ll end up using the step into, over and out buttons to explore your code.&lt;/p&gt;


&lt;center&gt;&lt;p id="attachment_5192"&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--El9_1m6L--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.particle.io/wp-content/uploads/2019/05/HighlightBreak.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--El9_1m6L--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.particle.io/wp-content/uploads/2019/05/HighlightBreak.png" alt="image of code with the debugger paused on a breakpoint" width="600" height="223"&gt;&lt;/a&gt;When paused on a breakpoint, the current line will be highlighted in yellow.&lt;/p&gt;&lt;/center&gt;

&lt;p&gt;Let’s consider the difference between stepping over and into the following line of code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;range = ultrasonic.MeasureInCentimeters();
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Clicking step over will move execution to the next line, &lt;code&gt;Serial.print()&lt;/code&gt; and pause again. From here, you can inspect variables, the call stack, and more. If the line in question is a function, you can also step into the source of that function. This is really handy when debugging in firmware libraries, like in the case of the &lt;code&gt;MeasureInCentimeters&lt;/code&gt; function, which is part of the &lt;a href="https://build.particle.io/libs/Grove-Ultrasonic-Ranger/1.0.1/tab/Ultrasonic.cpp"&gt;Grove-Ultrasonic-Ranger&lt;/a&gt; library!&lt;/p&gt;


&lt;center&gt;&lt;p id="attachment_5194"&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--D2-IQvPm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://blog.particle.io/wp-content/uploads/2019/05/StepInto.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--D2-IQvPm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://blog.particle.io/wp-content/uploads/2019/05/StepInto.gif" alt="Gif of step debugging into a library function" width="480" height="372"&gt;&lt;/a&gt;The debugger can step into locally-installed firmware libraries&lt;/p&gt;&lt;/center&gt;

&lt;p&gt;Once inside a function, you can use the “Step Out” option to continue execution through the rest of the current function and break again on the next line after that function returns.&lt;/p&gt;

&lt;p&gt;Step debugging allows you to inspect your code, code in firmware libraries, and even sources in the Device OS firmware! Ever wanted to explore the internals of how Particle’s brilliant firmware team implemented &lt;code&gt;Particle.publish()&lt;/code&gt;? With Workbench debugging, you can!&lt;/p&gt;


&lt;center&gt;&lt;p id="attachment_5242"&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--0xiH_6h6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://blog.particle.io/wp-content/uploads/2019/05/PublishStepIntoOpt.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0xiH_6h6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://blog.particle.io/wp-content/uploads/2019/05/PublishStepIntoOpt.gif" alt="Gif of stepping into a Particle.publish function call" width="640" height="424"&gt;&lt;/a&gt;You can also step-debug into Device OS internals!&lt;/p&gt;&lt;/center&gt;
&lt;h4&gt;
  
  
  Inspecting variables
&lt;/h4&gt;

&lt;p&gt;Step debugging is magical in itself, I know. Often, however, the reason we need to debug in the first place is to check the state of our application when it reaches a breakpoint. Workbench provides a number of ways for you to do this. To begin with, when paused on a breakpoint, you can hover over a variable or object and a tooltip will appear with information about its state. You can also inspect the values of local and global variables using the Variables panel.&lt;/p&gt;


&lt;center&gt;&lt;p id="attachment_5198"&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Se8cKmqy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.particle.io/wp-content/uploads/2019/05/VariablesPanel.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Se8cKmqy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.particle.io/wp-content/uploads/2019/05/VariablesPanel.png" alt="image of the variables panel with local and global variables" width="450" height="606"&gt;&lt;/a&gt;The variables panel contains information about local, global and static state&lt;/p&gt;&lt;/center&gt;
&lt;h4&gt;
  
  
  Watching values
&lt;/h4&gt;

&lt;p&gt;Beyond inspecting local and global variables, you can use the watch panel to tell the debugger to keep track of the state of a given variable or object. This can be quite useful if you want to see how a portion of your application mutates or is affected by another variable, or if you want to take a closer look at when a given variable or object comes into or goes out of scope as your app is running.&lt;/p&gt;


&lt;center&gt;&lt;p id="attachment_5196"&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--p_X4LxY3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://blog.particle.io/wp-content/uploads/2019/05/Watch.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--p_X4LxY3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://blog.particle.io/wp-content/uploads/2019/05/Watch.gif" alt="Gif of the watch panel with a value changing" width="640" height="274"&gt;&lt;/a&gt;The watch panel is useful for keeping track of state while you debug&lt;/p&gt;&lt;/center&gt;
&lt;h4&gt;
  
  
  Navigating the call stack
&lt;/h4&gt;

&lt;p&gt;One of my favorite debugging features is the Call Stack navigator, which can come in quite handy when you’re spelunking the internals of a library or the Device OS firmware. The pane keeps running track of the stack from your current position up, and you can click on any entry in the stack to quickly navigate to that position.&lt;/p&gt;


&lt;center&gt;&lt;p id="attachment_5243"&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--NvBTKQTP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://blog.particle.io/wp-content/uploads/2019/05/CallStackBigOpt.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--NvBTKQTP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://blog.particle.io/wp-content/uploads/2019/05/CallStackBigOpt.gif" alt="" width="640" height="388"&gt;&lt;/a&gt;With the Call Stack panel, you can move around anywhere in the stack of the current breakpoint&lt;/p&gt;&lt;/center&gt;
&lt;h4&gt;
  
  
  Advanced Debugging Features
&lt;/h4&gt;

&lt;p&gt;In addition to the features covered in this post, the Workbench debugger provides access to several debug features built-in to VS Code and leveraged by the cortex-debug extension, including the ability to inspect and edit hardware registers, peripherals, and even direct memory locations. All of these are outside of the scope of this post, so check out the &lt;a href="https://code.visualstudio.com/docs/editor/debugging"&gt;docs for these tools&lt;/a&gt; to learn more about how to use them.&lt;/p&gt;

&lt;h4&gt;
  
  
  Additional Tips and Tricks
&lt;/h4&gt;

&lt;p&gt;Once you’re done debugging and ready to resume normal coding and flashing, you’ll need to get your device out of its debug state, meaning that you want to replace the “monolithic” debug build with the hybrid application and device OS firmware. To do this, put the device back into DFU mode and run the “&lt;code&gt;Particle: Flash application &amp;amp; Device OS (local)&lt;/code&gt;” command in the Workbench command palette.&lt;/p&gt;

&lt;p&gt;And if you ever run into weird errors while debugging or flashing, the Workbench clean commands are your friends! In my experience, when these things pop up, running “&lt;code&gt;Particle: Clean application &amp;amp; Device OS (local)&lt;/code&gt;” and “&lt;code&gt;Particle: Clean application for debug (local)&lt;/code&gt;” are usually enough to set things right again.&lt;/p&gt;

&lt;p&gt;Much as the web has come a long way since the early days of &lt;code&gt;alert()&lt;/code&gt;-based debugging, the built-in debugging capabilities of Particle Workbench will enable Particle developers everywhere to peer under the covers of their embedded applications with ease and confidence. Debugging with Particle Workbench is already a game-changer for me, and I bet it will be for you too.&lt;/p&gt;

&lt;p&gt;The post &lt;a href="https://blog.particle.io/2019/05/03/professional-debugging-for-iot-with-particle-workbench-going-beyond-serial-print/"&gt;Professional debugging for IoT with Particle Workbench: going beyond Serial.print()&lt;/a&gt; appeared first on &lt;a href="https://blog.particle.io"&gt;Particle Blog&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>vscode</category>
      <category>cpp</category>
      <category>productivity</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Particle Workbench: supercharge your IoT development with professional tools</title>
      <dc:creator>David Scheltema</dc:creator>
      <pubDate>Tue, 16 Apr 2019 15:45:42 +0000</pubDate>
      <link>https://forem.com/particle/particle-workbench-supercharge-your-iot-development-with-professional-tools-4c7f</link>
      <guid>https://forem.com/particle/particle-workbench-supercharge-your-iot-development-with-professional-tools-4c7f</guid>
      <description>&lt;p&gt;Particle Workbench brings everything you need for IoT development into a single tool. Built on Microsoft Visual Studio Code, Workbench adds Particle-specific integrations to help make you more productive. This our most powerful, professional IoT development environment yet and starting today, it’s now generally available with our custom, cross-platform Particle installer with support for Windows, Linux (Ubuntu), and macOS — &lt;a href="https://www.particle.io/workbench/#installation"&gt;download your copy right now.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Code faster, work more efficiently, compile where you want, and say goodbye to the frustration of toolchain management. Particle Workbench includes these features right out of the box with a hassle-free installation.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Compile where you want: local or cloud&lt;/li&gt;
&lt;li&gt;Stress-free toolchain management&lt;/li&gt;
&lt;li&gt;Built-in version control and debugging&lt;/li&gt;
&lt;li&gt;Flexible deployment: over-the-wire or over-the-air&lt;/li&gt;
&lt;li&gt;Code complete with IntelliSense for Particle device libraries&lt;/li&gt;
&lt;li&gt;Quick installation experience for Windows, Linux, and macOS&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--NgzPMOpE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://blog.particle.io/wp-content/uploads/2019/04/Workbench-welcome.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--NgzPMOpE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://blog.particle.io/wp-content/uploads/2019/04/Workbench-welcome.png" alt="Image of the Particle Workbench welcome screen." width="800" height="510"&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;
Download now and supercharge your IoT development &lt;a href="https://www.particle.io/workbench/#installation"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Professional tools to support your product development
&lt;/h2&gt;

&lt;p&gt;When your job is to build connected solutions, it’s essential to use professional tools to help you along the way. Workbench builds upon all the great features you already love about Particle and adds even more powerful, professional tools to help you succeed.&lt;/p&gt;

&lt;p&gt;Take for example Workbench support for cloud and local compilation. You decide where your code is built, but that’s just the beginning. Thanks to a powerful &lt;a href="https://docs.particle.io/tutorials/developer-tools/workbench/#dependency-manager"&gt;Dependency Manager&lt;/a&gt;, your toolchain automatically stays up-to-date no matter the compile location you choose.&lt;/p&gt;

&lt;p&gt;Native support for git and &lt;a href="https://docs.particle.io/tutorials/developer-tools/workbench/#debugging-3rd-generation-"&gt;debugging&lt;/a&gt;, giving you the ability to collaborate with colleagues and more efficiently troubleshoot bugs. And flexible deployment options mean you can use over-the-wire or over-the-air device flashing depending on your project requirements.&lt;/p&gt;

&lt;h2&gt;
  
  
  Open source, customized for you
&lt;/h2&gt;

&lt;p&gt;Under the hood, Workbench takes advantage of all the great features you already know and love about Visual Studio Code and adds powerful, Particle specific capabilities.&lt;/p&gt;

&lt;p&gt;Workbench is built on Visual Studio Code not just because it’s the experience developers love for a desktop environment, but also because of Microsoft’s commitment to &lt;a href="https://github.com/Microsoft/vscode"&gt;open source&lt;/a&gt;. Visual Studio Code enables an ecosystem of customizable themes and extensions all with continued investment in powerful features that support both embedded and web development.&lt;/p&gt;

&lt;h2&gt;
  
  
  Get started with Workbench now
&lt;/h2&gt;

&lt;p&gt;Whether you’ve tried a Workbench Developer Preview or this is your first time using the tools, the new installer is quick and doesn’t require a deep understanding of cross-compilers or development toolchains. Installation takes a few clicks of the mouse before you’ll be coding.&lt;/p&gt;

&lt;p&gt;The installer is smart enough to check your system to determine if you have Visual Studio Code installed or not and knows what to install without any need for user action. Because of this, the installer is safe to use if you already have Visual Studio Code on your machine.&lt;/p&gt;

&lt;p&gt;Download Particle Workbench &lt;a href="https://www.particle.io/workbench/#installation"&gt;here&lt;/a&gt;, dive into the &lt;a href="https://docs.particle.io/workbench/"&gt;docs&lt;/a&gt;, and let us know what you think in the &lt;a href="https://community.particle.io/c/particle-workbench"&gt;community forum&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The post &lt;a href="https://blog.particle.io/2019/04/16/particle-workbench-ga/"&gt;Particle Workbench: supercharge your IoT development with professional tools&lt;/a&gt; appeared first on &lt;a href="https://blog.particle.io"&gt;Particle Blog&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>iot</category>
      <category>showdev</category>
      <category>vscode</category>
      <category>productivity</category>
    </item>
    <item>
      <title>How to build a control panel for your Particle-powered brewing projects</title>
      <dc:creator>Brandon Satrom</dc:creator>
      <pubDate>Wed, 27 Mar 2019 21:13:02 +0000</pubDate>
      <link>https://forem.com/particle/how-to-build-a-control-panel-for-your-particle-powered-brewing-projects-28m5</link>
      <guid>https://forem.com/particle/how-to-build-a-control-panel-for-your-particle-powered-brewing-projects-28m5</guid>
      <description>&lt;p&gt;A few weeks ago, I &lt;a href="https://dev.to/particle/upcycling-an-old-homebrewing-project-with-a-particle-argon-587k"&gt;detailed my process&lt;/a&gt; for upcycling a Photon-based project of mine—the Brew Buddy—to the new Particle Argon. I covered creating a new breadboard prototype, adding a few new features not in the Photon version, and the process of converting the firmware to work with the Argon.&lt;/p&gt;

&lt;p&gt;In this post, I’ll cover the second half of the project: from prototype to PCB and cloud-based control panel. As with the first part of this project, I’ve been &lt;a href="http://(https://twitch.tv/brandonsatrom)" rel="noopener noreferrer"&gt;live-streaming all my work on this project over on Twitch&lt;/a&gt;, so if you want to watch the replays, or join me for future projects, head over to my page and give me a follow to get notified.&lt;/p&gt;

&lt;h3&gt;
  
  
  Designing a new PCB with Eagle and OSH park
&lt;/h3&gt;

&lt;p&gt;Having the ability to breadboard a new project is amazing, but once I get everything working, I can’t wait to get rid of that rats nest of wires and replace them with a fancy, custom-designed Printed Circuit Board (PCB). My original Brew Buddy project saw several PCB revisions over its early life, so of course I had to spin another board for this Argon-based iteration.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.particle.io%2Fwp-content%2Fuploads%2F2019%2F03%2FBoardIterations.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.particle.io%2Fwp-content%2Fuploads%2F2019%2F03%2FBoardIterations.png" alt="Various iterations of the Brew Buddy board"&gt;&lt;/a&gt;Various iterations of the Brew Buddy custom PCB that I’ve used over the years.&lt;/p&gt;

&lt;h4&gt;
  
  
  Creating PCBs in Autodesk Eagle
&lt;/h4&gt;

&lt;p&gt;There are a number of tools out there for designing PCBs, including free tools like KiCAD and high-end tools like Altium and OrCAD. I tend to do my PCB design in Autodesk Eagle. It’s a powerful tool with a bit of a learning curve (like all tools of its ilk), but once you get the hang of it, it makes the process of bringing your breadboard prototypes to life a fun and rewarding process.&lt;/p&gt;

&lt;p&gt;Since I had an existing version of the PCB for my Photon-based project, my process here was a relatively straightforward one:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Replace the Photon with the Argon&lt;/li&gt;
&lt;li&gt;Re-route the pins to the proper places on the Argon&lt;/li&gt;
&lt;li&gt;Add an additional pin for the SD card chip-select on the Adafruit TFT breakout&lt;/li&gt;
&lt;li&gt;Add the Piezo disc (and resistor)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When creating custom PCBs, you could etch your own with dangerous chemicals, or let fabrication pros handle the process at a fairly affordable price. For the digital design of the final PCB, there are two key assets you’ll create: a schematic, and a layout. The schematic is the logical design of the board and is meant to show where all of the electrical connections are made between components on the board. Here’s a before and after view of how my schematic changed for this project:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.particle.io%2Fwp-content%2Fuploads%2F2019%2F03%2FBBSchematic-1024x423-test-1024x423.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.particle.io%2Fwp-content%2Fuploads%2F2019%2F03%2FBBSchematic-1024x423-test-1024x423.png"&gt;&lt;/a&gt;A side-by-side comparison of the Brew Buddy schematic.&lt;/p&gt;

&lt;p&gt;The layout describes the physical placement of the components on your PCB. It’s coupled tightly to the logical, schematic design so that your connections are logically, valid, but the layout is where you place components and draw copper traces between them. Here’s a before and after view of the physical layout of the PCB:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.particle.io%2Fwp-content%2Fuploads%2F2019%2F03%2FBBLayout-1024x703.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.particle.io%2Fwp-content%2Fuploads%2F2019%2F03%2FBBLayout-1024x703.png"&gt;&lt;/a&gt;A side-by-side comparison of the Brew Buddy layout&lt;/p&gt;

&lt;p&gt;My new Brew Buddy PCB is larger, partly to accommodate the larger Argon, and also to make room for the new Piezo. I could have made it smaller, but then I wouldn’t have an excuse to spin another rev of the boards, now would I?&lt;/p&gt;

&lt;p&gt;The most time-consuming aspect of the four-step migration was the first: moving from the Photon to the Argon required a re-mapping of every logical and physical connection. Eagle does have a Swap Part tool that makes this a bit easier, but in the spirit of being careful and thorough, I didn’t use it so that I could verify every connection.&lt;/p&gt;

&lt;p&gt;All in all, this part of the process took me just a couple of hours. If you’re interested in watching how this process played out, I live streamed it on Twitch, and you can find the recording below.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/AQd3qdI9BUE"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h4&gt;
  
  
  Ordering PCBs from OSH Park
&lt;/h4&gt;

&lt;p&gt;With the board design done, it was time to order PCBs. There are a bevy of great, online PCB fabs around these days, but one of my personal favorites is &lt;a href="https://oshpark.com/" rel="noopener noreferrer"&gt;OSH Park&lt;/a&gt;. They are inexpensive, quick, and if you like the color purple, you’ll love their PCBs.&lt;/p&gt;

&lt;p&gt;Ordering PCBs from OSH Park is simple. All you need to do is drag the Eagle &lt;code&gt;.brd&lt;/code&gt; file onto the “Let’s get started” drop zone and OSH Park will read the file, generate the layer instructions and give you a price estimate. If you have a Zip file with Gerber files (a set of individual files that represent the layers in a fabricated PCB, and pronounced like the baby food) you can upload those as well.&lt;/p&gt;

&lt;p&gt;OSH park also allows you to make your PCBs publicly available for others to consume and even order. &lt;a href="https://oshpark.com/shared_projects/PQWUFWaS" rel="noopener noreferrer"&gt;Here’s mine&lt;/a&gt; for the Brew Buddy if you’d like to take a look for yourself.&lt;/p&gt;

&lt;p&gt;Once I had my PCBs ordered, I passed the time waiting by working on my web-based control panel, which we’ll cover in the rest of this post. When the PCBs arrived a week or so later, I did live stream the assembly (often called PCBa) and testing, which you can check out below.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/33dgf-r6pe4"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h3&gt;
  
  
  Building a web-based control panel with Azure IoT and electric io
&lt;/h3&gt;

&lt;p&gt;For the “cloud” portion of this project, I wanted to build a control panel, not just a dashboard. I wanted to be able to move between brew monitoring states (brewing vs. fermenting) and trigger actions from the same interface where I would view charts, graphs and the current state of my app. With the Azure IoT Hub and a great open source project called &lt;a href="https://github.com/noopkat/electric-io" rel="noopener noreferrer"&gt;electric io&lt;/a&gt;, I was able to do just that.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.particle.io%2Fwp-content%2Fuploads%2F2019%2F03%2FScreenshot-2019-03-27-08.40.58-1024x689.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.particle.io%2Fwp-content%2Fuploads%2F2019%2F03%2FScreenshot-2019-03-27-08.40.58-1024x689.png"&gt;&lt;/a&gt;My electric io dashboard for Brew Buddy&lt;/p&gt;

&lt;p&gt;The entire process consisted of the following steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Wire my project up to Azure IoT Hub&lt;/li&gt;
&lt;li&gt;Configure electric io to display device data&lt;/li&gt;
&lt;li&gt;Add MQTT to my Firmware to receive cloud-to-device (C2D) messages from Azure&lt;/li&gt;
&lt;li&gt;Configure electric io to Send C2D Messages&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The first step is covered extensively in our Docs on setting up an Azure IoT Hub integration with the Particle Device Cloud, so I won’t repeat them here. In addition, Paul DeCarlo from Microsoft &lt;a href="https://blog.particle.io/2018/09/28/create-the-dashboard-of-your-dreams-with-particle-electric-io/" rel="noopener noreferrer"&gt;covered the second step in a recent blog post&lt;/a&gt;, so I’m going to gloss over that section as well. Key and unique to this project are steps three and four, which enabled me to turn electric io from a dashboard, into a true control panel.&lt;/p&gt;

&lt;h4&gt;
  
  
  Using MQTT to listen for Azure IoT Hub Messages
&lt;/h4&gt;

&lt;p&gt;The &lt;a href="https://docs.particle.io/tutorials/integrations/azure-iot-hub/" rel="noopener noreferrer"&gt;Particle Device Cloud to Azure IoT Hub integration&lt;/a&gt; gives you a quick, painless connection between your Particle Device and Azure. It allows you to use the Particle.publish API as you would in any other project, and pipe that data into Azure directly.&lt;/p&gt;

&lt;p&gt;In order to add Azure to Device communication, we need to do a bit more in our firmware. The Azure IoT Hub supports two modes of direct integration with the IoT hub: a language SDK, or through direct implementation of pub/sub through MQTT or AMQP. For this project, I opted to use MQTT.&lt;/p&gt;

&lt;p&gt;For Particle devices, there are two great MQTT libraries to choose from, &lt;a href="https://github.com/hirotakaster/MQTT" rel="noopener noreferrer"&gt;MQTT&lt;/a&gt; for basic support, and &lt;a href="https://github.com/hirotakaster/MQTT-TLS" rel="noopener noreferrer"&gt;MQTT-TLS&lt;/a&gt; when a secure, certificate-based MQTT connection is needed. Azure IoT Hub requires a secure connection, so I installed the MQTT-TLS library and included it in my project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include “MQTT-TLS.h”
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To create a TLS-based connection, you also need a client certificate, which Microsoft provides in their SDKs. I grabbed the DigiCert Baltimore Root certificate from their GitHub repo, and created a new file called &lt;code&gt;certs/h&lt;/code&gt; in my project, which I included right after the MQTT library include.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;"certs/certs.h"&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The next step is to declare a callback function for all MQTT inbound messages, and create an MQTT client. I created a forward declaration for the callback and configured the client URI and port based on the online docs. Be sure to replace the &lt;code&gt;{your hub name}&lt;/code&gt; string with the name of your own Azure IoT Hub, which you can find in the Azure Portal for your account.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;mqttCB&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;topic&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;byte&lt;/span&gt; &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;unsigned&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;MQTT&lt;/span&gt; &lt;span class="nf"&gt;client&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{your hub name}.azure-devices.net"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;8883&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;mqttCB&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The next step is to connect to the Azure MQTT server when the project starts up. In the &lt;code&gt;setup&lt;/code&gt; function, I enabled TLS and pass in the certificate I downloaded and created earlier. Then, I called the &lt;code&gt;connect&lt;/code&gt; method with my deviceID (&lt;code&gt;deviceID = System.deviceID();&lt;/code&gt;) and a username and password.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;enableTls&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;certificates&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;certificates&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;deviceID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"{your hub name}.azure-devices.net/"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;deviceID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
  &lt;span class="s"&gt;"SharedAccessSignature {your SAS Token here}"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the case of the Azure IoT Hub, the username you provide should be your hub endpoint—like &lt;code&gt;myhub.azure-devices.net—plus&lt;/code&gt; your Particle deviceID.&lt;/p&gt;

&lt;p&gt;For the password, &lt;a href="https://docs.microsoft.com/en-us/azure/iot-hub/iot-hub-devguide-security" rel="noopener noreferrer"&gt;Azure requires&lt;/a&gt; that you provide a SharedAccessSignature, or SAS Token. You can generate these for your own hubs with the Azure &lt;a href="https://github.com/Azure/azure-iot-sdk-csharp/blob/master/tools/DeviceExplorer" rel="noopener noreferrer"&gt;device explorer&lt;/a&gt;, the &lt;a href="https://docs.microsoft.com/en-us/cli/azure/ext/azure-cli-iot-ext/iot/hub?view=azure-cli-latest#ext-azure-cli-iot-ext-az-iot-hub-generate-sas-token" rel="noopener noreferrer"&gt;Azure CLI&lt;/a&gt; or the &lt;a href="https://marketplace.visualstudio.com/items?itemName=vsciot-vscode.azure-iot-tools" rel="noopener noreferrer"&gt;Azure IoT Tools for VS Code&lt;/a&gt;, which is what I did. I was already in VSCode building my app with Particle Workbench, so it was easy!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.particle.io%2Fwp-content%2Fuploads%2F2019%2F03%2FVSCode.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.particle.io%2Fwp-content%2Fuploads%2F2019%2F03%2FVSCode.gif"&gt;&lt;/a&gt;The Azure IoT Hub VSCode extension in action&lt;/p&gt;

&lt;p&gt;The next step is to check the &lt;code&gt;isConnected&lt;/code&gt; method to determine if I successfully made an MQTT connection to the Azure IoT Hub. In either case, I added some Particle.publish calls so that I can double-check this from the console.&lt;/p&gt;

&lt;p&gt;If I get a positive result, it’s time to set up a subscription. Azure IoT Hub provides two ways to receive communication on embedded devices, Direct Method calls (which always send a response) and Cloud-to-Device (or C2D) messages, which function more like fire-and-forget messages. I decided to use C2D messages. To receive these, the MQTT client needs to subscribe to the &lt;code&gt;devices/{deviceID}/messages/devicebound/#&lt;/code&gt; topic filter.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;isConnected&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt; 
  &lt;span class="n"&gt;Particle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;publish&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"mqtt/status"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"connected"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;msgSubResult&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"devices/"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;deviceID&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; 
    &lt;span class="s"&gt;"/messages/devicebound/#"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;MQTT&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;QOS0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="n"&gt;Particle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;publish&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"mqtt/message-sub-result"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;msgSubResult&lt;/span&gt; 
    &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="s"&gt;"subscribed to hub messages"&lt;/span&gt; 
    &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"subscription failed"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;Particle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;publish&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"mqtt/status"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"failed"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With the subscription set up, the last step is to define the callback. On the electric io side, my plan was to send a payload to the device that contained at least a property named &lt;code&gt;methodName&lt;/code&gt;, which would correspond to a brewing mode on the device, like “brew,” “ferment,” or “stop.” On the firmware side, that meant I needed to receive and parse the payload to extract the &lt;code&gt;methodName&lt;/code&gt;. Thankfully, there’s a great &lt;a href="https://github.com/rickkas7/JsonParserGeneratorRK" rel="noopener noreferrer"&gt;JsonParserGenerator library&lt;/a&gt; for just this purpose.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;mqttCB&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;topic&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;byte&lt;/span&gt; &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;unsigned&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt; 
  &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="n"&gt;pload&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt; 
  &lt;span class="n"&gt;memcpy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pload&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 
  &lt;span class="n"&gt;pload&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 

  &lt;span class="n"&gt;jsonParser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;clear&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; 
  &lt;span class="n"&gt;jsonParser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;addString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pload&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 

  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;jsonParser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
    &lt;span class="n"&gt;String&lt;/span&gt; &lt;span class="n"&gt;methodName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; 
      &lt;span class="n"&gt;jsonParser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getReference&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"methodName"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;valueString&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; 

    &lt;span class="n"&gt;Particle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;publish&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"mqtt/message-method"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;methodName&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 

    &lt;span class="n"&gt;setBrewMode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;methodName&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This method takes the payload byte array, converts it to a character array, loads it into the &lt;code&gt;jsonParser&lt;/code&gt;, and extracts the &lt;code&gt;methodName&lt;/code&gt; from the payload before calling the &lt;code&gt;setBrewMode&lt;/code&gt; function, which [fires off a number of actions based on the mode string](http://(&lt;a href="https://github.com/bsatrom/brew-buddy/blob/master/brew-buddy-firmware/src/brew-buddy-firmware.ino#L365" rel="noopener noreferrer"&gt;https://github.com/bsatrom/brew-buddy/blob/master/brew-buddy-firmware/src/brew-buddy-firmware.ino#L365&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;With MQTT in place, I was able to turn my electric io dashboard into a control panel!&lt;/p&gt;

&lt;h4&gt;
  
  
  Sending Messages from Electric IO to a Particle-powered project
&lt;/h4&gt;

&lt;p&gt;Electric Io provides a Button type that makes it easy to call functions and send messages. Just select “button” in the Card Type dropdown and click “create.”&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.particle.io%2Fwp-content%2Fuploads%2F2019%2F03%2FCreateButton.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.particle.io%2Fwp-content%2Fuploads%2F2019%2F03%2FCreateButton.gif"&gt;&lt;/a&gt;Creating a new button card in electric io&lt;/p&gt;

&lt;p&gt;Once you’ve created a button, you’ll need to choose the call type. If calling a Direct method on an Azure IoT device, you’ll want to specify the methodName and an optional payload. For a message, which is what I used, there’s no methodName, but you’ll want to specify a payload. In the example below, I define a payload of &lt;code&gt;{‘methodName’: ‘brew’}&lt;/code&gt; to tell my device to move into brewing mode.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.particle.io%2Fwp-content%2Fuploads%2F2019%2F03%2FBrewMessage.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.particle.io%2Fwp-content%2Fuploads%2F2019%2F03%2FBrewMessage.gif"&gt;&lt;/a&gt;Defining the button call type and payload&lt;/p&gt;

&lt;p&gt;After saving button settings, the card will change into just a title and button. To test, I can just click away!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.particle.io%2Fwp-content%2Fuploads%2F2019%2F03%2FStartBrew.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.particle.io%2Fwp-content%2Fuploads%2F2019%2F03%2FStartBrew.gif"&gt;&lt;/a&gt;Triggering a C2D Message with electric io&lt;/p&gt;

&lt;p&gt;And if everything was configured on the firmware side correctly, I’ll see my device respond to the inbound message from Azure IoT!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.particle.io%2Fwp-content%2Fuploads%2F2019%2F03%2FStartBrewDevice.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.particle.io%2Fwp-content%2Fuploads%2F2019%2F03%2FStartBrewDevice.gif"&gt;&lt;/a&gt;Brewing begins when the message is received!&lt;/p&gt;

&lt;h3&gt;
  
  
  What’s next?
&lt;/h3&gt;

&lt;p&gt;As an &lt;a href="https://dev.to/bsatrom/building-iot-firmware-with-azure-pipelines-and-particle-2m30"&gt;endless tinkerer&lt;/a&gt;, I’ll never claim that a project is done, but I feel pretty good about where this project is in terms of being on new Particle hardware and leveraging a sweet, cloud-based control panel.&lt;/p&gt;

&lt;p&gt;I suppose the next logical step is to brew some beer!&lt;/p&gt;

&lt;p&gt;If you’re interested in seeing the nitty-gritty as I assembled my custom PCB and built out the Azure IoT Hub integration with MQTT, you can check out the live stream replays below. I stream my IoT builds on Mondays and Thursdays on Twitch, so be sure to follow and join me for more Particle-powered fun!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://youtu.be/33dgf-r6pe4" rel="noopener noreferrer"&gt;Part 5 – PCB Soldering and Assembly&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://youtu.be/t-lQW4xnHA4" rel="noopener noreferrer"&gt;Part 6 – Implementing Sleep modes and fermentation support&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://youtu.be/GVgVbZCyZ5w" rel="noopener noreferrer"&gt;Part 7 – Integrating Brew Buddy with Azure IoT Hub and electric io&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://youtu.be/eJM_d4UVQ9Y" rel="noopener noreferrer"&gt;Part 8 – Adding MQTT Support to Brew Buddy firmware&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://youtu.be/GJ9Qs-vwPyU" rel="noopener noreferrer"&gt;Part 9 – Adding MQTT Support (continued)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://youtu.be/ZMyPXpL0l44" rel="noopener noreferrer"&gt;Part 10 – Implementing C2D Message Support in electric io&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://youtu.be/Iol2KemBENE" rel="noopener noreferrer"&gt;Part 11 – Implementing C2D Message Support in electric io (continued)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The post &lt;a href="https://blog.particle.io/2019/03/27/how-to-build-a-control-panel-for-your-particle-powered-brewing-projects/" rel="noopener noreferrer"&gt;How to build a control panel for your Particle-powered brewing projects&lt;/a&gt; appeared first on &lt;a href="https://blog.particle.io" rel="noopener noreferrer"&gt;Particle Blog&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>cpp</category>
      <category>programming</category>
      <category>web</category>
      <category>iot</category>
    </item>
    <item>
      <title>Take your IoT career to new heights with these 3 instructive IoT video playlists</title>
      <dc:creator>David Scheltema</dc:creator>
      <pubDate>Mon, 25 Mar 2019 21:10:50 +0000</pubDate>
      <link>https://forem.com/particle/take-your-iot-career-to-new-heights-with-these-3-instructive-iot-video-playlists-171e</link>
      <guid>https://forem.com/particle/take-your-iot-career-to-new-heights-with-these-3-instructive-iot-video-playlists-171e</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.particle.io%2Fwp-content%2Fuploads%2F2019%2F03%2Fmountain-1246297_1920.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.particle.io%2Fwp-content%2Fuploads%2F2019%2F03%2Fmountain-1246297_1920.jpg"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I might not bring the intensity quite like Steve Ballmer famously did while chanting “&lt;a href="https://youtu.be/Vhh_GeBPOhs" rel="noopener noreferrer"&gt;Developers! Developers! Developers!&lt;/a&gt;” during the Microsoft 25 Anniversary Celebration in 2000, but that doesn’t mean I’m not &lt;em&gt;super&lt;/em&gt; excited for great IoT videos for developers.&lt;/p&gt;

&lt;p&gt;Whether you consume your videos at work or watch them with a big tub of popcorn from the comfort of your home, you can’t go wrong learning about new technical topics from instructive IoT videos. Here are three new Particle videos series that you’ll not want to miss.&lt;/p&gt;

&lt;h2&gt;
  
  
  Particle 101: the video series designed to help you become an IoT pro
&lt;/h2&gt;

&lt;p&gt;Over the past few months, &lt;a href="https://blog.particle.io/author/brandonsatrom/" rel="noopener noreferrer"&gt;Brandon Satrom&lt;/a&gt; our Developer Advocate has been busy putting together a series of videos covering the essentials to help you get the most out of your Particle products. Most of the videos in the series focus on Gen 3 hardware — that’s the &lt;a href="https://store.particle.io/collections/mesh" rel="noopener noreferrer"&gt;Argon, Boron, and Xenon&lt;/a&gt; — however many of the non-mesh content is applicable to Gen 2 hardware like the &lt;a href="https://store.particle.io/collections/photon" rel="noopener noreferrer"&gt;Photon&lt;/a&gt; and &lt;a href="https://store.particle.io/collections/electron" rel="noopener noreferrer"&gt;Electron&lt;/a&gt; as well.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/xf9nCV_cur8"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;In the latest Particle 101 video, Brandon tackles how you can use &lt;code&gt;publish()&lt;/code&gt; and &lt;code&gt;subscribe()&lt;/code&gt; to send messages between different devices on your local, mesh network. This video is one of seven (at the time of publication) Particle 101 videos to help you get started with IoT and Particle. &lt;a href="https://www.youtube.com/watch?v=0T5rFu-9JAI&amp;amp;list=PLIeLC6NIW2tKvC5W007j_PU-dxONK_ZXR" rel="noopener noreferrer"&gt;Here’s the link&lt;/a&gt; to the full Particle 101 playlist.&lt;/p&gt;

&lt;h2&gt;
  
  
  Introducing Particle: Interviews with the people building Particle
&lt;/h2&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/OgW8yMLZE3Q"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Equal parts &lt;a href="https://www.npr.org/people/2100593/terry-gross" rel="noopener noreferrer"&gt;Terry Gross&lt;/a&gt; and &lt;a href="https://youtu.be/Vhh_GeBPOhs" rel="noopener noreferrer"&gt;Steve Ballmer&lt;/a&gt;, Brandon’s newest video series focuses on getting to know the people powering Particle. Get ready for great conversations and tune in live for a chance to have your question answered.&lt;/p&gt;

&lt;p&gt;In the first episode of the series, &lt;a href="https://youtu.be/OgW8yMLZE3Q" rel="noopener noreferrer"&gt;Brandon sat down with Mohit Bhoite&lt;/a&gt; to talk circuits, rapid prototyping, and what it feels like to have designed every piece of Particle hardware ever released. Mohit’s interest span from low-level electrical engineering to gorgeous solder sculptures that should rightly be called art.&lt;/p&gt;

&lt;h2&gt;
  
  
  Twitching for more videos: here’s a live solution
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.particle.io%2Fwp-content%2Fuploads%2F2019%2F03%2FBrandon-Streaming.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.particle.io%2Fwp-content%2Fuploads%2F2019%2F03%2FBrandon-Streaming.jpg"&gt;&lt;/a&gt;A typical &lt;a href="https://www.twitch.tv/brandonsatrom" rel="noopener noreferrer"&gt;Twitch streaming&lt;/a&gt; setup from Brandon. Catch him weekly on Monday and Thursday.&lt;/p&gt;

&lt;p&gt;And if you’re still looking for more video content, Brandon has you covered. Each Monday and Thursday he &lt;a href="https://www.twitch.tv/brandonsatrom" rel="noopener noreferrer"&gt;livestreams on Twitch&lt;/a&gt;. While you never know exactly what Brandon will be working on, his livestream is a fantastic way to get clues on what cool new things are coming next.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://makezine.com/projects/diy-swarmbots/" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.particle.io%2Fwp-content%2Fuploads%2F2019%2F03%2FMakeMagcover_68-231x300.jpg"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Most recently, Brandon upcycled an old Photon DIY brewing project to use an Argon and hacked inexpensive Drug Store remote controlled cars to use Particle Gen 3 hardware — you can see his full instructions in the annual &lt;a href="https://makezine.com/projects/diy-swarmbots/" rel="noopener noreferrer"&gt;Make: magazine board’s issue here&lt;/a&gt;. Here’s a quick link to the start of the &lt;a href="https://youtu.be/krEzdnlpqC0" rel="noopener noreferrer"&gt;brewing playlist&lt;/a&gt; and to the &lt;a href="https://youtu.be/Ye1tNUzeoLk" rel="noopener noreferrer"&gt;R/C car hacking&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  IoT Developers, IoT Developers, IoT Developers!
&lt;/h2&gt;

&lt;p&gt;Whew, it does feel good! Perhaps Ballmer was onto something here. Regardless of your intensity level, be sure to watch the videos and let us know what you think. Comments, suggestions, and constructive criticism are always welcome. Oh, and don’t miss the next &lt;a href="https://www.twitch.tv/brandonsatrom/videos" rel="noopener noreferrer"&gt;Particle livestream&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Finally, be sure to share what you’re working on in the &lt;a href="https://community.particle.io/" rel="noopener noreferrer"&gt;community forum&lt;/a&gt; or on &lt;a href="https://twitter.com/particle" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;. I can’t wait to see what you’re making.&lt;/p&gt;

&lt;p&gt;The post &lt;a href="https://blog.particle.io/2019/03/25/instructive-iot-video-playlists/" rel="noopener noreferrer"&gt;Take your IoT career to new heights with these 3 instructive IoT video playlists&lt;/a&gt; appeared first on &lt;a href="https://blog.particle.io" rel="noopener noreferrer"&gt;Particle Blog&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>developer</category>
      <category>iot</category>
      <category>hardware</category>
      <category>firmware</category>
    </item>
    <item>
      <title>Upcycling an old homebrewing project with a Particle Argon</title>
      <dc:creator>Brandon Satrom</dc:creator>
      <pubDate>Mon, 04 Mar 2019 18:24:59 +0000</pubDate>
      <link>https://forem.com/particle/upcycling-an-old-homebrewing-project-with-a-particle-argon-587k</link>
      <guid>https://forem.com/particle/upcycling-an-old-homebrewing-project-with-a-particle-argon-587k</guid>
      <description>

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--DlzyJ4rJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/wmcv1lilznvflmdxkxh8.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--DlzyJ4rJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/wmcv1lilznvflmdxkxh8.jpg" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;New 3rd generation &lt;a href="https://particle.io"&gt;Particle&lt;/a&gt; hardware is here, and there’s a lot to love. I have an old, Photon-based project that I’ve been itching to update and add a few new features to, so I decided to see just how easy it would be to migrate a Photon-based project to the new &lt;a href="https://store.particle.io/products/argon-kit"&gt;Argon&lt;/a&gt;, hardware, firmware and all.&lt;/p&gt;

&lt;p&gt;In addition to this post, you can also go behind the scenes with this build in a series of &lt;a href="https://twitch.tv/brandonsatrom"&gt;Twitch live streams&lt;/a&gt; I’ve recorded and &lt;a href="https://www.youtube.com/channel/UCpYjkSkGOXAMXeZjZkbb-PQ"&gt;posted to YouTube&lt;/a&gt; over the last several weeks. &lt;a href="https://youtu.be/krEzdnlpqC0"&gt;Here’s the first video in the series&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Introducing the Brew Buddy
&lt;/h2&gt;

&lt;p&gt;I’m a home brewer, which is no surprise given that I live in Austin, TX. Not only is homebrewing common in these parts, but every Austin area household must have at least one homebrewer in order to claim city residence.&lt;/p&gt;

&lt;p&gt;That last statement is not true, but it should be.&lt;/p&gt;

&lt;p&gt;I’ve been homebrewing for about eight years, and I’m drawn to it for the same reason many are: not so much for the end product but the process and chemistry of it all. As with cooking and baking, it’s fascinating to take discrete ingredients and—by alchemy—transform them into something enjoyable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Current Brew Buddy Specs
&lt;/h2&gt;

&lt;p&gt;As a techie and maker, it should come as no surprise that I’ve explored ways to incorporate technology into my brewing. One example is the Brew Buddy, a connected homebrew monitoring system that tracks wort—the pre-beer mixture of water, grains, malt, and hops — temperatures during the cooking stage of the brewing process. The current version of the project includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A Particle Photon as the brains of the project&lt;/li&gt;
&lt;li&gt;One Type-K Thermocouple for measuring wort temperature&lt;/li&gt;
&lt;li&gt;A 2.2 in TFT display for showing temperature readings and a historical temperature graph&lt;/li&gt;
&lt;li&gt;A custom PCB designed in Eagle and fabricated by the fine folks at OSH Park&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--rMV4MMq_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.particle.io/wp-content/uploads/2019/03/PhotonBB.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--rMV4MMq_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.particle.io/wp-content/uploads/2019/03/PhotonBB.png" alt="Brew Buddy Photon"&gt;&lt;/a&gt;The original Brew Buddy build used a Photon with custom PCB.&lt;/p&gt;

&lt;p&gt;The Photon powers and orchestrates the board, while also publishing temperature readings to the Particle cloud so that I can visualize trends from one brew to the next.&lt;/p&gt;

&lt;p&gt;Brew Buddy began — as these things typically do — on a breadboard. Once my design was set, I CNC milled a few PCB revs (my first custom PCBs ever!) and when I was satisfied, contracted a PCB manufacturer for production. That was nearly four years ago, and Brew Buddy is ready for an upgrade.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Dy3ZUJud--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.particle.io/wp-content/uploads/2019/03/BoardIterations.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Dy3ZUJud--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.particle.io/wp-content/uploads/2019/03/BoardIterations.png" alt="Various iterations of the Brew Buddy board"&gt;&lt;/a&gt;Various iterations of the Brew Buddy custom PCB that I’ve used over the years.&lt;/p&gt;

&lt;p&gt;I had a few ideas for things to add to the project, like a piezo-based knock sensor to detect when fermentation begins. Particle’s new 3rd generation hardware was the perfect motivation to add those features, design a new board, and explore just how easy it would be to port my project from the Photon to the Argon.&lt;/p&gt;

&lt;p&gt;Spoiler alert: it was so easy! Like hitting that giant red office supply chain button easy.&lt;/p&gt;

&lt;h2&gt;
  
  
  Breadboarding a new prototype
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Iz5G1hFs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.particle.io/wp-content/uploads/2019/03/FeatureLarge-1024x492.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Iz5G1hFs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.particle.io/wp-content/uploads/2019/03/FeatureLarge-1024x492.jpg" alt=""&gt;&lt;/a&gt;Prototyping an Argon-powered Brew Buddy began with a breadboard and jumper wires.&lt;/p&gt;

&lt;p&gt;With any new hardware project, even when updating or swapping out components or MCUs, I like to start with a rats nest of jumper wires a breadboard prototype. This an essential step in making sure that I’ve wired everything correctly before taking the time and expense to design and order a board.&lt;/p&gt;

&lt;p&gt;As a bonus, the tangled mess of wires plugged into tiny, nearly invisible slots serves as a pleasant reminder of my ever-increasing age as I squint darkly between wires and try to get everything in the right place.&lt;/p&gt;

&lt;p&gt;Also, turning a mess of wires into copper traces under the solder mask is pretty amazing. It evokes the same feeling like the things in that &lt;a href="https://www.youtube.com/watch?v=MoAGqV7cvqY"&gt;Monday.com commercial&lt;/a&gt; that I find myself not skipping every time I go to YouTube to watch a video about how to beat my kids at Super Smash Bros.&lt;/p&gt;

&lt;h2&gt;
  
  
  My approach to Brew Buddy hardware migration
&lt;/h2&gt;

&lt;p&gt;For the Brew Buddy migration, there were two steps to my breadboard prototype:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Map the existing components (the TFT and Thermocouple) to new pins on the Argon&lt;/li&gt;
&lt;li&gt;Add new connections for the SD Card on the TFT (so I can display bitmaps on the screen) and a thin piezo to function as a “knock sensor.”&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;All-told, I ended up using 11 GPIO pins on the Argon, up from 9 on the Photon and this was just to get to features packed into the project. There was a bit of trial and error when adding the new features, but I was able to get my prototype up and running in just a few hours.&lt;/p&gt;

&lt;h2&gt;
  
  
  Porting the firmware
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--R1D2EDMn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.particle.io/wp-content/uploads/2019/03/CodeComparison.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--R1D2EDMn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.particle.io/wp-content/uploads/2019/03/CodeComparison.png" alt="Photon to Argon code changes"&gt;&lt;/a&gt;Images showing the difference between the Photon and Argon source code changes — only three lines needed an update.&lt;/p&gt;

&lt;p&gt;With the breadboard prototype all wired up, it was time to port the firmware. I expected that this would consist of three tasks:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Update pin-mappings from the Photon to the Argon.&lt;/li&gt;
&lt;li&gt;Update firmware libraries I used, if needed.&lt;/li&gt;
&lt;li&gt;Add libraries and new firmware for the knock sensor and displaying Images on the TFT.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Going into this stage, I wasn’t sure how long each step would take, especially the first two. I was confident that &lt;a href="https://www.particle.io/device-os/"&gt;Device OS&lt;/a&gt; would ensure that the changes needed between boards would be minimal, but I had no idea what “minimal” would entail.&lt;/p&gt;

&lt;h2&gt;
  
  
  Your migration may vary…
&lt;/h2&gt;

&lt;p&gt;And with the caveat that YMMV depending on the features and libraries that you’re using for an older project, I was pleasantly surprised to find that, in order to get my existing Photon-based project running on the Argon, I had to change a grand total of THREE lines of code. And all three were GPIO pin mappings for the thermocouple. You can see the &lt;a href="https://github.com/bsatrom/brew-buddy/commit/5024e5ee0dca1f4a5d0951f375b1c2292cdf25f0#diff-059541daca1fa00a0e7e9fa4579ab0a3"&gt;diff here&lt;/a&gt; if you want proof.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_JqqdDTO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.particle.io/wp-content/uploads/2019/03/BeerTFT2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_JqqdDTO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.particle.io/wp-content/uploads/2019/03/BeerTFT2.png" alt=""&gt;&lt;/a&gt;Testing the Argon-powered Brew Buddy firmware.&lt;/p&gt;

&lt;p&gt;The majority of the work was on the physical pin-mapping side as I was setting up the prototype. Since both the TFT and Thermocouple are SPI devices, I needed to make sure the jumper wires were connected to the Argon’s SPI pins (A6-A8) instead of A3-A5 for the Photon.&lt;/p&gt;

&lt;p&gt;On the firmware libraries front, everything “just worked.” When I first started this project, I was manually including libraries for the TFT and Thermocouple, so my only real step here was adding references to the libraries in my &lt;a href="https://github.com/bsatrom/brew-buddy/commit/7aa10f9ffbea99801ba9d6c5b2b7bed7eb690eb2"&gt;project.properties&lt;/a&gt; file and removing the library source files from my project. Everything compiled on the first try, and I was off to add new features.&lt;/p&gt;

&lt;p&gt;With the new features, I had a bit more work. The piezo is a simple analog sensor and was easy to add to my project. After a bit of trial and error, I was able to calibrate it to detect light movements for fermentation, and I even added Particle’s new sleep mode support so that my device can go offline during the 24-48 hours after cooking is done and wake up when the first sign of fermentation is detected.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;uint8_t&lt;/span&gt; &lt;span class="n"&gt;KNOCK_PIN&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;A4&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 

&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;setBrewMode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt; &lt;span class="n"&gt;command&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;command&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;"brew"&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;isBrewingMode&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
  &lt;span class="p"&gt;{&lt;/span&gt; 
    &lt;span class="c1"&gt;// Start brewing &lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; 
  &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;command&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;"ferment"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
  &lt;span class="p"&gt;{&lt;/span&gt; 
    &lt;span class="n"&gt;isBrewingMode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
    &lt;span class="n"&gt;isFermentationMode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
    &lt;span class="n"&gt;fermentationModeStartTime&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;millis&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="n"&gt;clearScreen&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;tft&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setCursor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;140&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;printSubheadingLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Waiting for"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;printSubheadingLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Fermentation..."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;KNOCK_PIN&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;CHANGE&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; 
  &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;command&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;"stop"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
  &lt;span class="p"&gt;{&lt;/span&gt; 
    &lt;span class="c1"&gt;// Stop&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; 

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;loop&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt; 
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;isFermentationMode&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; 
    &lt;span class="kt"&gt;int16_t&lt;/span&gt; &lt;span class="n"&gt;knockVal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;analogRead&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;KNOCK_PIN&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;knockVal&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
    &lt;span class="p"&gt;{&lt;/span&gt; 
      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;isFermenting&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt; 
        &lt;span class="n"&gt;isFermenting&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;fermentationStartTime&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;millis&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;lastKnock&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fermentationStartTime&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="n"&gt;clearScreen&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;tft&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setCursor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;tft&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setTextColor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ILI9341_YELLOW&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;tft&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setTextSize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;tft&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Fermentation started"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 
        &lt;span class="n"&gt;tft&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setTextColor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ILI9341_WHITE&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 

        &lt;span class="n"&gt;displayFermentationHeading&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="n"&gt;waitUntil&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Particle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;connected&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 
        &lt;span class="n"&gt;Particle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;publish&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"fermentation/state"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"start"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; 
  &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;isBrewingMode&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; 
    &lt;span class="c1"&gt;// Brewing mode logic&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Brew Buddy now with bitmap support
&lt;/h2&gt;

&lt;p&gt;Adding bitmaps to the TFT was a bit more complicated, and included porting the &lt;code&gt;Adafruit_ImageReader&lt;/code&gt; library into the Particle Ecosystem (&lt;a href="https://github.com/bsatrom/Adafruit_ImageReader"&gt;which is public, so please use it!&lt;/a&gt;). With a new library in hand, however, it was just a few more lines of code to get a nice fancy image on the splash screen of my project.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;Adafruit_ILI9341&lt;/span&gt; &lt;span class="n"&gt;tft&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Adafruit_ILI9341&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TFT_CS&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;TFT_DC&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;TFT_RST&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 
&lt;span class="n"&gt;Adafruit_ImageReader&lt;/span&gt; &lt;span class="n"&gt;reader&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
&lt;span class="n"&gt;SdFat&lt;/span&gt; &lt;span class="n"&gt;sd&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 

&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;setup&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;tft&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;begin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TFT_SPEED&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;sd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;begin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SD_CS&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;sd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;initErrorHalt&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; 

  &lt;span class="n"&gt;printSplash&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; 

&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;printSplash&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; 
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;ImageReturnCode&lt;/span&gt; &lt;span class="n"&gt;stat&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
  &lt;span class="n"&gt;tft&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setRotation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="n"&gt;clearScreen&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="n"&gt;stat&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;reader&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;drawBMP&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"brew.bmp"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tft&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="n"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="n"&gt;tft&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setCursor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;40&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 
  &lt;span class="n"&gt;printHeadingTextLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"BrewBuddy"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 
  &lt;span class="n"&gt;printHeadingTextLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;APP_VERSION&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="n"&gt;printSubheadingLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Created by"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 
  &lt;span class="n"&gt;printSubheadingLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Brandon Satrom"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="n"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  What’s next?
&lt;/h2&gt;

&lt;p&gt;I’m pleased to say that, so far, this Photon to Argon port has been a success! With minimal changes to firmware, I was able to take an older project, refresh it, and start adding new functionality.&lt;/p&gt;

&lt;p&gt;And of course, a new working prototype means an excuse to spin a new board and add some cloud-based visualizations of my brews! Stay tuned for part two of this post, where I’ll share the rest of this project and the results of a test brew!&lt;/p&gt;

&lt;p&gt;In the meantime, I’m streaming nearly every step of this project live on Twitch on Tuesdays and Thursdays. Be sure to follow me there, and click the links below for replays of the initial few streams:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://youtu.be/krEzdnlpqC0"&gt;Part 1 – Creating the Prototype and porting firmware&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://youtu.be/AQd3qdI9BUE"&gt;Part 2 – Creating a custom PCB in Eagle&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://youtu.be/EcKBL6Y56u8"&gt;Part 3 – Adding new firmware for the SD Card reader and Piezo&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://youtu.be/OgW8yMLZE3Q"&gt;Part 4 – PCB soldering and assembly&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;See you in a few weeks!&lt;/p&gt;

&lt;p&gt;The post &lt;a href="https://blog.particle.io/2019/03/04/upcycling-homebrewing/"&gt;Upcycling an old homebrewing project with a Particle Argon&lt;/a&gt; appeared first on &lt;a href="https://blog.particle.io"&gt;Particle Blog&lt;/a&gt;.&lt;/p&gt;


</description>
      <category>howto</category>
      <category>iot</category>
      <category>cpp</category>
      <category>particle</category>
    </item>
    <item>
      <title>How to Select the Right IoT Hardware: From Prototype to Production</title>
      <dc:creator>Jeffrey</dc:creator>
      <pubDate>Mon, 23 Jul 2018 11:06:01 +0000</pubDate>
      <link>https://forem.com/particle/how-to-select-the-right-iot-hardware-from-prototype-to-production-8f8</link>
      <guid>https://forem.com/particle/how-to-select-the-right-iot-hardware-from-prototype-to-production-8f8</guid>
      <description>&lt;h4&gt;
  
  
  A comprehensive guide that explores the difference between IoT development kits, MPM kits, and mass production modules
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://cdn-images-1.medium.com/max/1024/1*YH_uDaxpOcaod2LBIhrGGg.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://cdn-images-1.medium.com/max/1024/1*YH_uDaxpOcaod2LBIhrGGg.jpeg" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;IoT development boards and modules are at the center of every connected product. As IoT has developed, the variety and technical capabilities of these boards has only become more complex. When building an IoT product, you’ll want to start with a simple prototyping kit, but as you progress through the hardware development and design process, you’ll need to invest in hardware boards that are designed for scaling and manufacturing.&lt;/p&gt;

&lt;p&gt;But what is the difference between prototyping and production hardware? This article aims to clean up some of the noise and make it easier for you to choose the right hardware solution for your IoT product.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is the difference between prototyping and production hardware?
&lt;/h3&gt;

&lt;p&gt;In general, you can easily differentiate between prototype and production hardware based on these features:&lt;/p&gt;

&lt;p&gt;Prototyping hardware is optimized for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Flexibility&lt;/strong&gt;  — usually breadboardable and has an open SIM card slot&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Affordability&lt;/strong&gt;  — low cost&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Modularity&lt;/strong&gt;  — compatibility with other hardware ecosystems&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ease of use&lt;/strong&gt;  — can be setup in minutes and comes with tools&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Beginner audiences&lt;/strong&gt;  — content and examples optimized for beginners&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Mass production hardware is optimized for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Reliability&lt;/strong&gt;  — Has SMT(surface-mount-technology) components, can withstand extreme temperatures, and comes with hardware warranties&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Manufacturability&lt;/strong&gt;  — pick and place machine ready&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;High volumes&lt;/strong&gt;  — Can be purchased in bulk via a reliable distribution partner&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ease of integration&lt;/strong&gt;  — should have complete product certifications&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Advanced audiences&lt;/strong&gt;  — comprehensive datasheets and application notes&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Prototype &amp;amp; production hardware examples
&lt;/h3&gt;

&lt;p&gt;For instance, &lt;a href="https://www.particle.io/"&gt;Particle&lt;/a&gt; produces three basic kinds of hardware — Development kits (DKs), Evaluation kits (EVKs), and Mass production modules (MPMs). These are defined below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://cdn-images-1.medium.com/max/1000/0*ZAtehe3M2aiVPVrL.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://cdn-images-1.medium.com/max/1000/0*ZAtehe3M2aiVPVrL.jpg" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Development kits (DKs)
&lt;/h3&gt;

&lt;p&gt;Development kits are breadboard friendly and optimized for expandability, modularity, and ease-of-use. As a result, they can be used for scaling depending on the use case and application, but maybe best used as short term PoCs in friendly environments.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Intended use &lt;/strong&gt; — Useful for iterating/prototyping hardware and firmware systems quickly. It provides a quick start solution and gets an IoT project rolling.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Features&lt;/strong&gt;  — USB connectivity, ecosystem of hardware accessories, breadboard-able headers, RGB status LED, on-board antenna, affordable costs&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Audience &lt;/strong&gt; — Hobbyist developers, engineers very new to hardware&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Examples&lt;/strong&gt;  — &lt;a href="https://www.particle.io/wifi"&gt;Argon&lt;/a&gt;, &lt;a href="https://www.particle.io/cellular"&gt;Boron&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://cdn-images-1.medium.com/max/768/0*wBe0J5CSXeAIdmce.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://cdn-images-1.medium.com/max/768/0*wBe0J5CSXeAIdmce.jpg" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Mass production modules (MPMs)
&lt;/h3&gt;

&lt;p&gt;Mass production modules are optimized for deployment in a mass production product, not for development. These are the real deal, intended for deployment for 5–10 years in hostile environments and small spaces. These products have little utility until they are soldered into your end product.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Intended use&lt;/strong&gt;  — Deployment in a mass production product&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Features&lt;/strong&gt;  — Certifications, hardware warranty and support, environmental robustness, optimized for size and manufacturability&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Audience&lt;/strong&gt;  — Companies manufacturing products at scale&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Examples&lt;/strong&gt;  — &lt;a href="https://docs.particle.io/datasheets/photon-(wifi)/photon-datasheet/"&gt;P0&lt;/a&gt; / &lt;a href="https://docs.particle.io/datasheets/photon-(wifi)/p1-datasheet/"&gt;P1&lt;/a&gt; / &lt;a href="https://docs.particle.io/datasheets/electron-(cellular)/e-series-datasheet/"&gt;E Series MPMs&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://cdn-images-1.medium.com/max/1024/0*rZEP150fIwkK39df.png" class="article-body-image-wrapper"&gt;&lt;img src="https://cdn-images-1.medium.com/max/1024/0*rZEP150fIwkK39df.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  MPM evaluation kits (EVKs)
&lt;/h3&gt;

&lt;p&gt;MPM Evaluation kits are expansion boards for mass production modules and allow you to develop, iterate, and debug your IoT solution quickly and easily. In other words, they provide a friendlier development experience for mass production hardware solutions. They have a MPM soldered to them, and in many ways can act as a good reference design.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Intended use&lt;/strong&gt;  — Companies designing a product for deployment at scale, companies iterating from DKs to MPMs. Useful for iterating and refining production firmware in the context of production hardware (MPMs).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Features&lt;/strong&gt;  — Largest number of GPIO and peripherals, large/comfortable debugging-optimized board layout, application notes and professional documentation&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Audience &lt;/strong&gt; — Professional engineers who are comfortable designing custom circuit boards, companies with intentions to deploy at scale&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Example&lt;/strong&gt;  — &lt;a href="https://store.particle.io/products/e-series-evaluation-kit"&gt;E Series Evaluation Kit&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Other factors to consider when choosing IoT hardware
&lt;/h3&gt;

&lt;p&gt;When you’re sourcing hardware for prototyping or production, you should also look at the platform, tools, and support that comes with it:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Consistent platform, infrastructure, firmware, and development tools
&lt;/h3&gt;

&lt;p&gt;You’ll want to continue using the same cloud infrastructure and development tools as you scale. Switching between different hardware designs is enough of a task, you don’t want to carry this over to the software you are using. The same firmware application, when compiled on your DKs and MPMs, should perform exactly the same way. There should never be a need to tweak or modify the firmware application to get it running on a MPM.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Domain experts &amp;amp; support
&lt;/h3&gt;

&lt;p&gt;When selecting a hardware-solution, it’s also important to consider the community surrounding it. Hardware solutions with limited adoption will have fewer resources available to aid you in development. For example, Particle’s development kits have a large developer community surrounding it, which makes it easier to find information and support when needed.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Ease of deployment
&lt;/h3&gt;

&lt;p&gt;You want to be able to get your product up and running as quickly as possible. When sourcing hardware, check the articles and documentation that comes with it. Having these resources at the ready will make it easy for you to get your questions answered immediately.&lt;/p&gt;

&lt;h3&gt;
  
  
  The bottom line
&lt;/h3&gt;

&lt;p&gt;When sourcing prototyping and production hardware, you want to examine its accessibility, affordability, integrations, and manufacturing features. Whether you’re prototyping or building a scalable IoT product, you want to choose hardware that offers a consistent platform environment and ease-of-deployment.&lt;/p&gt;




</description>
      <category>iotplatform</category>
      <category>hardware</category>
      <category>iot</category>
      <category>howto</category>
    </item>
  </channel>
</rss>
