Sensing for Science - Level 6 Final Project
In this level we are going to create a circuit that will test the total dissolved
solids (TDS) in water using the GravityTDS sensor from DFRobot. It will also collect
the GPS location and save the data to a SD card. We will have a LCD display too. There
is a lot going on here with hardware and software, so take time to tape wires and
do some organizing. It will help with troubleshooting when out in the field. There
are many ways this circuit can be constructed. I will show you the way I did it, but
you can build it in the way you think is good.
Circuit Construction
Here is how I wired up this circuit. I will do a schematic for each device connected to the Arduino board. Take note, I will use the power rails on the breadboard for all 5v and GND connections.
LCD hook with I2C adaptor
GPS Hook up (Pin 1 = GND, Pin 2 = 6, Pin 3 = 7, Pin 4 = 5V)
TDS hook up (Image is from DFrobot’s wiki page)
SD car reader Hook Up
Button and Potentiometer hook up (note you can replace the potentiometer with a temperature sensor if you want, just make sure it is waterproof.)
Here is what mine looks like as a prototype. I used tape to organize wires and tape
down different modules.
Its now time to code this circuit. You can copy it from the worksheets or download
it from the Sensing for Science website. You will need the TDS library from DFRobot
which can be found here:
https://wiki.dfrobot.com/Gravity__Analog_TDS_Sensor___Meter_For_Arduino_SKU__SEN0244
#include <LiquidCrystal_I2C.h>
#include <SPI.h>
#include <SD.h>
#include <TinyGPS++.h>
#include <SoftwareSerial.h>
#include <EEPROM.h>
#include "GravityTDS.h"
// String to hold GPS data
String gpstext;
// GPS Connections
static const int RXPin = 6, TXPin = 5;
// GPS Baud rate (change if required)
static const uint32_t GPSBaud = 9600;
// TinyGPS++ object
TinyGPSPlus gps;
// SoftwareSerial connection to the GPS device
SoftwareSerial ss(RXPin, TXPin);
//I2C LCD
const int chipSelect = 4;
LiquidCrystal_I2C lcd(0x27,16,2); // set the LCD address to 0x3F for a 16 chars and 2 line display
//Button Push
int run;
int buttonPin;
//TDS
#define TdsSensorPin A1
GravityTDS gravityTds;
float tdsValue = 0;
//TMP
int degreesC = 0; //the temperature in Celsius, calculated
from the voltage
void setup() {
// Start Serial Monitor for debugging
Serial.begin(115200);
// Start SoftwareSerial
ss.begin(GPSBaud);
//Prep for Button Push
run = 0; //starts stopped
buttonPin = 7; //whatever pin your button is plugged into
pinMode(buttonPin, INPUT_PULLUP);
pinMode(2,INPUT);
//TDS startup
gravityTds.setPin(TdsSensorPin);
gravityTds.setAref(5.0); //reference voltage on ADC, default 5.0V on Arduino UNO
gravityTds.setAdcRange(1024); //1024 for 10bit ADC;4096 for 12bit ADC
gravityTds.begin(); //initialization
//LCD startup and SD Check
lcd.init();
lcd.clear();
lcd.backlight(); // Make sure backlight is on
if (!SD.begin(chipSelect)) {
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Card failed, or not present");
// don't do anything more:
while (1);
}
lcd.clear();
lcd.setCursor(0,0);
lcd.print("card initialized.");
delay(1000);
lcd.clear();
lcd.print("Finding Sats");
}
void loop() {
while (ss.available() > 0)
if (gps.encode(ss.read()))
// See if we have a complete GPS data string
if (displayInfo() != "0")
{
// Get GPS string
gpstext = displayInfo();
Serial.println(gpstext);
degreesC = map(analogRead(A0),0,1023,0,100);
gravityTds.setTemperature(degreesC); // set the temperature and execute temperature
compensation
gravityTds.update(); //sample and calculate
tdsValue = gravityTds.getTdsValue(); // then get the value
Serial.print(tdsValue,0);
Serial.println("ppm");
lcd.clear();
lcd.setCursor(0, 0); //set the cursor to the top left position
lcd.print("Degrees C: "); //print a label for the data
lcd.print(degreesC); //print the degrees Celsius
lcd.setCursor(0, 1); //set the cursor to the lower left position
lcd.print(tdsValue,0); //Print a label for the data
lcd.print("ppm"); //print the degrees Fahrenheit
//check button pressed, if so enter program condition (inside if statement)
if(digitalRead(buttonPin) == LOW) //functions based off of button pulling input pin
LOW
{
File dataFile = SD.open("datalog.txt", FILE_WRITE);
//if the file is available, write to it:
if (dataFile) {
dataFile.print("Degrees C: ");
dataFile.print(degreesC);
dataFile.print(",");
dataFile.print(tdsValue,0);
dataFile.print("ppm");
dataFile.print(",");
dataFile.println(gpstext);
dataFile.close();
lcd.clear();
lcd.setCursor(0,0);
lcd.print("info saved");
delay(1000);
}
// if the file isn't open, pop up an error:
else {
lcd.clear();
lcd.setCursor(0,0);
lcd.print("error SD");
delay(1000);
}}
delay(1000);
}}
String displayInfo()
{
// Define empty string to hold output
gps.encode(ss.read());
String gpsdata = "";
// Get latitude and longitude
if (gps.location.isValid())
{
gpsdata = String(gps.location.lat(), 6);
gpsdata += (",");
gpsdata += String(gps.location.lng(), 6);
gpsdata += (",");
}
else
{
return "0";
}
// Return completed string
return gpsdata;
}