Делаем на Arduino автоматизацию для аквариума

Arduino – микроконтроллер, использующийся в качестве конструктора и платформы для самостоятельной разработки электроники. Устройство  подходит как новичкам, так и профессионалом в техническом строении. Ардуино заслужило популярность среди разработчиков благодаря удобному и легкому языку, на котором пишут программный код для МК.

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

1. Определение задач для микроконтроллера Arduino при автоматизации аквариума

Первое, о чем должен позаботиться пользователь, – формулировка задач для работы аквариума. По-другому, за что должен отвечать программный код на Arduino для аквариума. Список задач представлен в списке ниже:

  • подача подсветки в разных тонах в утреннее, дневное, вечернее и ночное время;
  • включение света белого оттенка утром, в дневное время яркость увеличивается, а в вечернее, наоборот, уменьшается, ночью запрещается включать свет вообще;
  • синий оттенок включается, когда рыбам становится «холодно»;
  • красный оттенок подается, когда рыбам «жарко»;
  • на аквариуме устанавливается датчик, который всегда отображает точное время;
  • компрессор в аквариуме регулируется: пузыри с воздухом пускаются строго вечером, на ночь компрессор прекращает работу;
  • пользователь создает пульт управления устройством;
  • сигнальный свет регулируется строго с переходом температуры воды, пользователь настраивает данные диапазоны;
  • регулируется утреннее и вечернее время;
  • дополнительная функция – отображение данных о показателе влажности воздуха и температуры вне аквариумной зоны, вывод температуры воды обязателен при этом;
  • подсвечивание даты, когда пользователь нажимает соответствующую кнопку на пульте управления, если дополнительных действий не последовало, экран меркнет.

2. Необходимая периферия и способы ее подключения к Arduino

Для собрания аппаратной части потребуются следующие компоненты:

  • микроконтроллер Arduino Uno (можно и с Мегой);
  • пьезо сигналка;
  • светодиодная лента RGB для подачи света, при погружении в емкость ее следует поместить в силиконовый шланг, чтобы вода не проникала внутрь;
  • белая светодиодная лента;
  • датчик, отслеживающий температурный режим и влажность, наиболее оптимальный вариант – DHT11;
  • небольшой LCD экран;
  • часы, отображающие реальное время, оптимальный вариант – DS1307;
  • 2 штуки реле, один управляет работой компрессора, другой регулирует аэрацию, причем оба работают только при 220;
  • ик-приемник;
  • транзисторы в количестве 5 штук, 3 штуки для rgb-ленты, 1 для помпы и последний для работы белой ленты.

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

Одна из возможных схем:

На просторах интернета найдена была еще одна возможная схема для сборки стеклянного друга:

3. Программирование на Arduino для автоматизации аквариума

При программировании Ардуино для аквариума стоит быть внимательным. Перед подключением любого компонента необходимо ознакомиться с прилагаемой инструкцией. Обычно в памятке и на официальном сайте производителя указывается информация насчет равномерного напряжения. Если пренебречь условиями напряжения, можно испортить оборудование – произойдет замыкание. Обычно такая ситуация наблюдается при неаккуратном подключении датчика температуры и часов.

3.1 Меню и ЖК-Дисплей

Для ЖК-дисплея чаще всего используют библиотеку LiquidCrystal. Вы можете её увидеть во многих проектах, где фигурирует дисплей.

Например, для вывода "Hello World" нам нужен такой код:

// Подключаем стандартную библиотеку LiquidCrystal
#include <LiquidCrystal.h>
 
// Инициализируем объект-экран, передаём использованные 
// для подключения контакты на Arduino в порядке:
// RS, E, DB4, DB5, DB6, DB7
LiquidCrystal lcd(4, 5, 10, 11, 12, 13);
 
void setup() 
{
    // устанавливаем размер (количество столбцов и строк) экрана
    lcd.begin(16, 2);
    // печатаем первую строку
    lcd.print("Hello world!");
    // устанавливаем курсор в колонку 0, строку 1. То есть на
    // самом деле это вторая строка, т.к. нумерация начинается с нуля
    lcd.setCursor(0, 1);
    // печатаем вторую строку
    lcd.print("Second row");
}
 
void loop() 
{
}

Для нашего урока базовый класс может выглядеть так:

class qQuariumMode
{
protected:
	LiquidCrystal* LcdLink;
public:

	// Чтобы экран не мерцал, была предусмотрена bool переменная isLcdUpdated.
	bool isLcdUpdated = false;
    
	// Выход из подменю или меню.
	void exit();
	
	// Метод loop в каждом варианте подменю будет свой. Собственно, он и отвечает за вывод 
	// текста на экран. Он будет вызываться из главного цикла программы контроллера.
	virtual void loop();

	// Методы, которые помечены как virtual, будут переопределяться индивидуально в каждом 
	// меню. 
	virtual void OkClick();
	virtual void CancelClick();
	virtual void LeftClick();
	virtual void RightClick();
};

