Water Quality Monitor
Collect water quality metrics from various sensors and upload them to the cloud via a cellular connection.
You Will Need
- Visual Studio Code (VS Code) with the PlatformIO extension
- Notecarrier F
- Notecard
- Swan
- Gravity: Analog ORP Sensor Meter for Arduino
- Gravity: Analog Industrial pH Sensor / Meter Pro Kit V2
- Gravity: Analog TDS Sensor/ Meter for Arduino
- 3 Gravity: Analog Signal Isolators
- Gravity: Waterproof DS18B20 Temperature Sensor Kit
- 256 mV ORP calibration solution
- 4.00 pH calibration solution
- 7.00 pH calibration solution
- 1000 ppm TDS calibration solution
- 5V DC power supply*
- Micro USB cable
- Breadboard
- Male-to-male jumper wires
* A wall wart with an adapter for breadboarding or a bench power supply will work.
Sensor Calibration
This application uses 4 sensors to measure the following quantities:
- Oxidation Reduction Potential (ORP)
- pH
- Total Dissolved Solids (TDS)
- Temperature
Temperature is measured with a digital sensor, but the other three quantities are measured with analog sensors and require calibration with calibration solutions. Calibrate each analog sensor by following DFRobot's documentation and using the calibration solutions linked in the table below.
The ORP calibration procedure involves computing an offset value. Once you have that value, edit firmware/water_quality_monitor/water_quality_monitor.ino
and replace 0 in the line #define ORP_OFFSET 0
with your value.
Hardware Setup
With the analog sensors calibrated, you're ready to assembly the circuitry.
Power
Since we'll be powering several sensors and boards, you must use an external power supply. All the parts accept 5V power. We recommend using either a DC regulated bench power supply or a 5V DC wall wart and a power jack adapter to allow for breadboarding. If you go with a wall wart, be warned that the power supplied needs to be stable, as the analog sensors have tight tolerances around their power requirements (+/- 0.1 V). We used a bench power supply, connecting the minus and plus ports to the corresponding rails on a breadboard:
When it comes time to power the various sensors, you can easily wire them up to the breadboard.
Analog Sensors
Each analog sensor (ORP, pH, and TDS) needs to be connected to an analog signal isolator. Why? DFRobot's page for the analog signal isolator board explains:
In many cases, electrical isolation is required to ensure the reliable operation of the sensors. Some sensors, such as pH sensors and conductivity sensors, will interfere with each other and do not measure properly in the same container when they connect to the same power. To ensure stable and reliable operation of the sensors with no interference, it is necessary to isolate the signal and the power.
- Connect the ORP probe's BNC connector to the ORP board, and use the 3-wire connector to connect the ORP board to the port labeled "SEN" on one of the isolator boards.
- Connect the pH probe's BNC connector to the ORP board, and use the 3-wire connector to connect the pH board to the port labeled "SEN" on one of the isolator boards.
- Connect the TDS probe's 2-wire connector to the TDS board, and use the 3-wire connector to connect the ORP board to the port labeled "SEN" on one of the isolator boards.
- Using male-to-male jumper wires, connect all the red wires from the sensors to the + rail of the breadboard, and connect all the black wires to the - rail.
As shown in the photo above, the blue LEDs should turn on when you apply power. Leave the third, blue wire of each sensor disconnected, for now. These are the signal lines that will be wired up to the Notecarrier.
Temperature Sensor
The DS18B20 temperature sensor kit linked above comes with a resistor module that acts as a pull up on the sensor's signal line. Make the following connections between the 3 wires of the sensor's probe and the resistor module:
Probe | Resistor module |
---|---|
Yellow | A |
Red | B |
Black | C |
As with the analog sensors, connect the red wire to the + rail of the breadboard, and connect the black wire to the - rail. Leave the green wire disconnected. This is the signal line that will be wired up to the Notecarrier.
Notecarrier
- Assemble Notecard and Notecarrier as described in the Notecard Quickstart.
- Plug the Swan into the Notecarrier, aligning the Swan's male headers with the Notecarrier's female headers.
- Using male-to-male jumper wires, making the following connections between the signal lines of the sensors and the pins of the Notecarrier. Remember that the signal lines for the analog sensors are the blue wires, and the signal line for the temperature sensor is the green wire.
Sensor Notecarrier ORP F_A0 pH F_A1 TDS F_A2 Temperature F_D5 - Connect the GND pin of the Notecarrier to the minus rail of the breadboard. Do not forget this step! It's critical that everything shares this GND connection.
- Connect a micro USB cable between a free USB port on your development PC and the micro USB port of the Swan.
- Place the probes of all 4 sensors into a container of water.
Notehub Setup
Sign up for a free account on notehub.io and create a new project.
Firmware
Operation
The firmware periodically reads the sensors, computes the measurements, and uploads the measurements to Notehub via the Notefile sensor.qo
. The time between between sensor readings defaults to 10 minutes, but this can be changed using the environment variable sample_period
. For example, if you set sample_period
to 5, the sensors will be read every 5 minutes.
Data from Notehub to the Notecard is synced every 5 minutes, and data from the Notecard to Notehub is synced every 10 minutes. You can change these values at compile-time with the macros INBOUND_MINS
and OUTBOUND_MINS
, respectively. These values are passed directly to the hub.set
command that gets issued when the Swan starts up.
Building and Flashing
To build and upload the firmware onto the Swan, you'll need VS Code with the PlatformIO extension.
- Download and install Visual Studio Code.
- Install the PlatformIO IDE extension via the Extensions menu of Visual Studio Code.
- Click the PlatformIO icon on the left side of VS Code, then click Pick a folder, and select the the firmware directory,
48-water-quality-monitor/firmware
. - In the file explorer, open
water_quality_monitor/water_quality_monitor.ino
and uncomment this line:// #define PRODUCT_UID "com.my-company.my-name:my-project"
. Replacecom.my-company.my-name:my-project
with the ProductUID of the Notehub project you created in Notehub Setup. - Click the PlatformIO icon again, and under the Project Tasks menu, click Build to build the firmware image.
- Prepare the Swan to receive the firmware image via DFU by following these instructions from the Swan Quickstart.
- Under the Project Tasks menu, click Upload to upload the firmware image to the MCU.
From here, you can view logs from the firmware over serial with a terminal emulator (e.g. minicom). On Linux, the serial device will be something like /dev/ttyACM0
. Use a baud rate of 115200 and 8-N-1 for the serial parameters.
Notehub Events
With the firmware running, you should begin to see notes come into Notehub on your project's Events tab.*
* The analog sensor values shown in this image are not realistic, as the sensors generating the measurements in this case weren't calibrated, yet.
Datacake Dashboard
If you want to visualize the data coming in from the Notecard, you can set up a Notehub route that transforms the contents of the sensor.qo
notes and pushes the resulting data to Datacake. This guide on our developer site will walk you through the whole process. When you get to the section "Use JSONata to Transfrom JSON", use this code to populate the JSONata expression box when creating the route:
(
{
"device": device,
"orp": body.orp,
"ph": body.ph,
"tds": body.tds,
"temp": body.temp
}
)
This transform script pares down the data in the notes to output:
device
: The DeviceUID of the Notecard.orp
: The ORP value in mV.ph
: The pH value.tds
: The TDS value in ppm.temp
: The water temperature in Celsius.
When you get to the point in our guide where you're setting up the HTTP Payload Decoder in Datacake, use this code:
function Decoder(request) {
var data = JSON.parse(request.body);
console.log(JSON.stringify(data))
var device = data.device;
var decoded = {};
decoded.orp = data.orp;
decoded.ph = data.ph;
decoded.tds = data.tds;
decoded.temp = data.temp;
// Array where we store the fields that are being sent to Datacake
var datacakeFields = []
// take each field from decoded and convert them to Datacake format
for (var key in decoded) {
if (decoded.hasOwnProperty(key)) {
datacakeFields.push({field: key.toUpperCase(), value: decoded[key], device: device})
}
}
// forward data to Datacake
return datacakeFields;
}
Once you've completed the routing guide, you'll have a dashboard to monitor the various water quality metrics. Here's an example dashboard that we created:
Blues Community
We’d love to hear about you and your project on the Blues Community Forum!