ARDUINO для автоматизации аквариума

<< 123 567891011 >>

Свой на Aqa.ru




693 77
Выкса
8 мес. назад
ARDUINO для автоматизации аквариума
Создал отдельную тему по вопросам использования простых и не дорогих плат ARDUINO для целей автоматизации аквариума.
Идея такая - довести это устройство до полнофункционального контроллера для аквариума, в итоге - с WEB сервером для управления по сети в т.ч. Интернет, и GSM модулем с отправкой SMS.
Начало обсуждения в теме про дозатор :
http://www.aqa.ru/fo...

Информация будет, в основном, в виде конкретных примеров.

Пример 1. Использоание плат Arduino UNO и Arduino NANO для управления по времени суток устройствами в 2-х каналах посредством релейного модуля.
Предполагается использование для создания 2-х канального дозатора, но и для включения света, например подойдет, и для многих других целей также.

Используется модуль часов реального времени, для точного планирования по времени суток, и релейный модуль. В данном примере используется 4-канальный, но 2 канала не используются...

Схема коммутации в случае использования платы UNO R3:


Схема коммутации в случае использования платы NANO:


Программа для среды программирования Arduino:
//***************************************************
// Скетч для управления релейным модулем, в котором *
// использовано два канала. Используется также RTC *
// Релейный модуль - с инверсной логикой на входе *
// Автор: ZORS *
// Версия 1. Дата 21.12.2013 02:40 *
//***************************************************
//----------ИМПОРТ БИБЛИОТЕК-------------------------
#include <Wire.h> //Подключаем библиотеку для использования I2C интерфейса с модулем RTC
#include <RTClib.h> //Подключаем библиотеку для использования модуля часов реального времени RTC

RTC_DS1307 RTC; //Создаем переменную класса - для использования RTC

//----------Объявляем разные переменные------------
const int RelayChn1 = 6; //Используем цифровой ПОРТ 6 для ПЕРВОГО канала релейного модуля
const int RelayChn2 = 7; //Используем цифровой ПОРТ 7 для ВТОРОГО канала релейного модуля
//----------Настройки времени и продолжительности включения реле

//----------ПЕРВЫЙ канал----------------------------
const long StartRelCn_1 = 25200; //Время срабатывания в ПЕРВОМ канале релейного модуля (в секундах от начала суток)
//в данном случае 25200 - это 7 часов 00 минут = ( 60секунд *60 минут *7 = 25200)
const long DurationCh_1 = 10; //ДЛИТЕЛЬНОСТЬ срабатывания реле в ПЕРВОМ канале (в секундах)

//----------ВТОРОЙ канал----------------------------
const long StartRelCn_2 = 37800; //Время срабатывания во ВТОРОМ канале релейного модуля (в секундах от начала суток)
//В данном случае 10 часов 30 минут = (60 секунд * 60 минут * 10 часов + 60сек*30мин = 37800)
const long DurationCh_2 = 15; //ДЛИТЕЛЬНОСТЬ срабатывания реле во ВТОРОМ канале (в секундах)

//----------Модуль инициализации setup() - выполняется один раз при инициализации платы при подаче напряжение (и аналогичных событиях)
void setup(){

pinMode(RelayChn1,OUTPUT); //Инициализируем порт для ПЕРВОГО канала как ВЫХОД
pinMode(RelayChn2,OUTPUT); //Инициализируем порт для ВТОРОГО канала как ВЫХОД

digitalWrite(RelayChn1,HIGH); //Устанавливаем на входах релейного модуля ВЫСОКИЙ уровень
digitalWrite(RelayChn2,HIGH); //Т.к. используемый релейный модуль с опторазвязкой - управляется инверсной логикой



Wire.begin(); //Инициируем I2C интерфейс
RTC.begin(); //Инициирум RTC модуль

// RTC.adjust(DateTime(__DATE__, __TIME__)); //С этой строки необходимо убрать комментарии один раз в начале,
//для того, чтобы загрузить в RTC дату и время на момент компиляции программы
//Иногда необходимо заливать СКЕТЧ на плату со снятым комментарием - для поправки
//времени в RTC, НО оставлять такой СКЕТЧ в работе НЕЛЬЗЯ !!!!!!!!!!!!!

} // КОНЕЦ ИНИЦИАЛИЗАЦИИ