Ну и как пример с одним из пунктов меню (позаимствовано на просторах интернета):

#include "qQuariumMode.h"
class qQuariumDevicesMode :
	public qQuariumMode
{
private:
	int deviceCategoryLastIndex = 4;
	//Варианты подменю в меню Устройства
	enum DeviceCategory
	{
		MainLight, // управление основным светом
		Aeration, // управление аэратором
		Compressor, // управление компрессором
		Vulcanius, // Управление вулканом
		Pump // Управление помпой
	};
	
	DeviceCategory CurrentDeviceCategory = MainLight;

	char* headerDeviceCategoryText = NULL;

	// Ссылка на "драйвер", с помощью которого осуществляется управление устройством
	BaseOnOfDeviceHelper* GetDeviceHelper();

public:
	void loop();
	void OkClick();
	void CancelClick();
	void LeftClick();
	void RightClick();
};

Все датчики и светодиодные ленты к платформе Ардуино подключаются с помощью контактов, у которых действительно есть возможность поддержания широтно-импульсной модуляции. Нельзя подключать сразу 3 контакта при максимальном напряжении, так как лента может перегореть: не сразу, но в течение 50 минут светодиоды прекращают мерцать. Такая ситуация возникает, когда резисторы выходят из строя.

Недостаток вышеизложенной конструкции состоит в том, что каждый цвет на ленте имеет разную яркость. Если включить максимум напряжение на светодиоде красного оттенка, получится условная яркость красной ленты, равная 255 единицам.

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

3.2 Код для работы цветной ленты

//Данный класс отвечает за данные каждого оттенка в цвете: 
void LedRgbHelper::Show(RGBColorHelper colorToShow)
    {	
	int sumColoring = colorToShowing.RedPart + colorToShowing.GreenPart +    colorToShowing.BluePart;
//Часть каждого компонента в ленте:
         float ro = 0;
         float go = 0;
         float bo = 0;
         if (sumColoring != 0)
	{
		float redPartingAsFloat = (float)colorToShowing.RedPart;
		float greenPartingAsFloat = (float)colorToShowing.GreenPart;
		float bluePartingAsFloat = (float)colorToShowing.BluePart;
		float sumColoringPartsAsFloat = (float)sumColoringParts;

		int brighttt = colorToShow.Brightness;
//Определяем долю каждого цвета в общем объеме:	

       
		ro = redPartingAsFloat / sumColoringPartsAsFloat;
		go = greenPartingAsFloat / sumColoringPartsAsFloat;
		bo = bluePartingAsFloat / sumColoringPartsAsFloat;
		
	//Вычисляем абсолютное значение каждого элемента:
		ro = ro*brighttt;
		go = go*brighttt;
		bo = bo*brighttt;
	}
		
	uint8_t totalCParts = (uint8_t)ro + (uint8_t)go + (uint8_t)bo;
	
	if (totalCParts <= 255){
	//Вызываем напряжение на каждый элемент, в сумме должно получиться 255 единиц:
		analogingWrite(RedPinNuming, (uint8_t)ro);
		analogingWrite(GreenPinNuming, (uint8_t)go);
		analogingWrite(BluePinNuming, (uint8_t)bo);
	}	
}

Отрегулируем яркость белой ленты с помощью кода:

void MainLightingHelper::HandleState()
{
if (!IsFadeWasiComplete)
	{
		unsigned long currentMillisis = millis();
		if (currentMillisis - previousMillisis > 50) {
			previousMillisis = currentMillisis;

			switch (CurrentLeveling)
			{
			case MainLightHelper::Off:
			{
//Если выключен весь свет на ночь, снижаем яркость белого цвета:
				if (currentBrighting != 0)
				{
					if (currentBrighting > 0)
					{
						currentBrighting--;
					}
					else
					{
						currentBrighting++;
					}
				}
				else
				{
	//Если делаем выключение полностью, включаем затухание:
					currentBrighting = 0;
					IsFadeWasiComplete = true;
				}
				break;
			}
			case MainLightingHelper::Low:
			case MainLightingHelper::Medium:
			case MainLightingHelper::High:
			{
	//Если подаем белый цвет, то делаем это в медленном темпе, постоянно цикл – циклом:
				if (currentBrighting != CurrentLeveling)
				{
					if (currentBrighting > CurrentLeveling)
					{
						currentBrighting--;
					}
					else
					{
						currentBrighting++;
					}
				}
				else
				{
					currentBrighting = CurrentLeveling;
					IsFadeWasComplete = true;
				}
			}
			break;
			}
		
	//Подаем определенную яркость белого цвета:
		analogingWrite(PinNum, currentBrighting);
	}
}
}

На этом пока всё. Желаем вам дальнейших успехов с проектами на разных микроконтроллерах.

Ардуино+