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

<< 12 45678910 >>

Свой на 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

Постоянный посетитель




257 4
Новосибирск
6 мес. назад
попробовал на другом компьютере...
http://saveimg.ru/sh...
2014-03-13 добавлено 13/03/2014 13:38:29#1948833

Свой на Aqa.ru




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

А Вы какую конкретно модель платы подключаете?
На ней бутлоадер залит?
Вообще, если просто любой терминальной программой (например гипертерминалом) попытаться присоединиться - то соединение создается?

Можно так попробовать:
В гипертерминале создать новое соединение, на порту соответствующем виртуальному порту платы. При создании соединения использовать следущюии параметры:
Скорость 9600,
бит данных = 8,
четность = нет,
стоповые биты = 1,
управление потоком = аппаратное

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

Если все так, то значит проблеммы с бутлоадером, если не так, то проблемы с присоединением, с драйверами/настройкой виртуального компорта или настройками порта в программе.

Потом, еще проверьте какая скорость установлена на виртуальном ком-порту по умолчанию, иногда система выставляет 384000 или другие скорости отличные от 9600.
Необходимо выставить 9600 - это скорость по умолчанию....или если необходима другая скорость - это оговаривается в документации на плату....

Ошибки синхронизации очень часть возникают из за несоответствия скоростей портов на разных сторонах....поиграйтесь с этим параметром...
2014-03-13 добавлено 13/03/2014 13:54:55#1948839

Свой на Aqa.ru




693 77
Выкса
8 мес. назад
Настройки порта должны быть такими:


Кстати, на приведенной Вами картине - посмотрите на что ругается программа - у Вас скорость на порту выставлена 57600....

Изменено 13.3.14 автор Z0RS
2014-03-13 добавлено 13/03/2014 13:59:29#1948843

Новичок




2
Russian Federation
2 г. назад
Есть ли у кого опыт управления реле через приемник/передатчик на 433 Мгц? В частности интересует схема для приемной части (в эфире постоянный сигнал не есть гуд).
2014-03-17 добавлено 17/03/2014 09:17:51#1950840

Свой на Aqa.ru




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


Если Вы имеете ввиду девайс типа этого: http://www.ebay.com/... то это банальный удлинитель сигнала с TTL уровнем по радиоканалу 433 МГц, и высокий уровень на выходе будет означать наличие несущей в эфире.
Присоединение тоже не сложное как бы ...питание и один управляющий вход TTL на стороне передатчика, ну и TTL выход на стороне приемника, к которому можно напрямую присоединить вход релейного модуля, или другой потребитель TTL уровня.
Вот простейшая схема :
https://encrypted-tb...

Чтобы сделать использование этого модуля более "умным" и управляемым, на стороне приемника необходимо использовать более сложную логику, которая может быть реализована на каком-то микроконтроллере по-проще, например на серии ATMEL TINY. При использовании 2 микроконтрорллеров при обмене данными можно реализовать несложный протокол, результатом работы которого будет отсутствие постоянной несущей в эфире для обеспечения высокого выходного уровня, наличие защиты от чужого сигнала, и контроль передачи/приема.

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

И есть еще вариант, где все вышеперечисленное реализовано в "железе", причем удлиняется уже не один канал с TTL уровнями, а несколько, и все кодирования/декодирования реализованы в МК на платах:
http://www.ebay.com/...

Но цена, конечно уже другая...
2014-03-17 добавлено 17/03/2014 16:24:10#1951026

Новичок




2
Russian Federation
2 г. назад
Спасибо за ответ. Жаба душит использовать на стороне приема arduino, хотя есть библиотека VirtualWire (здесь описание ВОЗМОЖНО СПАМ. Если вы хотите открыть ссылку, скопируйте ее в адресную строку самостоятельно
). Думаю на простой логике что-то придумать, чтобы не писать лишний код для взаимосвязи двух микрух.
2014-03-17 добавлено 17/03/2014 16:44:47#1951038

Свой на Aqa.ru




693 77
Выкса
8 мес. назад
plus
Жаба душит использовать на стороне приема arduino


Да не обязательно ардуино использовать....Хотя какую нибудь NANO или MICRO рублей за 100 - было бы весьма логично, легко программируемо и бюджетно.
Можно и просто собрать несложную схемку на кусочке монтажки, на которую поставить
проц типа http://www.ebay.com/...
Пару конденсаторв, резисторов и кварц....но по цене будет так же, как NANO без USB. Не будет смысла заморачиваться....
Вообще весьма бюджетных вариантов много....
2014-03-17 добавлено 17/03/2014 17:21:52#1951052

Новичок




30
Тихорецк
1 мес. назад
Добрый день!!
Нужна консультация (заранее очень благодарен!!!)
Что хочеться:
управление светом, температурой, удо, фильтром включение выключение, оповещение звуковое: утечкой воды, утечка СО2, PH замеры, управление CO2, + управление через WEB интерфейс iphone,
что для ЭТО НУЖНО!???
что есть у меня на данный момент :
SainSmart Mega2560 R3 + 3.2" TFT Touch LCD SD Card + TFT Shield Kit For Arduino 1 штука
5V 4 Channel Electronic Relay Module Shield for Arduino ARM PIC AVR DSP 10A 2 штуки
RTC I2C DS1307 AT24C32 Real Time Clock Module For Arduino AVR PIC 51 ARM 1 штука

