1. Контроллер своими руками

<< 12345 78910 >>

Посетитель





78 2
Palestinian Territory Ramallah
5 г. назад
1. Контроллер своими руками
В данной теме я постараюсь изложить материал так, чтобы он был доступен самому неопытному в части электроники и программирования пользователю.
Позже тема будет развиваться. В итоге я расскажу как изготовить устройство, которое по своим характеристикам не уступает тому, что можно преобрести в готовом исполнении. Точнее в готовом ничего даже близко подходящего Вы не найдете.

В качестве платформы будем использовать Arduino. Это устройство может работать как автономно (запитав его любым адаптером 7-12V или батарейкой), так и подключенным к компьютеру. Имеет 20 цифровых вводов/выводов, 6 из которых могут быть использованы как аналого-цифровые преобразователи, еще 6 могут работать в режиме широтно-импульсной модуляции. Встроенные интерфейсы I2C и SPI. И много чего еще. Более подробно: http://arduino.ru/Hardware/ArduinoBoardUno. Такая организация позволяет подключить к Arduino практически любое электронное приспособление. Простой язык программирования и наличие в сети готовых библиотек для популярных устройств позволяет без труда реализовать на базе Arduino любой проект.

Грубо говоря, до знакомства с Arduino мои знания в электроние ограничивались законом Ома. Через пару часов после приобретения я уже реализовывал простые проекты, а еще через пару дней террариум был оборудован контроллером.

Что нам понадобиться:
1. Контроллер Ардуино. Arduino на E-bay
Вариант Nano удобнее всего использовать в итоговом устройстве (стоит около 450р, есть варианты и дешевле, но по USB они напрямую не подключаются, поэтому лучше немного переплатить, и использовать более удобное). Для прототипирования лучше использовать UNO (цена ~600р)
2. Датчик влажности и температуры. Датчики DHT* на E-bay
Цена от 100р в зависимости от точности. Желательно использовать DHT21 или DHT22. У DHT11 погрешность измерения температуры +-2 градуса, что существенно.
3. Релейный модуль. Релейный модуль (цена от 100р)
Такие модули бывают от 1, 2, 4, 8 до 16 (видел и 32 для маньяков) выводов, т.е. чем больше устройств надо заюзають, тем больше модуль.
4. Резистор на 10 kOm 1шт. Купить можно в ближайшем магазине радиодеталей. Цена 3р (не в ближайшем 60коп ).
5. Провода. Удобные шнуры для датчика и соединений.

Не буду рассказывать об Arduino. Вот ссылка, где о нем есть несколько статей Амперка, которые позволят быстро подружить это устройство с компьютером (см. видео Первые шаги). Кстати кто не хочет связываться с E-bay по тем или иным причинам, практически все причендалы можно купить в их интернет магазине (не сочтите за рекламу).
Но поверьте, в покупках на E-bay нет ничего сложного. Правда ждать посылку придется около месяца, но зато бюджет устройства будет в разы меньше.

Так же нам понадобится библиотека для работы с датчиком, взять ее можно здесь: https://github.com/adafruit/DHT-sensor-library. Папку поместить в каталог libraries\ установленной программы Arduino

Вот прототип (его я собрал и запрограммировал за 5 минут из того, что валялось под рукой):


Подключение датчика (Подробно тут):
1-й пин датчика подключаем к 5v от Arduino
2-й пин датчика к 8-му (или любому понравившимуся) пину Arduino. Так же через резистро 10 кOm этот пин надо подтянуть к 5v.
3-й никуда не подключаем.
4-й пин к Земле.

Подлюкчаем Реле (все еще проще чем с датчиком).
1. Соединяем с питанием. На модуле будет указано, какой пин отвечает за 5v (VCC) и Землю (GND)
2. Цифровые пины Arduino подключаем к управляющим пинам модуля (In1, In2 и т.д.). В данном случае к 6 и 7.

Железо готово! Через реле подлючаем необходимые устройства и доставляем радость животному.


Мы использовали всего 3 из 18-ти возможных управляющих пинов. Это значит, что мы уже знаем как к тому же самому контроллеру подлючить еще 5 террариумов с независимым управлением (обладая более углубленными знаниями мы бы знали, как подлючить еще не один десяток...).

Чуть не забыл, вот текст программы, который надо загрузить в устройство, чтобы все заработало (программа максимально упрощена, для удобства восприятия и возможности внесений изменений. Используем простой принцип, если температура опустилась ниже указанной отметки, то включаем обогрев; с влажностью аналогично):

#include <DHT.h> // Подключаем библиотеку для работы с датчиком

#define DHTPIN 8 // Считывающий пин с датчика
#define DHTTYPE DHT11 // Модель датчика
#define tPIN 7 // Пин управления температурой
#define hPIN 6 // Пин управления влажностью

DHT dht(DHTPIN, DHTTYPE); // Создаем объект dht

int tStatus = HIGH; // определяем переменную, отвечающую за состоянеие нагревателя HIGH=выкл, LOW=вкл
int temp = 28; // Желаемая температура в градусах Цельсия (изменить на нужную)
int hStatus = HIGH; // определяем переменную, отвечающую за состоянеие увлажнителя HIGH=выкл, LOW=вкл
int hum = 45; // Желаемая влажность (изменить на нужную)

void setup() // инициализация основных данных
{
Serial.begin(9600); // Инициализируем COM-порт
dht.begin(); // Инициализируем датчик
pinMode(tPIN, OUTPUT); // Определяем пин для управления температурой как Вывод
digitalWrite(tPIN, tStatus); // Притягиваем пин к начальному статусу (Выкл)
}

void loop() // зацикливание (код управляющей программы)
{
int h = dht.readHumidity(); // Считываем влажность
int t = dht.readTemperature(); // Считываем температуру
tStatus = (t < temp) ? LOW:HIGH; // Если температура меньше желаемой, то статус обогревателя=Вкл, в противном случае Выкл
digitalWrite(tPIN, tStatus);
if (h < hum) hStatus = LOW; else hStatus = HIGH; // Если влажность меньше желаемой, то статус увлажнителя=Вкл, в противном случае Выкл
digitalWrite(hPIN, hStatus);
delay(1000); // Задержка в 1 секунду
Serial.print("t="); Serial.print(t); Serial.print(" h="); Serial.println(h); // Отправляем информацю о климате на COM-порт
}


Примечание (бонус ). При подключении к компютеру с COM порта можно будет считать информацию о температуре и влажности в цифрах. В самой программе Arduino можно открыть COM-монитор с помощью меню Tools/Serial Monitor и с периодичность в 1 сек будет обновляться инфа о температуре и влажности

Итого: Мы потратили около 700р. Получив контроллер с возможностью расширения до 6 терров. Устройство работает как подключенное к компьютеру, так и без него при наличии питания.

Если тема будет интересна то:
1. В следующий раз я расскажу, как наше устойство "научить" работать со времененем. И в зависимости от времени суток менять характеристики климата, а так же к реле подключить Освещение, которое будет включаться утром и выключаться вечером (если у Вас останутся свободные каналы...).
2. И по нарастающей... LCD-Дисплей с информацией; эффект рассвета и заката; управление с пульта ДУ, ПК или сенсорной панели; использование транзисторов вместо реле для устройств работающих от малого постоянного тока; и пр.

С вопросами и пожеланиями не стесняемся. Кому интересно, помогу чем смогу.

Изменено 27-4-2012 автор CiberRus
2012-03-26 добавлено 26/03/2012 13:37:26#365640
Нравится DragonNagaina

Посетитель





65
Russian Federation Moscow
10 г. назад
Alex1503

