commit 7588dc9ac257bbc6b0eaebfa6fa71f3b94676ade Author: James Devine Date: Sun Sep 17 17:16:23 2017 +0200 diff --git a/Hydroponicsmeasure.ino b/Hydroponicsmeasure.ino new file mode 100644 index 0000000..3a07e58 --- /dev/null +++ b/Hydroponicsmeasure.ino @@ -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 //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;imax){ + amount+=max; //arr>max + max=arr[i]; + }else{ + amount+=arr[i]; //min<=arr<=max + } + }//if + }//for + avg = (double)amount/(number-2); + }//if + return avg; +} \ No newline at end of file