//--------------------------------------------------
void loop() // ПРОГРАММЫй безусловный ЦИКЛ
{
DateTime myTime = RTC.now(); //Читаем данные времени из RTC при каждом выполнении цикла

//----------Раздел обработки реле по времени ----
long utime = myTime.unixtime(); //сохраняем в переменную - время в формате UNIX
utime %= 86400; //Сохраняем в этой же переменной остаток деления на кол-во секнд в сутках,
//Это дает количество секунд с начала текущих суток

//------------КАНАЛ 1------------------------------
if ((utime >= StartRelCn_1) &&
(utime < (StartRelCn_1+DurationCh_1)))
//Если секунд с начала суток больше, чем задано для включения
//Но, одновременно и меньше, чем задано для включения + длительность
{
digitalWrite(RelayChn1,LOW); //Устанавливаем на ПЕРВОМ входе релейного модуля НИЗКИЙ уровень - реле срабатывает
}
else //во всех остальных случаях
{
digitalWrite(RelayChn1,HIGH); //Устанавливаем на ПЕРВОМ входе релейного модуля ВЫСОКИЙ уровень - реле выключается
}

//------------КАНАЛ 2 - все аналогично -----------
if ((utime >= StartRelCn_2) &&
(utime < (StartRelCn_2+DurationCh_2)))
{
digitalWrite(RelayChn2,LOW); //Устанавливаем на ВТОРОМ входе релейного модуля НИЗКИЙ уровень - реле срабатывает
}
else
{
digitalWrite(RelayChn2,HIGH); //Устанавливаем на ВТОРОМ входе релейного модуля ВЫСОКИЙ уровень - реле выключается
}

}//------------Конец ЦИКЛА-----------------------------


