go to bottom
Постоянный посетитель
Аквафорум рыбкаАквафорум рыбкаАквафорум рыбка
Аватар пользователя

693 90
Выкса
2 года

ARDUINO для автоматизации аквариума (страница 7)

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

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

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

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

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

для форума


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


Программа для среды программирования Arduino:
//***************************************************
// Скетч для управления релейным модулем, в котором *
// использовано два канала. Используется также RTC *
// Релейный модуль - с инверсной логикой на входе *
// Автор: ZORS *
// Версия 1. Дата 21.12.2013 02:40 *
//***************************************************
//----------ИМПОРТ БИБЛИОТЕК-------------------------
#include //Подключаем библиотеку для использования I2C интерфейса с модулем RTC
#include //Подключаем библиотеку для использования модуля часов реального времени 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
//Если секунд с начала суток больше, чем задано для включения
//Но, одновременно и меньше, чем задано для включения + длительность
{
digitalWrite(RelayChn1,LOW); //Устанавливаем на ПЕРВОМ входе релейного модуля НИЗКИЙ уровень - реле срабатывает
}
else //во всех остальных случаях
{
digitalWrite(RelayChn1,HIGH); //Устанавливаем на ПЕРВОМ входе релейного модуля ВЫСОКИЙ уровень - реле выключается
}

