Тестер качества воды с помощью Ардуино

Создание собственного тестера качества воды достаточно большой проект сам по себе, т.к. может включать в себя много датчиков, таких как ультразвуковой датчик, кислородный датчик, инфракрасная камера, мобильное приложение для графического представления результатов испытаний и другие.

Но этот урок будет интересен тем, у кого есть желание сделать свою собственную систему мониторинга воды или использовать ее под свои проекты.

Шаг 1: Комплектующие, датчики, сенсоры

Нам понадобится довольно много разных датчиков и комплектующих для создания тестера воды.

  1. DS1820 водонепроницаемый датчик температуры
  2. Arduino GSM-модуль SIM800L
  3. Датчик PH
  4. Датчик мутности
  5. Arduino Mega или UNO (мы использовали мега из-за большого количества датчиков, которые будут добавлены)
  6. Провода
  7. SIM-карта
  8. Макетная плата

С этими доступными деталями вы можете сделать себе систему мониторинга/теста воды, которая проверит качество воды и предупредит вас через SMS результатами.

Шаг 2: Процессор

Более подробная информация о модуле процессора памяти Arduino может помочь вам лучше понять, что вы делаете. Для новичков - вы можете просто взглянуть на это и дальше перейти к более интересной части.

Шаг 3: Схема

Создайте свою схему, как показано на рисунке. Датчики будут готовы выполнять свои команды.

Шаг 4: Собираем устройство

После подключения схема должна выглядеть примерно так как на рисунках выше. Проверьте, мигает ли модуль GSM при вставке SIM-карты. Когда все датчики готовы можно загрузить код в Arduino, используя программное обеспечение Arduino IDE, которое вы должны установить на вашем компьютере (вы можете загрузить онлайн и бесплатно). Более подробно как это сделать вы можете найти в подробном уроке по Arduino Nano по ссылке.

Шаг 5: Загрузка кода

Как сказано выше - нужно загрузить код в Ардуино:

#include <OneWire.h>
#include <DallasTemperature.h>
#include <SoftwareSerial.h>
#define SensorPin A2            //pH meter Analog output to Arduino Analog Input 0
#define Offset 0.00            //deviation compensate
unsigned long int avgValue;     //Store the average value of the sensor feedback

// Data wire is plugged into pin 2 on the Arduino
#define ONE_WIRE_BUS 6

SoftwareSerial mySerial(7, 8);

// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);

// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);

int sensorPin = A0;
float phValue;
float temperatureC;
long duration, cm;

void setup(void)
{
  // start serial port
  Serial.begin(9600);
  // Start up the library
  sensors.begin(); // IC Default 9 bit. If you have troubles consider upping it 12. Ups the delay giving the IC more time to process the temperature measurement
}

void loop() {
  sensors.requestTemperatures(); // Send the command to get temperature
  Serial.println(sensors.getTempCByIndex(0));
  int reading = analogRead(sensorPin);

  // converting that reading to voltage,
  float voltage = reading * 5.0;
  voltage /= 1024.0;

  // now print out the temperature
  float temperatureC = (voltage - 0.5) * 100 ;
  PH();
  temperature ();
  turbidity();
  send_sms();
  delay(4000);
  send_sms1();
  delay(8000);
}

//////////////////////////////////////////////////////////// FUNCTIONS ////////////////////////////////////////////////////////////////////
void PH(){
  Serial.println(" ");
  Serial.println("Taking Readings from PH Sensor");
  int buf[10];                //buffer for read analog
  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])
      {
        int 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*3.8/1030/6; //convert the analog into millivolt
  phValue=3.3*phValue+Offset;                      //convert the millivolt into pH value
  Serial.print("pH:");
  Serial.print(phValue,2);
  Serial.println(" ");

  if(phValue >= 7.30){
    Serial.print("PH VALUE: ");
    Serial.println(phValue);
    Serial.println("Water Alkalinity high");
    delay(3000);
   }

  if(phValue >= 6.90 && phValue <= 7.19){
    Serial.print("PH VALUE: ");
    Serial.println(phValue);
    Serial.println("Water Is  neutral (safe)");
  }

  if(phValue < 6.89){
    Serial.print("PH VALUE: ");
    Serial.println(phValue);
    Serial.println("Water Acidity High");
    delay(3000);
   }

  delay(8000);
}