посоветуйте подскажите ПО будет переделанно из
картинка
2014-03-21 добавлено 21/03/2014 13:39:09#1952973

Свой на Aqa.ru




693 77
Выкса
8 мес. назад
Для того, чтобы организовать
Миххаил
управление через WEB интерфейс iphone


- по крайней мере, необходимо иметь либо сетевую плату (EtherNet), либо аналогичный шилд.
Эти устройства, как правило, подключаются посредством I2C интерфейса, и имеют соответствуюие библиотеки....одну из плат я уже описывал в этой теме. Но с использованием сетевых плат - есть одна проблема, а именно : функция передачи сформированного в буффере сообщения - имеет недетерминированную длительность....т.е. может выполняться довольно длительное время...т.к. процессор на плате один, и он не многозадачный, то можно потерять по времени некоторые другие события, например отключения или включения чего либо....Естественно это справедливо при использовании стандартных библиотек. Отказавшись от стандартных библиотечных функций - это можно разрешить, но программирование становиться очень сложным, и новичку это будет сделать очень сложно, практически невозможно.
Платы EtherNet существуют 2х основных типов :

на чипе ENC28J60. Например http://www.ebay.com/...

и на чипе W5100. На основе этого чипа - есть и шилды и отдельные платы. Пример шилда http://www.ebay.com/...

Использование W5100 - является более предпочтительным, когда требуется снижать нагрузку на микропроцессор основной платы Arduino, т.к. сетевые устройства на основе W5100 многие операции выполняют на микросхеме W5100, а в случае ENC28J60 - нагрузка на основной процессор платы - больше.

Кроме сетевой платы, необходимо написать код самого WEB сервера...

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

Ну и так...далее...
А вообще, Вы начинаете с очень непростой задачи....
2014-03-21 добавлено 21/03/2014 15:35:04#1953021

Свой на Aqa.ru




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

Добрый день. На вашей блок-схеме с диммированием светодиодов Arduino получает питание от блока питания через преобразователь напряжения, правильно? Получатся, блок питания постоянно включен в сеть. В связи с этим вопрос: блок питания потребляет все время постоянную мощность в не зависимости от подключенной к нему нагрузки? Т.е. если светодиоды выключены, блок потребляет ту же мощность, что и при включенных? Это уже вопрос экономии денег за свет. Если это так, то может запитать aruino через что-то маломощное, а уже основной блок питания (и всю цепочку диодов) подключать к 220В через релейное соединение? Или я ошибаюсь?
ЗЫ.Спасибо за тему, по информативности она может поспорить со специализированными форумами "ардуинистов" .
2014-03-22 добавлено 22/03/2014 05:03:11#1953335

Новичок




30
Тихорецк
1 мес. назад
ZORS
Огромное спасибо что откликнулись так быстро!!
Не могли бы вы помочь с выбором остальных комплектующих (по образованию программист думаю напишу что нужно)))
в планах передача данных по Wi-Fi не по лану!!! или же проще и лучше по GSM ??
не могли бы вы с сылками дать что мнее еще нужно??
имеюю в виду: сенсоры, реле для компресоров, помп и так далее!!
тели я выбрал драйвера!!!
и можно ваш скайп??
2014-03-22 добавлено 22/03/2014 08:55:13#1953354

Свой на Aqa.ru




693 77
Выкса
8 мес. назад
Дядька-рыбомор
Добрый день. На вашей блок-схеме с диммированием светодиодов Arduino получает питание от блока питания через преобразователь напряжения, правильно? Получатся, блок питания постоянно включен в сеть. В связи с этим вопрос: блок питания потребляет все время постоянную мощность в не зависимости от подключенной к нему нагрузки? Т.е. если светодиоды выключены, блок потребляет ту же мощность, что и при включенных?

Нет, конечно....блок питания без нагрузки потребляет ток холостого хода, и мощность соответственно. Как правило это несколько процентов от номинальной мощности.
Ардуино запитано от одного Б\П для экономии. Для увеличения надежности схемы, можно запитать от отдельного б\п и сделать схему использования резервного источника, аккумулятора, например.

Дядька-рыбомор
ЗЫ.Спасибо за тему, по информативности она может поспорить со специализированными форумами "ардуинистов" .


Пожалуйста!

Миххаил
Не могли бы вы помочь с выбором остальных комплектующих (по образованию программист думаю напишу что нужно)))
в планах передача данных по Wi-Fi не по лану!!! или же проще и лучше по GSM ??

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

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

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

Вообще если позволяют средства - лучше брать уже "раскрученные" шилды, т.к. для них все есть, и библиотеки, и примеры.
Вот пример шилда с GSM : http://www.ebay.com/...


Миххаил
не могли бы вы с сылками дать что мне еще нужно??

Как я могу знать что ВАМ нужно?
Некоторые примеры периферии, такие как релейный модуль, датчик температуры - я уже приводил в этой теме....остальное аналогичное оборудование можете подобрать сами...


Миххаил
и можно ваш скайп??


Не пользуюсь скайпом....впрочем как и аськой - практически не пользуюсь.
2014-03-22 добавлено 22/03/2014 17:52:49#1953555

