Hello everybody,
I just wanted to share my code and fritzing file for a little project of mine. Here I wanted to measure parameters relevant for hydroponic plant cultivation. I have connected an UNO R4 Wifi with the following sensors:
- pH
- EC
- water temperature
- temperature/humidity
- light
The code also enables you to send the data to your Blynk cloud. You have to fill in your specific information for the fields with XXXXXXXXX. Please ignore or delete the Udp parts.
/***************************************************
This is an example for the HTU21D-F Humidity & Temp Sensor
Designed specifically to work with the HTU21D-F sensor from Adafruit
----> https://www.adafruit.com/products/1899
These displays use I2C to communicate, 2 pins are required to
interface
****************************************************/
#define BLYNK_PRINT Serial
/* Fill in information from Blynk Device Info here */
#define BLYNK_TEMPLATE_ID "XXXXXXXXXX"
#define BLYNK_TEMPLATE_NAME "XXXXXXXXX"
#define BLYNK_AUTH_TOKEN "XXXXXXXXXXXX"
#include <Wire.h>
#include "Adafruit_HTU21DF.h"
#include <BH1750.h>
#include <DallasTemperature.h>
//Wifi Setup
#include <WiFiS3.h>
#include <SPI.h>
#include <BlynkSimpleWifi.h>
int status = WL_IDLE_STATUS;
//#include "arduino_secrets.h"
#define SECRET_SSID "XXXXXXX"
#define SECRET_PASS "XXXXXXXXXX"
///////please enter your sensitive data in the Secret tab/arduino_secrets.h
char ssid[] = SECRET_SSID; // your network SSID (name)
char pass[] = SECRET_PASS; // your network password (use for WPA, or use as key for WEP)
int keyIndex = 0; // your network key index number (needed only for WEP)
unsigned int localPort = XXXX; // local port to listen on
char packetBuffer[256]; //buffer to hold incoming packet
char ReplyBuffer[] = "acknowledged\n"; // a string to send back
WiFiUDP Udp;
//WifiSetup
#define ONE_WIRE_BUS 6 //water temperature
// Connect Vin to 3-5VDC
// Connect GND to ground
// Connect SCL to I2C clock pin (A5 on UNO)
// Connect SDA to I2C data pin (A4 on UNO)
OneWire oneWire(ONE_WIRE_BUS); //water temperature
Adafruit_HTU21DF htu = Adafruit_HTU21DF();
BH1750 lightMeter;
DallasTemperature sensors(&oneWire); //water temperature
#define TdsSensorPin A0 //TDS meter
#define VREF 3.3 // analog reference voltage(Volt) of the ADC
#define SCOUNT 30 // sum of sample point
int analogBuffer[SCOUNT]; // store the analog value in the array, read from ADC
int analogBufferTemp[SCOUNT];
int analogBufferIndex = 0, copyIndex = 0;
float averageVoltage = 0, tdsValue = 0, temperature = 25;
IPAddress remoteIp(5,189,182,151);
unsigned int remotePort = 5000; //NEW
//pH:
#define SensorPin A1 //pH meter Analog output to Arduino Analog Input 1
unsigned long int avgValue; //Store the average value of the sensor feedback
float b;
int buf[10], temp;
void setup() {
Serial.begin(9600);
//WfiSetup
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
// check for the WiFi module:
if (WiFi.status() == WL_NO_MODULE) {
Serial.println("Communication with WiFi module failed!");
// don't continue
while (true)
;
}
String fv = WiFi.firmwareVersion();
if (fv < WIFI_FIRMWARE_LATEST_VERSION) {
Serial.println("Please upgrade the firmware");
}
// attempt to connect to WiFi network:
while (status != WL_CONNECTED) {
Serial.print("Attempting to connect to SSID: ");
Serial.println(ssid);
// Connect to WPA/WPA2 network. Change this line if using open or WEP network:
status = WiFi.begin(ssid, pass);
// wait 10 seconds for connection:
delay(10000);
}
Serial.println("Connected to WiFi");
printWifiStatus();
Serial.println("\nStarting connection to server...");
// if you get a connection, report back via serial:
Udp.begin(localPort);
//WifiSetUp
Serial.println("HTU21D-F test");
Wire.begin();
lightMeter.begin();
sensors.begin(); //water temperature
pinMode(TdsSensorPin, INPUT); //TDS meter
Serial.println(F("BH1750 Test begin"));
if (!htu.begin()) {
Serial.println("Couldn't find sensor!");
while (1)
;
}
Blynk.begin(BLYNK_AUTH_TOKEN, ssid, pass);
// You can also specify server:
//Blynk.begin(BLYNK_AUTH_TOKEN, ssid, pass, "blynk.cloud", 80);
//Blynk.begin(BLYNK_AUTH_TOKEN, ssid, pass, IPAddress(192,168,1,100), 8080);
}
void loop() {
Blynk.run();
Udp.beginPacket(remoteIp, remotePort); //Wifi
//pH:
for (int i = 0; i < 10; i++) //Get 10 sample value from the sensor for smooth the value
{
buf[i] = analogRead(SensorPin);
delay(10);
}
for (int i = 0; i < 9; i++) //sort the analog from small to large
{
for (int j = i + 1; j < 10; j++) {
if (buf[i] > buf[j]) {
temp = buf[i];
buf[i] = buf[j];
buf[j] = temp;
}
}
}
avgValue = 0;
for (int i = 2; i < 8; i++) //take the average value of 6 center sample
avgValue += buf[i];
float phValue = (float)avgValue * 5.0 / 1024 / 6; //convert the analog into millivolt
phValue = 3.5 * phValue; //convert the millivolt into pH value
Serial.print("pH:");
Serial.print(phValue, 2);
Serial.println(" ");
Udp.print(" ");
Udp.print(phValue, 2);
Udp.print("*");
//digitalWrite(2, HIGH);
delay(800);
float temp = htu.readTemperature();
float rel_hum = htu.readHumidity();
float lux = lightMeter.readLightLevel();
Serial.print("Temp: ");
Serial.print(temp);
Serial.print(" C");
Serial.println("\t\t");
Serial.print("Humidity: ");
Serial.print(rel_hum);
Serial.println(" \%");
Serial.print("Light: ");
Serial.print(lux);
Serial.println(" lx");
//Udp.print("Temp: ");
Udp.print(temp);
Udp.print("*");
//Udp.println("\t\t");
//Udp.print("Humidity: ");
Udp.print(rel_hum);
Udp.print("*");
//Udp.print("Light: ");
Udp.print(lux);
Udp.print("*");
//Udp.endPacket(); // Änderung 31.05
//sensorData = analogRead(phValue); // this is an example of reading sensor data
Blynk.virtualWrite(V1, lux);
Blynk.virtualWrite(V6, phValue);
Blynk.virtualWrite(V3, temp);
Blynk.virtualWrite(V5, rel_hum);
delay(3000);
sensors.requestTemperatures(); //water temperature
Serial.print("Celsius water temperature: ");
// Why "byIndex"? You can have more than one IC on the same bus. 0 refers to the first IC on the wire
Serial.print(sensors.getTempCByIndex(0));
Serial.print(" - Fahrenheit water temperature: ");
Serial.println(sensors.getTempFByIndex(0));
//Udp.print("Celsius water temperature: ");
Udp.print(sensors.getTempCByIndex(0));
Udp.print("*");
//Udp.println(sensors.getTempFByIndex(0));
Blynk.virtualWrite(V0, sensors.getTempCByIndex(0));
delay(3000);
//TDS meter
static unsigned long analogSampleTimepoint = millis();
if (millis() - analogSampleTimepoint > 40U) //every 40 milliseconds,read the analog value from the ADC
{
analogSampleTimepoint = millis();
analogBuffer[analogBufferIndex] = analogRead(TdsSensorPin); //read the analog value and store into the buffer
analogBufferIndex++;
if (analogBufferIndex == SCOUNT)
analogBufferIndex = 0;
}
static unsigned long printTimepoint = millis();
if (millis() - printTimepoint > 800U) {
printTimepoint = millis();
for (copyIndex = 0; copyIndex < SCOUNT; copyIndex++)
analogBufferTemp[copyIndex] = analogBuffer[copyIndex];
averageVoltage = getMedianNum(analogBufferTemp, SCOUNT) * (float)VREF / 1024.0; // read the analog value more stable by the median filtering algorithm, and convert to voltage value
float compensationCoefficient = 1.0 + 0.02 * (temperature - 25.0); //temperature compensation formula: fFinalResult(25^C) = fFinalResult(current)/(1.0+0.02*(fTP-25.0));
float compensationVolatge = averageVoltage / compensationCoefficient; //temperature compensation
tdsValue = (133.42 * compensationVolatge * compensationVolatge * compensationVolatge - 255.86 * compensationVolatge * compensationVolatge + 857.39 * compensationVolatge) * 0.5; //convert voltage value to tds value
//Serial.print("voltage:");
//Serial.print(averageVoltage,2);
//Serial.print("V ");
Serial.print("TDS-Value:");
Serial.print(tdsValue, 0);
Serial.println("ppm");
//Udp.print("TDS-Value:");
Udp.print(tdsValue, 0);
Udp.print("*");
Blynk.virtualWrite(V2, tdsValue);
}
Udp.endPacket();
}
int getMedianNum(int bArray[], int iFilterLen) {
int bTab[iFilterLen];
for (byte i = 0; i < iFilterLen; i++)
bTab[i] = bArray[i];
int i, j, bTemp;
for (j = 0; j < iFilterLen - 1; j++) {
for (i = 0; i < iFilterLen - j - 1; i++) {
if (bTab[i] > bTab[i + 1]) {
bTemp = bTab[i];
bTab[i] = bTab[i + 1];
bTab[i + 1] = bTemp;
}
}
}
if ((iFilterLen & 1) > 0)
bTemp = bTab[(iFilterLen - 1) / 2];
else
bTemp = (bTab[iFilterLen / 2] + bTab[iFilterLen / 2 - 1]) / 2;
return bTemp;
}
void printWifiStatus() {
// print the SSID of the network you're attached to:
Serial.print("SSID: ");
Serial.println(WiFi.SSID());
// print your board's IP address:
IPAddress ip = WiFi.localIP();
Serial.print("IP Address: ");
Serial.println(ip);
// print the received signal strength:
long rssi = WiFi.RSSI();
Serial.print("signal strength (RSSI):");
Serial.print(rssi);
Serial.println(" dBm");
}
Please try it out for yourself and give me some feedback