This commit is contained in:
commit
7588dc9ac2
1 changed files with 275 additions and 0 deletions
275
Hydroponicsmeasure.ino
Normal file
275
Hydroponicsmeasure.ino
Normal file
|
|
@ -0,0 +1,275 @@
|
|||
/*
|
||||
* Hydroponics system monitor
|
||||
* J. Devine
|
||||
* Runs on Arduino Pro 5V
|
||||
* Sensors:
|
||||
* DFRobot pHmeter V1.1
|
||||
* Waterproof DS18B20 water temperature sensor
|
||||
* TMP36 air temperature sensor
|
||||
* HC-SR04 distance sensor (for water level..)
|
||||
* Output in CSV; no error handling yet
|
||||
* write out all the results in the following format:
|
||||
* uptime (ms),water level (cm), pH, pH Voltage, water temp (degrees C), air temp (degrees C)
|
||||
*
|
||||
* This code is entirely based on some awesome examples, re-worked for this application
|
||||
* The internal pullup library is needed to avoid an external 4.7k resistor on the DS18B20
|
||||
* Great blog entry by josh levine @bigjoshlevine - Thanks! I was thinking EXACTLY the same thing
|
||||
* https://wp.josh.com/2014/06/23/no-external-pull-up-needed-for-ds18b20-temp-sensor/
|
||||
*
|
||||
* Pinouts:
|
||||
*
|
||||
* Pin 10 - DS18B20 data pin
|
||||
* Pin 12 - HC-SR04 Trig
|
||||
* Pin 13 - HC-SR04 Echo
|
||||
* Pin A2 - pH Meter V1.1 data (DF Robot breakout)
|
||||
* Pin A3 - TMP36 data pin
|
||||
*
|
||||
* Licensed under GPL V3. Read the license here:
|
||||
* https://www.gnu.org/licenses/gpl-3.0.en.html
|
||||
*
|
||||
*/
|
||||
#define SensorPin A2 //pH meter Analog output to Arduino Analog Input 2
|
||||
#define Offset 0.00 //deviation compensate
|
||||
//#define LED 13
|
||||
#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;
|
||||
|
||||
// DS18S20 Temperature chip i/o
|
||||
#include <OneWire.h> //this is the onewire version with the pullup high.
|
||||
|
||||
OneWire ds(10); // on pin 10
|
||||
|
||||
int echopin = 13;
|
||||
int trigpin = 12;
|
||||
int vcc = 11;
|
||||
long duration, distance;
|
||||
|
||||
|
||||
//tmp36 readout
|
||||
int sensorPin = 0;
|
||||
|
||||
void setup(void)
|
||||
{
|
||||
pinMode(echopin, INPUT);
|
||||
pinMode(trigpin, OUTPUT);
|
||||
// pinMode(LED,OUTPUT);
|
||||
Serial.begin(9600);
|
||||
// Serial.println("pH meter experiment!"); //Test the serial monitor
|
||||
}
|
||||
void loop(void)
|
||||
{
|
||||
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);
|
||||
// digitalWrite(LED,digitalRead(LED)^1);
|
||||
printTime=millis();
|
||||
|
||||
}
|
||||
|
||||
|
||||
digitalWrite(trigpin, LOW); // Added this line
|
||||
|
||||
delayMicroseconds(4); // Added this line
|
||||
|
||||
digitalWrite(trigpin, HIGH);
|
||||
|
||||
delayMicroseconds(20); // Added this line
|
||||
|
||||
digitalWrite(trigpin, LOW);
|
||||
|
||||
duration = pulseIn(echopin, HIGH);
|
||||
|
||||
distance = (duration/2) / 29.1;
|
||||
|
||||
Serial.print(millis());
|
||||
Serial.print(';');
|
||||
Serial.print(distance);
|
||||
|
||||
// if (distance >= 200 || distance <= 0){
|
||||
|
||||
// Serial.println("Out of range");
|
||||
|
||||
//}
|
||||
|
||||
//else {
|
||||
|
||||
//Serial.print(distance);
|
||||
|
||||
//Serial.println(" cm");
|
||||
|
||||
// }
|
||||
|
||||
//delay(500);
|
||||
|
||||
|
||||
|
||||
byte i;
|
||||
byte present = 0;
|
||||
byte data[12];
|
||||
byte addr[8];
|
||||
int Temp;
|
||||
float Ftemp;
|
||||
ds.reset_search();
|
||||
if ( !ds.search(addr)) {
|
||||
// Serial.print("No more addresses.\n");
|
||||
ds.reset_search();
|
||||
return;
|
||||
}
|
||||
|
||||
// Serial.print("R=");
|
||||
for( i = 0; i < 8; i++) {
|
||||
// Serial.print(addr[i], HEX);
|
||||
// Serial.print(" ");
|
||||
}
|
||||
|
||||
if ( OneWire::crc8( addr, 7) != addr[7]) {
|
||||
// Serial.print("CRC is not valid!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if ( addr[0] == 0x10) {
|
||||
// Serial.print("Device is a DS18S20 family device.\n");
|
||||
}
|
||||
else if ( addr[0] == 0x28) {
|
||||
// Serial.print("Device is a DS18B20 family device.\n");
|
||||
}
|
||||
else {
|
||||
// Serial.print("Device family is not recognized: 0x");
|
||||
// Serial.println(addr[0],HEX);
|
||||
return;
|
||||
}
|
||||
|
||||
ds.reset();
|
||||
ds.select(addr);
|
||||
ds.write(0x44,1); // start conversion, with parasite power on at the end
|
||||
|
||||
delay(1000); // maybe 750ms is enough, maybe not
|
||||
// we might do a ds.depower() here, but the reset will take care of it.
|
||||
|
||||
present = ds.reset();
|
||||
ds.select(addr);
|
||||
ds.write(0xBE); // Read Scratchpad
|
||||
|
||||
// Serial.print("P=");
|
||||
// Serial.print(present,HEX);
|
||||
// Serial.print(" ");
|
||||
for ( i = 0; i < 9; i++) { // we need 9 bytes
|
||||
data[i] = ds.read();
|
||||
// Serial.print(data[i], HEX);
|
||||
// Serial.print(" ");
|
||||
}
|
||||
Temp=(data[1]<<8)+data[0];//take the two bytes from the response relating to temperature
|
||||
// Serial.println("One, then 0");
|
||||
// Serial.println(data[1]); //msb
|
||||
// Serial.println(data[0]); //lsb
|
||||
//Temp=Temp>>4;//divide by 16 to get pure celcius readout
|
||||
Ftemp =(Temp * 0.0625);
|
||||
//next line is Fahrenheit conversion
|
||||
//Temp=Temp*1.8+32; // comment this line out to get celcius
|
||||
|
||||
// Serial.print("T=");//output the temperature to serial port
|
||||
// Serial.print(Temp);
|
||||
// Serial.print(" ");
|
||||
|
||||
//Serial.print(" fT=");//output the temperature to serial port
|
||||
// Serial.print(Ftemp);
|
||||
// Serial.print(" ");
|
||||
|
||||
// Serial.print(" CRC=");
|
||||
// Serial.print( OneWire::crc8( data, 8), HEX);
|
||||
// Serial.println();
|
||||
|
||||
|
||||
//getting the voltage reading from the temperature sensor
|
||||
int reading = analogRead(sensorPin);
|
||||
|
||||
// converting that reading to voltage, for 3.3v arduino use 3.3
|
||||
float ATvoltage = reading * 5.0;
|
||||
ATvoltage /= 1024.0;
|
||||
|
||||
// print out the voltage
|
||||
//Serial.print(ATvoltage); Serial.println(" volts");
|
||||
|
||||
// now print out the temperature
|
||||
float temperatureC = (ATvoltage - 0.5) * 100 ; //converting from 10 mv per degree wit 500 mV offset
|
||||
//to degrees ((voltage - 500mV) times 100)
|
||||
//Serial.print(temperatureC); Serial.println(" degrees C");
|
||||
|
||||
// now convert to Fahrenheit
|
||||
//float temperatureF = (temperatureC * 9.0 / 5.0) + 32.0;
|
||||
//Serial.print(temperatureF); Serial.println(" degrees F");
|
||||
|
||||
//delay(1000);
|
||||
|
||||
//write out all the results in the following format
|
||||
// uptime (ms),water level (cm), pH, pH Voltage, water temp (degrees C), air temp (degrees C)
|
||||
Serial.print(';');
|
||||
Serial.print(pHValue,2);
|
||||
Serial.print(';');
|
||||
Serial.print(voltage,2);
|
||||
Serial.print(';');
|
||||
Serial.print(Ftemp);
|
||||
Serial.print(';');
|
||||
Serial.print(temperatureC);
|
||||
Serial.println(';');
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
Loading…
Reference in a new issue