Общие сведения
Сегодня поговорим о том, как можно сделать устройство, которое будет автоматически регулировать насыщенность раствора, добавляя в него различные вещества при снижении концентрации.
Систему можно будет использовать для нормализации TDS/ЕС для гидропоники, хотя сфера применения этим не ограничивается. Кстати, мы уже собирали устройство, нормализующее pH, о нём можно почитать в этой статье.
Видео
Редактируется...
Нам понадобится
- 1х датчик TDS (солемер);
- 1х I2C символьный дисплей 1602, ИЛИ 1602 / 2004 + LCD-конвертер в I2C
- 1х I2C-Hub;
- 1x Потенциометр;
- 3х перистальтический насос;
- 3х силовой ключ: p-канал или n-канал. Можно использовать и обычные реле.
- 1х контроллер Piranha Trema;*
- 1х USB – UART преобразователь;**
- 1х понижающий DC-DC преобразователь на 5В;
- 1х блок питания на 12В;
- 1x Гнездо питания на корпус 5.5x2.1 мм
- ёмкости с концентратами и шланги для соединения;
- в качестве корпуса можно использовать ПВХ-конструктор и ПВХ-крепление дисплея.
* Можно использовать любой контроллер серии Piranha, Arduino, или ESP-32.
** Необходим для программирования контроллера Piranha Trema. Однако, можно обойтись без него: контроллер можно запрограммировать при помощи другого контроллера.
Схема
(картинка кликабельна)