Завсегдатай




460 39
Москва
3 мес. назад
Z0RS

Пришли тут мне арудино, но вот незадача - вместо i2c дисплея - обычный. Пока играюсь второй день, даже что-то получается. Но копаясь в инете наткнулся на такую штучку:

http://www.aliexpres...

Это очень плохо или терпимо - просто цена вроде более-менее. Цель - контроль Ph при подаче co2.
2014-03-22 добавлено 22/03/2014 17:58:45#1953558

Свой на Aqa.ru




693 77
Выкса
8 мес. назад
arch07
Пришли тут мне арудино, но вот незадача - вместо i2c дисплея - обычный.

Ну не страшно....впринципе, продаются отдельные модули I2C интерфейса. Например для дисплея размерностью 16Х2 подойдет такой : http://www.ebay.com/...

А при наличии достаточного количества цифровых портов OUTPUT - можно и без I2С использовать модуль дисплея. I2С - используется "не от хорошей жизни" - для экономии портов.

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


arch07
...копаясь в инете наткнулся на такую штучку:
http://www.aliexpres...
Это очень плохо или терпимо - просто цена вроде более-менее. Цель - контроль Ph при подаче co2.


По цене - нормально. Считайте, 2 операц.усилителя (ОУ)это 100-150 рублей, платка, разъемы делали еще рублей 150, электрод дешевый - 600-700 рублей.....вообщем если сами бы собрали - получилось либо так же, либо дороже...Производители таких наборов выигрывают на эффекте масштаба производства.

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

Вообще, попадались и другие аналогичные наборы - может еще имеет смысл по-выбирать, по искать ? Для того чтобы сравнивать, и выбрать лучшее.
2014-03-22 добавлено 22/03/2014 18:43:14#1953575

Завсегдатай




460 39
Москва
3 мес. назад
Z0RS

насчет дисплея - китайцы мне все равно либо пришлют i2c модуль, либо вернут бабки - я пока 5 баксов запросил за 3 бакса я уже нашел подобный модуль на мой 2004 (четырехстрочный) дисплей. Вот тока ждать его еще 2-3 недели. потому и обидно.
По поводу подключения без i2c - я в курсе, но по шине - решение изящней: лишние порты и проводов меньше. Думаю нагрузка на проц не сильно выше.

Сильно поразила разница в размерах платы мега и нано. Я нано досель не видел. Така махонька, а скока могет.

ПО Ph - мой химический тест от SERA имеет диапазон 4,5 - 9,0, шаг цветовой шкалы 0,5. Т.е. точность 0,25. Для пресняка вроде хватает. с учетом погрешностей 0,1 единицы набора вроде неплохо.
А что дает термокомпенсация? Насколько она актуальна в полосе температур аквариума? сколько может наврать электрод при разнице температур градусов 5? И как калибровать все это? на плате только один потенциометр. Как я понимаю калибровать стоит по 3 точкам - желательно внизу, в середине и в конце диапазона. В наборе вообще тока одна бутылочка.
А если еще температуру учитывать - тут вообще 9 точек калибровки минимум надо вводить.
Программно я понимаю - имеем напряжение, по точкам калибровки привязываем их к значениям pH. промежуточные значения вычисляем линейной интерполяцией.
Ну еще вводим поправку на температуру (благо датчиков температуры герметичных я набрал). С этим pH вообще вопросов полно - но запускать co2 без контроля стремно. Понятно, потом он нафик не нужен будет - процедура отладится и все заработает на "автомате", но пока заработает - можно и животину заморить.

P.S. Еще глупый вопросик - как правильно подключить кнопку? Что-бы избежать дребезга? Задача запустить выполнение скрипта, который выполняется по времени по нажатию кнопки. Понятно, что на кнопку назначаем аппаратное прерывание и она запускает скрипт независимо от того наступило расчетное время или нет.
пример: имеем NANO, кнопку. подключаем кнопку между D2 и +5V - нужен еще резистор 10 кОм от D2 на землю?

Изменено 22.3.14 автор arch07
2014-03-22 добавлено 22/03/2014 21:05:25#1953634

Свой на Aqa.ru




693 77
Выкса
8 мес. назад
arch07
По поводу подключения без i2c - я в курсе, но по шине - решение изящней: лишние порты и проводов меньше. Думаю нагрузка на проц не сильно выше.

Да. Для процессора разница в нагрузках, конечно, незначительна.

Кстати, такие модули, которые используются с дисплеями, можно использовать для расширения количества портов ВВОДА/ВЫВОДА, без каких либо ограничений, и сложностей. Собственно, основой таких модулей и является микросхема - расширитель портов (I\O ports expander).

На микросхему PCF8574, на основе которой сделан I2C модуль для дисплея размерностью 16Х2, кстати есть готовая библиотека : https://github.com/s...
Я обязательно, ее попробую, когда придут модули. Сделаю обзор, т.к. иногда требуется увеличить количество портов, из-за того, что некоторые вопросы и задачи не были учтены при покупке базовой модели платы ARDUINO.

arch07
Сильно поразила разница в размерах платы мега и нано. Я нано досель не видел. Така махонька, а скока могет.