//------------КАНАЛ 2 - все аналогично -----------
if ((utime >= StartRelCn_2) &&
(utime
{
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 FilesArduinolibraries
Сюда и помещайте папки с подключаемыми библиотеками. Если на этот момент, среда программирования была запущена - ее необходимо закрыть, и запустить заново. После этого библиотека будет доступна в меню Скетч/Импортировать библиотеку.

Микросхема 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-2121/12/2013 15:57:48
#1907148
Постоянный посетитель
Аквафорум рыбкаАквафорум рыбкаАквафорум рыбка
Аватар пользователя

693 90
Выкса
2 года

Дядька-рыбомор
Аппаратное решение сразу приходит на ум: через реле. В одном положении (ВКЛ) на кулер подается, к примеру, 12 В, а в другом (ВЫКЛ) - 5 В. За программным решением - к топикастеру Смайлик :)

Если поменять логику реле - то можно. Ну это первое что в голову приходит.
Делаем делитель напряжения на 2 резисторах, один параллельно двигателю куллера, а другой последовательно в цепь питания 12В.
Резисторы необходимо рассчитать таким образом, чтобы на куллере падало напряжение 5 В, тогда если контактами реле замкнуть резистор который последовательно, то на куллере упадет 12 вольт.
Это позволит использовать источник питания с одним напряжением, а если есть 2 источника и 5 и 12 вольт, то реле имеет переключающий контакт, тут вообще проблем - нет.
2014-04-0202/04/2014 23:44:00
#1958378
Посетитель
Аквафорум рыбкаАквафорум рыбка
Аватар пользователя

460 42
Москва
6 года

А тут пока копался такое нарыл 4-pin:
Общий - "минус" питания (черный провод).
Плюс питания - 12 В из БП (желтый провод).
Датчик - сенсор оборотов (2 импульса лог. 0 на один оборот крыльчатки).
Управление - сигнал PWM для управления скоростью.

У трех проводного тоже управление шим модуляцией оказывается (раньше думал, что напряжением) но по питающему проводу (12V).

Вывод - надо искать 4-pin кулеры. Ими рулить удобней.

2014-04-0303/04/2014 08:44:19
#1958408
Постоянный посетитель
Аквафорум рыбкаАквафорум рыбкаАквафорум рыбка
Аватар пользователя

693 90
Выкса
2 года

arch07
А тут пока копался такое нарыл


Это Вы про что? ЧТо за куллеры?

Потом, про OneWire удалось что-нибудь нарыть?

Я вот выяснил одну интересную проблему:

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

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

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

По-эксперементирую тут пару - тройку дней....потом посмотрим что получится....
2014-04-0303/04/2014 10:23:25
#1958428
Посетитель
Аквафорум рыбкаАквафорум рыбка
Аватар пользователя

460 42
Москва
6 года

Z0RS

По питанию onewire разобрался. Понравилось питание по проводу данных за счет паразитных токов.
Интересно, что DS18S20 обрабатывает температуру 750 мс. т.е. достаточно долго. Пробиться в анализ передаваемой информации не смог. И так пол-ночи просидел.
А как задержка может сказаться на удобрениях? В смысле при вызове опроса датчика температуры замрет главный цикл, а работа насоса подачи удобрений реализована через millis()??? Но это относится только к перильстатическим насосам с коллекторным двигателем.
Вариант подачу удобрений организовать циклическим насосом - мне понравился из этой темы: Простенький акваконтроллер на ARDUINO Тут задержка не критична. Или шаговый двигатель перильстатического насоса на даст передозировать.

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

Насчет кулеров - просто компьютерные вентиляторы с 4 пиновым подключением позволяют регулировать обороты шим-сигналом на голубом проводе. А контроль работы кулера - с кричневого провода - там простой датчик Холла. Это для охлаждения светильника. Что позволяет достаточно гибко регулировать обороты и, соответственно, шум.

Что-то у меня контроллер обрастает перифирией

P.S. При внимательном изучении даташита DS18B20 оказался предпочтительнее DS18S20 т.к.
- Thermometer Resolution is User Selectable from 9 to 12 Bits
- Converts Temperature to 12-Bit Digital Word in 750ms (Max)
т.е. при использовании 9 bit - ной разрядности время конвертации температуры сокращается в 8 раз. с 750 мс до 98 мс.
ИМХО существенное уменьшение.


Изменено 3.4.14 автор arch07
2014-04-0303/04/2014 13:38:59
#1958489
Постоянный посетитель
Аквафорум рыбкаАквафорум рыбкаАквафорум рыбка
Аватар пользователя

693 90
Выкса
2 года

arch07
Понравилось питание по проводу данных за счет паразитных токов.

Да...шина IC весьма оригинальна....и питание и процесс передачи данных.


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


Смотря как организован процесс подачи растворов УДО. Если будут использоваться перистальтич. помпы и концентрированные растворы - то потребуется очень точное измерение времени в теле главного цикла. Если так, организовывать -

arch07
Вариант подачу удобрений организовать циклическим насосом - мне понравился из этой темы: Простенький акваконтроллер на ARDUINO

То, конечно, точность измерения времени может быть ниже ...значительно. И это


arch07
А опрос температуры проводить не в каждом цикле, а каждые 30 сек. Тогда сократится число задержек.

также можно реализовать.



arch07
При внимательном изучении даташита ....

А....я как понимаю - Вы на правильном пути....Смайлик :)
2014-04-0303/04/2014 16:09:19
#1958541
Посетитель
Аквафорум рыбкаАквафорум рыбка
Аватар пользователя

460 42
Москва
6 года

Z0RS

ага вкурил я по вами приведенной функции. Немного напрягает HEX запись в даташитах - я ее плохо читаю, но там дублируется в двоичном коде и вроде все понятно после переваривания.
Только вызывает недоумение - датчики ds18х20 вроде достаточно популярны, но на на них нет своей библиотеки.

А по функции. Я в инете нашел похожий пример с одним отличием:

....
ds.reset();
ds.select(addr);
ds.write(0x44,1); // запускаем конвертацию

delay(1000); // скорее всего достаточно 750ms
// we might do a ds.depower() here, but the reset will take care of it.

present = ds.reset();
ds.select(addr);
ds.write(0xBE); // считываем ОЗУ датчика
....

у вас в коде выделенной строчки нет. И ведь работает. Значит задержка не нужна? Все равно ведь работает. Но даташит говорит, что нужно. Тогда получается что вы получаете температуру сконвертированную в предыдущем запросе?
Или наша система настолько медленная, что датчик успевает сформировать ответ.


P.S. Нашел библиотечку под термометры:
http://milesburton.c...
https://github.com/m...

Изменено 3.4.14 автор arch07
2014-04-0303/04/2014 20:03:02
#1958662
Постоянный посетитель
Аквафорум рыбкаАквафорум рыбкаАквафорум рыбка
Аватар пользователя

693 90
Выкса
2 года

arch07
у вас в коде выделенной строчки нет. И ведь работает. Значит задержка не нужна? Все равно ведь работает. Но даташит говорит, что нужно. Тогда получается что вы получаете температуру сконвертированную в предыдущем запросе?
Или наша система настолько медленная, что датчик успевает сформировать ответ.


Необходимо разделять, процесс конвертации температуры - в результате которого значение температуры записывается в регистр оперативной памяти датчика. Это процесс длительный и требует наличия высокого уровня на проводе DQ на протяжении времени, требуемого для конвертации - для обеспечения необходимого тока для аналогоцифрового преобразователя датчика.
Для датчика класса ds1820 - это ток около 1,5 мА.

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

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

Весь "финт" в использовании нескольких датчиков на шине OneWire - это развести по времени задания на конверсию и вычитывание данных, таким образом, чтобы МК делал как можно меньше бестолковой работы, и чтобы главный цикл, не был бы слишком загружен. И вот это "разведение" по времени, необходимо сделать, без использования функции delay().
2014-04-0303/04/2014 22:39:21
#1958723
Посетитель
Аквафорум рыбкаАквафорум рыбка
Аватар пользователя

460 42
Москва
6 года

Z0RS

Ага - я это понял. Итого по термометрам:
1. Т.к. у нас все - таки нет проблем с подводом 3 проводов, то лучше питать датчик полноценно.
2. Избавится от запроса в каждом цикле, даже 5-10 сек периода будет имхо достаточно - все-таки аквариум не такая шустрая система, даже если контролировать этими датчиками охлаждение светильника.
3. Если есть возможность брать серию DS18B20, а не DS18S20. Только выставить для нее разрешение в 0,5 градуса - максимальное. Это позволяет библиотека что я приводил. Причем в даташите сказано, что точность измерения без доп корректировок 0,5 градуса - получается 12 бит избыточны для передачи и 9 бит правильный размер пакета.
2014-04-0404/04/2014 06:47:08
#1958769
Постоянный посетитель
Аквафорум рыбкаАквафорум рыбкаАквафорум рыбка
Аватар пользователя

693 90
Выкса
2 года

arch07
Причем в даташите сказано, что точность измерения без доп корректировок 0,5 градуса - получается 12 бит избыточны для передачи и 9 бит правильный размер пакета


В обоих случаях принимать придется 2 байта....поэтому снижать дискретность, по большому счету, нет смысла.
2014-04-0404/04/2014 11:01:40
#1958813
Посетитель
Аквафорум рыбкаАквафорум рыбка
Аватар пользователя

460 42
Москва
6 года

Z0RS

Есть - я приводил по даташиту при снижении дискретности на 1 бит время конвертации снижается вдвое
с 12 до 9 бит - в 8 раз. с 750 мс до 98 мс. Дискретность надо только 1 раз прописать - потом она в ПЗУ запоминается.
Все равно надо будет считывать номер датчика для его расстановки по использованию. Тогда и "инициализировать".

А пример правильного меню скоро будет?
2014-04-0404/04/2014 12:12:57
#1958834
Постоянный посетитель
Аквафорум рыбкаАквафорум рыбкаАквафорум рыбка
Аватар пользователя

693 90
Выкса
2 года

arch07

Вот здесь есть интересная библиотека для DS1820:
https://github.com/m...
А...вообщето Вы ее и указали...
Я ее не пробовал еще, но судя по описанию - "самое оно" ...Смайлик :D

Здесь пример ее использования со множеством датчиков температуры
http://blockduino.bl...



arch07
А пример правильного меню скоро будет?


Вообще, я цель, такую не ставил. Основная цель - показать как работает связка клавиатура + I2C интерфейс. И это я постараюсь показать, как придет железо.

А меню, это так.... бесплатное приложение...можете и сами написать любое, тем более, что в учебном примере будет все очень упрощено.

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

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

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


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

Изменено 4.4.14 автор Z0RS
2014-04-0404/04/2014 14:32:22
#1958874
Посетитель
Аквафорум рыбкаАквафорум рыбка
Аватар пользователя

460 42
Москва
6 года

Z0RS

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

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

Но как то это все громоздко, конструкции что зреют в голове какие-то слишком не "кошерные"... К тому же почитав правильный код, осознав логику намного легче применить его к себе. Примеры из библиотек мало того, что слишком простые, так еще и не кошерные - т.к. почему-то постоянно там используется delay(). Еще и дребезг этот...

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

А еще можно узнать - что за железо вы ждете? Клавиатура на шину I2C? Может мне тоже ее стоит использовать? I2C мне понравилась. Может там еще и дребезг аппаратно обрабатывается?

P.S. Последний вопрос снимается - почитал даташиты по PCF8575 и PCF8575 - получается на PCF8574 - можно максимум 4х4 клаву замутить, а на PCF8575 - 8х8. Интересные штучки.

Изменено 4.4.14 автор arch07
2014-04-0404/04/2014 15:27:43
#1958889
Постоянный посетитель
Аквафорум рыбкаАквафорум рыбкаАквафорум рыбка
Аватар пользователя

693 90
Выкса
2 года

arch07
но каждую кнопку вешать на прерывание - при нажатии поднимать флаг, потом в главном цикле обрабатывать это нажатие и снимать флаг по выполнении.

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

И вообще, использование прерываний - не обязательно.
С обычной клавиатурой, присоединенной на некоторое количество портов (по количеству столбцов и строк) - это вообще плохо осуществимо.
А вот если использовать I2C экспандер портов, то как правило микросхемы такого класса - имеют выход для организации прерывания. В этом случае прерывание и функция по его обработке будет одна.


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

Естественно. И вариантов много. Даже в RTC на DS1307 - есть возможность хранить данные в энергонезависмой памяти. Можно в EEPROM микроконтроллера хранить, можно в присоединенной SD карте. Последний вариант - сложнее.


arch07
А сейчас прям дефицит аппаратных прерываний вырисовывается.

Не нужно очень сильно увлекаться использованием прерываний. Это сильный источник "блуждающих" ошибок - которые очень сложны в отладке...и требуют хороших знаний архитектуры МК.
Вообще - идеальная программа - это относительно плоский главный цикл, с ветвлением, выполненным таким образом, что время выполнения любой ветки не превышает 110 - 115% среднестатистического времени выполнения главного цикла. Без каких либо прерываний. Либо с минимумом прерываний...
Потом, с прерываниями тоже нужно научится работать. Необходимо оценивать возможность возникновения прерывания даже во время выполнения функции обработки самого прерывания, также во время выполненя других веток главного цикла, и где есть сомнения в возможности совмещения прерывания - необходимо запрещать прерывания а потом по ходу кода - разрешать, и т.д.
Правил, работы с прерываниями - много, также как и для правильного кода с точки зрения использования памяти....Мы многое в коде не пишем, т.к. считаем, что компилятор вставит это за нас, и бывают разочарования....Смайлик :D, особенно когда несколько часов или дней ищется источник утечки памяти.



arch07
А еще можно узнать - что за железо вы ждете?
Клавиатура на шину I2C? Может мне тоже ее стоит использовать? I2C мне понравилась. Может там еще и дребезг аппаратно обрабатывается?

[/q]
Не...я использую обычные клавиатурки - кнопочные или пленочные с организацией выводов по столбцам и строкам. А для того, чтобы сократить количество цифровых входов - можно использовать сдвиговые регистры. Классикой считается использование сдвигового регистра с последовательным выводом значений в порт с TTL уровнем.
Например можно использовать при расширении количества - для входов 74HC165N , а для выходов 74HC595.

А теперь хочу попробовать микросхему сдвигового регистра с I2C интерфейсом - PCF8574. Это микросхема двунаправленный экспандер портов ввода/вывода с I2C интерфейсом и возможностью организации апп.прерываний. Вот заказал десяток микросхем, да еще всякого "железа" для разных экспериментов...и использований.
2014-04-0404/04/2014 16:21:10
#1958922
Посетитель
Аквафорум рыбкаАквафорум рыбка
Аватар пользователя

460 42
Москва
6 года

Остался вопрос по дребезгу подключенной PCF8574 клавы - он все равно будет?

Изменено 4.4.14 автор arch07

2014-04-0404/04/2014 20:18:12
#1959025
Постоянный посетитель
Аквафорум рыбкаАквафорум рыбкаАквафорум рыбка
Аватар пользователя

693 90
Выкса
2 года

arch07
стался вопрос по дребезгу подключенной PCF8574 клавы - он все равно будет?


Смотря как подключенной....если классическим образом - то да...
2014-04-0404/04/2014 20:52:25
#1959062
Завсегдатай, Кандидат в Советники
Кандидат в советники аквафорумаРыбки аквафорумаРыбки аквафорумаРыбки аквафорумаРыбки аквафорума

Аватар пользователя

1362 586
Ростов-на-Дону
4 года

Привожу практические результаты экспериментов со временем, точнее его коррекции в некорректных RTC. Может оказаться полезным таким дубам в программировании, как я, коих тут приличное кол-во.
Сначала установил, что часики спешат на 36 сек/сут, получается ровно 1,5 сек/час.
Как советовал ZORS, задал период коррекции и время коррекции
uint32_t TimeAdjustPeriod = 3600;
uint32_t TimeCorrection = -1.5;
т.е. сдвиг часов назад каждый час на полторы секунды. Запустил - и ничего, как спешили, так и спешат (проверял по часикам в программе "Время", хоть какая-то польза от зомбоящика).
Решил, что дробные отрицательные величины в секундах UNIX контроллеру непонятны, поэтому надо задавать целые секунды. Сделал так
uint32_t TimeAdjustPeriod = 7200;
uint32_t TimeCorrection = 3; "3" без минуса
А в функции цикла void loop {} написал так:
RTC.adjust(DateTime(UTime-TimeCorrection));
т.е. тупо поменял "+" на "-". И все заработало! Поргешность минимальная, по крайней мере точно меньше целой секунды, но такая точность меня вполне устроит. Китайские таймеро-розетки убегают по 5-10 минут в год, кстати.

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

2014-04-0606/04/2014 12:12:08
#1959615
Постоянный посетитель
Аквафорум рыбкаАквафорум рыбкаАквафорум рыбка
Аватар пользователя

693 90
Выкса
2 года

Дядька-рыбомор
uint32_t TimeCorrection = -1.5;


Я конечно...прошу прощения, но нельзя же так не уважать основы языка СИ.

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

В нашем случае объявлена переменная типа
uint32_t - в данном случае "u" - unsigned - то есть беззнаковое, "int" - integer - целое. занимающее 32 бита.

При присвоении вы сделали несколько ошибок....наверное уже понятно каких. По идее компилятор должен бы ругнуться. И на нормальной платформе - так бы и было...а видимо, в IDE ARDUINO - многое чего из компиллера было изъято, для компактности. И в нашем случае похоже, что компиллер сделал преобразование типа при присвоении значения данной переменно, и что он в итоге присвоил - я не знаю....можно проверить - выведя значение данной переменной, например, в компорт.
2014-04-0606/04/2014 15:09:27
#1959689
Завсегдатай, Кандидат в Советники
Кандидат в советники аквафорумаРыбки аквафорумаРыбки аквафорумаРыбки аквафорумаРыбки аквафорума

Аватар пользователя

1362 586
Ростов-на-Дону
4 года

сообщение Z0RS
Я конечно...прошу прощения, но нельзя же так не уважать основы языка СИ.

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


uint32_t - в данном случае "u" - unsigned - то есть беззнаковое, "int" - integer - целое. занимающее 32 бита.

Ну вот до этого я интуитивно и методом тыка и дошел.

Изменено 6.4.14 автор Дядька-рыбомор
2014-04-0606/04/2014 15:30:06
#1959693
Постоянный посетитель
Аквафорум рыбкаАквафорум рыбкаАквафорум рыбка
Аватар пользователя

693 90
Выкса
2 года

Дядька-рыбомор

На самом деле некоторые операции над переменными разных типов всеже допустимы. Например операции со знаком в безнаковых переменных допустимы - компиллер попытается сделать преобразование типов....

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

Очень неплохо знать как хранятся в памяти переменные разных типов, как происходят над ними операции. Тогда на Си программировать легче, легче понять операции с указателями - а это основа эффективности языка.

Сейчас этому в школах стали учить...в некоторых....
2014-04-0606/04/2014 16:39:16
#1959734
Посетитель
Аквафорум рыбкаАквафорум рыбка
Аватар пользователя

460 42
Москва
6 года

Z0RS

Ну мы же не профи. И проекты у нас любительские. И ошибки глупые. Да по-большому счету немного поигравшись и закончив проект - другой в лучшем случае вернемся к теме мк только при обнаружении задач для них через годик-другой. Уже сейчас понимание того что ардуино все-таки учебная платформа приходит в наши умы, но профессиональный подход нам избыточен. Потому и ценим ваши советы. И просим не расстраиваться от наших ошибок, а просто указать нам на них - мы не обидимся и примем к сведению Смайлик :). И постараемся в будущем избежать.

