Aschalw AyeleDaniel QuinonesLaura Mock
Published

pH and Water Temp Sensor

This is a Photon project that collects the pH levels as well as the water's temperature in a given area.

IntermediateShowcase (no instructions)5 hours547
pH and Water Temp Sensor

Things used in this project

Hardware components

PH sensor
×1
water temp sensor
×1
LED (generic)
LED (generic)
red, blue, green
×3
Breadboard (generic)
Breadboard (generic)
×1
Resistor 475 ohm
Resistor 475 ohm
×1
40% Light Transmission White Acrylic Sheet
×1
Baltic Birch Plywood
1/8 thickness
×1
Jumper wires (generic)
Jumper wires (generic)
×1

Hand tools and fabrication machines

Laser cutter (generic)
Laser cutter (generic)
Hot glue gun (generic)
Hot glue gun (generic)

Story

Read more

Custom parts and enclosures

PH sensor and Temp sensor box designe

the left half is wood and the right half is acrylic

Schematics

Schematic Diagram

This diagram uses other sensors in place of the actual ones we used because fritzing did not have it

Code

Complete Combined Code

Arduino
This is the code that is flashed to the photon. It checks the temperature and ph of the tank.
// This #include statement was automatically added by the Particle IDE.
#include "DallasTemperature.h"

// This #include statement was automatically added by the Particle IDE.
#include <OneWire.h>

// This #include statement was automatically added by the Particle IDE.
#include <SparkFunPhant.h>

double tempParticle;
double phParticle;
double tooBasic = 10.0;
double tooAcidic = 4.0;



//ph code
#define SensorPin A0            //pH meter Analog output to Arduino Analog Input 0
#define Offset -21.20            //deviation compensate
#define LED 13
#define LEDRED 12
#define LEDBLUE 11
#define samplingInterval 20
#define printInterval 800
#define ArrayLenth  40    //times of collection
int pHArray[ArrayLenth];   //Store the average value of the sensor feedback
int pHArrayIndex=0;    

//////////////////////////////////


//Temperature Code
#define ONE_WIRE_BUS D2
#define TEMPERATURE_PRECISION 9
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);

//Run I2C Scanner to get address of DS18B20(s)
DeviceAddress inWaterThermometer = { 0x28, 0x56, 0xCB, 0x7F, 0x8, 0x0, 0x0, 0xC7 };
//CHNAGE TO YOUR DEVICE'S ADDRESS

double InTempC = -1;
double waterTempF = -1;

void update18B20Temp(DeviceAddress deviceAddress, double &tempC);

/////////////////////////////////


//Given Phant Code
double value1 = 0; //number 1 clicked
double value2 = 0; //number 2 clicked

const char server[] = "data.sparkfun.com"; // Phant destination server
const char publicKey[] = "0lw6ZGVRyOcNMwYMZ0WO"; // Phant public key - HAS TO BE CHANGED
const char privateKey[] = "D6vVmNoZyqiqaPEa8DjB"; // Phant private key  - HAS TO BE CHANGED
Phant phant(server, publicKey, privateKey); // Create a Phant object

const int POST_RATE = 3000; // Time between posts, in ms.
unsigned long lastPost = 0; // global variable to keep track of last post time

void setup() {
    
   Particle.variable("ph", phParticle);
   Particle.variable("tempParticle", tempParticle);
    
     // DS18B20 initialization
   pinMode(LED,OUTPUT); 
   pinMode(LEDRED, OUTPUT);
   pinMode(LEDBLUE, OUTPUT);
    sensors.begin();
    sensors.setResolution(inWaterThermometer, TEMPERATURE_PRECISION);

    Serial.begin(9600);
}

