Lab 4 - Putting it all together

Project Goal Explore messaging between Mesh devices, and other Particle primitives.
What you’ll learn How-to: use the Particle Web IDE to write device firmware; using Particle primitives to communicate between devices and networks.
Tools you’ll need An Argon, A Xenon, two Grove Shields, an Ultrasonic distance sensor, a 4-Digit Display, A Grove Chainable LED
Time needed to complete 30 minutes

In this session, it will all come together. One device is measuring a distance and broadcasting the value, while another is listening for updates and displaying them on a digital display.

Partner up with your neighbor

For this session, it is necessary to cooperate in groups of at least two participants. Group members will have to implement different code depending on the role of their device. One group member should implement the remote distance sensor code, the other(s) should implement the remote display code.

Did you come prepared?
Make sure you have completed all the prerequisites before advancing beyond this point.

Remote distance sensor

In a previous session you wrote code that read the distance from the ultrasonic distance sensor in the Grove sensor kit. Now we take those capabilities to the mesh. If you get stuck in the code, the final code for the remote distance measurer is available here.

  1. In the Particle Web IDE, make a new app and call it "RemoteDistanceSensor" (or come up with a more creative name).

  2. Add the Grove-Ultrasonic-Ranger library to the app.

  3. Copy paste the part of the code that did the reading of the sensor in the 2nd lab. It should look something like the following (delete the automatically added #include line when importing the library).

     #include "Ultrasonic.h"
    
     Ultrasonic ultrasonic(D2);
    
     int lastRange = 0;
    
     void setup() {
         Serial.begin(9600);
     }
    
     void loop() {
         int range;
    
         Serial.println("Obstacle found at:");
    
         range = ultrasonic.MeasureInCentimeters();
         Serial.print(range); //0~400cm
         Serial.println(" cm");
    
         if (range != lastRange) {
             lastRange = range;
    
             // Publish measurement
    
         }
    
         delay(250);
     }
    
  4. Now take that reading and publish it to the mesh network. The group needs to agree on a name for the event – in the example we will use distance. Insert the mesh.publish function instead of the Publish measurement comment line. Convert the range number to a String before publishing it.

     Mesh.publish("distance",String(range));
    
  5. Upload this code to the device connected to the distance sensor.

    You now have a working distance sensor publishing its readings to the network.

Remote display

Let's build a remote distance display. If you get stuck in the code, the final code for the remote distance measurer is available here.

  1. Make a new app for the displaying device and call it "Remote4DigitDisplay" (feel free to freestyle the name though).

  2. Add the Grove_4Digit_Display library to the app.

  3. Replace the include statement that was added with #include "TM1637.h".

  4. Define the pins used for the display, create a display variable and initialize the display. The app should now look something like this.

     #include "TM1637.h"
    
     #define CLK D4
     #define DIO D5
    
     TM1637 disp(CLK,DIO);
    
     void setup() {
         Serial.begin(9600);
    
         disp.init();
         disp.set(BRIGHT_TYPICAL);
     }
    
     void loop() {
    
     }
    
  5. You can now run the code, but it will not do anything interesting. So let's subscribe to the event data published by the other device in our mesh network. Add the subscription line to the setup function.

     Mesh.subscribe("distance", displayDistance);
    
  6. Now, every time the device receives a distance event, the function displayDistance will be called. We will write this function now. Insert the function above the setup function, and simply just write the received String to the terminal.

     void displayDistance(const char *event, const char *data) {
         Serial.print("Mesh 'distance' event received with data: ");
         Serial.println(data);
     }
    
  7. Right now the number is stored as a String, so it needs to be converted to an integer (int). This is simply done by the build-in atoi function. Insert the following line right before the print statements.

     // Convert String (data) to int (range)
     int range = atoi(data);
    
  8. Now that you have an integer, you can display the value in the 4-digit display. First declare these two variables in the beginning of the displayDistance function.

     int digit;
     int pos = 3;
    
  9. Then paste the forand while loop you used previously with the display, to the bottom of the displayDistance function.

     // Fill display with zeros
     for (int i = 0; i < 4; i++) {
         disp.display(i, 0);
     }
    
     // Extract each digit from the range and write it to the display
     while (range >= 1) {
         // Get the current digit by performing modulo (%) division on the range
         digit  = range % 10;
         // Remove the trailing digit by whole-number division
         range /= 10;
    
         disp.display(pos, digit);
         pos--;
     }
    
  10. Upload this code to the device connected to the distance sensor.

Now, every time a distance measurement is broadcast by the sensor device, the display is updated, hooray!!!

This concludes the workshop

Feedback for the workshop
If you fill out this 5 question survey, we may improve this workshop to benefit future workshoppers, or just pat ourselves on the back for doing great.

More mesh?

Feel you want more mesh? Try adding features to your IoT mesh solution see these hidden hints.