(Редактор текста на данном сайте - к сожалению, "ломает" красивое форматирование.

PS: Выложил этот скетч на файлообменник :
http://my-files.ru/h...

В данной программе реализован, довольно-таки простой подход, а простота - основа надежности.

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

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

У комплектных минутных и секундных таймеров "с розеткой" - об этом можно только мечтать....не реализован такой функционал, и еще у них есть один минус. Реле в таких таймерах - не удерживаемое, а переключаемое, со всеми вытекающими последствиями....

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

Главное ограничение этого подхода - включение и выключение реле - должно произойти в одних сутках. Если необходимо чтобы, реле включилось в одних сутках, а выключилось в других - необходимо разбить это задание на 2 задания, или применить другой метод проверки условий наступления событий включения и выключения.

Весь этот пример тестировался на "живом" железе :

Для наглядности отладки был еще подключен LCD дисплей 16 сим в 2 строках.
Схема итоговая была такая:

Обратите внимание, что при использовании I2C последовательного интерфейса - соединения значительно упрощаются. И LCD дисплей подключен транзитом через модуль RTC (часов реального времени). Никаких паяных соединений нет вообще....все скоммутировано - проводами с разъемами.
Скетч - естественно, несколько другой использовался с добавлением строк инициализации и использования LCD 16x2.

Плата использовалась типа такой:
http://www.ebay.com/...
цена примерно 350 руб.

Релейный модуль
http://www.ebay.com/...
цена примерно 150 руб.

Модуль часов реального времени:
http://www.ebay.com/...
Цена примерно 55 руб.

Для сокращения бюджета можно использовать плату проще:
http://www.ebay.com/...
Цена примерно 200 руб.

Если есть потребность подключить ЖК дисплейчик, то лучше брать ЖК дисплей (LCD) c I2C интерфейсом - это сильно упрощает коммутацию, и сокращает количество использованных портов на микроконтроллере.
Например такой можно использовать :
http://www.ebay.com/...
цена около 180 руб.

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

Для использования I2C интерфейса - необходима библиотека Wire. Она есть в стандартном дистрибутиве среды программирования Arduino.
Для использования модуля RTC на микросхеме DS1307 нужна библиотека RTClib.
Если ее не будет в стандартном дистрибутиве, то ее можно взять в интернет. Например здесь :
http://arduino-info....

Необходимо, скачать, и разархивировать zip-файл в папку с понятным названием, например RTCLib. Затем эту папку поместить в папку, где среда Arduino хранит свои библиотеки. Если ставили среду программирования с настройками по умолчанию, то этой папкой будет :
C:\Program Files\Arduino\libraries
Сюда и помещайте папки с подключаемыми библиотеками. Если на этот момент, среда программирования была запущена - ее необходимо закрыть, и запустить заново. После этого библиотека будет доступна в меню Скетч/Импортировать библиотеку.

Микросхема RTC модуля DS1307, как правило использует адрес на шине I2C равный 0x68
поэтому, необходимо проверить в библиотечных файлах, библиотеки RTClib наличие строки типа этой:
#define DS1307_ADDRESS 0x68

Если будет использоваться LCD 16x2 с I2C интерфейсом, то - понадобиться библиотека LiquidCrystal_I2C. Можно скачать здесь :
http://dvrobot.ru/lc...
Как подключить к среде программирования Arduino - см. выше

ВАЖНО : при использовании I2C устройств - в скетче, библиотека Wire - должна быть объявлена первой, иначе - будут ошибки компиляции.

По этому примеру - все....

в следующем - присоединение термо-датчика DS18B20, и создание несложного терморегулятора.....


Изменено 24.12.13 автор Z0RS
2013-12-21 добавлено 21/12/2013 15:57:48#1907148

Новичок




46
Germany Seubersdorf
2 г. назад
Z0RS


Спасибо огромное.
Вроде всё понял, буду переделывать.
А что сделать чтобы обойтись без delay ?
2014-03-25 добавлено 25/03/2014 16:56:19#1954676

Свой на Aqa.ru




693 77
Выкса
8 мес. назад
kirex05
А что сделать чтобы обойтись без delay ?


В вашем случае она вообще ненужна...а вообще можно использовать функцию millis() запоминать значение в некоторой переменной и сравнивать в главном цикле. Такой подход обеспечить непрерывность и скорость выполнения главного цикла...но свои НО также имеются....
2014-03-25 добавлено 25/03/2014 17:07:52#1954684

Новичок




46
Germany Seubersdorf
2 г. назад
Z0RS


Понял, убрал.
2014-03-25 добавлено 25/03/2014 17:24:36#1954695

Новичок




46
Germany Seubersdorf
2 г. назад
Извините за наглость, но может поможете ещё с кнопками.
Нужна возможность включения и выключения света LW и LR кнопками (UP-Вкл., DOWN-Выкл.), независимо от времени. А также возможность включения и выключения нагревателя Н2 кнопками (LEFT-Вкл., RIGHT-Выкл.), независимо от температуры.

Вот кусок кода:

lcd_key = read_LCD_buttons();

switch (lcd_key)
{
case btnRIGHT:
{
digitalWrite(41, HIGH);
lcd.setCursor(7, 1);
lcd.print("H2-Off");
break;
}
case btnLEFT:
{
digitalWrite(41, LOW);
lcd.setCursor(7, 1);
lcd.print("H2-On ");
break;
}
case btnUP:
{
lcd.print("UP ");
break;
}
case btnDOWN:
{
lcd.print("DOWN ");
break;
}
}
}//------------Конец ЦИКЛА

Изменено 25.3.14 автор kirex05
2014-03-25 добавлено 25/03/2014 17:34:53#1954700

Новичок




46
Germany Seubersdorf
2 г. назад
Я пока кнопку держу H2 выключается, отпускаю кнопку он опять включается.
2014-03-25 добавлено 25/03/2014 17:37:45#1954701

Свой на Aqa.ru




693 77
Выкса
8 мес. назад
kirex05