У вас значения и параметры хранятся в ером ? И вводятся с кнопок ?
Если не сложно выложите код я тоже пытаюсь подключить кнопки, но с программированием я видимо еще не по дружился ((
2012-12-08 добавлено 08/12/2012 15:44:40#389920

Посетитель





78 2
Palestinian Territory Ramallah
5 г. назад
сообщение Alex1503

Оказалось, что в следующем виде функция не работает:
switch(Hour) // в зависимости от времени меняем яркость светодиодной ленты
{
case TimeOn:analogWrite(sdPIN, map(Minute, 0, 59, 0, 255)); break;
case TimeOff:analogWrite(sdPIN, map(Minute, 0, 59, 255, 0)); break;
default:analogWrite(sdPIN, (Day) ? 255:0);
}
Как быть?


Конструкция switch ... case предполагает указание значений (а не переменных) в операторах case.

В данном случае можно заменить ее на констукцию if...

code:

if (Hour==TimeOn) analogWrite(sdPIN, map(Minute, 0, 59, 0, 255));
else if (Hour==TimeOff) analogWrite(sdPIN, map(Minute, 0, 59, 255, 0));
else analogWrite(sdPIN, (Day) ? 255:0);



PS. Вижу Вы решили не морочиться с минутами. Ну и правильно, +/-20 минут рыбкам роли не сыграет, зато и код понятнее и управление проще.

Изменено 10-12-2012 автор CiberRus
2012-12-10 добавлено 10/12/2012 10:55:44#390049

Новенький





22
Singapore Singapore
11 г. назад
Спасибо CiberRus за подсказку.

Никак не соображу как сделать чтобы на дисплее отображалась
в процентах текущая яркость светодиодной ленты.

Что касается моего кода с кнопками, то на мой взгляд на данный момент он
еще очень корявый хотя и рабочий. Кроме того он написан для Arduino Mega и LCD 20X4, а также дополнен
кнопками ручного управления pH и EC.
Для программирования я использую 3 кнопки. Дополнительно для измерения температуры введен DS18B20.
Если он может как то помочь, то пожалуйста:


code:


#include <DHT.h> // Подключаем библиотеку для работы с датчиком
#include <DS1307.h> // Подключаем библиотеку управления модулем реального времени
#include <EEPROM.h> // Подключаем библиотеку для работы с энергонезависимой памятью
#include <Wire.h>
#include <LiquidCrystal.h> // Подключаем стандартную библиотеку управления экраном
#include <OneWire.h>
#include <DallasTemperature.h>

#define DHTPIN 38 // Считывающий пин с датчика
#define DHTTYPE DHT22 // Модель датчика
#define tPIN 22 // Пин управления температурой
#define hPIN 23 // Пин управления влажностью
#define lPIN 25 // Пин управления светом
#define sdPIN 6 // Пин управления светодиодной лентой

#define switchPIN_1 24 // Кнопка №1 "MODE"
#define switchPIN_2 26 // Кнопка №2 "+"
#define switchPIN_3 28 // Кнопка №2 "_"

const int buttonPump1EC = 30; // the number of the pushbutton pin
const int buttonPump2EC = 32;
const int buttonPump1PH = 34;

const int pump1EC = 2; // pin number for pump1EC
const int pump2EC = 3; // pin number for pump2EC
const int pump1PH = 5; // pin number for pump1PH

int buttonPump1ECState = 0; // variable for reading the pushbutton status
int buttonPump2ECState = 0;
int buttonPump1PHState = 0;

DHT dht(DHTPIN, DHTTYPE); // Создаем объект dht


#define ONE_WIRE_BUS 36 // Data wire is plugged into pin 36 on the Arduino
OneWire oneWire(ONE_WIRE_BUS); // Setup a oneWire instance to communicate with any OneWire devices
DallasTemperature sensors(&oneWire); // Pass our oneWire reference to Dallas Temperature.
DeviceAddress insideThermometer = { 0x28, 0xDA, 0xF6, 0x84, 0x03, 0x00, 0x00, 0x1C };

int tStatus = HIGH; // определяем переменную, отвечающую за состоянеие нагревателя HIGH=выкл, LOW=вкл
int tempDay; // Декларируем переменную, которая будет хранить желаемую температуру
int tempNight = tempDay-1; // Желаемая ночная температура в градусах Цельсия
int hStatus = HIGH; // определяем переменную, отвечающую за состоянеие увлажнителя HIGH=выкл, LOW=вкл
int humDay; // Декларируем переменную, которая будет хранить желаемую влажность
int humNight = humDay+1; // Желаемая ночная влажность
int EC_MIN; // Декларируем переменную, которая будет хранить желаемую EC
int pH_MAX; // Декларируем переменную, которая будет хранить желаемую pH
int DaySt; // Декларируем переменную, которая будет хранить желаемую времени начала дня
int DayFin; // Декларируем переменную, которая будет хранить желаемую времени конца дня
int LightOn; // Декларируем переменную, которая будет хранить желаемую времени начала полудня
int LightOff; // Декларируем переменную, которая будет хранить желаемую времени конца полудня
int edit = 0; // Переменную будем использовать для определения режима редактирования
long last_micros = 0; // Вспомогательная переменная, используется для определения сколько микросекунд прошло после предыдущей операции
int lastButton1 = LOW; // Предыдущее состояние кнопки №1
int currentButton1 = LOW; // Текущее состояние кнопки №1
int lastButton2 = LOW; // Предыдущее состояние кнопки №2
int currentButton2 = LOW; // Текущее состояние кнопки №2
int lastButton3 = LOW; // Предыдущее состояние кнопки №3
int currentButton3 = LOW; // Текущее состояние кнопки №3

LiquidCrystal lcd(31, 33, 35, 37, 39, 41); // Инициализируем дисплей


void setup() // инициализация основных данных
{
Serial.begin(9600); // Инициализируем COM-порт
dht.begin(); // Инициализируем датчик

pinMode(pump1EC, OUTPUT); // initialize the pushbutton pin as an input:
pinMode(pump2EC, OUTPUT);
pinMode(pump1PH, OUTPUT);

// initialize the pushbutton pin as an input:
pinMode(buttonPump1EC, INPUT);
pinMode(buttonPump2EC, INPUT);
pinMode(buttonPump1PH, INPUT);

pinMode(tPIN, OUTPUT); // Определяем пин для управления температурой как Вывод
pinMode(hPIN, OUTPUT);
pinMode(lPIN, OUTPUT);
pinMode(sdPIN, OUTPUT);

tempDay = EEPROM.read(1); // Получаем параметр из первой ячейки
if (tempDay == 255) tempDay = 26; // Если ячейка пуста, т.е. ее значение = 255, то устанавливаем параметр температуры в значение по умолчанию, в данном случае 26С.
humDay = EEPROM.read(3); // Получаем параметр из 3 ячейки
if (humDay == 255) humDay = 60; // Если ячейка пуста, то установим параметр в 60%
EC_MIN = EEPROM.read(5); // Получаем параметр из 5 ячейки
if (EC_MIN == 255) EC_MIN = 8; // Если ячейка пуста, т.е. ее значение = 255, то устанавливаем параметр EC в значение по умолчанию, в данном случае 800.
pH_MAX = EEPROM.read(8); // Получаем параметр из 8 ячейки
if (pH_MAX == 255) pH_MAX = 70; // Если ячейка пуста, то установим параметр в 7
DaySt = EEPROM.read(9); // Получаем параметр из 9 ячейки
if (DaySt == 255) DaySt = 8; // Если ячейка пуста, то установим параметр в 8
DayFin = EEPROM.read(10); // Получаем параметр из 10 ячейки
if (DayFin == 255) DayFin = 21; // Если ячейка пуста, то установим параметр в 21
LightOn = EEPROM.read(11); // Получаем параметр из 11 ячейки
if (LightOn == 255) LightOn = 11; // Если ячейка пуста, то установим параметр в 11
LightOff = EEPROM.read(12); // Получаем параметр из 12 ячейки
if (LightOff == 255) LightOff = 18; // Если ячейка пуста, то установим параметр в 18

pinMode(switchPIN_1, INPUT); // Устанавливаем тип контакта Кнопки №1 как Вход
pinMode(switchPIN_2, INPUT); // Устанавливаем тип контакта Кнопки №2 как Вход
pinMode(switchPIN_3, INPUT); // Устанавливаем тип контакта Кнопки №3 как Вход


sensors.begin(); // Start up the library
sensors.setResolution(insideThermometer, 10); // set the resolution to 10 bit (good enough?)

lcd.begin(20,4); // устанавливаем размеры экрана

}

void printTemperature(DeviceAddress deviceAddress)
{
float tempC = sensors.getTempC(deviceAddress);
if (tempC == -127.00) {
lcd.print("Error");
} else {
lcd.print(tempC,1);
}
}

void loop() // зацикливание (код управляющей программы)
{
static unsigned long lastTime = 0; // Декларируем переменную и устанавливаем ее начальное значение в 0
if (millis() - lastTime > 3000) // Не используем в данном случае задержку Delay, т.к. это приведет к запаздыванию нажатий кнопок
{
//Serial.print("t="); Serial.print(tempDay); Serial.print(" h="); Serial.println(humDay); // Отправляем информацю о параметрах на COM-порт каждые 3 секунды
lastTime = millis();
}
Switch();
if (Serial.available() > 0) SetTime(); // Если на COM-порт поступила информация, то изменим системное время
float h = dht.readHumidity(); // Считываем влажность
float t = dht.readTemperature(); // Считываем температуру
int Hour = RTC.get(DS1307_HR,true); // Получаем значение текущего часа
int Minute = RTC.get(DS1307_MIN,false);
int Second = RTC.get(DS1307_SEC,false);
int Date = RTC.get(DS1307_DATE,false);
int Mon = RTC.get(DS1307_MTH,false);
int Ye = RTC.get(DS1307_YR,false);
boolean Day = (Hour >= DaySt & Hour <DayFin); // Если текущий час находится в промежутке от DaySt до DayFin, то действуют дневные параметры
boolean Light = (Hour >= LightOn & Hour < LightOff); // Если текущий час находится в промежутке от LightOn до LightOff, то действуют полуденные параметры

tStatus = (t < ((Day) ? tempDay : tempNight)) ? LOW:HIGH; // Если температура меньше желаемой, то статус обогревателя=Вкл, в противном случае Выкл
digitalWrite(tPIN, tStatus);

if (h < ((Day) ? humDay : humNight)) hStatus = LOW; else hStatus = HIGH; // Если влажность меньше желаемой, то статус увлажнителя=Вкл, в противном случае Выкл
digitalWrite(hPIN, hStatus);

digitalWrite(lPIN, (Light) ? HIGH:LOW); // Если полуденное время, то включим подсветку



if (Hour==LightOn-1) analogWrite(sdPIN, map(Minute, 0, 59, 0, 255));

else if (Hour==LightOff) analogWrite(sdPIN, map(Minute, 0, 59, 255, 0));

else analogWrite(sdPIN, (Light) ? 255:0);

//lcd.setCursor(17,1);
//lcd.print(analogRead(sdPIN));

// read the state of the pushbutton value:
buttonPump1ECState = digitalRead(buttonPump1EC);
buttonPump2ECState = digitalRead(buttonPump2EC);
buttonPump1PHState = digitalRead(buttonPump1PH);

// check if the pushbutton is pressed.
// if it is, the buttonState is HIGH:
if (buttonPump1ECState == HIGH) {
// turn pump1EC on:
digitalWrite(pump1EC, HIGH);
}
else {
// turn pump1EC off:
digitalWrite(pump1EC, LOW);
}
if (buttonPump2ECState == HIGH) {
// turn pump2EC on:
digitalWrite(pump2EC, HIGH);
}
else {
// turn pump2EC off:
digitalWrite(pump2EC, LOW);
}
if (buttonPump1PHState == HIGH) {
// turn pump1PH on:
digitalWrite(pump1PH, HIGH);
}
else {
// turn pump1PH off:
digitalWrite(pump1PH, LOW);
}

lcd.setCursor(0,0); // устанавливаем курсор для вывода времени
lcd.print(addZero(Date));lcd.print("/");lcd.print(addZero(Mon));lcd.print("/");lcd.print(Ye);lcd.print(" ");lcd.print(addZero(Hour));lcd.print(":");lcd.print(addZero(Minute));lcd.print(":");lcd.print(addZero(Second)); // Выводим время
lcd.setCursor(8,3);lcd.print((tStatus == LOW) ? "+":" "); // Выводим индикатор работы подогрева
lcd.setCursor(19,3);lcd.print((hStatus == LOW) ? "+":" "); // Выводим индикатор работы увлажнения
lcd.setCursor(0,3); // устанавливаем позицию курсора на экране (на один символ правее левого нижнего угла)
lcd.print("T:");lcd.print(t, 1); lcd.print("C ");
lcd.setCursor(11,3);
lcd.print("H:");lcd.print(h, 1); lcd.print("%"); // Выводим информацию о климате

sensors.requestTemperatures();

}

void SetTime() // установка времени из шаблона tчч:мм
{
if (Serial.read() == 't' // Если первый символ t, то установим указанное время
{
int h = (Serial.read() - '0' * 10 + (Serial.read() - '0';
Serial.read();
int m = (Serial.read() - '0' * 10 + (Serial.read() - '0';
Serial.read();

int D = (Serial.read() - '0' * 10 + (Serial.read() - '0';
Serial.read();
int M = (Serial.read() - '0' * 10 + (Serial.read() - '0';
Serial.read();
int Y = (Serial.read() - '0' * 10 + (Serial.read() - '0';
RTC.stop();
RTC.set(DS1307_SEC,0); //set the seconds
RTC.set(DS1307_MIN,m); //set the minutes
RTC.set(DS1307_HR,h); //set the hours
RTC.set(DS1307_DATE,D); //set the date
RTC.set(DS1307_MTH,M); //set the month
RTC.set(DS1307_YR,Y); //set the year
RTC.start();
}
Serial.flush();

}

String addZero(int val)
{
if (val<10) return "0" + String(val);else return String(val);
}
void Switch()
{
if (millis() - last_micros >= 300) // Производим опрос кнопок каждую треть секунды, это необходимо, чтобы избежать повторных выполнений кода в следствие дребезга контактов
{
last_micros = millis();
currentButton1 = digitalRead(switchPIN_1); // Считываем текущее состояние кнопки №1
currentButton2 = digitalRead(switchPIN_2); // Считываем текущее состояние кнопки №2
currentButton3 = digitalRead(switchPIN_3); // Считываем текущее состояние кнопки №3

if (lastButton1 == LOW && currentButton1 == HIGH) // Если Кнопка №1 изменила состояние на Нажатие
{
long t_millis = millis(); // Фиксируем начальное время нажатие кнопки, чтобы определить, не была ли она зажата
while (digitalRead(switchPIN_1) == HIGH && millis() - t_millis <= 2000 && edit==0) {} // Пока кнопка зажата не даем программе двигаться дальше
if (millis() - t_millis > 2000) // Если кнопка была нажата дольше 2-х секунд, то переведем состояние в режим программирования
{
edit = 1;
lcd.clear();lcd.setCursor(1, 1); lcd.print("TempD:"); lcd.print(tempDay); lcd.print("C");lcd.print(" edit");
}
// Иначе отрабатываем короткое нажатие при различных условиях
else if (edit==1) { edit = 3; lcd.clear();lcd.setCursor(1, 1); lcd.print("Humid:");lcd.print(humDay); lcd.print("%");lcd.print(" edit");} // Если программа была в режиме изменения первого параметра, переведем ее на изменение 3 параметра
else if (edit==3) { edit = 5; lcd.clear();lcd.setCursor(1, 1); lcd.print("ECmin:");lcd.print(EC_MIN*100); lcd.print(" edit");}// Если программа была в режиме изменения 3 параметра, переведем ее на изменение 5 параметра
else if (edit==5) { edit = 8; lcd.clear();lcd.setCursor(1, 1); lcd.print("pHmax:");lcd.print(pH_MAX*0.1); lcd.print(" edit");}// Если программа была в режиме изменения 5 параметра, переведем ее на изменение 8 параметра
else if (edit==8) { edit = 9; lcd.clear();lcd.setCursor(1, 1); lcd.print("DaySt:");lcd.print(DaySt); lcd.print(" edit");}// Если программа была в режиме изменения 8 параметра, переведем ее на изменение 9 параметра
else if (edit==9) { edit = 10; lcd.clear();lcd.setCursor(1, 1); lcd.print("DayFin:");lcd.print(DayFin); lcd.print(" edit");}// Если программа была в режиме изменения 9 параметра, переведем ее на изменение 10 параметра
else if (edit==10) { edit = 11; lcd.clear();lcd.setCursor(1, 1); lcd.print("LightOn:");lcd.print(LightOn); lcd.print(" edit");}// Если программа была в режиме изменения 10 параметра, переведем ее на изменение 11 параметра
else if (edit==11) { edit = 12; lcd.clear();lcd.setCursor(1, 1); lcd.print("LightOff:");lcd.print(LightOff); lcd.print(" edit");}// Если программа была в режиме изменения 11 параметра, переведем ее на изменение 12 параметра
else if (edit==12) // Если программа была в режиме изменения 8 параметра, переведем ее в штатный режим и сохраним параметры в энергонезависимую память
{
edit = 0;
lcd.clear();
EEPROM.write(1, tempDay); // Запимываем параметр температуры в 1-ю ячейку памямти
EEPROM.write(3, humDay);
EEPROM.write(5, EC_MIN);
EEPROM.write(8, pH_MAX);
EEPROM.write(9, DaySt);
EEPROM.write(10, DayFin);
EEPROM.write(11, LightOn);
EEPROM.write(12, LightOff);


}
else {}; // Если программа не была в режиме редактирования, то можно выполнить тоже какое-то действие, для этого в фигурных скобках необходимо описать его функционал
}

if (currentButton2 == HIGH && edit != 0) // Если нажата Кнопка №2, при состоянии редактирования параметров то...
{
if (edit == 1) // ...если режим изменения температуры
{
lcd.clear();
lcd.setCursor(1, 1);
lcd.print("TempD:");
lcd.print(tempDay);
lcd.print("C +");
tempDay = (tempDay == 35) ? 10tempDay+1);
}
else if (edit == 3) // ...если режим изменения влажности
{
lcd.clear();
lcd.setCursor(1, 1);
lcd.print("Humid:");
lcd.print(humDay);
lcd.print("% +");
humDay = (humDay == 95) ? 20humDay+1);
}
else if (edit == 5) // ...если режим изменения EC
{
lcd.clear();
lcd.setCursor(1, 1);
lcd.print("ECmin:");
lcd.print(EC_MIN*100);
lcd.print(" + ");
EC_MIN = (EC_MIN == 20) ? 5EC_MIN+1);
}
else if (edit == 8) // ...если режим изменения pH
{
lcd.clear();
lcd.setCursor(1, 1);
lcd.print("pHmax:");
lcd.print(pH_MAX*0.1);
lcd.print(" + ");
pH_MAX = (pH_MAX == 90) ? 40pH_MAX+1);
}
else if (edit == 9) // ...если режим изменения DaySt
{
lcd.clear();
lcd.setCursor(1, 1);
lcd.print("DaySt:");
lcd.print(DaySt);
lcd.print(" + ");
DaySt = (DaySt == 23) ? 0DaySt+1);
}
else if (edit == 10) // ...если режим изменения DayFin
{
lcd.clear();
lcd.setCursor(1, 1);
lcd.print("DayFin:");
lcd.print(DayFin);
lcd.print(" + ");
DayFin = (DayFin == 23) ? 0DayFin+1);
}
else if (edit == 11) // ...если режим изменения LightOn
{
lcd.clear();
lcd.setCursor(1, 1);
lcd.print("LightOn:");
lcd.print(LightOn);
lcd.print(" + ");
LightOn = (LightOn == 23) ? 0LightOn+1);
}
else if (edit == 12) // ...если режим изменения LightOff
{
lcd.clear();
lcd.setCursor(1, 1);
lcd.print("LightOff:");
lcd.print(LightOff);
lcd.print(" + ");
LightOff = (LightOff == 23) ? 0LightOff+1);
}
}
else if (lastButton2 == LOW && currentButton2 == HIGH) // Если было короткое нажатие на Кнопку №2 не в режиме редактирования, то можно выполнить какое либо действие, если описать его в фигурных скобках ниже
{lcd.setCursor(0,3);
lcd.print("T1:");
printTemperature(insideThermometer);
delay (2000);}

if (currentButton3 == HIGH && edit != 0) // Если нажата Кнопка №3, при состоянии редактирования параметров то...
{
if (edit == 1) // ...если режим изменения температуры
{
tempDay = (tempDay == 10) ? 35tempDay-1);
lcd.clear();
lcd.setCursor(1, 1);
lcd.print("TempD: ");
lcd.print(tempDay);
lcd.print("C -");
}
else if (edit == 3) // ...если режим изменения влажности
{
humDay = (humDay == 20) ? 95humDay-1);
lcd.clear();
lcd.setCursor(1, 1);
lcd.print("Humid:");
lcd.print(humDay);
lcd.print("% -");
}
else if (edit == 5) // ...если режим изменения EC
{
EC_MIN = (EC_MIN == 5) ? 20EC_MIN-1);
lcd.clear();
lcd.setCursor(1, 1);
lcd.print("ECmin:");
lcd.print(EC_MIN*100);

lcd.print(" -");
}
else if (edit == 8) // ...если режим изменения pH
{
pH_MAX = (pH_MAX == 40) ? 90pH_MAX-1);
lcd.clear();
lcd.setCursor(1, 1);
lcd.print("pHmax:");
lcd.print(pH_MAX*0.1);
lcd.print(" -");
}
else if (edit == 9) // ...если режим изменения DaySt
{
lcd.clear();
lcd.setCursor(1, 1);
lcd.print("DaySt:");
lcd.print(DaySt);
lcd.print(" - ");
DaySt = (DaySt == 0) ? 23DaySt-1);
}
else if (edit == 10) // ...если режим изменения DayFin
{
lcd.clear();
lcd.setCursor(1, 1);
lcd.print("DayFin:");
lcd.print(DayFin);
lcd.print(" - ");
DayFin = (DayFin == 0) ? 23DayFin-1);
}
else if (edit == 11) // ...если режим изменения LightOn
{
lcd.clear();
lcd.setCursor(1, 1);
lcd.print("LightOn:");
lcd.print(LightOn);
lcd.print(" - ");
LightOn = (LightOn == 0) ? 23LightOn-1);
}
else if (edit == 12) // ...если режим изменения LightOff
{
lcd.clear();
lcd.setCursor(1, 1);
lcd.print("LightOff:");
lcd.print(LightOff);
lcd.print(" - ");
LightOff = (LightOff == 0) ? 23LightOff-1);
}
}
else if (lastButton3 == LOW && currentButton3 == HIGH) // Если было короткое нажатие на Кнопку №3 не в режиме редактирования, то можно выполнить какое либо действие, если описать его в фигурных скобках ниже
{}
lastButton1 = currentButton1; // Запоминаем предыдущее значение Кнопки №1
lastButton2 = currentButton2; // Запоминаем предыдущее значение Кнопки №2
lastButton3 = currentButton3; // Запоминаем предыдущее значение Кнопки №23
}
}