Вот я сейчас столкнулся с тем, что система опять уперлась в концептуальный вопрос - сколько насосов для подачи удобрений надо контролировать.
И проект встал до того как я разберусь в этом вопросе. Причем профи дают уклончивые советы - "в зависимости от многих факторов", воинствующие дилетанты - "тока как у меня иначе все плохо", но им доверия меньше.
Пока остановился на системе http://www.aqua-bota...
Получается: азот, фосфор, микро, магний, калий.
5 леек или 6 (+ кальций). Но тут я уперся в аппаратную проблему - я просто не представлял что вносить потребуется столько много разных растворов - думал ну три-четыре максимум. И просто не имею приводов. А Китай до-о-о-олго шлет.
И в голове бродит - а оно надо? может я перезаложился? 6 каналов для удо тупо займут слишком много места. - 6 литровых (или по пол-литра взять?) бутылок плюс насосы.
2014-04-0606/04/2014 21:40:14
#1959886
Посетитель
Аквафорум рыбкаАквафорум рыбка
Аватар пользователя

94 1
Москва
7 года

Наконец-то пришли все компоненты Arduino. сегодня собрал схему, припаял где надо. Подключаю к компу (Mac OS), через программу для мака устанавливаю библиотеки из первого поста. Далее вставляю скетч ARDUINO для автоматизации аквариума нажимаю загрузить, идет загрузка в память и на дисплеи в нижнем ряду одни квадраты. Где косяк?