void temperature (){
  Serial.println(" ");
  Serial.println("Taking Readings from Temperature Sensor");
  temp_check_surr();
  delay(4000);
  temp_check_water();
}

void temp_check_surr(){
  int reading = analogRead(sensorPin);

  // converting that reading to voltage,
  float voltage = reading * 5.0;
  voltage /= 1024.0;

  // now print out the temperature
  float temperatureC = (voltage - 0.5) * 100 ;  //converting from 10 mv per degree wit 500 mV offset
  //to degrees ((voltage - 500mV) times 100)
  Serial.print("Surrounding Temperature: ");
  Serial.println(temperatureC);

  if(temperatureC > 50){
    Serial.print("Surrounding Temperature: ");
    Serial.print(temperatureC);
    Serial.println(" degree C");
    Serial.println("Surrounding Temperature high");
    delay(3000);
   }

  if(temperatureC >= 10 && temperatureC <= 50){
    Serial.print("Surrounding Temperature: ");
    Serial.print(temperatureC);
    Serial.println(" degree C");
    Serial.println("Surrounding Temperature normal");
  }

  if(temperatureC < 10){
    Serial.print("Surrounding Temperature: ");
    Serial.print(temperatureC);
    Serial.println(" degree C");
    Serial.println("Surrounding Temperature low");
    delay(3000);
   }
  delay(8000);
}


void temp_check_water(){
  sensors.requestTemperatures(); // Send the command to get temperature
  Serial.print("Water Temperature: ");
  Serial.println(sensors.getTempCByIndex(0));

  if(sensors.getTempCByIndex(0) > 40){
    Serial.print("Water Temperature: ");
    Serial.print(sensors.getTempCByIndex(0));
    Serial.println(" degree C");
    Serial.println("Water Temperature high");
    delay(3000);
  }

  if(sensors.getTempCByIndex(0) >= 15 && sensors.getTempCByIndex(0) <= 40){
    Serial.print("Water Temperature: ");
    Serial.print(sensors.getTempCByIndex(0));
    Serial.println(" degree C");
    Serial.println("Water Temperature normal");
  }

  if(sensors.getTempCByIndex(0) < 15){
    Serial.print("Water Temperature: ");
    Serial.print(sensors.getTempCByIndex(0));
    Serial.println(" degree C");
    Serial.println("Water Temperature low");
    delay(3000);
  }
  delay(8000);
}

void turbidity() {
  Serial.println(" ");
  Serial.println("Taking Readings from turbidity Sensor");
  int turbidityValue = analogRead(A1);
  float turbidityV = turbidityValue/100;
  Serial.print("Turbidity level: ");
  Serial.println(turbidityV);

  if( turbidityV > 9){
    Serial.print("Turbidity Level: ");
    Serial.print(turbidityV);
    Serial.println("NTU");
    Serial.println("Water Very Clean ");
    delay(3000);
  }

  if( turbidityV >= 6 && turbidityValue/100 <= 9 ){
    Serial.print("Turbidity Level: ");
    Serial.print(turbidityV);
    Serial.println("NTU");
    Serial.println("Water Clean ");
  }

  if( turbidityV < 6){
    Serial.print("Turbidity Level: ");
    Serial.print(turbidityV);
    Serial.println("NTU");
    Serial.println("Water Very Dirty ");
    delay(3000);
   }
  delay (8000);
}