Извиняюсь перед CiberRus, что занял столько места, но не знаю как закатать данный код используя меньше места.
Подскажете, исправлю.

Изменено 16-12-2012 автор Alex1503

Изменено 16-12-2012 автор Alex1503
2012-12-16 добавлено 16/12/2012 06:12:48#390814

Новенький





22
Singapore Singapore
11 г. назад
Недостатком данного скетча является то, что для задания нужных параметров
кнопками используется вторая строка дисплея, а в штатном режиме она остается пустой.
Третья строка зарезервирована для вывода pH и EC.

Кроме того для экономии места в скетче отсутствует кусок, отвечающий за измерение и контроль pH и EC.

Pic 1
Pic 2

Вопрос о минутах я задал для общего развития, хорошо иметь в загашнике такую возможность.

Изменено 16-12-2012 автор Alex1503
2012-12-16 добавлено 16/12/2012 09:41:42#390819

Посетитель





65
Russian Federation Moscow
10 г. назад
Подскажите зачем ph в террариуме ?
2012-12-16 добавлено 16/12/2012 13:15:53#390834

Новенький





22
Singapore Singapore
11 г. назад
Это контролер для гидропоники или морского аквариума ( для последнего влажность не нужна ).
В случае террариума pH и EC не нужны.
2012-12-16 добавлено 16/12/2012 17:57:38#390870