Ну "могет" то по большому счету - не плата, а микроконтроллер, на ней установленный. А размеры... да ...маленькие.


arch07
А что дает термокомпенсация? Насколько она актуальна в полосе температур аквариума? сколько может наврать электрод при разнице температур градусов 5?

Для Ваших требований к точности измерения pH - термокомпенсация даст не много.

arch07
И как калибровать все это? на плате только один потенциометр.

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

Т.к. бывают электроды с сопротивлением в десятки мегоом (так называемые низкоомные) и в сотни и тысячи мегаом, для каждого из них, по идее необходимо менять входную часть, согласующую выходное сопротивление электрода и входное сопротивление предусилителя. Но иногда, в простейших случаях, пытаются это изменением коэффициента усиления (GAIN) сделать, для этого и потенциометр. Потом, может быть небольшой проблемой, отсутствие регулировки смещения напряжение на электроде.
Плата выдаст смещенный (вот только не знаю на сколько, по идее нужно не менее 500 mV) и усиленный потенциал электрода. Назовем это "исправленным" потенциалом электрода.

В Вашем случае калибровка будет выглядеть, как запоминание значения исправленного потенциала электрода в двух точках ( как правило с pH=7.0 pH=4.01). Наборы для приготовления буферных растворов с указанными pH - есть в продаже на ebay http://www.ebay.com/...
Однако...они подорожали....я брал десяток по цене около 40 руб.

Из этого набора нужны только 2 - с с pH=7.00 pH=4.01. Кстати о термокомпенсации - обратите внимание при какой температуре указнанные на упаковке значения pH соответствуют действительности.

Калиброваться лучше по указанным pH, т.к. например буффер с pH=6.86 обладает меньшей точность, из за особенностей химических соединений входящих в состав. Если измеритель использовался бы в морском аквариуме то лучше калиброваться по точкам с pH=7.00 pH=10.01

Далее, при калибровке программа запомнит два значения и все остальные значения между ними или за ними, будут вычисляться как линейная интерполяция, с использованием простейшей функции вида f(x)= ax + b. Ну это в самом простейшем случае, и без термокомпенсации.

Вообщем, Вы практически все правильно понимаете.....осталось дело за малым - реализовать...
2014-03-22 добавлено 22/03/2014 22:47:15#1953684

Новичок




46
Germany
2 г. назад
Вот для этого кода нужно плавное включение света в заданное время и плавное выключение в другое заданное время. Помогите разобраться.

// Библиотеки необходимые для работы модуля часов
#include "Wire.h"
#include "DS1307new.h"

// библиотека экрана
#include "LiquidCrystal.h"
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

int hours;
int minutes;
int LW = 3;
int LR = 11;
int LB = 12;
int On_Time =0;
int Off_Time =0;
int Curent_Time =0;

void setup(){
Serial.begin(9600);
lcd.begin(16, 2); // запускаем библиотеку экрана
pinMode(LW, OUTPUT);
pinMode(LR, OUTPUT);
pinMode(LB, OUTPUT);
}

void loop(){
analogWrite(10, 100);
RTC.getTime();// получить время от модуля
RTC.hour;
RTC.minute;
printTimeToSerial(); // выводим полученное время в лог
printTimeToLCD();; // выводи время на экран
lcd.setCursor(0, 1); // Set the cursor to column 0, line 1
doSerialCommands(); // слушаем и выполняем команды из Serial
On_Time=(20*60+27);
Off_Time=(20*60+29);
Curent_Time=RTC.hour*60+RTC.minute;//текущее время
if(On_Time < Off_Time) //Проверка, таймер в течении одних суток?
{
if (Curent_Time >= On_Time && Curent_Time <= Off_Time)
for(int fadeValue = 0; fadeValue <= 255; fadeValue +=3)
{
analogWrite(LR, fadeValue);
}
else
for(int fadeValue = 255; fadeValue >= 0; fadeValue -=3)
{
analogWrite(LR, fadeValue);
}
}
else // если сутки сменились
{
if ((Curent_Time >= On_Time && Curent_Time <= 2820)||(Curent_Time >= 0 && Curent_Time <= Off_Time))//2820=24часа*60
for(int fadeValue = 0; fadeValue <= 255; fadeValue +=3)
{
analogWrite(LR, fadeValue);
}
else
for(int fadeValue = 255; fadeValue >= 0; fadeValue -=3)
{
analogWrite(LR, fadeValue);
}
}
}

// Выводит текущие время в Serial
void printTimeToSerial(){

byte static prevSecond=0; // тут будем хранить, сколько секунд было при прошлом отчете

if(RTC.second!=prevSecond){ // что-то делаем только если секунды поменялись
Serial.print(RTC.hour); // часы

Serial.print(":"); // разделитель
Serial.print(RTC.minute);

Serial.print(":");
Serial.println(RTC.second);

prevSecond=RTC.second; // запомнили когда мы "отчитались"
}
}

// Выводит текущие время на LCD