//////////////////////////////////////////////////////// SMS FUNCTION /////////////////////////////////////////////////////////////////////
void send_sms(){
  String temp;
  String phm;
  String turb;
  int turbidityValue = analogRead(A1);
  float turbidityV = turbidityValue/100;

  int buf[10];                //buffer for read analog
  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])
      {
        int 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*3.8/1030/6; //convert the analog into millivolt
  phValue=3.3*phValue+Offset;

    if(sensors.getTempCByIndex(0) > 40){
    temp = String("HIGH");
    }
    if(sensors.getTempCByIndex(0) >= 10 && sensors.getTempCByIndex(0) <= 40){
    temp = String("NORMAL");
    }
    if(sensors.getTempCByIndex(0) < 10){
     temp = String("LOW");
    }

    if(phValue >= 7.30){
    phm = String("ALKALINE");
    }
    if(phValue >= 6.90 && phValue <= 7.19){
    phm = String("NORMAL");
    }
    if(phValue < 6.89){
     phm = String("ACIDIC");
    }

    if(turbidityV >= 6 && turbidityValue/100 <= 9){
    turb = String("CLEAN");
    }
    if(turbidityV < 6){
    turb = String("DIRTY");
    }

  mySerial.begin(19200);  //Default serial port setting for the GPRS modem is 19200bps 8-N-1
  mySerial.print("\r");
  delay(1000);                    //wait for a second while the modem sends an "OK"
  mySerial.print("AT+CMGF=1\r");    //Because we want to send the SMS in text mode
  delay(1000);
  mySerial.print("AT+CMGS=\"+447450867345\"\r");    //Start accepting the text for the message
  delay(1000);
  mySerial.print(temp);
  mySerial.print(" \r");
  mySerial.print("WATER TEMPERATURE= \r");   //The text for the message
  mySerial.print(sensors.getTempCByIndex(0));
  mySerial.print("*C\r");
  mySerial.println("\r");
  mySerial.print(" \r");
  mySerial.print(phm);
  mySerial.print(" \r");
  mySerial.print("WATER PH VALUE= \r");   //The text for the message
  mySerial.print(phValue);
  mySerial.println("\r");
  mySerial.print(turb);
  mySerial.print(" \r");
  mySerial.print("WATER TURBIDITY= \r");   //The text for the message
  mySerial.print(turbidityV);
  mySerial.print("NBT\r");
  delay(3000);
  mySerial.write(0x1A);  //Equivalent to sending Ctrl+Z
}

void send_sms1(){
  String temp;
  String phm;
  String turb;
  int turbidityValue = analogRead(A1);
  float turbidityV = turbidityValue/100;

  int buf[10];                //buffer for read analog
  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])
      {
        int 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*3.8/1030/6; //convert the analog into millivolt
  phValue=3.3*phValue+Offset;

    if(sensors.getTempCByIndex(0) > 40){
    temp = String("HIGH");
    }
    if(sensors.getTempCByIndex(0) >= 10 && sensors.getTempCByIndex(0) <= 40){
    temp = String("NORMAL");
    }
    if(sensors.getTempCByIndex(0) < 10){
     temp = String("LOW");
    }

    if(phValue >= 7.30){
    phm = String("ALKALINE");
    }
    if(phValue >= 6.90 && phValue <= 7.19){
    phm = String("NORMAL");
    }
    if(phValue < 6.89){
     phm = String("ACIDIC");
    }

    if(turbidityV >= 6 && turbidityValue/100 <= 9){
    turb = String("CLEAN");
    }
    if(turbidityV < 6){
    turb = String("DIRTY");
    }

  mySerial.begin(19200);  //Default serial port setting for the GPRS modem is 19200bps 8-N-1
  mySerial.print("\r");
  delay(1000);                    //wait for a second while the modem sends an "OK"
  mySerial.print("AT+CMGF=1\r");    //Because we want to send the SMS in text mode
  delay(1000);
  mySerial.print("AT+CMGS=\"+233265188849\"\r");    //Start accepting the text for the message
  delay(1000);
  mySerial.print(temp);
  mySerial.print(" \r");
  mySerial.print("WATER TEMPERATURE= \r");   //The text for the message
  mySerial.print(sensors.getTempCByIndex(0));
  mySerial.print("*C\r");
  mySerial.println("\r");
  mySerial.print(" \r");
  mySerial.print(phm);
  mySerial.print(" \r");
  mySerial.print("WATER PH VALUE= \r");   //The text for the message
  mySerial.print(phValue);
  mySerial.println("\r");
  mySerial.print(turb);
  mySerial.print(" \r");
  mySerial.print("WATER TURBIDITY= \r");   //The text for the message
  mySerial.print(turbidityV);
  mySerial.print("NBT\r");

  delay(3000);
  mySerial.write(0x1A);  //Equivalent to sending Ctrl+Z
}

Не забывайте подключать дополнительные библиотеки.

Шаг 6: Тест и его результаты

Теперь, когда код загружен, попробуйте проверить датчики, например, в чашке воды. Попробуйте апельсиновый сок и другие жидкости, чтобы убедиться, что все датчики работают точно, поскольку для этого требуется калибровка кода. Если всё работает - откройте Serial Monitor в среде Arduino для просмотра того, что делают датчики в настоящее время в режиме реального времени.

Дождитесь текстового сообщения после того, как датчик завершил тест. В коде указано для сообщений - каждые 20 секунд, но вы можете изменить это и обновить код в зависимости от того, что вы хотите.

Ардуино+