Новенький





46
Russian Federation Perm
5 г. назад
Alex1503


А вы светодиодную ленту в морском аквариуме для досветки к основному свету хотите использовать?
Есть интересные темы по свету и не только, для моря:

http://www.aqualogo....

http://www.aqualogo....

http://www.aqualogo....

http://www.aqualogo....

Может Вы это уже видели,но если нет посмотрите.
Очень интересно.
2012-12-16 добавлено 16/12/2012 19:52:10#390895

Посетитель





65
10 г. назад
а как измеряете Ph и Ec ?
давно хотел сделать комп для аквариума но сначала решил поэкспериментировать на террариуме
а потом может и для аквариума буду делать
а за код большое спасибо

Изменено 17-12-2012 автор aleksjet
2012-12-17 добавлено 17/12/2012 08:44:56#390937

Посетитель





65
10 г. назад
сообщение Alex1503

Pic 1
Pic 2

если Вас не затруднит расскажите про устройство,
что за моторы у Вас установлены, блок управления нагрузкой, и еще две платы маленькие


Изменено 16-12-2012 автор Alex1503
2012-12-17 добавлено 17/12/2012 10:20:57#390948

Новенький





46
Russian Federation Kazan
5 г. назад
aleksjet


Для аквариума

http://www.aqualogo....