void printTimeToLCD(){
byte static prevSecond=0; // тут будем хранить, сколько секунд было при выводе

if(RTC.second!=prevSecond){ // что-то делаем только если секунды поменялись
lcd.setCursor(11,0); // устанавливаем позицию курсора

if(RTC.hour<10)lcd.print(" ");
lcd.print(RTC.hour); // часы

lcd.print( (RTC.second % 2)?" ":":"); // разделитель моргает

if(RTC.minute<10)lcd.print(0); // лидирующий ноль, если нужен
lcd.print(RTC.minute);

prevSecond=RTC.second; // запомнили когда мы "отчитались"
}
}

// устанавливает часы модуля на какое-то заранее определенное время
void setSomeTime(){
RTC.stopClock();// останавливаем часы
RTC.fillByHMS(20,24,0); // "подкручиваем стрелки на 2000
RTC.setTime();// отправляем "подкрученное время" самому модулю
RTC.startClock(); // и опять запускаем часы
}

// слушает из Serial команды и выполняет их. Каждая команда - один символ.
// доступны команды:
// s - установить время указанное в функции setSomeTime()
void doSerialCommands(){
if(Serial.available()){ // что-нибудь пришло?
char ch=Serial.read(); // читаем что пришло

switch(ch){
case 's': // команда установки времени
setSomeTime(); // устанавливаем
break;

// тут, в будущем, мы можем добавлять дополнительные команды
default:;
// на неизвестную команду - ничего не делаем
};
}
}
2014-03-24 добавлено 24/03/2014 02:19:52#1954163

Свой на Aqa.ru




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


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

if(On_Time < Off_Time) //Проверка, таймер в течении одних суток?
{
if (Curent_Time >= On_Time && Curent_Time <= Off_Time)
for(int fadeValue = 0; fadeValue <= 255; fadeValue +=3)
{
analogWrite(LR, fadeValue);
}
else
for(int fadeValue = 255; fadeValue >= 0; fadeValue -=3)
{
analogWrite(LR, fadeValue);
}
}

Эта конструкция буде много раз повторена в цикле и каждый раз при совпадении условий if (Curent_Time >= On_Time && Curent_Time <= Off_Time)
будет выполнен ваш цикл изменения яркости

for(int fadeValue = 0; fadeValue <= 255; fadeValue +=3)
{
analogWrite(LR, fadeValue);
}

Причем это будет выполнено с частотой процессора, т.е. яркость от 0 до 100 процентов будет увеличена за несколько микросекунд, что будет незаметно человеческому глазу....тем более у Вас шаг инкремента = 3. Т.е. пока условия выполняются светодиод будет вспыхивать с частотой главного цикла. Нарастание яркости будет очень кратковременным, а остальное время светодиод находится в состоянии максимальной яркости. В итоге, при этих условиях, светодиод будет гореть с яркостью чуть меньше максимальной....

Выход в том, чтобы делать приращения значения, которое пишется в аналоговый порт (ШИМ) не в каждом повторении главного цикла, а тогда когда это нужно, исходя из длительность периода увеличения яркости.

Или можно, после функции analogWrite(LR, fadeValue); добавить задержку в цикл изменения яркости, например функцией delay(), подобрав в качестве аргумента значение, которое будет равно длительности периода увеличения яркости светодиода, выраженное в миллисекундах, деленное на 255.

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

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

Изменено 24.3.14 автор Z0RS
2014-03-25 добавлено 25/03/2014 00:27:36#1954463

Новичок




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


Да поймите просто, что я в программировании почти полный ноль. Поэтому и прошу помощи у знающих людей.
Я понял смысл того, что вы написали, но как воплотить всё это в реальность для меня проблема.
2014-03-25 добавлено 25/03/2014 02:17:35#1954477

Свой на Aqa.ru




693 77
Выкса
8 мес. назад
kirex05
Да поймите просто, что я в программировании почти полный ноль. Поэтому и прошу помощи у знающих людей.
Я понял смысл того, что вы написали, но как воплотить всё это в реальность для меня проблема.


Да все понятно.....просто пути стать более удаленным от нуля я Вам указал.

Один из этих путей - это изучение и использование чужого опыта. Я еще раз предлагаю по-изучайте пример с рассветом и закатом. Это пример рабочий....он корректно отрабатывает в диапазоне одних суток, но можно изменив константу количества секунд в сутках заставить этот код отрабатывать и в других интервалах.

Специально для вас привожу ссылку на обновленный код с расширенными комментариями:

http://my-files.ru/4...

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

В другом случае, если у Вас существует желание, ничего не изучать, и чтобы кто-то просто написал Вам полностью комплектное ПО для контроллера - то лучше обращаться к программистам фрилансерам на соответстующих сайтах...там бывает толковый народ со скромными запросами по оплате....
2014-03-25 добавлено 25/03/2014 11:12:45#1954558

Новичок




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


Спасибо за пример.
Подскажите где я допустил ошибку. Не меняется максимальная яркость по каналам, всегда на максимум.

#include <Wire.h> //Подключаем библиотеку для использования I2C интерфейса с модулем RTC
#include <RTClib.h> //Подключаем библиотеку для использования модуля часов реального времени RTC


#define PWM_LW_MIN 0 //Если необходим ток покоя на LED - изменить эту константу
#define PWM_LW_MAX 128 //Если необходимо ограничить максимальную яркость - уменьшить значение
#define PWM_LW_PIN 11 //Пин порта, где будет ШИМ LW