void loop() {
    //Serial.println(digitalRead(6));
    //delay(5000);
    //value1++;
    //value2++;

    //Replace the if statement below with whatever your trigger is
    
    //PH Loop
    static unsigned long samplingTime = millis();
  static unsigned long printTime = millis();
  static float pHValue,voltage;
  
  if(millis()-samplingTime > samplingInterval)
  {
      pHArray[pHArrayIndex++]=analogRead(SensorPin);
      if(pHArrayIndex==ArrayLenth)pHArrayIndex=0;
      voltage = avergearray(pHArray, ArrayLenth)*5.0/1024;
      pHValue = 3.5*voltage+Offset;
      
      samplingTime=millis();
      
  }
  if(millis() - printTime > printInterval)   //Every 800 milliseconds, print a numerical, convert the state of the LED indicator
  {
	Serial.print("Voltage:");
        Serial.print(voltage,2);
        Serial.print("    pH value: ");
	Serial.println(pHValue,2);
	printTime=millis();
	if(pHValue < tooBasic && pHValue > tooAcidic )
	{
        digitalWrite(LED, HIGH);
        delay(1000);
        digitalWrite(LED, LOW);
       // printTime=millis();
	}
	else if(pHValue < tooAcidic)
	{
	   digitalWrite(LEDRED, HIGH);
        delay(1000);
        digitalWrite(LEDRED, LOW);
       // printTime=millis(); 
	}
	else if(pHValue > tooBasic)
	{
	    digitalWrite(LEDBLUE, HIGH);
        delay(1000);
        digitalWrite(LEDBLUE, LOW);
       // printTime=millis();
	}
  }
    phParticle = pHValue;
    
    ////////////////////////////
    
    
    
   //Temperature Loop
     // DS18B20
        sensors.requestTemperatures();
        update18B20Temp(inWaterThermometer, InTempC);

        waterTempF = (InTempC * 9)/5 + 32;

        Serial.print("Water Temp:");
        Serial.print(waterTempF);
        Serial.println("F");
        tempParticle = waterTempF;
        
        
   
   
   /////////////////////////////
   
   
   
  //Button Code Below 
    boolean somethingHappened = false;
   
    Serial.println(digitalRead(4) + " d4");
    Serial.println(digitalRead(3) + " d3");
    delay(2000);
  
   //If statement for phant
   /* if(digitalRead(4) == 0) //When button 1 is clicked
    {
        Serial.print("d4 clicked ");
        value1 = 1;
        somethingHappened = true;
    }
    if(digitalRead(3)==0) //When button 2 is clicked
    {
        Serial.print("d3 clicked ");
        value2 = 1;
        somethingHappened = true;
    }
    if (somethingHappened)
    {
      //  postToPhant();
    }
    value1 = 0;
    value2 = 0;
    
    */

}

int postToPhant()
{    
    // Use phant.add(<field>, <value>) to add data to each field.
    // Phant requires you to update each and every field before posting,
    // make sure all fields defined in the stream are added here.
    phant.add("ph", value1);
    phant.add("temp", value2);
        	
    TCPClient client;
    char response[512];
    int i = 0;
    int retVal = 0;
    
    if (client.connect(server, 80)) // Connect to the server
    {
		// Post message to indicate connect success
        Serial.println("Posting!"); 
		
		// phant.post() will return a string formatted as an HTTP POST.
		// It'll include all of the field/data values we added before.
		// Use client.print() to send that string to the server.
        client.print(phant.post());
        delay(1000);
		// Now we'll do some simple checking to see what (if any) response
		// the server gives us.
        while (client.available())
        {
            char c = client.read();
            Serial.print(c);	// Print the response for debugging help.
            if (i < 512)
                response[i++] = c; // Add character to response string
        }
		// Search the response string for "200 OK", if that's found the post
		// succeeded.
        if (strstr(response, "200 OK"))
        {
            Serial.println("Post success!");
            retVal = 1;
        }
        else if (strstr(response, "400 Bad Request"))
        {	// "400 Bad Request" means the Phant POST was formatted incorrectly.
			// This most commonly ocurrs because a field is either missing,
			// duplicated, or misspelled.
            Serial.println("Bad request");
            retVal = -1;
        }
        else
        {
			// Otherwise we got a response we weren't looking for.
            retVal = -2;
        }
    }
    else
    {	// If the connection failed, print a message:
        Serial.println("connection failed");
        retVal = -3;
    }
    client.stop();	// Close the connection to server.
    return retVal;	// Return error (or success) code.
}


//temperature method
void update18B20Temp(DeviceAddress deviceAddress, double &tempC)
{
  tempC = sensors.getTempC(deviceAddress);
}



//ph method
double avergearray(int* arr, int number){
  int i;
  int max,min;
  double avg;
  long amount=0;
  if(number<=0){
    Serial.println("Error number for the array to avraging!/n");
    return 0;
  }
  if(number<5){   //less than 5, calculated directly statistics
    for(i=0;i<number;i++){
      amount+=arr[i];
    }
    avg = amount/number;
    return avg;
  }else{
    if(arr[0]<arr[1]){
      min = arr[0];max=arr[1];
    }
    else{
      min=arr[1];max=arr[0];
    }
    for(i=2;i<number;i++){
      if(arr[i]<min){
        amount+=min;        //arr<min
        min=arr[i];
      }else {
        if(arr[i]>max){
          amount+=max;    //arr>max
          max=arr[i];
        }else{
          amount+=arr[i]; //min<=arr<=max
        }
      }//if
    }//for
    avg = (double)amount/(number-2);
  }//if
  return avg;
}

Credits

Aschalw Ayele

Aschalw Ayele

-1 projects • 0 followers
Daniel Quinones

Daniel Quinones

-1 projects • 0 followers
Laura Mock

Laura Mock

-1 projects • 0 followers

Comments