самое то, мне кажется.

Изменено 17-12-2012 автор Rust
2012-12-17 добавлено 17/12/2012 13:15:04#390967

Посетитель





65
10 г. назад
сообщение Rust
aleksjet


Для аквариума

http://www.aqualogo....

самое то, мне кажется.

Изменено 17-12-2012 автор Rust


этот контроллер дороговато выходит мне бы по проще
2012-12-17 добавлено 17/12/2012 13:18:59#390968

Новенький





46
Russian Federation Saint Petersburg
5 г. назад
aleksjet


Там, в теме, есть ссылки на более простые.

Вот, много тем по светильникам на лед для моря. С контроллерами и без.

http://www.aqualogo....

Вот еще простенькое,

http://www.reefledco...

но эта тема не полная, затем хозяин ушел на контроллер по первой ссылке.

P.S. Кстати о дороговизне. "Бутерброд" из Ардуино 2560,аквашилда, сделанного Oleg_il, и тач-панелью "3.2",
обходится в 100 долларов (товарищ брал) плюс 7долларов почта Израиля берет за пересылку.

Изменено 17-12-2012 автор Rust

Изменено 17-12-2012 автор Rust
2012-12-17 добавлено 17/12/2012 15:25:38#390979

Посетитель





78 2
Palestinian Territory Ramallah
5 г. назад
сообщение Alex1503
Никак не соображу как сделать чтобы на дисплее отображалась
в процентах текущая яркость светодиодной ленты.


Если вопрос в формуле, то она тривиальная. Яркость принимает значение от 0 до 255, Вам необходимо, пропорционально преобразовать данный параметр так, чтобы он уложился в интервал от 0 до 100:
1. Bright/255*100. Ну или проще говоря Bright/2.55
2. Есть универсальная функция в IDE, которая автоматом укладывает значения из одного интервала в другой map(Bright,0,255,0,100);


if (Hour==LightOn-1) analogWrite(sdPIN, map(Minute, 0, 59, 0, 255));
else if (Hour==LightOff) analogWrite(sdPIN, map(Minute, 0, 59, 255, 0));
else analogWrite(sdPIN, (Light) ? 255:0);


Так же есть небольшой недостаток этого тестового примера. Светодиодная лента достаточно ярко начинает светить уже на 3-й минуте, а так же за достаточно короткий срок ее яркость изменяется от достаточно яркой до 0. Зверек только начинает задумываться о том, что надо искать укрытие, а освещение уже погасло... Можно использовать иную функцию изменения яркости, чтобы растянуть этот промежуток (квадратичную или логарифмическую)

Вот улучшение алгоритма (функцию взял навскидку, можете поэкспериментировать с другими...):