#define PWM_LR_MIN 0 //Если необходим ток покоя на LED - изменить эту константу
#define PWM_LR_MAX 200 //Если необходимо ограничить максимальную яркость - уменьшить значение
#define PWM_LR_PIN 3 //Пин порта, где будет ШИМ LR

#define PWM_LB_MIN 0 //Если необходим ток покоя на LED - изменить эту константу
#define PWM_LB_MAX 255 //Если необходимо ограничить максимальную яркость - уменьшить значение
#define PWM_LB_PIN 12 //Пин порта, где будет ШИМ LB

#define mn 60UL //Дополнительные константы для удобства
#define hr 3600UL //Отражают соответствующие количества секунд
#define d 86400UL

RTC_DS1307 RTC;

long sunrise_start = 11*hr+28*mn; //Начало восхода в 9 - 45
long sunrise_duration = 1*mn; //Длительность восхода 30 минут
long sunset_start = 11*hr+30*mn; //начало заката в 21-15
long sunset_duration = 1*mn; //Длительность заката 30 минут
long moonrise_start = 11*hr+30*mn ; //Начало луны в 9 - 45
long moonrise_duration = 1*mn; //Длительность восхода
long moonset_start = 11*hr+32*mn; //Конец луны в 11
long moonset_duration = 1*mn; //Длительность заката луны
//********************************************************************************************
void setup(){


Wire.begin(); //Инициируем I2C интерфейс
RTC.begin(); //Инициирум RTC модуль
analogWrite(PWM_LW_PIN, PWM_LW_MIN); //Пишем в порт минимальное значение
analogWrite(PWM_LR_PIN, PWM_LR_MIN);
analogWrite(PWM_LB_PIN, PWM_LB_MIN);
//RTC.adjust(DateTime(__DATE__, __TIME__));
} // КОНЕЦ ИНИЦИАЛИЗАЦИИ

//********************************************************************************************
void loop() // ПРОГРАММЫй безусловный ЦИКЛ
{

long pwm;
DateTime myTime = RTC.now(); //Читаем данные времени из RTC при каждом выполнении цикла
long Day_time = myTime.unixtime() % 86400; //сохраняем в переменную - время в формате UNIX
//*********************************************************************************************
// обработка интервала до восхода и после заката
//*********************************************************************************************
if ((Day_time<sunrise_start) || //Если с начала суток меньше чем начало восхода
(Day_time>=sunset_start+sunset_duration)) { //Или больше чем начало заката + длительность
pwm = PWM_LW_MIN; //Величина для записи в порт равна минимуму
pwm = PWM_LR_MIN;

//*********************************************************************************************
// обработка интервала восхода
//*********************************************************************************************
}else if ((Day_time>=sunrise_start) && //Если с начала суток больше чем начало восхода
(Day_time<sunrise_start+sunrise_duration)){ //И меньше чем начало восхода + длительность

pwm = ((Day_time - sunrise_start)*(PWM_LW_MAX-PWM_LW_MIN)) / sunrise_duration; //Вычисляем для рассвета величину для записи в порт ШИМ
pwm = ((Day_time - sunrise_start)*(PWM_LR_MAX-PWM_LR_MIN)) / sunrise_duration;

//*********************************************************************************************
// обработка интервала заката
//*********************************************************************************************
}else if ((Day_time>=sunset_start) && //Если начала суток больше чем начало заката и меньше чем
(Day_time<sunset_start+sunset_duration)){ //начало заката плюс длительность

pwm = ((sunset_start+sunset_duration - Day_time)*(PWM_LW_MAX-PWM_LW_MIN)) / sunrise_duration; //Вычисляем для заката величину для записи в порт ШИМ
pwm = ((sunset_start+sunset_duration - Day_time)*(PWM_LR_MAX-PWM_LR_MIN)) / sunrise_duration;

//********************************************************************************************
// обработка интервала от конца рассвета и до начала заката,
// когда свет должен быть включен на максимальную яркость
//********************************************************************************************
}else {
pwm = PWM_LW_MAX; //Устанавливаем максимальную величину для записи в порт ШИМ
pwm = PWM_LR_MAX;
}

analogWrite(PWM_LW_PIN, pwm); //Пишем в порт вычисленное значение
analogWrite(PWM_LR_PIN, pwm);

// обработка интервала до восхода луны и после заката
//*********************************************************************************************
if ((Day_time<moonrise_start) || //Если с начала суток меньше чем начало восхода
(Day_time>=moonset_start+moonset_duration)) { //Или больше чем начало заката + длительность
pwm = PWM_LB_MIN; //Величина для записи в порт равна минимуму

//*********************************************************************************************
// обработка интервала восхода луны
//*********************************************************************************************
}else if ((Day_time>=moonrise_start) && //Если с начала суток больше чем начало восхода
(Day_time<moonrise_start+moonrise_duration)){ //И меньше чем начало восхода + длительность

pwm = ((Day_time - moonrise_start)*(PWM_LB_MAX-PWM_LB_MIN)) / moonrise_duration; //Вычисляем для рассвета величину для записи в порт ШИМ

//*********************************************************************************************
// обработка интервала заката луны
//*********************************************************************************************
}else if ((Day_time>=moonset_start) && //Если начала суток больше чем начало заката и меньше чем
(Day_time<moonset_start+moonset_duration)){ //начало заката плюс длительность

pwm = ((moonset_start+moonset_duration - Day_time)*(PWM_LB_MAX-PWM_LB_MIN)) / moonrise_duration; //Вычисляем для заката величину для записи в порт ШИМ

//********************************************************************************************
// обработка интервала от конца рассвета и до начала заката луны,
// когда свет должен быть включен на максимальную яркость
//********************************************************************************************
}else {
pwm = PWM_LB_MAX; //Устанавливаем максимальную величину для записи в порт ШИМ
}

analogWrite(PWM_LB_PIN, pwm); //Пишем в порт вычисленное значение

}//------------Конец ЦИКЛА-----------------------------
2014-03-25 добавлено 25/03/2014 13:31:46#1954578