Ну вообще управлять нагрузкой в стрктуре опроса кнопок - это моветон....
Лучше делать это через промежуточную переменную. Т.е вы изменяете переменную взависимости от нажатия кнопок, а потом в главном цикле на порту, который отвечает за нагрузку устанавливаете состояние в зависимости от промежуточной переменной....
То, что в каждом повторении главного цикла будет выполнятся функция digitalWrite(pin, вашаПеременная) - ничего страшного нет...
2014-03-25 добавлено 25/03/2014 18:20:14#1954724
Нравится Дэмиан

Новичок




46
Germany Seubersdorf
2 г. назад
Z0RS


Смысл понял, а вот как воплотить это для меня опять прблема.
2014-03-25 добавлено 25/03/2014 18:38:34#1954728

Свой на Aqa.ru




693 77
Выкса
8 мес. назад
kirex05
Смысл понял, а вот как воплотить это для меня опять прблема.


Всмысле "проблема" ? Яж все подробно написал. Я уж не буду кейсы по обработке клавиш описывать. А в главном цикле для каждого порта должна быть функция, указанная выше.
Но это в простейшем случае...если нагрузкой требуется и в ручную и автоматически управлять, то еще понадобится переменная-флаг для хранения режима управления нагрузкой.
А в главном цикле потребуется проверка этого флага и соответствующие действия.

И еще...у Вас в коде нет защиты от дребезга контактов....а кнопки его (дребезг имеется ввиду) имеют...посмотрите как это делается по поиску фразы "arduino debounce".
http://arduino.cc/en... вот здесь простейший пример по ликвидации дребезга.
2014-03-25 добавлено 25/03/2014 18:57:15#1954735

Новичок




46
Germany Seubersdorf
2 г. назад
Z0RS


Да не разберусь я нифига. И управление нужно и в ручную и в автомате.
С дребезгом всё понял.
Может я выложу свой код, а вы мне поможете с кропками?
2014-03-25 добавлено 25/03/2014 19:05:18#1954743

Посетитель




121 16
Russian Federation
1 дн. назад
Z0RS

Очень прошу также сопровождать хотя бы ориентировочной калькулляцией по стоимости комплектующих. Также предлагаю обсудмть, ведь немного среди аквариумистов программистов - электронщиков, сколько можно добавить человеку, взявшемуся комплектовать и прошивать готовые изделия (вопрос корпуса - отдельная песня!) и снабжать ими заинтересованных. Учтите, приобретение плат - довольно долгая песня, почта у нас неспешна.
2014-03-25 добавлено 25/03/2014 19:21:38#1954750

Свой на Aqa.ru




693 77
Выкса
8 мес. назад
kirex05
Может я выложу свой код, а вы мне поможете с кропками?


В тему - не надо...на файлообменник выкладываете..сюда например http://my-files.ru/
А в тему ссылку. Посмотрю на досуге...


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

А Вы тему с конца читаете? Вообще в первом сообщении темы - цены на некоторые комплектующие были указаны....и где их можно посмотреть вслучае чего...

сообщение FoxBat
Также предлагаю обсудмть ....

Вы не предлагайте, а начинайте обсуждать, я присоединюсь обязательно....

сообщение FoxBat
(вопрос корпуса - отдельная песня!)


Нет никакого вопроса с корпусом - есть множество вариантов...я иногда использую например пластиковые протяжные коробки по 90 рублей за шт. оргстекло и стойки латунные для монтажа плат. Вопросы с корпусом есть только у ленивых...

сообщение FoxBat
Учтите, приобретение плат - довольно долгая песня, почта у нас неспешна.


3-4 недели в среднем.....из Тайваня и Китая...по России до 2 недель доходило, а в основном дней 5-6...

Изменено 25.3.14 автор Z0RS
2014-03-25 добавлено 25/03/2014 20:05:45#1954776

Новичок




46
Germany Seubersdorf
2 г. назад
сообщение Z0RS
kirex05
Может я выложу свой код, а вы мне поможете с кропками?


В тему - не надо...на файлообменник выкладываете..сюда например http://my-files.ru/
А в тему ссылку. Посмотрю на досуге...


Код выложил, вот ссылка: http://dropmefiles.c...
2014-03-25 добавлено 25/03/2014 21:20:50#1954808

Новичок




46
Germany Mariaposching
2 г. назад
Вот так вот работает от одной кнопки