int Bright = 0; // Где-нубудь вначале программы задаем переменную яркости
...
if (Hour==LightOn-1) Bright = 1 + sq(Minute)/15; // функция 1+x^2/15 позволяет растянуть промежуток тусклого свечения ленты
else if (Hour==LightOff) Bright = 1+sq(60-Minute)/15;
else Bright = (Light) ? 255:0;
analogWrite(sdPIN, Bright);
...
lcd.setCursor(<x>,<y>;lcd.print("Bright:");lcd.print(Bright/2.55, 1); lcd.print("%"); // Информация о яркости
2012-12-17 добавлено 17/12/2012 15:27:38#390980

Новенький





22
Singapore Singapore
11 г. назад
CiberRus как всегда огромное спасибо.
Обязательно воспользуюсь Вашей рекомендацией.

Что касается устройства:

Маленькие платы это схемы измерения pH и EC.
Взяты отсюда:
http://www.atlas-scientific.com/kits.html
Довольно дорогие, но точность высокая. Так как моя жена серьезно занимается
гидропоникой, то пришлось потратиться. Причем первый комплект спалил. Подозреваю, что
из за наличия в них EEPROM памяти их нельзя размещать близко к микромоторам. Вероятно
магнитное поле влияет на память и устройство начинает чудить.

Моторы являются частью перисталтических насосов.
Используются для дозирования химикатов для поддежания нужных pH и EC.
Взяты отсюда:
http://www.ebay.com.sg/itm/Aquarium-Peristaltic-Dosing-Pump-head-/281031431550?pt=LH_DefaultDomain_0&hash=item416ec7557e

Блок управления нагрузкой;
http://www.ebay.com.sg/itm/New-4-Route-MOSFET-Button-IRF540-V2-0-MOSFET-Switch-Module-Arduino-Compatible-/261125619383?pt=LH_DefaultDomain_0&hash=item3ccc4cbeb7

Кроме того поверх Arduino Mega стоит Ethernet Shield R3.
http://www.sgbotic.com/index.php?dispatch=products.view&product_id=1087
Мечтой идиота является возможность проверки параметров устройства по интернету.
Проблемой является то, что рядом нет человека, который мог бы научить.
Приходится до многих вещей доходить самому. Ей богу иногда голова буквально трещит.
Спасибо CiberRus, что возится с такими как я.
2012-12-18 добавлено 18/12/2012 03:20:16#391092

Посетитель





65
Russian Federation Moscow
10 г. назад
Спасибо за ссылки
Еще остался вопрос зачем кнопки возле насосов ? Или это принудительное включение ?
2012-12-18 добавлено 18/12/2012 06:32:21#391094

Посетитель





65
Russian Federation Moscow
10 г. назад
[q]сообщение Rust
[q]aleksjet[/

P.S. Кстати о дороговизне. "Бутерброд" из Ардуино 2560,аквашилда, сделанного Oleg_il, и тач-панелью "3.2",
обходится в 100 долларов (товарищ брал) плюс 7долларов почта Израиля берет за пересылку.

Изменено 17-12-2012 автор Rust

Изменено 17-12-2012 автор Rust [/q]

Из Израиля ? Расскажите по подробней ?
2012-12-18 добавлено 18/12/2012 06:35:06#391096

Новенький





46
Russian Federation Saint Petersburg
5 г. назад
aleksjet


Это все есть в ссылке

http://www.aqualogo....

я её уже давал.Там очень много чего есть и ссылок куча.

Конкретно по шилду:

- крепеж экрана на 4х винтах, а не на соплях как сейчас
- два варианта часов (или/или), дорогие сверхточные ds3231 или обычные ds3107
- вместо батарейки конденсатор (ионистор) на 350- 400 часов поддержки без питания
- место под дополнительную память
- 8 каналов 0-10в или ШИМ (в любых сочетаниях), с напряжениями от 5 и до 10в - по запайке. Т.е совместимо с абсолютно всеми известными на сегодня драйверами
- 6 транзисторных ключей средней мощности под вентиляторы или реле. Часть из них ШИМ (для вентиляторов), часть просто ключи (под реле, помпы и тд)
- собственный достаточно мощный источник питания (+5в и + 3.3в), т.о стабилизатор на меге перестает греться так сумашедше как сейчас при питании от 12в
- питание от 12в
- отдельный ШИМ "драйвер" луны - под индикаторные диоды
- разьем с питанием и связью под wireless (nordic cpu)
- разьемы под платки atlas (PH, ORP и тд http://atlas-scienti... )
- электрически нормальное согласование экрана и SD карты с мегой, а не то дерьмо что на шилде версии 1.2 и немного лучше чем на шилде версии 2
- выход на термодатчики (резистор внутри платы)
- пищалка аларма
- легкодоступная кнопка сброса платы меги, вместо внутренней

Эта инфа и фото в сообщении сообщение #1012
по ссылке
http://www.aqualogo....

Жаль,что это нам не подойдет (для аквариума,да),а нам придется делать самим.
В новогодние "каникулы" надо поробовать,что-то типа менюшки сделать. Надеюсь CiberRus поможет.
Спасибо,что он тему не бросает и помогает, если люди пытаются что-то сделать.
Может,что и получится,ну а нет,значит будем продолжать учиться дальше.
Может и добьем наконец.
2012-12-18 добавлено 18/12/2012 14:41:39#391134

Новенький





22
Singapore Singapore
11 г. назад
Добавил отображение яркости светодиодной ленты на дисплее.
Очень удобно.


Спасибо за ссылки Еще остался вопрос зачем кнопки возле насосов ? Или это принудительное включение ?


Да, три кнопки рядом с насосами это их принудительное включение.
Они есть в скетче.
2012-12-18 добавлено 18/12/2012 17:12:41#391156

Посетитель





65
Russian Federation Moscow
10 г. назад
сообщение Alex1503
Добавил отображение яркости светодиодной ленты на дисплее.
Очень удобно.


Спасибо за ссылки Еще остался вопрос зачем кнопки возле насосов ? Или это принудительное включение ?


Да, три кнопки рядом с насосами это их принудительное включение.
Они есть в скетче.

А по подробней можно код ?
2012-12-18 добавлено 18/12/2012 19:30:24#391173

Посетитель





65
Russian Federation Moscow
10 г. назад
Посидел вечерок и перебрал код для UNo но что то не получилось подскажите где ошибся и как правильно подключить кнопки ?

#include <DHT.h>
#include <DS1307.h> // Подключаем библиотеку управления модулем реального времени
#include <LiquidCrystalExt.h> // Подключаем библиотеку управления экраном
#include <LineDriver.h> // Далее вспомогательные библиотеки для реализации интерфейса SPI
#include <SPI.h>
#include <SPI_Bus.h>
#include <Wire.h>
#include <EEPROM.h> // Подключаем библиотеку для работы с энергонезависимой памятью

#define DHTPIN 9 // Считывающий пин с датчика
#define DHTTYPE DHT22 // Модель датчика
#define tPIN 7 // Пин управления температурой
#define hPIN 6 // Пин управления влажностью
#define lPIN 8 // Пин управления светом
#define sdPIN 5 // Пин управления светодиодной лентой
#define switchPIN_1 4 // Кнопка №1 "MODE"
#define switchPIN_2 3 // Кнопка №2 "+"
#define switchPIN_3 2 // Кнопка №2 "_"


DHT dht(DHTPIN, DHTTYPE); // Создаем объект dht

int tStatus = HIGH; // определяем переменную, отвечающую за состоянеие нагревателя HIGH=выкл, LOW=вкл
int tempDay; // Декларируем переменную, которая будет хранить желаемую температуру
int tempNight = tempDay-1; // Желаемая ночная температура в градусах Цельсия
int hStatus = HIGH; // определяем переменную, отвечающую за состоянеие увлажнителя HIGH=выкл, LOW=вкл
int humDay; // Декларируем переменную, которая будет хранить желаемую влажность
int humNight = humDay+1; // Желаемая ночная влажность
int DaySt; // Декларируем переменную, которая будет хранить желаемую времени начала дня
int DayFin; // Декларируем переменную, которая будет хранить желаемую времени конца дня
int LightOn; // Декларируем переменную, которая будет хранить желаемую времени начала полудня
int LightOff; // Декларируем переменную, которая будет хранить желаемую времени конца полудня
int edit = 0; // Переменную будем использовать для определения режима редактирования
long last_micros = 0; // Вспомогательная переменная, используется для определения сколько микросекунд прошло после предыдущей операции
int lastButton1 = LOW; // Предыдущее состояние кнопки №1
int currentButton1 = LOW; // Текущее состояние кнопки №1
int lastButton2 = LOW; // Предыдущее состояние кнопки №2
int currentButton2 = LOW; // Текущее состояние кнопки №2
int lastButton3 = LOW; // Предыдущее состояние кнопки №3
int currentButton3 = LOW; // Текущее состояние кнопки №3


SPI_Bus shreg(_8bit, 10); // Подключаем сдвиговый регистр
LiquidCrystal lcd(1, 2, 3, 4, 5, 6, &shreg, 7); // Инициализируем дисплей


void setup() // инициализация основных данных
{
Serial.begin(9600); // Инициализируем COM-порт
dht.begin(); // Инициализируем датчик


pinMode(tPIN, OUTPUT); // Определяем пин для управления температурой как Вывод
pinMode(hPIN, OUTPUT);
pinMode(lPIN, OUTPUT);
pinMode(sdPIN, OUTPUT);

tempDay = EEPROM.read(1); // Получаем параметр из первой ячейки
if (tempDay == 255) tempDay = 26; // Если ячейка пуста, т.е. ее значение = 255, то устанавливаем параметр температуры в значение по умолчанию, вданном случае 26С.

humDay = EEPROM.read(3); // Получаем параметр из 3 ячейки

DaySt = EEPROM.read(9); // Получаем параметр из 9 ячейки
if (DaySt == 255) DaySt = 8; // Если ячейка пуста, то установим параметр в 8

DayFin = EEPROM.read(10); // Получаем параметр из 10 ячейки
if (DayFin == 255) DayFin = 21; // Если ячейка пуста, то установим параметр в 21

LightOn = EEPROM.read(11); // Получаем параметр из 11 ячейки
if (LightOn == 255) LightOn = 11; // Если ячейка пуста, то установим параметр в 11

LightOff = EEPROM.read(12); // Получаем параметр из 12 ячейки
if (LightOff == 255) LightOff = 18; // Если ячейка пуста, то установим параметр в 18

pinMode(switchPIN_1, INPUT); // Устанавливаем тип контакта Кнопки №1 как Вход
pinMode(switchPIN_2, INPUT); // Устанавливаем тип контакта Кнопки №2 как Вход
pinMode(switchPIN_3, INPUT); // Устанавливаем тип контакта Кнопки №3 как Вход

lcd.begin(12,2); // устанавливаем размеры экрана
}

void loop() // зацикливание (код управляющей программы)

{

static unsigned long lastTime = 0; // Декларируем переменную и устанавливаем ее начальное значение в 0
if (millis() - lastTime > 3000) // Не используем в данном случае задержку Delay, т.к. это приведет к запаздыванию нажатий кнопок

{

lastTime = millis();

}

Switch();

if (Serial.available() > 0) SetTime(); // Если на COM-порт поступила информация, то изменим системное время
float h = dht.readHumidity(); // Считываем влажность
float t = dht.readTemperature(); // Считываем температуру
int Hour = RTC.get(DS1307_HR,true); // Получаем значение текущего часа
int Minute = RTC.get(DS1307_MIN,false);
int Second = RTC.get(DS1307_SEC,false);
int Date = RTC.get(DS1307_DATE,false);
int Mon = RTC.get(DS1307_MTH,false);
int Ye = RTC.get(DS1307_YR,false);
boolean Day = (Hour >= DaySt & Hour <DayFin); // Если текущий час находится в промежутке от DaySt до DayFin, то действуют дневные параметры
boolean Light = (Hour >= LightOn & Hour < LightOff); // Если текущий час находится в промежутке от LightOn до LightOff, то действуют полуденные параметры

tStatus = (t < ((Day) ? tempDay : tempNight)) ? LOW:HIGH; // Если температура меньше желаемой, то статус обогревателя=Вкл, в противном случае Выкл
digitalWrite(tPIN, tStatus);
if (h < ((Day) ? humDay : humNight)) hStatus = LOW; else hStatus = HIGH; // Если влажность меньше желаемой, то статус увлажнителя=Вкл, в противном случае Выкл
digitalWrite(hPIN, hStatus);

digitalWrite(lPIN, (Light) ? HIGH:LOW); // Если полуденное время, то включим подсветку
if (Hour==LightOn-1) analogWrite(sdPIN, map(Minute, 0, 59, 0, 255));
else if (Hour==LightOff) analogWrite(sdPIN, map(Minute, 0, 59, 255, 0));
else analogWrite(sdPIN, (Light) ? 255:0);

lcd.setCursor(0,0); // устанавливаем курсор для вывода времени
lcd.print(addZero(Hour));lcd.print(":");lcd.print(addZero(Minute));lcd.print(":");lcd.print(addZero(Second)); //Выводим время
lcd.setCursor(0,9);lcd.print((tStatus == LOW) ? "+":" "); // Выводим индикатор работы подогрева

lcd.setCursor(1,0); // устанавливаем позицию курсора на экране (на один символ правее левого нижнего угла)
lcd.print("T:");lcd.print(t, 1); lcd.print("C ");
lcd.setCursor(12,0);
lcd.print("H:");lcd.print(h, 1); lcd.print("%"); // Выводим информацию о климате

}



void SetTime() // установка времени из шаблона tчч:мм

{

if (Serial.read() == 't' // Если первый символ t, то установим указанное время

{

int h = (Serial.read() - '0' * 10 + (Serial.read() - '0';
Serial.read();
int m = (Serial.read() - '0' * 10 + (Serial.read() - '0';
Serial.read();
int D = (Serial.read() - '0' * 10 + (Serial.read() - '0';
Serial.read();
int M = (Serial.read() - '0' * 10 + (Serial.read() - '0';
Serial.read();
int Y = (Serial.read() - '0' * 10 + (Serial.read() - '0';

RTC.stop();
RTC.set(DS1307_SEC,0); //set the seconds
RTC.set(DS1307_MIN,m); //set the minutes
RTC.set(DS1307_HR,h); //set the hours
RTC.set(DS1307_DATE,D); //set the date
RTC.set(DS1307_MTH,M); //set the month
RTC.set(DS1307_YR,Y); //set the year
RTC.start();

}
Serial.flush();
}

String addZero(int val)
{
if (val<10) return "0" + String(val);else return String(val);
}

void Switch()

{

if (millis() - last_micros >= 300) // Производим опрос кнопок каждую треть секунды, это необходимо, чтобы избежать повторных выполнений кода в следствие дребезга контактов

{

last_micros = millis();

currentButton1 = digitalRead(switchPIN_1); // Считываем текущее состояние кнопки №1
currentButton2 = digitalRead(switchPIN_2); // Считываем текущее состояние кнопки №2
currentButton3 = digitalRead(switchPIN_3); // Считываем текущее состояние кнопки №3

if (lastButton1 == LOW && currentButton1 == HIGH) // Если Кнопка №1 изменила состояние на Нажатие

{

long t_millis = millis(); // Фиксируем начальное время нажатие кнопки, чтобы определить, не была ли она зажата

while (digitalRead(switchPIN_1) == HIGH && millis() - t_millis <= 2000 && edit==0) {} // Пока кнопка зажата не даем программе двигаться дальше

if (millis() - t_millis > 2000) // Если кнопка была нажата дольше 2-х секунд, то переведем состояние в режим программирования

{

edit = 1;

lcd.clear();lcd.setCursor(1, 1); lcd.print("TempD:"); lcd.print(tempDay); lcd.print("C");lcd.print(" edit");

}

// Иначе отрабатываем короткое нажатие при различных условиях

else if (edit==1) { edit = 3; lcd.clear();lcd.setCursor(1, 1); lcd.print("Humid:");lcd.print(humDay);
lcd.print("%");lcd.print(" edit");} // Если программа была в режиме изменения первого параметра, переведем ее на изменение 3 параметра

else if (edit==8) { edit = 9; lcd.clear();lcd.setCursor(1, 1); lcd.print("DaySt:");lcd.print(DaySt); lcd.print(" edit");}//Если программа была в режиме изменения 8 параметра, переведем ее на изменение 9 параметра

else if (edit==9) { edit = 10; lcd.clear();lcd.setCursor(1, 1); lcd.print("DayFin:");lcd.print(DayFin); lcd.print(" edit");}//Если программа была в режиме изменения 9 параметра, переведем ее на изменение 10 параметра

else if (edit==10) { edit = 11; lcd.clear();lcd.setCursor(1, 1); lcd.print("LightOn:");lcd.print(LightOn); lcd.print("edit");}// Если программа была в режиме изменения 10 параметра, переведем ее на изменение 11 параметра

else if (edit==11) { edit = 12; lcd.clear();lcd.setCursor(1, 1); lcd.print("LightOff:");lcd.print(LightOff); lcd.print("edit");}// Если программа была в режиме изменения 11 параметра, переведем ее на изменение 12 параметра

else if (edit==12) // Если программа была в режиме изменения 8 параметра, переведем ее в штатный режим и сохраним параметры в энергонезависимую память


{

edit = 0;

lcd.clear();

EEPROM.write(1, tempDay); // Запимываем параметр температуры в 1-ю ячейку памямти

EEPROM.write(3, humDay);

EEPROM.write(9, DaySt);

EEPROM.write(10, DayFin);

EEPROM.write(11, LightOn);

EEPROM.write(12, LightOff);


}

else {}; // Если программа не была в режиме редактирования, то можно выполнить тоже какое-то действие, для этого в фигурных скобках необходимо описать его функционал

}

if (currentButton2 == HIGH && edit != 0) // Если нажата Кнопка №2, при состоянии редактирования параметров то...

{

if (edit == 1) // ...если режим изменения температуры

{

lcd.clear();

lcd.setCursor(1, 1);

lcd.print("TempD:");

lcd.print(tempDay);

lcd.print("C +");

tempDay = (tempDay == 35) ? 10tempDay+1);

}

else if (edit == 3) // ...если режим изменения влажности

{

lcd.clear();

lcd.setCursor(1, 1);

lcd.print("Humid:");

lcd.print(humDay);

lcd.print("% +");

humDay = (humDay == 95) ? 20humDay+1);

}


else if (edit == 9) // ...если режим изменения DaySt

{

lcd.clear();

lcd.setCursor(1, 1);

lcd.print("DaySt:");

lcd.print(DaySt);

lcd.print(" + ");

DaySt = (DaySt == 23) ? 0DaySt+1);

}

else if (edit == 10) // ...если режим изменения DayFin

{

lcd.clear();

lcd.setCursor(1, 1);

lcd.print("DayFin:");

lcd.print(DayFin);

lcd.print(" + ");

DayFin = (DayFin == 23) ? 0DayFin+1);

}

else if (edit == 11) // ...если режим изменения LightOn

{

lcd.clear();

lcd.setCursor(1, 1);

lcd.print("LightOn:");

lcd.print(LightOn);

lcd.print(" + ");

LightOn = (LightOn == 23) ? 0LightOn+1);

}

else if (edit == 12) // ...если режим изменения LightOff

{

lcd.clear();

lcd.setCursor(1, 1);

lcd.print("LightOff:");

lcd.print(LightOff);

lcd.print(" + ");

LightOff = (LightOff == 23) ? 0LightOff+1);

}

}

else if (lastButton2 == LOW && currentButton2 == HIGH) // Если было короткое нажатие на Кнопку №2 не в режиме редактирования, то можно выполнить какое либо действие, если описать его в фигурных скобках ниже

{
}



if (currentButton3 == HIGH && edit != 0) // Если нажата Кнопка №3, при состоянии редактирования параметров то...

{

if (edit == 1) // ...если режим изменения температуры

{

tempDay = (tempDay == 10) ? 35tempDay-1);

lcd.clear();

lcd.setCursor(1, 1);

lcd.print("TempD: ");

lcd.print(tempDay);

lcd.print("C -");

}

else if (edit == 3) // ...если режим изменения влажности

{

humDay = (humDay == 20) ? 95humDay-1);

lcd.clear();

lcd.setCursor(1, 1);

lcd.print("Humid:");

lcd.print(humDay);

lcd.print("% -");

}


else if (edit == 9) // ...если режим изменения DaySt

{

lcd.clear();

lcd.setCursor(1, 1);

lcd.print("DaySt:");

lcd.print(DaySt);

lcd.print(" - ");

DaySt = (DaySt == 0) ? 23DaySt-1);

}

else if (edit == 10) // ...если режим изменения DayFin

{

lcd.clear();

lcd.setCursor(1, 1);

lcd.print("DayFin:");

lcd.print(DayFin);

lcd.print(" - ");

DayFin = (DayFin == 0) ? 23DayFin-1);

}

else if (edit == 11) // ...если режим изменения LightOn

{

lcd.clear();

lcd.setCursor(1, 1);

lcd.print("LightOn:");

lcd.print(LightOn);

lcd.print(" - ");

LightOn = (LightOn == 0) ? 23LightOn-1);

}

else if (edit == 12) // ...если режим изменения LightOff

{

lcd.clear();

lcd.setCursor(1, 1);

lcd.print("LightOff:");

lcd.print(LightOff);

lcd.print(" - ");

LightOff = (LightOff == 0) ? 23LightOff-1);

}

}

else if (lastButton3 == LOW && currentButton3 == HIGH) // Если было короткое нажатие на Кнопку №3 не в режиме редактирования, то можно выполнить какое либо действие, если описать его в фигурных скобках ниже

{}

lastButton1 = currentButton1; // Запоминаем предыдущее значение Кнопки №1

lastButton2 = currentButton2; // Запоминаем предыдущее значение Кнопки №2

lastButton3 = currentButton3; // Запоминаем предыдущее значение Кнопки №23

}

}
2012-12-18 добавлено 18/12/2012 23:44:05#391213

Посетитель





65
10 г. назад
одну ошибку нашел уже )
объявил экран 12Х2 а у меня 16х2 может из за этого глюки ))
но хочу узнать как правильно подключить кнопки ?