Вопрос еще таков что при добавлении билиотек у меня там три файла всегда например для RTS%
-datecalc
-ds1307
-softrts
что открывать?

2014-04-0606/04/2014 21:54:33
#1959897
Посетитель
Аквафорум рыбкаАквафорум рыбка
Аватар пользователя

94 1
Москва
7 года

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

а далее где инициализация там написано

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


при попытке заменить на LiquidCrystal_I2C пишет ошибку. да и вообще не хочет записывать в плату

2014-04-0606/04/2014 22:21:46
#1959912
Постоянный посетитель
Аквафорум рыбкаАквафорум рыбкаАквафорум рыбка
Аватар пользователя

693 90
Выкса
2 года

Bwzs

Начните с более простых вещей. Залейте на плату скетч-пример с названием Blink, из стандартного пакета примеров.
Или можете скопировать вот этот код. Далее, необходимо откомпилировать его и залить на плату. Кстати, какая у вас модель платы?

int led = 13;
void setup() {
pinMode(led, OUTPUT);
}
void loop() {
digitalWrite(led, HIGH);
delay(1000);
digitalWrite(led, LOW);
delay(1000);
}
В результате, на 13 пине должен моргать светодиод с частотой 0,5 герца примерно. На разных платах, это светодиод находится в разных местах и он может быть разного цвета, посмотрите инфо по вашей плате.

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