int flag=0;
int analog=0;

void setup()
{

pinMode(41, OUTPUT);
}

void loop()
{
analog=analogRead(0);

if(analog>0&&analog<100==HIGH&&flag==0) //если кнопка нажата
// и перемення flag равна 0 , то ...
{
digitalWrite(41,!digitalRead(41));
flag=1;
}
if(analog>0&&analog<100==LOW&&flag==1) //если кнопка НЕ нажата
//и переменная flag равна - 1 ,то ...
{
flag=0; //обнуляем переменную flag
}
}

Нужно както применить это в моём коде.

Изменено 26.3.14 автор kirex05
2014-03-26 добавлено 26/03/2014 16:16:33#1955108

Свой на Aqa.ru




1149 188
Ростов-на-Дону
3 дн. назад
Z0RS

Сижу и играюсь с вкл/выкл реле и димированием диодов и, честно говоря, надоело громоздкое написание времени событий либо в секундах unix или в виде типа "у*hr+х*mn". Подумал и попробовал задать значения времени через команду #define. К примеру, включение ламп (рассвет) в 8:00 зададим так

#define SunRise 8*hr (или 28800 в секундах unix).

Соответственно, в командах "if" или "else if" можно писать не время цифрами, а название события, т.е. SunRise.
Мне кажется, это удобнее, особенно если одно и то же временное значение повторяется в нескольких местах. Стоит однажды его задать в начале скетча - и все.
Проверил подобный скетч в программе - ошибок комп не нашел. На саму ардуину еще не компилировал, уже поздно, но на выходных попробую. Должно работать, вроде.
ЗЫ. И вопрос - а можно ли задавать повторяющееся событие раз в 4 недели (это для "лунной подсветки", имитация полнолуния так сказать)?

Изменено 26.3.14 автор Дядька-рыбомор

Изменено 26.3.14 автор Дядька-рыбомор
2014-03-26 добавлено 26/03/2014 22:22:43#1955330

Свой на Aqa.ru




693 77
Выкса
8 мес. назад
сообщение Дядька-рыбомор
Z0RS

Сижу и играюсь с вкл/выкл реле и димированием диодов и, честно говоря, надоело громоздкое написание времени событий либо в секундах unix или в виде типа "у*hr+х*mn". Подумал и попробовал задать значения времени через команду #define. К примеру, включение ламп (рассвет) в 8:00 зададим так

#define SunRise 8*hr (или 28800 в секундах unix).

Соответственно, в командах "if" или "else if" можно писать не время цифрами, а название события, т.е. SunRise.
Мне кажется, это удобнее, особенно если одно и то же временное значение повторяется в нескольких местах. Стоит однажды его задать в начале скетча - и все.


Вообще, директива препроцессора #define для этого и задумывалась. Это директива макроподстановки. Поэтому необходимо помнить, что насколько бы короткое имя вы не придумали (левая часть) для правой части этой директивы ( а в правой части могут быть не только цифры, но и куски кода) все эти подстановки в коде при компиляции будут заменены на то, что будет содержаться в правой части этой директивы, и соответственно общий размер кода будет увеличен.
В простейших случаях - да....удобство, но в более сложных случаях можно за удобство заплатить размером кода...а в случае AVR микроконтроллеров (и не только для тех, на основе которых построены платы ARDUINO) оптимизация размера кода - это актуально....

сообщение Дядька-рыбомор
ЗЫ. И вопрос - а можно ли задавать повторяющееся событие раз в 4 недели (это для "лунной подсветки", имитация полнолуния так сказать)?


Вы о каком куске кода сейчас спрашиваете. Если о многокомандном таймере - то может обрабатыватся любой период с дискретностью одна секунда.....от одной и более...
...раз в 4 недели это .... 4 недели х 7дней х 24часа х 60минут х 60секунд = 2419200 секунд....
Это значение вставьте во второй параметр задания, и задание будет выполнятся раз в 4 недели.
А если Вы так....теоретически спросили - то вообще нет проблем...запрограммировать можно все, что можно себе представить....
2014-03-27 добавлено 26/03/2014 23:48:39#1955373