Обратите внимание на установку джамперов на силовых ключах и DC-DC преобразователе.
Если насосы не перекачивают жидкость, поменяйте полярность их подключения: от неё зависит направление подачи раствора.
Скетч проекта
Установите библиотеку для работы с TDS-метром и LCD-дисплеем. Если необходима помощь в её установке, читайте статью. Если вы впервые работаете с контроллерами, вам поможет статья.
Загрузите код к контроллер при помощи USB-UART преобразователя. В пункте выбора контроллера Arduino IDE необходимо указать контроллер Arduino Mini.
#include <Wire.h> // Подключаем библиотеку для работы с шиной I2C #include <iarduino_I2C_TDS.h> // Подключаем библиотеку для работы с TDS/EC-метром I2C-flash. #include <LiquidCrystal_I2C.h> // Подключаем библиотеку для работы с LCD дисплеем по шине I2C #define pomp1 2 // Первый насос подключен к выводу 2 #define pomp2 3 // Второй насос подключен к выводу 3 #define pomp3 4 // Третий насос подключен к выводу 4 #define resPin A3 // Вывод, в которому подключен потенциометр // Создаём объекты, указывая адрес модуля на шине I2C: LiquidCrystal_I2C lcd(0x27,20,4); // Дисплей(адрес I2C = 0x27, количество столбцов = 20, количество строк = 4) (для диспления 1602 параметры будут 16 и 2) iarduino_I2C_TDS TDSsens(0x09); // TDS/EC-метр /////////НАСТРОЙКИ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// const uint8_t productivity = 40; // Производительность насоса (мл/мин) float valPomp1 = 1.5; // Объём порции первого насоса, мл float valPomp2 = 1.0; // Объём порции второго насоса, мл float valPomp3 = 1.5; // Объём порции третьего насоса, мл const uint32_t timeWait = 10000; // Время одижания между подачами порции (время на размешивание раствора) // Настройка TDS: const uint16_t tdsDown = 500; // от (минимум) const uint16_t tdsUp = 1500; // до (максимум) const uint32_t lcdPeriod = 500; // Период обновления значений на дисплее const uint32_t changeTimeDelay = 3000; // Время задержки после установления значения потенциометром, во время которого не будет производиться корректировка раствора, мс //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// uint16_t tds; // Измеренный уровень TDS uint16_t tdsOn; // Нижний уровень TDS, после которого начнётся долив концентратов (зависит от поворота ручки потенциометра) uint32_t timeLastPortion; // Время последнего долива порции uint32_t timeLastLcdUpdate; // Время последнего обновления значений на дисплее uint32_t timeChange; // Время изменения заданного значения TDS int16_t res, lastRes=0; // Текущее и предыдущее значение c потенциометра uint8_t symbol[3][8] = { // Объявляем массив из 3 собственных символов, каждый символ состоит из 8 байт {B01110,B10001,B00001,B00010,B00001,B10001,B01110,B00000,}, // Буква "З" {B01111,B00101,B00101,B01001,B10001,B11111,B10001,B00000,}, // Буква "Д" {B00100,B01110,B10101,B10101,B00100,B00100,B00100,B00100}}; // Стрелка вверх void setup() { delay(500); pinMode(pomp1, OUTPUT); // Насос - выход pinMode(pomp2, OUTPUT); // Насос - выход pinMode(pomp3, OUTPUT); // Насос - выход Serial.begin(9600); // Открываем последовательный порт передачи данных lcd.init(); // Инициируем работу с LCD дисплеем lcd.backlight(); // Включаем подсветку LCD дисплея if (!TDSsens.begin()) Serial.println("TDS/EC-метр не инициализирован. Проверьте подключение и I2C-адрес модуля"); // Иниируем работу с TDS/EC-метром. Если не удалось выполнить подклчение, выводим сообщение об ошибке lcd.clear(); lcd.createChar(1, symbol[0]); // Загружаем 1 символ "З" в ОЗУ дисплея lcd.createChar(2, symbol[1]); // Загружаем 2 символ "Д" в ОЗУ дисплея lcd.createChar(3, symbol[2]); // Загружаем стрелку в ОЗУ дисплея lcd.setCursor(0, 0); // Устанавливаем курсор в 0 столбец 0 строку дисплея lcd.print("PACTBOP: "); // Выводим текст на дисплей lcd.setCursor(0, 1); // Устанавливаем курсор в 0 столбец 1 строку дисплея lcd.print("\1A\2AHO: "); // Выводим текст на дисплей delay(2000); // Задержка для завершения переходных процессов (в частности, устновление показаний TDS-метра) } void loop() { tds = TDSsens.getTDS(); // Измерение TDS Serial.println("TDS: "+ (String)tds); // Вывод значения TDS в монитор порта res = analogRead(resPin); // Получение значения с потенциометра tdsOn = (map(res, 0, 1023, tdsDown, tdsUp)/10)*10; // Перевод значений потенциометра (АЦП) в значения установки TDS. Делим и умножаем на 10 для округления десятков if (abs(lastRes-res) > 5){ // Начали поворачивать ручку потенциометра timeChange = millis(); // Обновляем время изменения значений } if (timeChange + changeTimeDelay <= millis()){ // Если после ввода значений прошло достаточное время if (timeLastPortion + timeWait <= millis()){ // Если с момента добавления предыдущей порции прошло необходимое время if (tds < tdsOn) { // Если концентрация раствора ниже заданной lcd.setCursor(14, 0); // Устанавливаем курсор в 14 столбец 0 строку дисплея lcd.print(" "); // Очищаем lcd.setCursor(14, 0); // Устанавливаем курсор в 14 столбец 0 строку дисплея lcd.print("\3"); // Выводим стрелку lcd.setCursor(9, 0); // Устанавливаем курсор в 9 столбец 0 строку дисплея lcd.print(" "); // Очищаем lcd.setCursor(9, 0); // Устанавливаем курсор в 9 столбец 0 строку дисплея lcd.print(tds); // Выводим показания TDS на экран correctTDS(); // TDS снизился, нужно повысить } else{ // Если концентрация раствора больше или равна заданной lcd.setCursor(14, 0); // Устанавливаем курсор в 14 столбец 0 строку дисплея lcd.print("OK"); // Выводим текст } } } lastRes = res; // Обновляем прежнее значение с потенциометра if (timeLastLcdUpdate + lcdPeriod <= millis()){ // Если пора обновить значения на дисплее lcd.setCursor(9, 0); // Устанавливаем курсор в 9 столбец 0 строку дисплея lcd.print(" "); // Очищаем lcd.setCursor(9, 0); // Устанавливаем курсор в 9 столбец 0 строку дисплея lcd.print(tds); // Выводим показания TDS на экран lcd.setCursor(9, 1); // Устанавливаем курсор в 9 столбец 1 строку дисплея lcd.print(" "); // Очищаем lcd.setCursor(9, 1); // Устанавливаем курсор в 9 столбец 1 строку дисплея lcd.print(tdsOn); // Выводим показания TDS на экран timeLastLcdUpdate = millis(); // Обновляем время } } void correctTDS (){ // Функция дозации компонентов digitalWrite(pomp1,HIGH); // Включаем первый насос delay((float)productivity/60.0*valPomp1*1000.0); // Выполняем задержку, равную времени работы насоса, треюуемому для подачи нужного количества жидкости digitalWrite(pomp1,LOW); delay(200); // Пауза для завершения переходных процессов (в частности, по питанию) // Повторяем для остальных насосов digitalWrite(pomp2,HIGH); delay((float)productivity/60.0*valPomp2*1000.0); digitalWrite(pomp2,LOW); delay(200); digitalWrite(pomp3,HIGH); delay((float)productivity/60.0*valPomp3*1000.0); digitalWrite(pomp3,LOW); timeLastPortion = millis(); // Фиксируем время, когда произошел долив компонентов }
Ссылки
- Устройство для автоматической нормализации pH;
- Библиотека для работы с TDS-метром;
- Библиотека для работы с LCD-дисплеем;
- Инструкция по установке библиотек;
- Инструкция по установке и настройке Arduino IDE;
- Полностью автоматизированная гидропоника с управлением через WiFi.
Обсуждение