Контроллер управления освещением для экономных и ленивых
- Войдите на сайт для отправки комментариев
Всем доброго времени суток.
Преамбула:
3 дня назад я первый раз подключил ардуино к компу, я прекрасно знаю, что я нумб и т.д. и т.п
Всё, что мне требуется, лично я от ардуино получил по полной.
Может тогда у вас возникнет вопрос, какого хрена я тут нарисовался... А на это есть несколько причин.
1. Для реализации моего проекта мне очень помог пост про титановый велосипед для титановой кнопки. Просто хотел скзать ОГРОМНОЕ СПАСИБО автору этого класса. От всей души! Огромного здоровья Вам!
2. Раз уж мне помог пост с этого сайта, может и мой пост поможет кому-либо, а может и мне самому через много много лет.
И так к чему эта тема:
Обзавёлся я большой квартирой от застройщика в которой не было электрики, только вводной щиток и увсё.
Решил электрику делать сам (денег на электриков уже нет, да и у самого руки не из жопы, да и найти электриков, которые смогут реализовать мой проект по управлению освещением я не смогу), а всё потому что на рынке нет нормальных модулей управления освещением, хоть убейти, уж поверти гуглить я умею. Всё сводится либо к мега проекту умного дома с мегаценой разных мега модулей, либо просто к самым простейшим и тупым реле и кучей проводов.
Пока застройщик строил мне хату я год назад купил одну китайскую ардуину мегу 2560 и 2 модуля с 16тью 5ти вольтовыми реле на каждом (на них написано 16 Relay Module Low Level Trigger, гугл сразу правильные картинки показывает), купил проводков ну и успокоелся (вернее ещё купил книгу по ардуинке, нахрена - сам не пойму). Не помню сколько потратил, точно менее 2-х килорублей за всё. Всем, кто мне будет говорить, что лучше брать 12ти вольтовые реле, я даже спорить не буду, просто молча соглашусь и сам советую брать именно их, ну а пока у меня что есть, то есть.
Квартиру сдали, я начал кидать провода по следующим принципам:
От каждого выключателя до щитовой (да, у меня дома уже есть маленькая щитовая) идёт utp 2 пары.
От каждой зоны освещения до щитовой идуи силовые провода (под каждый источник нужного сечения с запасом, это не важно).
Кто нить подумает, что это лишнее и это просто дурость, но если представить преимущества, то наверное спорить будут только самые упоротые троли, я даже позволю перечислить их:
1. Любой выключатель может управлять любой зоной освещения.
2. Если вдруг надо переделать выключатель, не надо вскрывать потолки и лезть в коробки
3. Экономия кучи бабла на проводах и на выключателях и на крепеже проводов, да и на времени.
Итак у меня подходит время всю канитель в щитовой подключать и тут я вспомнил о том, что в ардуино я полный дебил, и что мозгов меня наврят ли хватит на всё это дело. Я чуть даже не решился на приобретение тупых реле (думал даже о твердотельных), но что то меня канало изнутри... Типо ардуино же лежит на полке, там даже дети программируют и я начал капать....
Выяснилось, что у меги всего 54 входа-выхода + 16 аналоговых входов. Математика мне дала возможность посчитать, что на 32 реле и 64 кнопки (именно столько мне надо, у меня всего 10 выключателе трёхклавишный и 12 двухклавишных, вот только я же ленивый, я не подписал провода, просто решил, что потом методом тыка разбирусь). Сразу скажу, что я купил выключатели, которые легко переделываются из обычных в кнопочные (пружинка ставится и просто огонь). Ну да ладно, едем далее - ног не хватает, куплю ещё одну, потом соединю через rs232 и поедет наверное. Начинаю разбираться с кнопками, оказывается есть какой то дребезг и там целый здец.... Бог привёл меня на ваш форум к титановому велику. Я перечитал все посты на одном дыхании, просто не знаю сколько у автара темы нервов, я бы поубивал треть зверьков в этой теме.... Премного благодарен этому дару. Я смог поправить математику, понял что с помощью велика прикручу 63 кнопки на 8 аналоговых входов. Решил что выключатели подключу матрицей 7 столбцов, 9 строк
3 дня назад достал друину, с горем подключил к ide (драйвер долго подбирал к этому китайскому чуду), написал свой первый скейтч, который мигал мусорным пином (всмысле 13) SOS. Приятно для себя осознал, что мы с ардуинкой подружимся.
В тот же день я не смог удержаться и написал скетч, который в дальнейшем сможет мне помочь найти откуда какой провод болтается в щитовой, даже не писал к нему комментариев, просто тупо ловит момент нажатия кнопки и говорит его индекс в сериал порт, тупым putty коннекто к com порту с любого ноута позволит сопаставить место расположения выключателя и его адрес в матрице
#include <Matrix.h> Matrix knop; void setup() { pinMode (13,OUTPUT); Serial.begin(9600); // put your setup code here, to run once: knop.NO(); // N.O. Normal Open // test.NC(); // N.C. Normal Closed knop.pullUp(); // test.pullDn(); knop.TKRO(); knop.duration_bounce ( 50); knop.duration_click_Db ( 250); knop.duration_inactivity_Up(5000); knop.duration_inactivity_Dn(1000); knop.duration_press ( 500); knop.matrix_x( A7, A8, A9, A10, A11, A12, A13, A14, A15); // arduino pins connected to rows knop.matrix_y( A0, A1, A2, A3, A4, A5, A6); // arduino pins connected to columns // test.matrix_x(); // test.matrix_y(); } void loop() { knop.read(); for (int i=0; i<=63; i++) { digitalWrite(13, !digitalRead(13)); Serial.println(i); } }
На второй день я подключил к ардуинке 2 платы с реле, немного ими поиграл и начал писать всякую хрень. К концу дня я реализовал все функции, которые меня бы полностью устроили, но кое что мне не давало покоя. Именно то, что в продаже готовых блоков реле нет. Просто рассказать идею об организации управления освещением и тупо выложить свой скетч как то не по себе. Честно скажу, для следующего скетча я потратил добрых 5-6 часов. И так, в чём идея: берём 32 реле и распределяем их в группы (я изначально предположил 32 группы, по 1 реле в каждой группе, но количество групп легко поправить). В группе может быть 4 реле, одно реле - основное, два дополнительных и одно реле вспомогательное (я его назвал предмастер реле). Для чего это может понадобится: У вас 3 светодиодные ленты и 1 блок питания. И вам надо ими управлять по отдельности. то есть вы берёте нажимаете на клавишу в коридоре, у вас включается блок питания и лента в коридоре, нажимаете на клавишу ещё раз, добавляется ещё одна лентав том же корридоре, а вот если нажать на выключатель на кухне включится третья лента, и всё с одного блока питания, которым как раз и должно управлять предмастер реле. так же на группу я предусмотрел таймер отключения по реле-условию. Тобишь допустим вы в ванной, зашли, включили отдельной кнопкой включили вытяжку, отдельной свет, сделали свои дела, вышли и выключили только свет, а про вытяжку либо забыли, либо нарочно оставили, зная что после того, как отключится реле света, вытяжка сама должна отключится через 5 минут (ну или любое другое время). На данном этапе скетч обкатан и работает, скоро всё устройства со стола уедет в щитовую, пока ещё есть возможность что-либо допилить.
Просто может кому пригодится (скетч для матрицы кнопок 8на8, использую выключатели без фиксации):
#include <Matrix.h> Matrix knop; //Сопоставляем пины управления реле их порядковым номерам номерам, так удобнее // 13 пин - мусор и для правильной работы всего этого маразма в теле программы, после каждого действия кнопки, он, на всякий случай, переходит в 1, иначе - белая лисичка, танцы с бубнами и т.п. и т.д. //Номер реле 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32 int pinRelay[33]={13,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53}; //Далее определяем параметры групп реле (32 группы, можно и более), нулевая группа управляет всеми реле одновременно int GroupCount = 32; //вдруг не хватит групп //Номер группы 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32 int masterRelay[33]={ 0, 2, 5, 7, 10, 12, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; //Определяем предмастер реле, которое должно включаться перед мастер реле (допустим включение блока питания лент осуществляется пре реле, а дальнейшая коммутация осуществляется мастер реле) int preRelay[33] = { 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; //Определяем дополнительно 2 реле (максимальное кол-во реле в группе 3, просто не вижу смысла добавлять более трёх реле в группу) int dop1Relay[33] = { 0, 3, 6, 8, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; int dop2Relay[33] = { 0, 4, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; //2 следующих массива определяют таймер отключения группы по следующему условию: после того как отключится реле timerRele отключить всю группу через время timerGroup (в сек). int timerRelay[33]= { 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; int timerGroup[33]= { 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; //Определяем режим работы 0-ничего не делать, 1-вкл/выкл всей группы, 2-последовательное включение с полным отключением, 3-бегущий огонь из 2-х реле, 4-вкл. всей группы, 5-откл. всей группы int modeGroup[33] = { 5, 2, 2, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}; //Привязываем кнопоки к группам (по умолчанию всё привязываю к 32 группе, которая ничего не делает) // кнопка 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63 int keyGroup[64] = { 0, 1, 2, 3, 4,32, 6, 5,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32}; //Вспомогательный массив, для хранения времени сработки условия и ещё одна переменная, которая почему то не хотела работать как надо при объявлении в теле программы (количество дополнительных реле в канале) unsigned long rtimeGroup[33]= {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; int countdr; void setup() { pinMode (13,OUTPUT); //мусорный пин, дай Бог не сгорит светодиод for (int y=1; y<=GroupCount;y++) //инициализируем пины модулей реле, ставим их в 1, так как комутируются они нулём { pinMode (pinRelay[y],OUTPUT); // delay(500); //Тупо по приколу, а если честно, то это позволяет определить в правильной ли последовательности подключены все реле digitalWrite(pinRelay[y], HIGH); } Serial.begin(9600); //тупо для отладки //Огромнейший респект создателю титанового велосипеда для титановой кнопки. Благодаря этой штуки я прикрутил 64 кнопки на 8 аналоговых входов и потратил на это 10 минут! Мужик, ты гений! // put your setup code here, to run once: knop.NO(); // N.O. Normal Open // test.NC(); // N.C. Normal Closed knop.pullUp(); // test.pullDn(); knop.TKRO(); knop.duration_bounce ( 50); knop.duration_click_Db ( 250); knop.duration_inactivity_Up(5000); knop.duration_inactivity_Dn(1000); knop.duration_press ( 500); knop.matrix_x( A8, A9, A10, A11, A12, A13, A14, A15); // arduino pins connected to rows knop.matrix_y( A0, A1, A2, A3, A4, A5, A6, A7); // arduino pins connected to columns // test.matrix_x(); // test.matrix_y(); } void loop() { digitalWrite(13,1); //Обойти грабли //Проверить статус таймера и если пора что-то выключить, то это надо выключить unsigned long CurrentTime=millis(); for (int x=1; x <= GroupCount; x++) if (timerRelay[x] !=0 && rtimeGroup[x] != 0) if (CurrentTime-rtimeGroup[x] > (timerGroup[x]*1000) || CurrentTime-rtimeGroup[x] < 0) //это условие должно пердусмотреть переполнение параметра миилис за 50 дней, и если вдруг будет перескок и при этом активный таймер, то реле отключится раньше заданного времени (зато отключится), ну лень мне ещё и часы прикручивать { digitalWrite(pinRelay[masterRelay[x]],1); digitalWrite(pinRelay[dop1Relay[x]],1); digitalWrite(pinRelay[dop2Relay[x]],1); if (preRelay[x]!=0) //Иногда в группе с таймером может быь и предмастер реле, надо проверить нужно ли данное реле для других групп, если нет - выключить его { int flagpr=0; for (int p=1; p<=GroupCount; p++) if (preRelay[p]==preRelay[x]) if (digitalRead(pinRelay[masterRelay[p]])==0 || digitalRead(pinRelay[dop1Relay[p]])==0 || digitalRead(pinRelay[dop2Relay[p]])==0) flagpr=flagpr+1; if (flagpr==0) digitalWrite(pinRelay[preRelay[x]],1); } rtimeGroup[x]=0; } //Читаем кнопки, вдруг что-нить нажали... // а если нажали - определяем какой группой надо работать и по какому сценарию и проверить таймер, вдруг мы включили группу с таймером, а реле-условие выключено, значит надо выключить группу через заданное время knop.read(); for (int i=0; i<=63; i++) { if (knop.event_click_Dn ( i) == 1) { int CurrentGroup=keyGroup[i]; int CurrentMode=modeGroup[CurrentGroup]; Serial.print("mode ");Serial.println(CurrentMode); if (timerRelay[CurrentGroup]!=0){ if (digitalRead(pinRelay[timerRelay[CurrentGroup]])==1) {rtimeGroup[CurrentGroup]=millis();}} switch (CurrentMode) { case 0: //Неназначенная кнопка, ничего не делаем break; case 1: //Вкл/выкл всей группы if (digitalRead(pinRelay[masterRelay[CurrentGroup]])==1) // Если выключено, тупо всё включить { if (preRelay[CurrentGroup]!=0) digitalWrite(pinRelay[preRelay[CurrentGroup]],0); // Сам не знаю, зачем я проверяю это предмастер реле, даже если бы в конфе было ноль, то я тупо бы выключил 13 пин и на следующем цикле он автоматом бы врубился, надо убрать условие digitalWrite(pinRelay[masterRelay[CurrentGroup]],0); digitalWrite(pinRelay[dop1Relay[CurrentGroup]],0); digitalWrite(pinRelay[dop2Relay[CurrentGroup]],0); } else // Если включено, то всё выключить, проверив предмастер { digitalWrite(pinRelay[masterRelay[CurrentGroup]],1); digitalWrite(pinRelay[dop1Relay[CurrentGroup]],1); digitalWrite(pinRelay[dop2Relay[CurrentGroup]],1); if (preRelay[CurrentGroup]!=0) //эта вставка будет много раз встречаться, это всё проверка предмастер реле { int flagpr=0; for (int p=1; p<=GroupCount; p++) if (preRelay[p]==preRelay[CurrentGroup]) if (digitalRead(pinRelay[masterRelay[p]])==0 || digitalRead(pinRelay[dop1Relay[p]])==0 || digitalRead(pinRelay[dop2Relay[p]])==0) flagpr=flagpr+1; if (flagpr==0) digitalWrite(pinRelay[preRelay[CurrentGroup]],1); } } break; case 2: //Включение волной и полное отключение countdr=0; //Считаем количество доп реле в группе, ведь их может быть и 1, и 2, и не быть, если их не будет, то не будет никакой реакции на кнопку, а потом гадайте почему и как этот маразм не работает if (dop1Relay[CurrentGroup]!=0 && dop2Relay[CurrentGroup]==0) {countdr=1;} if (dop1Relay[CurrentGroup]!=0 && dop2Relay[CurrentGroup]!=0) {countdr=2;} Serial.print("countdr ");Serial.println(countdr); if (digitalRead(pinRelay[masterRelay[CurrentGroup]])==1 && countdr >= 1) //Одно длинное условие, при каждом последующем нажатии кнопки оно проваливается всё ниже и ниже, но вдруг в результате неправильной конфигурации какой нить другой канал включит или выключит нужное реле.... Ничего страшного, максимум после 3х нажатий всё вырубится (надеюсь) { if (preRelay[CurrentGroup]!=0) digitalWrite(pinRelay[preRelay[CurrentGroup]],0); digitalWrite(pinRelay[masterRelay[CurrentGroup]],0); } else if (digitalRead(pinRelay[dop1Relay[CurrentGroup]])==1 && countdr >= 1) { digitalWrite(pinRelay[dop1Relay[CurrentGroup]],0); } else if (digitalRead(pinRelay[dop1Relay[CurrentGroup]])==0 && countdr==1) { digitalWrite(pinRelay[masterRelay[CurrentGroup]],1); digitalWrite(pinRelay[dop1Relay[CurrentGroup]],1); if (preRelay[CurrentGroup]!=0) { int flagpr=0; for (int p=1; p<=GroupCount; p++) if (preRelay[p]==preRelay[CurrentGroup]) if (digitalRead(pinRelay[masterRelay[p]])==0 || digitalRead(pinRelay[dop1Relay[p]])==0 || digitalRead(pinRelay[dop2Relay[p]])==0) flagpr=flagpr+1; if (flagpr==0) digitalWrite(pinRelay[preRelay[CurrentGroup]],1); } } else if (digitalRead(pinRelay[dop2Relay[CurrentGroup]])==1 && countdr == 2) { digitalWrite(pinRelay[dop2Relay[CurrentGroup]],0); } else { digitalWrite(pinRelay[masterRelay[CurrentGroup]],1); digitalWrite(pinRelay[dop1Relay[CurrentGroup]],1); digitalWrite(pinRelay[dop2Relay[CurrentGroup]],1); if (preRelay[CurrentGroup]!=0) { int flagpr=0; for (int p=1; p<=GroupCount; p++) if (preRelay[p]==preRelay[CurrentGroup]) if (digitalRead(pinRelay[masterRelay[p]])==0 || digitalRead(pinRelay[dop1Relay[p]])==0 || digitalRead(pinRelay[dop2Relay[p]])==0) flagpr=flagpr+1; if (flagpr==0) digitalWrite(pinRelay[preRelay[CurrentGroup]],1); } } break; case 3: //Переключение бегущей волной из двух реле. На первом нажатии кнопки врубается мастер реле (само собой, если надо, то и предмастер), на втором нажатии подключается доп1 реле, на третье - мастер вырубается, подрубается доп2, на четвёртом - вырубается доп1, ну и на пятом - всё выключается, если доп реле в конфигураторе 2, то всё закончится раньше. Да, и предмастер тоже отслеживается. countdr=0; //Считаем количество доп реле в группе if (dop1Relay[CurrentGroup]!=0 && dop2Relay[CurrentGroup]==0) {countdr=1;} if (dop1Relay[CurrentGroup]!=0 && dop2Relay[CurrentGroup]!=0) {countdr=2;} Serial.print("countdr ");Serial.println(countdr); // Опять одно длинное условие, которое тоже должно предусматривать вмешывание другого канала в наш... пусть всё вырубится, главное не повешать дуинку if ((digitalRead(pinRelay[masterRelay[CurrentGroup]])==1 && digitalRead(pinRelay[dop1Relay[CurrentGroup]])==1 && countdr==1) || (digitalRead(pinRelay[masterRelay[CurrentGroup]])==1 && digitalRead(pinRelay[dop1Relay[CurrentGroup]])==1 && digitalRead(pinRelay[dop2Relay[CurrentGroup]])==1 && countdr==2) ) { if (preRelay[CurrentGroup]!=0) digitalWrite(pinRelay[preRelay[CurrentGroup]],0); digitalWrite(pinRelay[masterRelay[CurrentGroup]],0); } else if (digitalRead(pinRelay[masterRelay[CurrentGroup]])==0 && digitalRead(pinRelay[dop1Relay[CurrentGroup]])==1) { digitalWrite(pinRelay[dop1Relay[CurrentGroup]],0); } else if (digitalRead(pinRelay[masterRelay[CurrentGroup]])==0 && digitalRead(pinRelay[dop1Relay[CurrentGroup]])==0 && digitalRead(pinRelay[dop2Relay[CurrentGroup]])==1 && countdr==2) { digitalWrite(pinRelay[masterRelay[CurrentGroup]],1); digitalWrite(pinRelay[dop2Relay[CurrentGroup]],0); } else if (digitalRead(pinRelay[masterRelay[CurrentGroup]])==1 && digitalRead(pinRelay[dop1Relay[CurrentGroup]])==0 && digitalRead(pinRelay[dop2Relay[CurrentGroup]])==0 && countdr==2) { digitalWrite(pinRelay[dop1Relay[CurrentGroup]],1); } else if (digitalRead(pinRelay[masterRelay[CurrentGroup]])==1 && digitalRead(pinRelay[dop1Relay[CurrentGroup]])==1 && digitalRead(pinRelay[dop2Relay[CurrentGroup]])==0 && countdr==2) { digitalWrite(pinRelay[dop2Relay[CurrentGroup]],1); if (preRelay[CurrentGroup]!=0) { int flagpr=0; for (int p=1; p<=GroupCount; p++) if (preRelay[p]==preRelay[CurrentGroup]) if (digitalRead(pinRelay[masterRelay[p]])==0 || digitalRead(pinRelay[dop1Relay[p]])==0 || digitalRead(pinRelay[dop2Relay[p]])==0) flagpr=flagpr+1; if (flagpr==0) digitalWrite(pinRelay[preRelay[CurrentGroup]],1); } } else if (digitalRead(pinRelay[masterRelay[CurrentGroup]])==0 && digitalRead(pinRelay[dop1Relay[CurrentGroup]])==0 && countdr==1) { digitalWrite(pinRelay[masterRelay[CurrentGroup]],1); } else if (digitalRead(pinRelay[masterRelay[CurrentGroup]])==1 && digitalRead(pinRelay[dop1Relay[CurrentGroup]])==0 && countdr==1) { digitalWrite(pinRelay[dop1Relay[CurrentGroup]],1); if (preRelay[CurrentGroup]!=0) { int flagpr=0; for (int p=1; p<=GroupCount; p++) if (preRelay[p]==preRelay[CurrentGroup]) if (digitalRead(pinRelay[masterRelay[p]])==0 || digitalRead(pinRelay[dop1Relay[p]])==0 || digitalRead(pinRelay[dop2Relay[p]])==0) flagpr=flagpr+1; if (flagpr==0) digitalWrite(pinRelay[preRelay[CurrentGroup]],1); } } else { digitalWrite(pinRelay[masterRelay[CurrentGroup]],1); digitalWrite(pinRelay[dop1Relay[CurrentGroup]],1); digitalWrite(pinRelay[dop2Relay[CurrentGroup]],1); if (preRelay[CurrentGroup]!=0) { int flagpr=0; for (int p=1; p<=GroupCount; p++) if (preRelay[p]==preRelay[CurrentGroup]) if (digitalRead(pinRelay[masterRelay[p]])==0 || digitalRead(pinRelay[dop1Relay[p]])==0 || digitalRead(pinRelay[dop2Relay[p]])==0) flagpr=flagpr+1; if (flagpr==0) digitalWrite(pinRelay[preRelay[CurrentGroup]],1); } } break; case 4: //Вкл всей группы. Без коментариев. if (preRelay[CurrentGroup]!=0) digitalWrite(pinRelay[preRelay[CurrentGroup]],0); digitalWrite(pinRelay[masterRelay[CurrentGroup]],0); digitalWrite(pinRelay[dop1Relay[CurrentGroup]],0); digitalWrite(pinRelay[dop2Relay[CurrentGroup]],0); break; case 5: //Выкл всей группы, но с проверкой на предмастер реле, вдруг оно нужно другому каналу if (CurrentGroup != 0) { digitalWrite(pinRelay[masterRelay[CurrentGroup]],1); digitalWrite(pinRelay[dop1Relay[CurrentGroup]],1); digitalWrite(pinRelay[dop2Relay[CurrentGroup]],1); if (preRelay[CurrentGroup]!=0) { int flagpr=0; for (int p=1; p<=GroupCount; p++) if (preRelay[p]==preRelay[CurrentGroup]) if (digitalRead(pinRelay[masterRelay[p]])==0 || digitalRead(pinRelay[dop1Relay[p]])==0 || digitalRead(pinRelay[dop2Relay[p]])==0) flagpr=flagpr+1; if (flagpr==0) digitalWrite(pinRelay[preRelay[CurrentGroup]],1); } } else //а вот это самое интересное, здесь одним нажатием выключается всё освещение, при этом в начале я по дефолту брал 32 канал, как бы по честному я решил для себя, что на 32-ром реле я сделаю управление компом-хоум сервером и в этот блок я для себя допишу ещё и отключение ПК 32-рым реле { for (int s=1; s <= GroupCount; s++) digitalWrite(pinRelay[s],1); } break; } // а тут я прикрутил таймер, сам толком не понимаю как я это выдумал, но зато всё работает. даже предусмотрел условие, что если вы сперва включите канал, при этом реле-условие будет выключено (перед свитч стоит детектор такого события), а чуть позже (в течении вермени temerGroup) включите реле-условие, то этот детектор сбросится и канал будет работать дальше, не отключаясь for (int z=1; z <= GroupCount; z++) { if (timerRelay[z] != 0 && rtimeGroup[z] != 0) { if (digitalRead(pinRelay[timerRelay[z]])==0) {rtimeGroup[z]=0;} } if (timerRelay[z] != 0 && rtimeGroup[z] == 0 && (digitalRead(pinRelay[masterRelay[z]])==0 || digitalRead(pinRelay[dop1Relay[z]])==0 || digitalRead(pinRelay[dop2Relay[z]])==0)) { if (digitalRead(pinRelay[timerRelay[z]])==1) {rtimeGroup[z]=millis();} } } } } }
От себя хочу сказать, что хотелось бы подключить и дисплей и сделать возможность конфигурации с кнопок на корпусе устройства на дин роейку, собранного из германских реле, да и радио пульт прикрутить, и веб сервер поставить, да и вообще светом управлять с телефона, Честно хочу, но не вижу в этом смысла, да и нет на это время. Основную задачу для себя я выполнил ещё вчера. Цена данного контроллера думаю будет составлять от 30$ до 50$, в зависимости от качества комплектующих.
P.S. Если б я смог загуглить готовое адекватное устройство даже за 10-15 килорублей я б его проще купил.
для первого опыта неплохо, но сознайтесь, вы ведь программировали и раньше? а если да. то легко поймете справедливость того. что написано ниже
Код очень избыточен. Советую открыть для себя процедуры и функции. Повторяющиеся группы операторов - признак говнокода....
Вот это вот повторяется в коде 8 раз (написано, кстати. в пиндо-стиле - куча операторов без скобок, рано или поздно вы пожалеете об этом)
а вот эти строчки - 6 раз
В итоге логика программы ускользает от взгляда при таком многократном дублировании кода. думаю. скетч можно легко сократить раз в 4, тем более что задача включения 32 реле по 64 кнопкам явно не требует такого количества операторов.
А чё не в "Проектах"?
Скорее кодил, на турбо паскале, пхп, баше, но не на си. Я ж написал, в ардуино я ноль, разбираться как правильно определять процедуры и функции я не стал. Я просто решил задачу в кратчайшие сроки, просто время дышит мне в спину. И да, управлять всеми реле, это не проблема. Главная задумка в объединении реле в группы. Можно и обучалку приделать и данные в еепром писать. Если б я делал устройство на продажу или за деньги на сторону, всё было бы иначе. На данный момент скетч проверен и работает. Главное при программировании учесть все грабли, что я максимально сделал. Чуть позже опишу ограничения на конфиг. массивов инициализации. И да, другие версии скетча появятся не ранее 2х месяцев. Сперва обкатаю всё в реальных условиях эксплуатации.
Будете дальше развивать - обязательно подробно распишите, в чем смысл этих групп. Честно говоря. из ваших разъяснений в первом посте я так и не поял. зачем они нужны. Полез в код, чтобы посмотреть там, но код настолько "непрозрачный", что ничего не обьясняет.
Хорошо бы все это не глючило. Вы на столе испытывали или проверялось, когда все элементы на своих местах и соответсвующей длиной проводов?
Будете дальше развивать - обязательно подробно распишите, в чем смысл этих групп. Честно говоря. из ваших разъяснений в первом посте я так и не поял. зачем они нужны. Полез в код, чтобы посмотреть там, но код настолько "непрозрачный", что ничего не обьясняет.
Сам код вообще не важен, главное понять как писать конфиг в первые массивы.
Один очень просто пример, который и заставил меня объединять реле в группы:
Представьте, что у вас есть 1 люстра, у которой 2 режима. (наверное у всех были такие в детсве, одну кнопку включил - зажглось 2 лампы на люстре, вторую кнопку - ещё 4 лампы, обе включил - все 6 ламп горит). Вот такую люстру я буду подключать на 2 реле. А если я захочу управлять люстрой одной клавишей? Тогда мне и поможет объединение реле в группу.
А если у вас 3 зоны освещения в комнате (2 бра и люстра), и 4 выключателя (1 на входе, 1 прикроватный, по одному около бра), и вы не хотите вставть с кровати для передвижения к выключателям? Делаем 4 группы:
1 группа - реле люстры (реле номер1), 1-вый режим (режим переключения вкл/выкл)
2 группа - реле бра1 (реле номер2), 1-вый режим (режим переключения вкл/выкл)
3 группа - реле бра2 (реле номер3), 1-вый режим (режим переключения вкл/выкл)
4 группа - в неё пихаем все три вышеупомянутых реле и делаем 5-тый режим (режим отключения группы)
Остаётся только распихать по клавишам данные режимы (внизу пример конфига для описанной ситуации), последним массивом первые 4 кнопки привязваем к 4-рём группам.
И да, во всём этом - главное идея, можно сделать больше групп, можно описать больше действий, можно в группе добавить количество реле, добавить таймер отложенного включения, прикрутить матрицу кнопок по схеме с подтяжкой пинов к +5 вольтам и установкой диодов, тем самым повысив устойчивость к помехам и обеспечив гарантированные срабатывание нескольких кнопок одновременно, при этом можно будет использовать обычные выключатели с фиксацией и отрабатывать одной кнопкой два события (кнопка нажата и кнопка отпущена)...
Хорошо бы все это не глючило. Вы на столе испытывали или проверялось, когда все элементы на своих местах и соответсвующей длиной проводов?
Полностью согласен. Отчасти эта тема не даром в разделе для новичков. Дабы на проект это совсем не тянет. Через пару месяцев я обкатаю данную схему в реальных условиях и уже смогу полностью рассказать о всех глюках данной связки. Скорее всего я допишу ещё несколько режимов управления группам. Собиру всё в кучу, нарисую схему подключения матрицы кнопок и создам тему в проектах (если данная тема вообще будет кому-либо интересна).
Да и обсуждения на форуме помогут скорректировать дальнейшее развитие собственной идеи.
Код, канеш, как в страшном сне. Крофь из глаз.
Код, канеш, как в страшном сне. Крофь из глаз.
Сам в шоке. Зато могу точно сказать, что для новичка больше половины всех кодов дедушек вызывает не менее кошмарные ощущения (не все новички могут работать с классами, функциями, процедурами, объектно-ориентированным програмированием). Я ж не пришёл сюда уится писать на ардуино ide, я тут просто поделился идеей. Конечно я осознаю, что в принципе я мог почитать кучу инфы по программированию на С, создать класс группы реле, в этот классе прописать все данные с массивов инициализации, и даже отслеживать переменные не по сигналам с пинов контроллера, а по переменным, привязанным к классу. Я как бы админ с большим стажем. Когда начинаются такие вещи, первый вопрос в голове, а сколько ресурсов на данной плате, а не переполню ли я оперативку, а не получится ли ещё что-нить... 3 дня назад я первый раз в жизни воткнул ардуину к компу и совсем не претендую на звание "писатель года", так что тролинг про код мне по барабану. Когда я пишу код, я пытаюсь отловить максимум Багов, которые могут возникнуть в результате выполнения программы. Вот этот говнокод работает именно так, как я задумал. На сколько грабель я наступил с объявлением переменных я даже не буду рассказыать, на сколько бы грабель я наступил внедряя красивый код с классами, функциями и процедурами я даже не хочу представлять. Если не дай Бог я начну увлекаться этими штуками, мне физически не хватит время на многое другое...
Вот этот говнокод работает именно так, как я задумал.
Если б ты тока знал, как жестоко ты ашыбаешься.
Вот этот говнокод работает именно так, как я задумал.
Если б ты тока знал, как жестоко ты ашыбаешься.
Если бы ты только знал, сколько комбинаций я опробовал, пока тестировал этот код. Как бы объяснить, кто такой админ: я тот самый суровый админ, у которого аптайм некоторых серверов более года, а некоторых приближается к двум годам. Любое своё действие, которое может навредить серверакам, я должен взвешивать и проверять. Прежде, чем залить этот скетч, эти реле у меня перещёлкивали не одну сотню раз. Для меня самый главный враг-это юзер, именно он делает такие штуки, которые не один вирус не воспроизведёт и любое своё деяние я проверяю много много раз. Так что КОД рабочий, елси правильно сконфигурировать массивы, то контроллер будет отрабатывать всё именно так, как задуманно.
Ну и чтобы просто так не постить всякой перепалки, немного инфы для тех, кому данный скетч может пригодиться:
Главное ограничение конфигурации: НИ В КОЕМ СЛУЧАЕ реле, объявленные в массиве preRelay не должны встречаться в массвах masterRelay, dop1Relay, dop2Relay. И ещё, если в группе будут объявлены masterRelay и dop2Relay, при этом dop1Relay == 0 режимы 2и3 работать не будут. Точно так же, если объявлены dop1Relay и dop2Relay, при этом masterRelay == 0. Это единственные ограничения, которые я породил своим говнокодом. Позже я допилю код, вставлю в void setup() функцию (вернее говнокод) проверки конфигурации, которая будет удалять из массивов masterRelay, dop1Relay, dop2Relay реле, объявленные в массиве preRelay и переформировывать массивы как положено.
Если бы ты только знал, сколько комбинаций я опробовал, пока тестировал этот код. Как бы объяснить, кто такой админ: я тот самый суровый админ, у которого аптайм некоторых серверов более года, а некоторых приближается к двум годам. Любое своё действие, которое может навредить серверакам, я должен взвешивать и проверять. Прежде, чем залить этот скетч, эти реле у меня перещёлкивали не одну сотню раз. Для меня самый главный враг-это юзер, именно он делает такие штуки, которые не один вирус не воспроизведёт и любое своё деяние я проверяю много много раз. Так что КОД рабочий, елси правильно сконфигурировать массивы, то контроллер будет отрабатывать всё именно так, как задуманно.
Ну, мы преклоняемся пред блистающим разумом твоим, Великий.
Но я бы на твоем месте, во всех местах, где ты так адресуешь массивы
for
(
int
p=1; p<=GroupCount; p++)
ничему бы не удивлялся.
Но я бы на твоем месте, во всех местах, где ты так адресуешь массивы
for
(
int
p=1; p<=GroupCount; p++)
ничему бы не удивлялся.
К чему это? Что я делаю не так? Адресую массивы? я их тупо перебираю, при это осознано не затрагивая группу с номером 0 и с учётом того, что я могу в любой момент изменить количество групп, существенно не меня скетч. То есть ты считаешь, что в разделе для новичков можешь сделать такой высер, и тебя все новички поймут и охренеют от твоей мудрости? Вот выше меня нормально ткнули носов в часто повторяющихся инструкций и возможности упращения кода, полностью согласен, а зачем тут такое писать? Что я должен понять из написанного? чему не удивляться? Почему ничему не удивляться? Что это конструкция может натворить? В каком случае произойдёт аннигиляция пространства и времни? Хоть бы ссылку кинул. Типо вот от этого дерьма в твоём коде может получится всякое говно и ссылку.... Я же написал, я 3 дня назад первый раз ардуино к компу прикрутил, что за неконструктивная критика.
Вопросов больше не имею.
пойду, заварю себе.
Ты это, меня не сильно слушай, я тут просто месный дурачок, да еще вечно спахмелья. Шут, одним словом.
То есть ты считаешь, что в разделе для новичков можешь сделать такой высер, и тебя все новички поймут и охренеют от твоей мудрости?
вообще да, я вот например считаю, что Дед может "делать такой высер" - а ты ОБЯЗАН задуматься и попытаться понять, что он имел в виду. Хотя бы потому. что он - опытный программист и давно известен на форуме, а ты новичок, о котором мы ничего не знаем. Точнее не так - ты новичок, про которого мы знаем. что он пишет кривой глючный код.
Слушай DAK. если ты пришел сюда рассказать нам о своейГЕНИАЛЬНОЙ ИДЕЕ управления освещением и готов принимать только мелкие льстивые замечания - ты на этом форуме долго не задержишься. Чтобы укрепится на этом форуме, ты должен доказать, что умеешь не только кричать о своей гениальности, но и принимать критику, умеешь не только предлагать свое - но и выслушивать чужие замечания и учиться на них. И я тебе скажу. что именно это - общение -самое интересное на форуме. А о чем общаться - не так и важно. Сами проекты в большинстве случаев никому нахер не нужны, 99% процентов из самых красивых идей уходят в архив и оказываются забытыми всеми если не через неделю, то через месяц.
Так и твоя система - лишь повод обсудить твой код, а с чисто практической стороны он вряд ли кого заинтересует, 80% здешних обитателей при необходимости напишут подобное за один вечер. Так что если ты не готов подойти к задаче с точки зрения красоты и правильности алгоритма - ты выбрал для публикации неправильную площадку.
Ещё один, да как бы тебе ответить то. У меня нет цели доказывать кому-что либо.... Если честно, то и в архивах нет нихрена полезных проектов. Хоть банте, хоть удаляйте, мне по барабану.
Я ж не пришёл сюда уится писать на ардуино ide, я тут просто поделился идеей.
Когда я писал пост выше - я еще не видел этой фразы и только предполагал твой настрой. Теперь могу сказать прямо - мужик, ты неверно зашел.
Это форум по программированию Ардуино и программированию вообще, а не по системам "умного дома" или, скажем, автосигнализаций. Главное, что всех нас тут держит - интерес к ПРОЦЕССУ программирования, а не к результатам. Твоя идея системы управления может заинтересовать форум только как повод к написанию КРАСИВОГО КОДА. Если же для тебя код не важен - иди предложи свою систему где-нибудь на форуме , посвещенном ремонту квартир и обустройству дач - там почти всегда тусуются любители "умного света" или автоматических вытяжек из клозета...
Если честно, то и в архивах нет нихрена полезных проектов.
так и я о том же. Полезность проекта тут на втором... если не на десятом месте. Направленность площадки другая
То что твоя полезная система реализована кривым глючным кодом - сразу ставит ее ниже плинтуса. А вот напиши ты красивый класс без всякого практического смысла. но с кучей возможностей - будет три страницы обсуждения :)
Я, конечно, утрирую, но в целом все почти так.
Этот форум походу просто даёт возможность дедам програмистам повыпендриваться, я тут много тем почитал, вывод один. Не на тот форум я написал, не на тот. Нахрен я вообще предположил, что кому то взбредёт в голову обсуждать идею. Здесь у вас просто программисты с похмелья от нехер делать развлекаются. Люди с идеями не пишут тут ничего, они просто читают и черпают знания. Но в реале могу одно сказать, всё просто засрано бестолковыми постами, полезной инфы очень мало.
ну почему же? Вот например в соседней ветке ты можешь прочитать, что переполнение миллис не влияет на таймеры. Разве это не полезно для тебя и твоей системы реле?
Я уже почитал, спасибо. А каким образом получить эту полезность? Это просто агонь! Да и мой код никто даже не читал, и коменты про 50 дней там были, и никто ничего не говорил... В соседней ветки просто дед с похмелья решил повыё... А тут кровь у него из глаз пошла... Акуенно, все деды, а парняги элементарные правки в скетч не можете внести. Ну не всем дано, а ему этот скетч по ночам поливает... Противно, реально, одно говно льётся и всё.
Противно, зато не с нас льёцца.
ты совсем чтоль тупой? Твои комменты про 50 дней прочитали - и именно на них был ответ Деда. что ты написал полную фигню. Вполне по делу ответ.
а если ты не в состоянии этого понять - так надо учиться, а Г по конфе разливать
Всё, закройте и удалите тему, забаньте меня, и удалите нахрен с этого ресурса навсегда! Всем удачи.