Новичок




46
Germany Mariaposching
2 г. назад
Z0RS


Здравствуйте.
Вы не смотрели мой код?
А то я так и не добился результата.
2014-03-27 добавлено 27/03/2014 00:39:30#1955389

Свой на Aqa.ru




693 77
Выкса
8 мес. назад
сообщение kirex05
Z0RS


Здравствуйте.
Вы не смотрели мой код?
А то я так и не добился результата.


Я посмотрел бегло....что сказать..очень много ошибок, особенно в условных выражениях. Я если честно, не всегда понимаю, как их разберет компилятор.
Вы раньше на чем-то программировали? Это всего скорее не был язык Си или Си++.

Вы поработайте над кодом еще...ближе к выходным посмотрю по-подробнее....
2014-03-27 добавлено 27/03/2014 01:14:38#1955400

Новичок




46
Germany Mariaposching
2 г. назад
сообщение Z0RS
сообщение kirex05
Z0RS


Здравствуйте.
Вы не смотрели мой код?
А то я так и не добился результата.


Я посмотрел бегло....что сказать..очень много ошибок, особенно в условных выражениях. Я если честно, не всегда понимаю, как их разберет компилятор.
Вы раньше на чем-то программировали? Это всего скорее не был язык Си или Си++.

Вы поработайте над кодом еще...ближе к выходным посмотрю по-подробнее....


Да я же писал, что в программировании почти полный ноль.
Данный код был составлен из нескольких, найденых на просторах интернета.
Но он вроде работает, осталось только с кнопками разобраться. От этого весь процесс встал, рыбок просто жалко.
Два дня уже сижу мудрю с условиями, переменными, флагами, а толку ноль.
Спасибо, что не отказываете в помощи.
2014-03-27 добавлено 27/03/2014 01:31:10#1955402

Свой на Aqa.ru




1149 188
Ростов-на-Дону
3 дн. назад
сообщение Z0RS
Вообще, директива препроцессора #define для этого и задумывалась. Это директива макроподстановки.

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

Вы о каком куске кода сейчас спрашиваете. Если о многокомандном таймере - то может обрабатыватся любой период с дискретностью одна секунда.....от одной и более...
...раз в 4 недели это .... 4 недели х 7дней х 24часа х 60минут х 60секунд = 2419200 секунд....
Это значение вставьте во второй параметр задания, и задание будет выполнятся раз в 4 недели.

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

Изменено 27.3.14 автор Дядька-рыбомор
2014-03-27 добавлено 27/03/2014 21:00:52#1955771

Свой на Aqa.ru




693 77
Выкса
8 мес. назад
Дядька-рыбомор
Да, я именно о многокомандном таймере, вы правы. Т.е. меняем DAILY на необходимое временное значение, и задание будет выполняться с периодичностью хоть неделя, хоть год, я правильно понял?

Абсолютно верно...

Есть в этом методе и свои ограничения: "раз в месяц" - таким образом сделать не удастся - т.к. "месяц" понятие нечеткое - может 30 дней содержать, может 31, а может вообще 28.

Для того, чтобы запрограммировать какое-то действие, которое должно, например, выполнятся 2 числа каждого месяца - его придется программировать отдельно и чуть сложнее...
2014-03-28 добавлено 27/03/2014 23:07:32#1955838

Новичок




46
Germany
2 г. назад
Z0RS


Простите за мою наглость, но осмелюсь спросить по поводу моей просьбы.
2014-03-28 добавлено 27/03/2014 23:55:07#1955864

Свой на Aqa.ru




1149 188
Ростов-на-Дону
3 дн. назад
сообщение Z0RS
Есть в этом методе и свои ограничения: "раз в месяц" - таким образом сделать не удастся - т.к. "месяц" понятие нечеткое - может 30 дней содержать, может 31, а может вообще 28.

Это понятно. Но относительно луны все довольно просто: лунный цикл между двумя полнолуниями примерно 29,5 суток, поэтому лунные ночи можно довольно просто запрограммировать. Насколько это имеет практическое значение для аквриумных растений (скорее это важнее для рыб)я не знаю, но теоретически интересно.
2014-03-28 добавлено 28/03/2014 04:08:41#1955897