Изменено 6.4.14 автор Z0RS
2014-04-0606/04/2014 22:57:36
#1959924
Посетитель
Аквафорум рыбкаАквафорум рыбка
Аватар пользователя

460 42
Москва
6 года

Bwzs

У вас должны быть на компе установлены библиотеки.
Как на маке не в курсе, но вроде от других операционок - не особо отличается.

в папке с установленной программой Arduino есть подпапка libraries.
В ней лежат файлы библиотек.
Вы подгружаете библиотеки. Вернее автоматом подгружаются в среду все библиотеки, лежащие в папке libraries при запуске среды программирования, а вы их вставляете в собственный скетч.
Wire (для работы с шиной I2C). - для шины, только для шины. Конкретно файл Wire.h, который среда сама находит в папке Wire (если он там есть).
RTClib - для работы с часами по протоколу I2C. Соответственно файл RTClib.h
LiquidCrystal_I2C - для работы с жк экраном по I2C, т.е. файл LiquidCrystal_I2C.h


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

И не забудьте после добавления библиотек, а добавляются они простым разархивированием папки библиотеки в папку libraries, презапустить среду программирования. И еще один ньюанс - папка должна иметь простое название без русских букв и пробелов - иначе будет ругаться среда при запуске.
Удачи!

Изменено 6.4.14 автор arch07
2014-04-0606/04/2014 23:13:10
#1959932
Посетитель
Аквафорум рыбкаАквафорум рыбка
Аватар пользователя

94 1
Москва
7 года

Z0RS


Все работает.ну всмысле мигает на 13 пине. Как я понял в данном скетче нет обращения к модулю дисплея, правильно? при добавлении библиотеки LiquidCrystal_I2C он выдает ошибку.
2014-04-0707/04/2014 08:02:25
#1959997



Польвователь
Польвователь
Польвователь
Польвователь
Польвователь
Польвователь
Польвователь
Польвователь
Польвователь
Польвователь
Польвователь
Top