Новичок




46
Germany Seubersdorf
2 г. назад
Спасибо, уже разобрался
2014-03-25 добавлено 25/03/2014 13:58:25#1954587

Свой на Aqa.ru




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

Напишите точную маркировку вашего процессора на плате.

И еще...этот код, который я привел в качестве примера нельзя "тупо в лоб" использовать для управления несколькими каналами ШИМ.
Я проанализирую, что Вы напрограммировали и отвечу по-позже...пока ответьте по процессору...
2014-03-25 добавлено 25/03/2014 14:08:38#1954593

Новичок




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


ATMEGA 2560
16AU 1346


Вот конечный результат:

#include <Wire.h> //Подключаем библиотеку для использования I2C интерфейса с модулем RTC
#include "RTClib.h" //Подключаем библиотеку для использования модуля часов реального времени RTC
// библиотека экрана
#include "LiquidCrystal.h"
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);


#define PWM_LW_MIN 0 //Если необходим ток покоя на LED - изменить эту константу
#define PWM_LW_MAX 128 //Если необходимо ограничить максимальную яркость - уменьшить значение
#define PWM_LW_PIN 11 //Пин порта, где будет ШИМ LW

#define PWM_LR_MIN 0 //Если необходим ток покоя на LED - изменить эту константу
#define PWM_LR_MAX 200 //Если необходимо ограничить максимальную яркость - уменьшить значение
#define PWM_LR_PIN 3 //Пин порта, где будет ШИМ LR

#define PWM_LB_MIN 0 //Если необходим ток покоя на LED - изменить эту константу
#define PWM_LB_MAX 235 //Если необходимо ограничить максимальную яркость - уменьшить значение
#define PWM_LB_PIN 12 //Пин порта, где будет ШИМ LB

#define mn 60UL //Дополнительные константы для удобства
#define hr 3600UL //Отражают соответствующие количества секунд
#define d 86400UL

RTC_DS1307 RTC;

long sunrise_start = 11*hr+52*mn; //Начало восхода в 9 - 45
long sunrise_duration = 1*mn; //Длительность восхода 30 минут
long sunset_start = 11*hr+54*mn; //начало заката в 21-15
long sunset_duration = 1*mn; //Длительность заката 30 минут
long moonrise_start = 11*hr+54*mn ; //Начало луны в 9 - 45
long moonrise_duration = 1*mn; //Длительность восхода
long moonset_start = 11*hr+56*mn; //Конец луны в 11
long moonset_duration = 1*mn; //Длительность заката луны
//********************************************************************************************
void setup(){

Serial.begin(9600);
lcd.begin(16, 2); // запускаем библиотеку экрана
Wire.begin(); //Инициируем I2C интерфейс
RTC.begin(); //Инициирум RTC модуль
analogWrite(PWM_LW_PIN, PWM_LW_MIN); //Пишем в порт минимальное значение
analogWrite(PWM_LR_PIN, PWM_LR_MIN);
analogWrite(PWM_LB_PIN, PWM_LB_MIN);
if (! RTC.isrunning()) {
Serial.println("RTC is NOT running!");
RTC.adjust(DateTime(2014, 7, 12, 22, 48, 1));
}
//RTC.adjust(DateTime(2012, 7, 31, 21, 53, 1));
//RTC.adjust(DateTime(__DATE__, __TIME__));
} // КОНЕЦ ИНИЦИАЛИЗАЦИИ