Изменено 19-12-2012 автор aleksjet
2012-12-19 добавлено 19/12/2012 09:00:45#391236

Новенький





22
Singapore Singapore
11 г. назад
Выявилась одна особенность моего скетча.
Из-за недостатка места на дисплее значение температуры от DS18B20
выводится при коротком нажатии на кнопку 2 (высвечивается в левом нижнем углу
вместо температуры от DHT22 ) и остается видимым в течении 2 секунд.
Затем опять высвечивается значение температуры от DHT22. Это обеспечивается
за счет использования Delay(2000).
Но теперь при нажатии кнопок принудительного включения насосов они начинают работать
только примерно через 2 секунды и остаются включенными около 2 секунд.
2012-12-19 добавлено 19/12/2012 15:27:48#391291

Посетитель





65
Russian Federation Moscow
10 г. назад
Alex1503

что то не выходмт у меня каменный цветок ((
на экране абракадабра
расскажите как подключали кнопки
2012-12-19 добавлено 19/12/2012 20:26:08#391329

Новенький





22
Singapore Singapore
11 г. назад
В принципе CyberRus довольно подробно описывал в начале ветки и схемы подключения кнопок и давал примеры
скетча организации меню с их использованием.
Причем для себя я отметил хорошую способность CyberRus грамотно и доступно объяснять ( в отличии от меня ).
Я сам полный чайник в программировании и именно эта ветка мне очень помогла.

Но в любом случае для изучения азов желательно почитать тьюториалы.
Самый лучший на мой взгляд:
http://www.ladyada.net/learn/arduino/

Кнопки в моей схеме притянуты к земле через 10 кОм.
http://arduino.ru/tutorials/button

Перешел на Mega из-за недостаточного количества пинов на UNO.

Честнот говоря чувствую себя не очень удобно перед CyberRus, что вперся в эту ветку со своим вариантом его скетча.
2012-12-20 добавлено 20/12/2012 06:30:18#391370

Посетитель





65
Russian Federation Moscow
10 г. назад
Я думаю что тут не кто обижаться не будет
Може общими усилиями сделаем хорошее устройство
А за ссылки спасибо
Правда и языком у меня не очень
А за вторую очень благодарен
2012-12-20 добавлено 20/12/2012 06:49:48#391375

<< 12345 78910 >> Создать новую темуБыстрый ответ