Свой на Aqa.ru




693 77
Выкса
8 мес. назад
kirex05
Простите за мою наглость, но осмелюсь спросить по поводу моей просьбы.


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

Потом....

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

Главная идея, которая должна быть реализована в программах на однопоточных микроконтроллерах - это "короткий" по времени исполнения главный цикл. Поэтому Обработку события нажатия на кнопку, и реакцию на нажатие нужно разделять....

В одном месте необходимо зафиксировать нажатие на кнопку изменением состояния переменной флага. Это сделать в структуре условного оператора if или в структуре множественного выбора case. И все..из структуры нужно выходить, а в главном цикле сделать простую строчку (или несколько) - изменение состояния порта в соответствие с установленным флагом, типа этого:
digitalWrite(pinOutPort_01, flagOutPort_01);
Эта строка должна быть в теле главного цикла в самой левой позиции, т.е. не должна входить ни в какие условные операторы. Не нужно боятся что, в каждом повторении главного цикла будет выполнятся запись в порт одного и того же значения. От этого состояние порта - не изменяется.

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

Потом, если порт управляется какой-то програмной частью, то необходимо ввести еще один флаг. Флаг режима работы - ручной/автоматический (0/1). И обходить часть кода, которая отвечает за выявление условий изменения состояния порта в автоматическом режиме, когда этот флаг установлен в 0.
Попробуйте это реализовать в тестовом примере.


Это основная концепция...Таким образом можно обрабатывать некоторое количество портов. Когда количество портов станет довольно большим, и в одном проходе по главному циклу их будет обрабатываться большое количество таким образом, что длительность главного цикла станет критичной - тогда порты будет необходимо обрабатывать по одному в каждом проходе, или по нескольку, выбирая обрабатываемый порт из массива, а указатель массива инкременировать "по кругу" - т.е. до максимума количества портов и затем сброс на первый элемент массива.

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

Потом ненужно использовать конструкции, уравнивающие булиновкие выражения типа A<=B==HIGH ....это масло-маслянное и компилятор, разбирая строку справа-налево может понять совсем по-другому, нежли Вы задумывали.
2014-03-28 добавлено 28/03/2014 10:42:43#1955985

Новичок




46
Germany
2 г. назад
Z0RS
Спросить можно....но я Вам и так уже не раз дал понять, что копаться в чужих кодах - особой заинтересованности нет у меня. Вообще, работа по оптимизации кода - одна из самых сложных работ...и у меня есть другие интересы, кроме как убивать свое свободное время на то, чтобы у кого-то хорошо получилось...Потом, обработка меню - это не самое любимое занятие...ну не хочется мне это делать...я и для себя этот момент всячески обхожу...Кнопок с опросом по аналоговому сигналу - у меня тоже нет, чтобы проверить некоторые моменты.
Я не знаю, есть ли дребезг значений у такого способа опроса кнопок.


Да я не прошу оптимизировать мой код, и меню мне тоже не надо. Мне нужна только возможность включения и выключения света LW и LR кнопками (UP-Вкл., DOWN-Выкл.), независимо от времени. А также возможность включения и выключения нагревателя Н2 кнопками (LEFT-Вкл., RIGHT-Выкл.), независимо от температуры. А с дребезгом я сам разберусь. Просто поймите меня, я в программировании не силён. Вот и прошу пмощи у добрых людей.

Изменено 28.3.14 автор kirex05
2014-03-28 добавлено 28/03/2014 11:08:14#1956000

Свой на Aqa.ru




693 77
Выкса
8 мес. назад
kirex05
Мне нужна только возможность включения и выключения света LW и LR кнопками (UP-Вкл., DOWN-Выкл.), независимо от времени


Понимаете, включая или выключая свет принудительно нажатием кнопки, вы должны потом как-то вернутся в автоматический режим, либо по нажатию кнопки либо по другому событию.
По какому событию вы хотите восстанавливать автоматический режим?
2014-03-28 добавлено 28/03/2014 15:23:06#1956101

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