//********************************************************************************************
void loop() // ПРОГРАММЫй безусловный ЦИКЛ
{
analogWrite(10, 100);
lcd.setCursor(0, 1);
long pwm_LW;
long pwm_LR;
long pwm_LB;
DateTime myTime = RTC.now(); //Читаем данные времени из RTC при каждом выполнении цикла
long Day_time = myTime.unixtime() % 86400; //сохраняем в переменную - время в формате UNIX
lcd.clear();
lcd.setCursor(11,0);
lcd.print(myTime.hour(),DEC);
lcd.print(":");
lcd.print(myTime.minute(),DEC);
delay(1000);
//*********************************************************************************************
// обработка интервала до восхода и после заката
//*********************************************************************************************
if ((Day_time<sunrise_start) || //Если с начала суток меньше чем начало восхода
(Day_time>=sunset_start+sunset_duration)) { //Или больше чем начало заката + длительность
pwm_LW = PWM_LW_MIN; //Величина для записи в порт равна минимуму
pwm_LR = PWM_LR_MIN;

//*********************************************************************************************
// обработка интервала восхода
//*********************************************************************************************
}else if ((Day_time>=sunrise_start) && //Если с начала суток больше чем начало восхода
(Day_time<sunrise_start+sunrise_duration)){ //И меньше чем начало восхода + длительность

pwm_LW = ((Day_time - sunrise_start)*(PWM_LW_MAX-PWM_LW_MIN)) / sunrise_duration; //Вычисляем для рассвета величину для записи в порт ШИМ
pwm_LR = ((Day_time - sunrise_start)*(PWM_LR_MAX-PWM_LR_MIN)) / sunrise_duration;

//*********************************************************************************************
// обработка интервала заката
//*********************************************************************************************
}else if ((Day_time>=sunset_start) && //Если начала суток больше чем начало заката и меньше чем
(Day_time<sunset_start+sunset_duration)){ //начало заката плюс длительность

pwm_LW = ((sunset_start+sunset_duration - Day_time)*(PWM_LW_MAX-PWM_LW_MIN)) / sunrise_duration; //Вычисляем для заката величину для записи в порт ШИМ
pwm_LR = ((sunset_start+sunset_duration - Day_time)*(PWM_LR_MAX-PWM_LR_MIN)) / sunrise_duration;

//********************************************************************************************
// обработка интервала от конца рассвета и до начала заката,
// когда свет должен быть включен на максимальную яркость
//********************************************************************************************
}else {
pwm_LW = PWM_LW_MAX; //Устанавливаем максимальную величину для записи в порт ШИМ
pwm_LR = PWM_LR_MAX;
}

analogWrite(PWM_LW_PIN, pwm_LW); //Пишем в порт вычисленное значение
analogWrite(PWM_LR_PIN, pwm_LR);

// обработка интервала до восхода луны и после заката
//*********************************************************************************************
if ((Day_time<moonrise_start) || //Если с начала суток меньше чем начало восхода
(Day_time>=moonset_start+moonset_duration)) { //Или больше чем начало заката + длительность
pwm_LB = PWM_LB_MIN; //Величина для записи в порт равна минимуму

//*********************************************************************************************
// обработка интервала восхода луны
//*********************************************************************************************
}else if ((Day_time>=moonrise_start) && //Если с начала суток больше чем начало восхода
(Day_time<moonrise_start+moonrise_duration)){ //И меньше чем начало восхода + длительность

pwm_LB = ((Day_time - moonrise_start)*(PWM_LB_MAX-PWM_LB_MIN)) / moonrise_duration; //Вычисляем для рассвета величину для записи в порт ШИМ

//*********************************************************************************************
// обработка интервала заката луны
//*********************************************************************************************
}else if ((Day_time>=moonset_start) && //Если начала суток больше чем начало заката и меньше чем
(Day_time<moonset_start+moonset_duration)){ //начало заката плюс длительность

pwm_LB = ((moonset_start+moonset_duration - Day_time)*(PWM_LB_MAX-PWM_LB_MIN)) / moonrise_duration; //Вычисляем для заката величину для записи в порт ШИМ

//********************************************************************************************
// обработка интервала от конца рассвета и до начала заката луны,
// когда свет должен быть включен на максимальную яркость
//********************************************************************************************
}else {
pwm_LB = PWM_LB_MAX; //Устанавливаем максимальную величину для записи в порт ШИМ
}

analogWrite(PWM_LB_PIN, pwm_LB); //Пишем в порт вычисленное значение

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


Изменено 25.3.14 автор kirex05

Изменено 25.3.14 автор kirex05
2014-03-25 добавлено 25/03/2014 14:16:35#1954597

Свой на Aqa.ru




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


А этот код, который Вы привели в предыдущем сообщении - у меня работает. Я выкинул из него все что относится к LCD, т.к. он у меня не подключен, сделал для отладки длительность рассвета и заката по 3 минуты. По портам ШИМ на 11 пине и на 3 пине, этот код корректно отработал все интервалы.

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

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

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

В коде нужно определить константу - смещение
#drfine moonLightOffset 72000UL

потом вот так мы определяем время начало суток для операций с дневным светом в 2х каналах:
long Day_time = myTime.unixtime() % 86400; //сохраняем в переменную - время в формате UNIX

А вот так нужно определить время начала суток для операций с лунным светом:
long MoonDay_time = (myTime.unixtime() + moonLightOffset) % 86400; //сохраняем в переменную - время в формате UNIX

НО интервалы восхода луны и заката луны - нужно задать относительно измененного вренени начала суток для луны, т.е. относительно Смещения - moonLightOffset. Например вот так:

long moonrise_start = 2*hr+30*mn; //Начало восхода луны в 22 часа 30 минут (это с учетом смещения)
long moonrise_duration = 30*mn; //Длительность восхода луны
long moonset_start = 12*hr+45*mn; //Начало заката луны в 8 часов 45 минут (на следующие астрономические сутки)
long moonset_duration = 30*mn; //Длительность заката луны

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

И еще....не используйте всеже функцию delay в главном цикле loop(). И в целях отладки не делайте длительность рассвета и заката равными одной минуте...делайте хотя бы 3 минуты.
2014-03-25 добавлено 25/03/2014 16:36:27#1954662

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