Learn how this Particle Argon uses BLE to send temperature readings to a smartphone app

Learn how to use the new Particle Bluetooth APIs to send temperature data from a Xenon to your mobile phone.

Jordy Moors article author avatarJordy MoorsJune 26, 2019
Learn how this Particle Argon uses BLE to send temperature readings to a smartphone app

As you can probably guess, I’m a huge fan of connected devices. But many IoT projects send everything to the cloud by default. While this might not seem like a problem, it can introduce a few unexpected consequences like increased latency and data availability. That’s why, when I design connected projects, I always ask myself, “can I keep it local?”

In this tutorial, I’ll show you how to build a connected thermometer that can relay its data locally, using the new Particle BLE APIs. This build is inspired by one of the many new BLE API examples and expands the project to add a Grove sensor. My hope is that by following my build, you’ll end up with an understanding of how BLE can help your connect project.

Required hardware

In order to follow along with this guide, you’ll need the following items:


Hardware assembly

The physical build of this project is straightforward, so I decided to build an enclosure to keep things tidy — scroll down for my design files.

The physical build of this project is straightforward, so I decided to build an enclosure to keep things tidy — scroll down for my design files.

Assembly of the project is really easy, thanks to the simplicity of the Grove system. No need to solder anything.

First, insert your Particle Argon into the Grove FeatherWing. Then connect a wire between the FeatherWing’s A2 port and the Grove Temperature and Humidity sensor. Your wiring should look like the image shown above.

Grove FeatherWing port Sensor
A2 Temperature & humidity sensor

Go the extra mile with a custom enclosure

The custom enclosure I made for the project features easy access to the Grove connectors and keeps the project all in one place.

The custom enclosure I made for the project features easy access to the Grove connectors and keeps the project all in one place.

To keep the project tidy, now and for future additions, I decided to create a universal enclosure for the Grove shield and a battery. I opted to use a laser cutter since it’s quick, leaves a nice finish and I happened to have access to one. You can find the design files I made here.

While I used a laser, there’s no reason you couldn’t adapt my design files for a 3D printer or even a hand-cut enclosure. Whatever approach you take to create a box for your build, if you do make changes to my design, please be sure to share your work with the community — a Particle forum post is a great way to share.

Sprinkle a bit of code on it and you’ll be connected in no time

Type Grove in the library manager and look for the Grove_Temperature_And_Humidity_Sensor library.

Type Grove in the library manager and look for the Grove_Temperature_And_Humidity_Sensor library.

The hardware assembly is of secondary importance in this build, whereas the software makes it interesting. Since the example this project is based on, is well documented, I’ll mostly focus on the changes that need to be made to make it work with the grove sensor.

Copy and paste the example code into a new project in the Web IDE. Or you can click here to automatically load the code in the Web IDE for you.

Find the Grove_Temperature_And_Humidity_Sensor library by searching for it in the library manager of the Web IDE. Include the library in your project by clicking the “include in project” button after which you can select your project, and confirm the include.

Take a closer look at the source code

Take a look at the temperature library example to see what it’s made up of. That way, it’s easier to grasp what needs to be added to the existing code in order for it to work. As you’ll notice there’s a pin definition before the setup routine, along with a library object. Both of those will need to be present in the combined project. Make sure you change the pin to the correct port you’re using – I’m using A2.

The content of the setup routine can be copied in its entirety and added to the new combined setup.

Finally, the actual measurement part needs to be taken care of. In the existing code, this is simply a random number that gets increased or decreased randomly.

float getTempC() {
    // Adjust this by a little bit each check so we can see it change
    if (rand() > (RAND_MAX / 2)) {
        lastValue += 0.1;
    }
    else {
        lastValue -= 0.1;
    }

    return lastValue;
}

In order to get the actual temperature from the sensor, you’ll replace this by the code from the library example loop, with the exception of the delay.

float getTempC() {
    //Read Humidity
    float h = dht.getHumidity();
    // Read temperature as Celsius
    float tempC = dht.getTempCelcius();
    // Read temperature as Farenheit
    float tempF = dht.getTempFarenheit();

    // Check if any reads failed
    if (isnan(h) || isnan(tempC) || isnan(tempF)) {
        Serial.println("Failed to read from DHT11 sensor!");
        return -1;
    }

    Serial.print("Humid: ");
    Serial.print(h);
    Serial.println("%  ");
    Serial.print("Temp: ");
    Serial.print(tempC);
    Serial.println("*C ");
    Serial.print("Temp: ");
    Serial.print(tempF);
    Serial.println("*F ");
    Serial.println();
    Serial.println();

    return tempC;
}

You’ll notice I’ve changed the variable names for the temperature to be a little bit more descriptive. Furthermore, I’ve added a negative return value in the failure check to indicate a failure, yet comply with the float return type of the function. Finally, I’ve made the last return value return the temperature in Celsius, since that’s what the rest of the code expects.

A large part of the code above isn’t strictly necessary, but available for debugging purposes. You could condense it down to the following while maintaining functionality.

float getTempC() {
    // Read temperature as Celsius
    float tempC = dht.getTempCelcius();

    // Check if any reads failed
    if (isnan(h) || isnan(tempC) || isnan(tempF)) {
        Serial.println("Failed to read from DHT11 sensor!");
        return -1;
    }

    return tempC;
}

You can find a copy of the entire code over here. Simply click this link, and select copy this app when you’re in the Web IDE.

What you can expect from the code

Provided you’ve followed the instructions correctly, you should now have a working thermometer whose values can be seen over bluetooth. In order to do so, download the Nordic nRF Toolbox mobile app, open it up and select the HTM sensor. Next, click connect and select your device. That’s it, you should now be able to see the current temperature.

Get started building your body temperature thermometer

Now you’ve got your device broadcasting data over Bluetooth, there’s a wide range of possibilities available. Here just a few of the ideas I have for where to go next.

  • Use it for local diagnostics, so you don’t use up data.
  • Eliminate a screen on your electric scooter by using your phone do display trip information without wasting valuable data.
  • Connect with additional bluetooth-only sensors you might already possess.
  • Or alternatively, check out some of the remaining tutorials in the Particle Docs.

Whatever you choose to do, share what you are building. The Particle forum is a great place to start — especially if you want feedback on unfinished builds. When you’re ready to share your full build, consider Hackster. And, be sure to Tweet a photo @Particle!