Не надо мне тыкать. Вы мне никто. Повторяю, не пишите мне. Наговорили уде достаточно для блокировки на любом другом форуме. Здесь к сожалению нет модерации.
Не надо мне тыкать. Вы мне никто. Повторяю, не пишите мне. Наговорили уде достаточно для блокировки на любом другом форуме. Здесь к сожалению нет модерации.
Если мне надо кого то найти я сам нахожу
Общепринятый формат общения на форумах - на ты. Если тебя не устраивает - твои проблемы. Насчёт адреса - только скажи, я сообщу, чтобы не утруждать тебя поисками ;)
Вообще не понимаю, чего ты взъелся - несвежее съел, наверное? Бывает, выпей активированного угля и всё пройдёт. Кстати, не поверишь - я тебя прекрасно понимаю: это очень обидно, когда твои труды начинают критиковать. Однако, мудрый человек примет критику как старт для дальнейшего саморазвития, другой - начнёт переводить стрелки вовне.
Заметь, всё, чего я просил - называть вещи своими именами, не более того. И кстати, тут впомнилось про Википедию - ты не поверишь, какой только чуши там нет, ибо каждый суслик может редактировать статьи. Кстати, статья, цитату из которой ты приводил, носит гордый шильдик "не проверена опытными участниками" ;) Впрочем, для тебя и это не авторитет, ипстественно.
Смотрю на твои посты - в целом грамотный парень, но тебя, по ходу, заносит временами. Учись принимать критику конструктивно, и всё будет зашибись.
Для тех кому не хватает возможности понять самому. Обращение на вы в данном контексте это не комплекс. Это прием русского языка для обозначения дистанции. Я общаюсь на ты лишь с людьми равными по интеллектуальному и культурному уровню, с остальными не общаюсь или общаюсь на "расстоянии".
в данной теме я писал для автора с нормальным проектом значение которого вы пытаетесь принизить доказывая всем, что никто кроме вас не в состоянии писать "крутые" программы. Я писал не для вас. Вас не исправить. У вас потребность что то кому то доказать, но именно доказывать не хватает интеллекта, поэтому опускаетесь до хамства. Мне вас жаль, но это уже я повторяюсь
сделайте усилие над собой. В следующий раз перед тем как что то писать, подумайте не над тем как круто вы будете выглядеть, а о том какую пользу это может представлять для того кому пишите. Шанс у вас есть. Верю
значение которого вы пытаетесь принизить доказывая всем, что никто кроме вас не в состоянии писать "крутые" программы.
Слушай, правдолюб: будь последователен, и покажи мне, плз, где я утверждал, что никто кроме меня не в состоянии писать "крутые" программы? Ты опять порешь чушь, пытаясь выглядеть не гопотой, которая угрожает физической расправой, а якобы культурным воспитанным мальчиком. И это, к слову, у тебя выходит крайне отвратительно.
Не надо приписывать мне слова, которых я никогда не произносил. Если ты этого усвоить не способен, а способен лишь на грязные передёргивания - мне тебя жаль.
Всем привет, столкнулся с проблемой подвисания шилда W5100, напруга стабильная 4,88-4,92 V. Три дня подряд после 8-12 часов работы. Контроллер работает. Что может быть?
Всем привет, столкнулся с проблемой подвисания шилда W5100, напруга стабильная 4,88-4,92 V. Три дня подряд после 8-12 часов работы. Контроллер работает. Что может быть?
По питанию точно проблем нет? Подвисает что именно? Я имею в виду - как вы понимаете, что подвис именно W5100? Возможно, проблема не в железе даже ;) В общем - дайте побольше вводных, и тогда будет полегче разобраться, думаю.
В общем - дайте побольше вводных, и тогда будет полегче разобраться, думаю.
Вначале думал что проблема в меге, создал в void(loop) мигание светодиода, когда железка перестает отвечать диод продолжает мигать, отсюда сделал вывод что подвисает w5100, питание пробовал менять измений нет.
Такая же проблема, как у uservasil, но только в другом проекте. Тоже используется шилд. Точнее перебпробовал на двух шилдах. На WL5100 и на ENC28J60. Второй тоже в виде шилда, только на Нану.
Я использовал в шлюзе MySensors. Тоже подвисает через 2-3 дня. Питание тут скорее всего не при чем, так как работало от упса через сетевой фильтр. По моим ощущениям, его задрюкивают другие устройства в сети. Так как все подключено через свитч, а устройств много >50, то блудняка в эфире много. Вот и не выдерживает Ethernet шилд.
Может кто подскажет что можно сделать. Или хоть как продиагностировать? Я даже не знаю какие еще симптомуы описать... Логов нет. Перестает пинговаться и все. Думаю повесить на него RTC часы и раз в сутки ребутать. Но наверно это не выход...
Такая же проблема, как у uservasil, но только в другом проекте. Тоже используется шилд. Точнее перебпробовал на двух шилдах. На WL5100 и на ENC28J60. Второй тоже в виде шилда, только на Нану.
Я использовал в шлюзе MySensors. Тоже подвисает через 2-3 дня. Питание тут скорее всего не при чем, так как работало от упса через сетевой фильтр. По моим ощущениям, его задрюкивают другие устройства в сети. Так как все подключено через свитч, а устройств много >50, то блудняка в эфире много. Вот и не выдерживает Ethernet шилд.
Может кто подскажет что можно сделать. Или хоть как продиагностировать? Я даже не знаю какие еще симптомуы описать... Логов нет. Перестает пинговаться и все. Думаю повесить на него RTC часы и раз в сутки ребутать. Но наверно это не выход...
зря исключаете питание, это наиболее вероятный источник. шилд вставленный поверз UNO или MEGA питается от стабилизатора ардуины и тот может не потянуть. Может даже сгореть. В моих первых экспериментах с мега и шилдом именно так и произошло. связку ардуино и шилд или шилд отдельно надо питать от хорошего DC-DC. Линейному стабилизатору 250-300ма потянуть сложно, особенно если к ардуине подключено 12в и больше
насчет "блудняка". это не причина. у меня 4-ре гейта mysensors в довольно большой сети с кучей устройств работают без зависаний, уже можно годами измерять. На ENC28J60 но с хорошим питанием
продиагностировать стоит и саму ардуину, запустить какой-то другой скетч или закоментировать работу с шилдом, шилд отсоединить и поставить на несколько дней.
еще причина может быть - скетч. Ардуина не контролирует выход за пределы доступной памяти при работе с переменными. Если скетч требует при работе слишком много памяти то может нарушаться целостность и это может привести к чему угодно, в том числе к зависанию
В моем случае нано + шилд питаются от USB адаптера. Имеет смысл перевешивать питание на Vвх? И как понять, Много ему питания или наоборот мало?
Посмотрел я - Нано выдает 150mA максимум. Лучше наверно отдельно запитать? А ethernet шилд нигде не написано сколько потребляет. Давно как-то экспериментировал, на шилде было написано, 3.3V ему надо. Но завелся только на 5V. А милиампер сколько ему надо - не нашел нигде.
В моем случае нано + шилд питаются от USB адаптера. Имеет смысл перевешивать питание на Vвх? И как понять, Много ему питания или наоборот мало?
Посмотрел я - Нано выдает 150mA максимум. Лучше наверно отдельно запитать? А ethernet шилд нигде не написано сколько потребляет. Давно как-то экспериментировал, на шилде было написано, 3.3V ему надо. Но завелся только на 5V. А милиампер сколько ему надо - не нашел нигде.
основной потребитель на шилде это сам чип. Про wiznrt5100 не смотрел, ENC28J60 требует порядка 250мА. Думаю у wiznet что то типо того же. Я лично считаю, что линейные стабилизаторы для питания ethernet не подходят ну либо надо городить нормальный LM7805 с радиатором. Ибо ни 78M05 который стоит на UNO и MEGA ни тем более AMS1117 который стоит на NANO не могут с запасом обеспечить работу шилда
Лучше, конечно, чуть переписать - зачем дёргать два раз substring, дважды создавая локальные объекты String, если можно это сделать один раз?
Продолжай, проект интересный. Самому интересно, без дураков. Но у меня интерес несколько другого свойства, статистический, так сказать - хочу посмотреть, на чём ты остановишься. Не в плохом смысле (а то опять обвинят ни за что) - а в том смысле - когда увидишь границу применимости такого подхода. Скажу про себя - не далее как сегодня полностью отказался от идеи хранения вебморды на МК, и перевёл всё на простые шлюзы UART-TCP, ибо, как показала практика, не барское это дело - обслуживать вебморду из МК, которая, кстати, может быть ооочень объёмной, плюс ещё и аггрегированной с другими частями умного дома. В малом приближении - да, зашибись и удобно, в большом - начинают жать маленькие ресурсы дуины.
Это я всё к тому - какой у меня к твоему проекту интерес ;) Напоследок - закину удочку: подумай про openWRT, как вариант ;) Тогда МК будет заниматься обслуживанием периферии, а всё управление ардуиной будет через роутер, с жирной вебморды, простыми командами. При необходимости поменять оформление вебморды - не надо будет перезаливать прошивку. Я не нестаиваю на этом варианте как на единственно верном, просто хочу показать ещё один путь для развития проекта.
Да, стало интереснее. Тоже задам пару глупых вопросов:
1-24 каналы - там на них реально что-то висит? По скетчу увидел только три реле. И что будет по "Включить все"?
И по датчикам температуры то же самое. В скетче прописано два - выводит с четырех. Сколько их всего?
Воот, начальник транспортного цеха поднял совершенно справедливые вопросы ;) Которые сразу приводят нас к необходимости, как минимум, автоматического подстраивания внешнего вида вебморды к тому - сколько реально каналов используется в прошивке, сколько датчиков температуры есть и т.п.
К чему пришёл я, когда столкнулся с подобным вопросом: команды, по которым МК отдаёт кол-во датчиков температуры, кол-во датчиков влажности и тому подобные вещи. Как следствие - можно при первом опросе контроллера получить его полный внутренний слепок, так сказать.
В прошивке ТС данную проблему можно решить директивами условной компиляции - и тогда всё будет намного прозрачнее для конечного пользователя прошивки: не придётся искать места, где выпилить кусок кода, если используется не 20 каналов, а всего 5, например.
Лучше, конечно, чуть переписать - зачем дёргать два раз substring, дважды создавая локальные объекты String, если можно это сделать один раз?
3. подумай про openWRT, как вариант ;) Тогда МК будет заниматься обслуживанием периферии, а всё управление ардуиной будет через роутер, с жирной вебморды, простыми командами. При необходимости поменять оформление вебморды - не надо будет перезаливать прошивку.
1. пока ОЗУ не забито, поэтому и не везде, это заметно влияет на скорость ответа.
2. присвоить значение переменной, потом работать с ней?
int comInt = command.substring(3).toInt();
if(comInt>=0&&comInt<=28){}
3. Спасибо за советы, обязательно ознакомлюсь. Пока хочется по максимуму загрузить МЕГУ, а еслу будет поджимать планировал смотреть в сторону промышленных терминалов =)
Artemiy пишет:
1-24 каналы - там на них реально что-то висит? По скетчу увидел только три реле. И что будет по "Включить все"?
И по датчикам температуры то же самое. В скетче прописано два - выводит с четырех. Сколько их всего?
Железка пока на работе, в скором времени переедет на дачу где установлено инфракрасное отопление, 3 реле которые управляются заданием требуемой температуры, каналы 1-24 будут подключены к освещению (14-16 каналов) и к некотороым розеткам и т.д.. В данный момент подключено 3 датчика температуры, в недалеком будущем их будет около 10-13 которые будут отображать температуру на улине, помещений, бани, парилки, дымоходной трубы, воды холодной и горячей и т.д. В перспективе подключить солнечный коллектор, насос, датчики давления и расхода воды, и многое другое =)
Очень громоздкий html, на мой взгляд. Да ещё и помешено определение стилей в заголовке и в самих тэгах. Большое кол-во одинаковых строк было бы компактнее скриптом формировать, инача eeprom скоро кончится. :) Но, коли это домашнее устройство и используется шилд WizNet, у которого на борту TF ридер, уж лучше на туда всё запихать, установив карточку на 2 гига. :)
Очень громоздкий html, на мой взгляд. Да ещё и помешено определение стилей в заголовке и в самих тэгах. Большое кол-во одинаковых строк было бы компактнее скриптом формировать, инача eeprom скоро кончится. :) Но, коли это домашнее устройство и используется шилд WizNet, у которого на борту TF ридер, уж лучше на туда всё запихать, установив карточку на 2 гига. :)
Что вы имели ввиду под выражением eeprom скоро кончится объясните пожалуйста, запихать в карту html нет желания в виду его медленной работы
Очень громоздкий html, на мой взгляд. Да ещё и помешено определение стилей в заголовке и в самих тэгах. Большое кол-во одинаковых строк было бы компактнее скриптом формировать, инача eeprom скоро кончится. :) Но, коли это домашнее устройство и используется шилд WizNet, у которого на борту TF ридер, уж лучше на туда всё запихать, установив карточку на 2 гига. :)
Что вы имели ввиду под выражением eeprom скоро кончится объясните пожалуйста, запихать в карту html нет желания в виду его медленной работы
Объём eeprom очень невелик. Пока оно у Вас вмещается, вроде, а потом аппетиты вырастут и опаньки. :)
Чтобы не постарадать от медленности TF карты, есть простой путь: грузить на клиента сразу все страницы в одном html, при этом ненужные display: none. Далее включать/выключать страницы, а не тянуть их каждый раз из дуни, и скриптом читать данные и заносить в поля страниц.
грузить на клиента сразу все страницы в одном html, при этом ненужные display: none. Далее включать/выключать страницы, а не тянуть их каждый раз из дуни, и скриптом читать данные и заносить в поля страниц.
На клиента грузится сразу весь код, при нажатии на открытие окна оно всплывает а не грузится с дуни. Про скриптом заносить в поля это я так понимаю про Ajax, который я еще не освоил. Аппетиты а данном проекте по моему уже доходят до конца) и вряд ли еще чем то будет забиваться eeprom, кстати подскажите как узнать объем занятой/свободной памяти eeprom?
На клиента грузится сразу весь код, при нажатии на открытие окна оно всплывает а не грузится с дуни.
Замеряли скорость отдачи контента с дуни в браузер? Что получилось? Удивите меня и скажите, что у вас получилось больше 10 Кб/с. Именно по этой причине я отказался от затеи держать вебморду на МК, который, собственно, совершенно к этому не приспособлен.
Думаю, и вы со временем придёте к такому же решению ;)
Никаких аякс и жиквери - зачем Вам чужие глюки? :) Я говорю о getElementById('...').value и innerHTML. Страница сидит в клинте постоянно, а обновлением данных и обменом с дуней занимается скрипт.
Как Вы храните HTML - в виде массива в eeprom? Так дунина иде вам после компиляции расскажет какой памяти и сколько поедено.
Кстати, для своих нужд написал молотилку, которая из HTML убирает лишние пробелы форматирования и создаёт массив. Если необходимо, могу выдать тут.
На клиента грузится сразу весь код, при нажатии на открытие окна оно всплывает а не грузится с дуни.
Замеряли скорость отдачи контента с дуни в браузер? Что получилось? Удивите меня и скажите, что у вас получилось больше 10 Кб/с. Именно по этой причине я отказался от затеи держать вебморду на МК, который, собственно, совершенно к этому не приспособлен.
Думаю, и вы со временем придёте к такому же решению ;)
Миллионы устройст на МК имеют web-интерфес. Почему МК для этого не приспособлен? Даже 10кБ/с вполне достаточно, ибо в эти 10 кБ всё может и поместиться. А и удивать Вас легко - не отдавайте страницы через print по одному символу на ethernet пакет и передачей fin каждый раз, используя кривые библиотеки дуни, а формируйте IP пакеты самостоятельно по 1кБ и потелит оно ого-го как. :) К тому же измерение скороти загрузки мелких страниц может обманывать, засекая сколько за секунду пролетело, а не сколько времени ушло на обмен. :)
Миллионы устройст на МК имеют web-интерфес. Почему МК для этого не приспособлен? Даже 10кБ/с вполне достаточно, ибо в эти 10 кБ всё может и поместиться. А и удивать Вас легко - не отдавайте страницы через print по одному символу на ethernet пакет и передачей fin каждый раз, используя кривые библиотеки дуни, а формируйте IP пакеты самостоятельно по 1кБ и потелит оно ого-го как. :) К тому же измерение скороти загрузки мелких страниц может обманывать, засекая сколько за секунду пролетело, а не сколько времени ушло на обмен. :)
Вы опять чисто пофиздеть зашли? Ну что-ж, не впервой, стерплю и на этот раз :) Миллионы устройств на МК типа Ардуины? Примеры в студию, плз. И не страничку в 500 байт с одной кнопкой - а нормальную такую вебморду объёмом хотя бы как у автора темы.
По поводу "не отдавайте страницы через print по одному символу на ethernet пакет" - не надо мерить людей по себе и держать их за идиотов.
"и потелит оно ого-го как" - вот именно, что потелит, а вот летать - никогда не сможет. Я, конечно, понимаю, что мсье великий теоретик и зашёл сюда чисто так, пальцами погнуть, но всё же осмелюсь задать вопрос: сами-то пробовали поднять жирную вебморду на дуне? Пускай даже на относительно медленной SD (читать оттуда)? Какими скоростями отдачи на канальном уровне можете похвастать? 10, 20, 30, 40, 50 КБ/с?
Давайте так: возьмите всего навсего текстовый файлик в 500 Кб и выдавайте его по Ethernet с SD-карты. Субьективную скорость вполне себе можно замерить, высокая точность нам не нужна, достаточно даже порядка. Вот как получите результаты - приходите, и расскажите, как оно "потелит оно ого-го как".
У автора - совсем не дебильный интерфейс века эдак девятнадцатого - а вполне себе нагруженный и современный. С такими хотелками он быстро упрётся в ограничения используемого камня и поймёт, что не место вебморде на дуне. Вот если бы STM32 - тогда я бы тут и не базлал по этому поводу.
Миллионы устройст на МК имеют web-интерфес. Почему МК для этого не приспособлен? Даже 10кБ/с вполне достаточно, ибо в эти 10 кБ всё может и поместиться. А и удивать Вас легко - не отдавайте страницы через print по одному символу на ethernet пакет и передачей fin каждый раз, используя кривые библиотеки дуни, а формируйте IP пакеты самостоятельно по 1кБ и потелит оно ого-го как. :) К тому же измерение скороти загрузки мелких страниц может обманывать, засекая сколько за секунду пролетело, а не сколько времени ушло на обмен. :)
Вы опять чисто пофиздеть зашли? Ну что-ж, не впервой, стерплю и на этот раз :) Миллионы устройств на МК типа Ардуины? Примеры в студию, плз. И не страничку в 500 байт с одной кнопкой - а нормальную такую вебморду объёмом хотя бы как у автора темы.
По поводу "не отдавайте страницы через print по одному символу на ethernet пакет" - не надо мерить людей по себе и держать их за идиотов.
"и потелит оно ого-го как" - вот именно, что потелит, а вот летать - никогда не сможет. Я, конечно, понимаю, что мсье великий теоретик и зашёл сюда чисто так, пальцами погнуть, но всё же осмелюсь задать вопрос: сами-то пробовали поднять жирную вебморду на дуне? Пускай даже на относительно медленной SD (читать оттуда)? Какими скоростями отдачи на канальном уровне можете похвастать? 10, 20, 30, 40, 50 КБ/с?
Давайте так: возьмите всего навсего текстовый файлик в 500 Кб и выдавайте его по Ethernet с SD-карты. Субьективную скорость вполне себе можно замерить, высокая точность нам не нужна, достаточно даже порядка. Вот как получите результаты - приходите, и расскажите, как оно "потелит оно ого-го как".
У автора - совсем не дебильный интерфейс века эдак девятнадцатого - а вполне себе нагруженный и современный. С такими хотелками он быстро упрётся в ограничения используемого камня и поймёт, что не место вебморде на дуне. Вот если бы STM32 - тогда я бы тут и не базлал по этому поводу.
При чём тут дуня? Вы же говорили об МК, который по совпадению и в дуне используется. К тому же, дуни бывают разные, можно переехать на 2560, а то и на DUE. Примеры? Да как-то мало на ум приходит, разве что все сетевые устройства... :) Возможно, среди МК низкого т.с. уровня, WEB-управление ещё не стало модным, ибо громоздкое оно, достаточно неудобное, корявое, неочевидное, много засад, безусловно, но дело времени. И сам не раз матюкался - написать экзеху для управления было бы в 100 раз быстрее.
Для скорости есть одно ораничение - скорость SPI по которому отдаётся на сетефой интерфейс поток. Но оно значительо больше 10 и даже 50 кБ/сек. А давно ли интерент стал быстрее 2-х МБит/с и часто ли сайты отдают более 2-х МБит/с на сокет? Исли не гонять страницы, не устраивать на МК аппачь с пхп, то совершенно неощитимо тормозов.
Я не эмперик по складу ума, меня не убеждает чей-то опыт, не имеющий обоснования. Со скоростью web-интерфейса я не заморачиваюсь, ибо мне не важно будет страница полсекунды загружаться или 2 секунды. Да и работать оно будет в фоне. Для меня было важно проверить скорость ModbusTCP. Сколько Сименс попросил в непрерывном цикле, столько мега 328-я ему и ответила. И оказалось не меньше, чем другой Сименс. Запрашивал запись поряд 16 32 битных регистров и возврат их же. Буквально наковырял кусок корявого кода лишь бы проверить, порадовася и выбросил. И это, кстати, на WizNet, у которого непонятно что внутри творится и дуниной библлиотекой еще более тёмной.
А что STM32? Прикрутить к нему сетевой интерфейс с DMA? Сколько оно стоить будет?
Я считаю совершенно номальным web-интерфейс для МК, особенно, если есть возможность использовать TF карту - можно туда налепить и картинок и библиотек. В моём случае карточка не неприменима, стараюсь писать компактно, возможно, придётся упаковать, если получится много и всё это вложить в флэшку 2560. Пока не приехал STM32F403... :)
Я считаю совершенно номальным web-интерфейс для МК, особенно, если есть возможность использовать TF карту - можно туда налепить и картинок и библиотек. В моём случае карточка не неприменима, стараюсь писать компактно, возможно, придётся упаковать, если получится много и всё это вложить в флэшку 2560.
Вот когда налепите, когда размер вебморды вылезет килобайт за 500, когда будут картинки всякие, подключаемые CSS и т.п. - тогда скажете, как оно - быстро или нет. А пока все ваши излияния - бла бла бла, ничего не имеющее с практикой. К тому же заметил у вас странную тягу к путанию круглого с мягким, причём постоянно - ему про одно, он - совершенно про другое, приплёл сюда зачем-то Modbus over TCP. Мы вообще-то совершенно о другом говорим, если вы не заметили. Да, на каком-то уровне модели OSI мы утыкаемся в TCP, но речь, повторюсь, идёт не о TCP вовсе, а совсем даже о другом.
Что такое вебморда - понимаете? По какому протоколу работает - понимаете? Что такое вебморда сложнее одного некрупного файла - понимаете?
Ещё раз, для тугих: вебморду можно поднять на дуне, на практически любой дуне. Я не ставлю вопрос как "можно" или "нельзя" - я поднимаю вопрос о целесообразности данной затеи в век, когда есть дешёвые роутеры, на которые можно накатить openWRT и радоваться мегабитным скоростям и отсутствию ограничений на размер вебморды. Дуня при этом - откликается на простые запросы, типа "дай-ка мне, любезная, слепок внутреннего состояния" или "а ну ка, милая, выполни вот эту команду" - и всё.
Я через это уже прошёл - была и вебморда на SD, и вебсервер был реализован с корректной обработкой запросов и пакетной выдачей результатов (это к слову о побайтовой выдаче, упомянутой вами) - не понравилось. Скорость не та - требования у меня, наверное, завышенные, но я хочу видеть нормально работающую и современно выглядящую морду, а не убогое чудовище.
Потом: никакая масштабируемость и отсутствие аггрегирования как класса. Накой мне к каждому контроллеру стучаться, чтобы получить данные на вебморде? А если их (контроллеров) будет десяток? Десять адресов и десять вебморд? Нахер сразу. Именно для этого и есть решения типа openWRT, под которым можно развернуть аггрегатор, со своей БД и нормальной мордой.
А МК - должен заниматься тем, для чего он, собственно, и предназначен - обслуживанием периферии, всё. Остальное - от лукавого.
В общем, как обычно, каждый останется при своих. Спорить по этому поводу мне совершенно не интересно, я лишь высказал свой взгляд на вещи, обращаясь не к вам, а к ТС - подсознательно надеясь, конечно, что буду услышан. Впрочем, каждый должен сам наступить на грабли, тут я никого не отговариваю. Да и слежу за темой скорее из-за того, чтобы не пропустить тот момент, когда автору станет тесно с вебмордой на дуне. Но, скорее всего, он поступит по-другому - удовлетворится тем, что есть. Однако, не буду домысливать за него - время покажет.
Чувствуется плохое понимание работы т.с. транспортов и оптимизации их задач... :))) МК не интернет-магазин, не живой т.с. сайт, в нём web-интерфейс для управления и весёлый картинки в нём даже нежелательны. Зачем что-то подключать? И что подключать? Кличество сокетов очень невелико в МК и достаточно затратно их плодить, загружать в МК сраницу с подключемыми в виде отдельных файлов стилями и скриптами глупо, ибо эксплорер полезет в несколько потоков их грузить, пытаясь создать отдельные сокеты. Для web интерфейса MK необходимо отдельной молотилкой, преобразовывать создаваемые страницы, стили и крипты в один файл. Писать в один файл всё сразу неудобно при разработке, но удобно сделать несложную экзешку которая перемолотит. Пролема с сокетами решена: потребуются всего 2: на саму html со всеми описаниями и на favicon, котрую эксплорер будет всё равно искать. И решена проблема с загрузкой страниц - они уже все на клиенте и переключаются, а не грузятся.
А про openРазные здрово, безусловно... Я продам устройство потребителю, и сообще ему, что надо бы ещё роутер прикупить, залить в него кое-чего для счастья. И не простой роутер, а золотой т.е. с поддержкой офигительной фичи. :))) Странно, почему производители сетевых устройст до этого ещё не додумались и лепят в каждый экземпляр персональный web интерфейс... Дикари! Оформляйте патент с openWRT скорее. :) Сосвсем не думают о людях, которые потом кучу этих устроств в сеть поставят и будут управлять ими, открывая на каждом web интерфейс, не понимая, что это лишь персональная ковырялка для одиночного использования или первоначальной настройки, чаще всего, лишь адреса. :)))
Опять бла бла, и опять - мыши плакали, кололись, но продолжали жрать кактус вместо того, чтобы выкинуть веб-интерфейс из МК, который для этого не предназначен. Вместо этого - надо кучу плясок с бубном: что-то там объединить, перемолотить, забить кувалдой. Я же говорю - теоретик.
Насчёт openWRT - поверьте, никаких сложностей в поставке роутера с прошитым и настроенным openWRT в составе конечного продукта - нет, от слова вообще.
Конечно, кому не нужна масштабируемость, не нужно аггрегирование - пусть его балуются с отдельной вебмордой на каждом МК: и такое имеет право на жизнь, не отрицаю. Просто я смотрю на автора темы и вижу, что по сути задачи, которые он решает - это некий прообраз системы умного дома. Для которой - ну совершенно глупо и неоправдано держать всю вебморду на одном МК, который, к тому же, занимается обслуживанием периферии. Налицо смешение мух с котлетами.
И вообще - прекращайте пороть чушь, у вас это, похоже, в крови - как чего ни скажете, так словно в лужу пёрнули. Это я относительно сентенций "Странно, почему производители сетевых устройст до этого ещё не додумались и лепят в каждый экземпляр персональный web интерфейс". Вы не поверите - но в современных сетевых устройствах, например, тех же роутерах - стоит вполне себе *nix-операционка, openWRT, собственно - из той же оперы. Так кто дикарь - вы, безграмотный, или производители?
МК имеет интерфейс и протокол, по которому отдаёт сырые данные или данные определённого формата, возможно, не один - бери чем хочешь и агрегатируй как хочешь. МК имеет внутри себя html код, кторый возможно загрузить в экплорер, который берёт те же самые сырыи данные и приводит к удобному для оператора виду, на случай если одинокий МК используется или что-то несложилось при интеграции в систему. Это уже настолько очевидное и распространённое решение, что и напоминать о нём неловко. И уж тем более слюни лить за обиду и пытаться чем-то уколоть меня. :)))
Агрегатировать несколько устройст умного дома, запросто можно простой страницей с <iframe>, например. :)
Будущее систем управения в уходе от централизации. Этот путь уже прошли "апаратчики", когда процессор всё сам делал, выступая и кунецом, и жнецом. Теперь переферия стала умной и почти всё делает самостоятельно. Точно так же устройства "умных домов" будут свои задачи решать самостоятельно, в т.ч. и по отображению информации, общаясь друг с другом системой сообщений.
P.S. МК - это не только Мега328. Малому МК - малый интерфейс, от каждого по возможности.
P.S.2. Ждать всемогущего властителя в центре и рулить всем подряд - это, похоже, менталитет такой. :))) P.S.3. Какие тут все крутые, бляха муха, да обидчивые... Прям как с девочками... :)))
Тут крутой только вы, по ходу. И в своей крутости пороть чушь - вам нет равных, это точно! Какая, нахер, аггрегация с iframe? Вы хоть понимаете значение этого термина, млять?
Надоело с воинствующим дилетантом разговаривать - бессмысленно. Чао.
Дааа... Поднабралось бабёх трепливых - чуть что, чуть сказать нечего по делу, обидки и личные оскорбления. :))) А аргументы - нафига, мои можно не заметить скромно, своих всё равно нет. Проще же фыркнуть. Ржунемагу тут с некоторых. :)))
См. Вики, чтобы не быть голословным, в отличии от некоторых баб тут: Агрегация или агрегирование (лат. aggregatio «присоединение») — процесс объединения элементов в одну систему.
Простейшей объединённой системой, совершенно очевидно, можно считать вывод информации от нескольких элементов на единый монитор (не путать с экраном ПК). Если каждый элемент системы имеет свой самостоятельный web интерфейс, вполне возможно создать страницу, в котрой несколькими тегами <iframe> загрузить интефейсы с каждого устройства на одну страницу, каждый в своё подокошко. В итоге страница агрегирует вывод информации в единое окно отображения. Возражения есть?
А для тупорылых добавлю - там смайлик был в конце фразы. Вот такой :)
P.S. Вы бы уже объединились, обсудили какой я нехороший, толпой бы поорали - девочки так ведь делат? В форуме не знаю сколько человек, но есть один хамуга пустобрёх, один выскочка, один советчик уровня чайника, и изобретатель системы продаж маршрутизаторов внагрузку. Все четвера на меня зуб точат, идинаково умеют против аргументов лишь сопли лить. Ржунемагу! :)))
такой вопрос, делаю управление освещением с помощью кнопок которые будут раскиданы по дому вместо выключателей, будет 10 кнопок подключеных к одному аналоговому входу через разное сопротивления, скетч обработки написал, но вот быстродействие и факт нажатия огорчает) подскажите как это связать с внешним прерыванием, проблема в том для прерывания нужен дистретный сигнал, а для отпределения кнопки аналоговый, тянуть отдельные провода для прерывания не вариант, и просьба не советовать свякую по-русски говоря хуйню
такой вопрос, делаю управление освещением с помощью кнопок которые будут раскиданы по дому вместо выключателей, будет 10 кнопок подключеных к одному аналоговому входу через разное сопротивления, скетч обработки написал, но вот быстродействие и факт нажатия огорчает) подскажите как это связать с внешним прерыванием, проблема в том для прерывания нужен дистретный сигнал, а для отпределения кнопки аналоговый, тянуть отдельные провода для прерывания не вариант, и просьба не советовать свякую по-русски говоря хуйню
Давайте скетч. Быстродействия аналогового входа (АЦП), скорее всего, тут совершенно не при чём. Факт нажатия, предполагаю, портится помехами.
P.S. Лучше создайте отдельную тему в разделе "Программирование".
как раз таки быстродействие АЦП не успевает прочитать импульс 100-200 мс, потому что занята другими задачами, поэтому и решено использовать прерывание, собрал вот такую схему, но дребезг вызывает прерывание 3-5 раз за одно нажатие. В функции которое вызывает прерывание не работает ни delay ни millis, поэтому программно убить дребезг не выходит, вот и не знаю как это реализовать... =)
как раз таки быстродействие АЦП не успевает прочитать импульс 100-200 мс, потому что занята другими задачами, поэтому и решено использовать прерывание, собрал вот такую схему, но дребезг вызывает прерывание 3-5 раз за одно нажатие. В функции которое вызывает прерывание не работает ни delay ни millis, поэтому программно убить дребезг не выходит, вот и не знаю как это реализовать... =)
Это кто у Вас там кнопки так быстро нажимает? :)
Создайте внешнюю переменную - флаг времени вызова предыдущего прерывания.
На прерывании таймера эту переменную декриментируйте, если она больше нуля.
На прерывании от кнопки, если флаг не равен нулю - ничего не делать и вывалиться из прерывания, иначе записать в флаг значение времени нечувствительности и прочитать значение.
Кроме того, не забывайте, что прерывания имеют разные варианты: по фронтам, по низкому/высокому уровню и по изменению состояния. Если прерывание от кнопок будет настроено как по низкому/высокому уровню, то оно будет постоянно вызываться, пока нажата/отпущена кнопка.
Вы опустились до личных оскорблений. Мне вас жаль. Больше никогда мне не пишите, а то ведь могу найти в оффлайне и взять сполна за словоблудие.
Тебе адрес дать? А то словоблудие только от тебя слышу, да пацанские угрозы.
Не надо мне тыкать. Вы мне никто. Повторяю, не пишите мне. Наговорили уде достаточно для блокировки на любом другом форуме. Здесь к сожалению нет модерации.
Если мне надо кого то найти я сам нахожу
Не надо мне тыкать. Вы мне никто. Повторяю, не пишите мне. Наговорили уде достаточно для блокировки на любом другом форуме. Здесь к сожалению нет модерации.
Если мне надо кого то найти я сам нахожу
Общепринятый формат общения на форумах - на ты. Если тебя не устраивает - твои проблемы. Насчёт адреса - только скажи, я сообщу, чтобы не утруждать тебя поисками ;)
Вообще не понимаю, чего ты взъелся - несвежее съел, наверное? Бывает, выпей активированного угля и всё пройдёт. Кстати, не поверишь - я тебя прекрасно понимаю: это очень обидно, когда твои труды начинают критиковать. Однако, мудрый человек примет критику как старт для дальнейшего саморазвития, другой - начнёт переводить стрелки вовне.
Заметь, всё, чего я просил - называть вещи своими именами, не более того. И кстати, тут впомнилось про Википедию - ты не поверишь, какой только чуши там нет, ибо каждый суслик может редактировать статьи. Кстати, статья, цитату из которой ты приводил, носит гордый шильдик "не проверена опытными участниками" ;) Впрочем, для тебя и это не авторитет, ипстественно.
Смотрю на твои посты - в целом грамотный парень, но тебя, по ходу, заносит временами. Учись принимать критику конструктивно, и всё будет зашибись.
А насчёт адреса - ты подумай, подумай.
Для тех кому не хватает возможности понять самому. Обращение на вы в данном контексте это не комплекс. Это прием русского языка для обозначения дистанции. Я общаюсь на ты лишь с людьми равными по интеллектуальному и культурному уровню, с остальными не общаюсь или общаюсь на "расстоянии".
в данной теме я писал для автора с нормальным проектом значение которого вы пытаетесь принизить доказывая всем, что никто кроме вас не в состоянии писать "крутые" программы. Я писал не для вас. Вас не исправить. У вас потребность что то кому то доказать, но именно доказывать не хватает интеллекта, поэтому опускаетесь до хамства. Мне вас жаль, но это уже я повторяюсь
сделайте усилие над собой. В следующий раз перед тем как что то писать, подумайте не над тем как круто вы будете выглядеть, а о том какую пользу это может представлять для того кому пишите. Шанс у вас есть. Верю
axill, я вам аплодирую!
значение которого вы пытаетесь принизить доказывая всем, что никто кроме вас не в состоянии писать "крутые" программы.
Слушай, правдолюб: будь последователен, и покажи мне, плз, где я утверждал, что никто кроме меня не в состоянии писать "крутые" программы? Ты опять порешь чушь, пытаясь выглядеть не гопотой, которая угрожает физической расправой, а якобы культурным воспитанным мальчиком. И это, к слову, у тебя выходит крайне отвратительно.
Не надо приписывать мне слова, которых я никогда не произносил. Если ты этого усвоить не способен, а способен лишь на грязные передёргивания - мне тебя жаль.
Всем привет, столкнулся с проблемой подвисания шилда W5100, напруга стабильная 4,88-4,92 V. Три дня подряд после 8-12 часов работы. Контроллер работает. Что может быть?
Всем привет, столкнулся с проблемой подвисания шилда W5100, напруга стабильная 4,88-4,92 V. Три дня подряд после 8-12 часов работы. Контроллер работает. Что может быть?
По питанию точно проблем нет? Подвисает что именно? Я имею в виду - как вы понимаете, что подвис именно W5100? Возможно, проблема не в железе даже ;) В общем - дайте побольше вводных, и тогда будет полегче разобраться, думаю.
В общем - дайте побольше вводных, и тогда будет полегче разобраться, думаю.
Вначале думал что проблема в меге, создал в void(loop) мигание светодиода, когда железка перестает отвечать диод продолжает мигать, отсюда сделал вывод что подвисает w5100, питание пробовал менять измений нет.
Такая же проблема, как у uservasil, но только в другом проекте. Тоже используется шилд. Точнее перебпробовал на двух шилдах. На WL5100 и на ENC28J60. Второй тоже в виде шилда, только на Нану.
Я использовал в шлюзе MySensors. Тоже подвисает через 2-3 дня. Питание тут скорее всего не при чем, так как работало от упса через сетевой фильтр. По моим ощущениям, его задрюкивают другие устройства в сети. Так как все подключено через свитч, а устройств много >50, то блудняка в эфире много. Вот и не выдерживает Ethernet шилд.
Может кто подскажет что можно сделать. Или хоть как продиагностировать? Я даже не знаю какие еще симптомуы описать... Логов нет. Перестает пинговаться и все. Думаю повесить на него RTC часы и раз в сутки ребутать. Но наверно это не выход...
Такая же проблема, как у uservasil, но только в другом проекте. Тоже используется шилд. Точнее перебпробовал на двух шилдах. На WL5100 и на ENC28J60. Второй тоже в виде шилда, только на Нану.
Я использовал в шлюзе MySensors. Тоже подвисает через 2-3 дня. Питание тут скорее всего не при чем, так как работало от упса через сетевой фильтр. По моим ощущениям, его задрюкивают другие устройства в сети. Так как все подключено через свитч, а устройств много >50, то блудняка в эфире много. Вот и не выдерживает Ethernet шилд.
Может кто подскажет что можно сделать. Или хоть как продиагностировать? Я даже не знаю какие еще симптомуы описать... Логов нет. Перестает пинговаться и все. Думаю повесить на него RTC часы и раз в сутки ребутать. Но наверно это не выход...
зря исключаете питание, это наиболее вероятный источник. шилд вставленный поверз UNO или MEGA питается от стабилизатора ардуины и тот может не потянуть. Может даже сгореть. В моих первых экспериментах с мега и шилдом именно так и произошло. связку ардуино и шилд или шилд отдельно надо питать от хорошего DC-DC. Линейному стабилизатору 250-300ма потянуть сложно, особенно если к ардуине подключено 12в и больше
насчет "блудняка". это не причина. у меня 4-ре гейта mysensors в довольно большой сети с кучей устройств работают без зависаний, уже можно годами измерять. На ENC28J60 но с хорошим питанием
продиагностировать стоит и саму ардуину, запустить какой-то другой скетч или закоментировать работу с шилдом, шилд отсоединить и поставить на несколько дней.
еще причина может быть - скетч. Ардуина не контролирует выход за пределы доступной памяти при работе с переменными. Если скетч требует при работе слишком много памяти то может нарушаться целостность и это может привести к чему угодно, в том числе к зависанию
В моем случае нано + шилд питаются от USB адаптера. Имеет смысл перевешивать питание на Vвх? И как понять, Много ему питания или наоборот мало?
Посмотрел я - Нано выдает 150mA максимум. Лучше наверно отдельно запитать? А ethernet шилд нигде не написано сколько потребляет. Давно как-то экспериментировал, на шилде было написано, 3.3V ему надо. Но завелся только на 5V. А милиампер сколько ему надо - не нашел нигде.
В моем случае нано + шилд питаются от USB адаптера. Имеет смысл перевешивать питание на Vвх? И как понять, Много ему питания или наоборот мало?
Посмотрел я - Нано выдает 150mA максимум. Лучше наверно отдельно запитать? А ethernet шилд нигде не написано сколько потребляет. Давно как-то экспериментировал, на шилде было написано, 3.3V ему надо. Но завелся только на 5V. А милиампер сколько ему надо - не нашел нигде.
основной потребитель на шилде это сам чип. Про wiznrt5100 не смотрел, ENC28J60 требует порядка 250мА. Думаю у wiznet что то типо того же. Я лично считаю, что линейные стабилизаторы для питания ethernet не подходят ну либо надо городить нормальный LM7805 с радиатором. Ибо ни 78M05 который стоит на UNO и MEGA ни тем более AMS1117 который стоит на NANO не могут с запасом обеспечить работу шилда
я везде для питания шилдов ставлю DC-DC
вот обещанная версия 1.4:
добавлено:
1. Установка точной желаемой температуры
2. ручная запись и сброс состояний дискретных выходов во флеш
3. причесал и местами изменил говнокод =)
4. таблица влажности помещений
скетч:
#include <Ethernet.h> #include <SPI.h> #include <EEPROM.h> #include <DHT.h> #include <OneWire.h> //////////////////////////////////////////////////////////////////////// //CONFIGURATION //////////////////////////////////////////////////////////////////////// //IP manual settings byte ip[] = { 10, 16, 30, 2 }; //Manual setup only byte gateway[] = { 10, 16, 30, 3 }; //Manual setup only byte subnet[] = { 255, 255, 255, 0 }; //Manual setup only // if need to change the MAC address (Very Rare) byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; //Ethernet Port EthernetServer server = EthernetServer(80); //default html port 80 //The number of outputs going to be switched. int outputQuantity = 24; //should not exceed 10 //Invert the output of the leds boolean outputInverted = false; //true or false // This is done in case the relay board triggers the relay on negative, rather then on positive supply //Html page refresh int refreshPage = 15; //default is 10sec. //Beware that if you make it refresh too fast, the page could become inacessable. //Display or hide the "Switch on all Pins" buttons at the bottom of page //Button Array //Just for a note, varables start from 0 to 9, as 0 is counted as well, thus 10 outputs. // Select the pinout address int outputAddress[24] = { 3,5,6,7,8,9,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31}; //Allocate 10 spaces and name the output pin address. //PS pin addresses 10, 11, 12 and 13 on the Duemilanove are used for the ethernet shield, therefore cannot be used. //PS pin addresses 10, 50, 51 and 52 and 53 on the Mega are used for the ethernet shield, therefore cannot be used. //PS pin addresses 4, are used for the SD card, therefore cannot be used. //PS. pin address 2 is used for interrupt-driven notification, therefore could not be used. // Write the text description of the output channel String buttonText[24] = { "01. Канал","02. Канал","03. Канал","04. Канал","05. Канал","06. Канал","07. Канал","08. Канал","09. Канал","10. Канал","11. Канал","12. Канал","13. Канал","14. Канал","15. Канал","16. Канал","17. Канал","18. Канал","19. Канал","20. Канал","21. Канал","22. Канал","23. Канал","24. Канал"}; //////////////////////////////////////////////////////////////////////// int twenty[] = {11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34}; //char twentyTEXT[] = {'d1','d2','d3','d4','d5','d6','d7','d8','d9','d10','d11','d12','d13','d14','d15','d16','d17','d18','d19','d20'}; //////////////////////////////////////////////////////////////////////// //VARIABLES DECLARATION //////////////////////////////////////////////////////////////////////// int outp = 0; boolean printLastCommandOnce = false; boolean printButtonMenuOnce = false; boolean initialPrint = true; boolean reading = false; boolean outputStatus[24]; //Create a boolean array for the maximum ammount. String rev = "V1.4"; unsigned long timeConnectedAt; boolean writeToEeprom = false; int page=1; //////////////переменные упрвавления температурой const byte PinSSR1 = 44; // Реле Pin for SSR 1 const byte PinSSR2 = 45; // Реле Pin for SSR 2 const byte PinSSR3 = 46; // Реле Pin for SSR 3 char chartemp1[10]; char chartemp2[10]; char chartemp3[10]; char chartemp4[10]; int TargetTemp1; int TargetTemp2; int TargetTemp3; int Humidity1; int Humidity2; float temp1; float temp2; OneWire ds(47); DHT dht1(48, DHT11); DHT dht2(49, DHT11); //////////////////////////////// const int ledPin = 33; // номер выхода, подключенного к светодиоду // Variables will change: int ledState = LOW; // этой переменной устанавливаем состояние светодиода long previousMillis = 0; // храним время последнего переключения светодиода long interval = 1000; // интервал между включение/выключением светодиода (1 секунда) //////////////////////////////////////////////////////////////////////// //RUN ONCE //////////////////////////////////////////////////////////////////////// //Beginning of Program void setup(){ // мигаем светодиодом pinMode(ledPin, OUTPUT); Serial.begin(9600); initEepromValues(); readEepromValues(); //Set pins as Outputs boolean currentState = false; for (int var = 0; var < outputQuantity; var++){ pinMode(outputAddress[var], OUTPUT); //Switch all outputs to either on or off on Startup if(outputInverted == true) { //digitalWrite(outputAddress[var], HIGH); if(outputStatus[var] == 0){currentState = true;}else{currentState = false;} //check outputStatus if off, switch output accordingly digitalWrite(outputAddress[var], currentState); } else{ //digitalWrite(outputAddress[var], LOW); if(outputStatus[var] == 0){currentState = false;}else{currentState = true;}//check outputStatus if off, switch output accordingly digitalWrite(outputAddress[var], currentState); } } //Setting up the IP address. Comment out the one you dont need. //Ethernet.begin(mac); //for DHCP address. (Address will be printed to serial.) Ethernet.begin(mac, ip, gateway, subnet); //for manual setup. (Address is the one configured above.) server.begin(); Serial.print("Server started at "); Serial.println(Ethernet.localIP()); ////////////////управление температурой pinMode(PinSSR1, OUTPUT); pinMode(PinSSR2, OUTPUT); pinMode(PinSSR3, OUTPUT); TargetTemp1 = EEPROM.read(1000); TargetTemp2 = EEPROM.read(1002); TargetTemp3 = EEPROM.read(1004); dht1.begin(); dht2.begin(); } //////////////////////////////////////////////////////////////////////// //LOOP //////////////////////////////////////////////////////////////////////// //Run once void loop(){ // мигаем светодиодом unsigned long currentMillis = millis(); //проверяем не прошел ли нужный интервал, если прошел то if(currentMillis - previousMillis > interval) { // сохраняем время последнего переключения previousMillis = currentMillis; // если светодиод не горит, то зажигаем, и наоборот if (ledState == LOW) ledState = HIGH; else ledState = LOW; // устанавливаем состояния выхода, чтобы включить или выключить светодиод digitalWrite(ledPin, ledState); } // listen for incoming clients, and process requests. checkForClient(); ///////////////////////управление температурой float temp3; float temp4; byte sensor1[8] = {0x28, 0xFF, 0x34, 0x2C, 0x50, 0x15, 0x01, 0x87}; // Адрес сенсора byte sensor2[8] = {0x28, 0xDF, 0x7E, 0xDC, 0x06, 0x00, 0x00, 0xF3}; // Адрес сенсора //DHT temp1 = dht1.readTemperature(); dtostrf(temp1, 3, 1, chartemp1); Humidity1=dht1.readHumidity(); temp2 = dht2.readTemperature(); dtostrf(temp2, 3, 1, chartemp2); Humidity2=dht2.readHumidity(); //DS18B20 temp3 = tempread(sensor1); dtostrf(temp3, 3, 1, chartemp3); temp4 = tempread(sensor2); dtostrf(temp4, 3, 1, chartemp4); if (TargetTemp1==0) { digitalWrite(PinSSR1, HIGH); } else { if (temp1<TargetTemp1-0.5) { digitalWrite(PinSSR1, LOW); } else if (temp1>TargetTemp1+0.5) { digitalWrite(PinSSR1, HIGH); } } if (TargetTemp2==0) { digitalWrite(PinSSR2, HIGH); } else { if (temp2<TargetTemp2-0.5) { digitalWrite(PinSSR2, LOW); } else if (temp2>TargetTemp2+0.5) { digitalWrite(PinSSR2, HIGH); } } if (TargetTemp3==0) { digitalWrite(PinSSR3, HIGH); } else { if (temp3<TargetTemp3-0.5) { digitalWrite(PinSSR3, LOW); } else if (temp3>TargetTemp3+0.5) { digitalWrite(PinSSR3, HIGH); } } } //////////////////////////////////////////////////////////////////////// //checkForClient Function //////////////////////////////////////////////////////////////////////// // void checkForClient(){ EthernetClient client = server.available(); if (client) { // an http request ends with a blank line boolean currentLineIsBlank = true; boolean sentHeader = false; String command; //String tcommand; while (client.connected()) { if (client.available()) { //read user input char c = client.read(); if(c == '*'){ printHtmlHeader(client); //call for html header and css printHtmlFooter(client); //sentHeader = true; break; } if(!sentHeader){ printHtmlHeader(client); //call for html header and css printHtmlButtonTitle(client); //print the button title //This is for the arduino to construct the page on the fly. sentHeader = true; } //if there was reading but is blank there was no reading if(reading && c == ' '){ reading = false; } //http://10.16.30.2/?t1-10 //if there is a ? there was user input if(c == '?') { reading = true; //found the ?, begin reading the info command = F(""); // clear current command // tcommand = F(""); // clear current command } // if there was user input switch the relevant output if(reading){ //if user input is H set output to 1 if(c == 'H') { outp = 1; } //if user input is L set output to 0 if(c == 'L') { outp = 0; } if(c!='?'&&c!='H'&&c!='L') {command +=c;} if(command.substring(0,3) == "T1=") { if(command.substring(3).toInt()>=0&&command.substring(3).toInt()<=28) { TargetTemp1=command.substring(3).toInt();EEPROM.write(1000, TargetTemp1);Serial.println(" "); Serial.print("T1:"); Serial.print(TargetTemp1); } } if(command.substring(0,3) == "T2=") { if(command.substring(3).toInt()>=0&&command.substring(3).toInt()<=28) { TargetTemp2=command.substring(3).toInt();EEPROM.write(1002, TargetTemp2);Serial.println(" "); Serial.print("T2:"); Serial.print(TargetTemp2); } } if(command.substring(0,3) == "T3=") { if(command.substring(3).toInt()>=0&&command.substring(3).toInt()<=28) { TargetTemp3=command.substring(3).toInt();EEPROM.write(1004, TargetTemp3);Serial.println(" "); Serial.print("T3:"); Serial.print(TargetTemp3); } } if(command == "d11") {triggerPin(outputAddress[0], client, outp); Serial.println(" "); Serial.println("case 1 OK"); } if(command == "d12") {triggerPin(outputAddress[1], client, outp); Serial.println(" "); Serial.println("case 2 OK"); } if(command == "d13") {triggerPin(outputAddress[2], client, outp); Serial.println(" "); Serial.println("case 3 OK"); } if(command == "d14") {triggerPin(outputAddress[3], client, outp); Serial.println(" "); Serial.println("case 4 OK"); } if(command == "d15") {triggerPin(outputAddress[4], client, outp); Serial.println(" "); Serial.println("case 5 OK"); } if(command == "d16") {triggerPin(outputAddress[5], client, outp); Serial.println(" "); Serial.println("case 6 OK"); } if(command == "d17") {triggerPin(outputAddress[6], client, outp); Serial.println(" "); Serial.println("case 7 OK"); } if(command == "d18") {triggerPin(outputAddress[7], client, outp); Serial.println(" "); Serial.println("case 8 OK"); } if(command == "d19") {triggerPin(outputAddress[8], client, outp); Serial.println(" "); Serial.println("case 9 OK"); } if(command == "d20") {triggerPin(outputAddress[9], client, outp); Serial.println(" "); Serial.println("case 10 OK"); } if(command == "d21") {triggerPin(outputAddress[10], client, outp); Serial.println(" "); Serial.println("case 11 OK"); } if(command == "d22") {triggerPin(outputAddress[11], client, outp); Serial.println(" "); Serial.println("case 12 OK"); } if(command == "d23") {triggerPin(outputAddress[12], client, outp); Serial.println(" "); Serial.println("case 13 OK"); } if(command == "d24") {triggerPin(outputAddress[13], client, outp); Serial.println(" "); Serial.println("case 14 OK"); } if(command == "d25") {triggerPin(outputAddress[14], client, outp); Serial.println(" "); Serial.println("case 15 OK"); } if(command == "d26") {triggerPin(outputAddress[15], client, outp); Serial.println(" "); Serial.println("case 16 OK"); } if(command == "d27") {triggerPin(outputAddress[16], client, outp); Serial.println(" "); Serial.println("case 17 OK"); } if(command == "d28") {triggerPin(outputAddress[17], client, outp); Serial.println(" "); Serial.println("case 18 OK"); } if(command == "d29") {triggerPin(outputAddress[18], client, outp); Serial.println(" "); Serial.println("case 19 OK"); } if(command == "d30") {triggerPin(outputAddress[19], client, outp); Serial.println(" "); Serial.println("case 20 OK"); } if(command == "d31") {triggerPin(outputAddress[20], client, outp); Serial.println(" "); Serial.println("case 21 OK"); } if(command == "d32") {triggerPin(outputAddress[21], client, outp); Serial.println(" "); Serial.println("case 22 OK"); } if(command == "d33") {triggerPin(outputAddress[22], client, outp); Serial.println(" "); Serial.println("case 23 OK"); } if(command == "d34") {triggerPin(outputAddress[23], client, outp); Serial.println(" "); Serial.println("case 24 OK"); } if(command == "100"){ for (int var = 0; var < outputQuantity; var++) { triggerPin(outputAddress[var], client, outp); } } if(command == "page1") {page=1; Serial.println(" "); Serial.println("page 1 OK"); } if(command == "page0") {page=0; Serial.println(" "); Serial.println("page 0 OK"); } if(command == "save") {writeEepromValues(); Serial.println(" "); Serial.println("save"); } if(command == "reset") {resetEepromValues(); Serial.println(" "); Serial.println("reset"); } }//end if(reading) //if user input was blank if (c == '\n' && currentLineIsBlank){ printLastCommandOnce = true; printButtonMenuOnce = true; triggerPin(777, client, outp); //Call to read input and print menu. 777 is used not to update any outputs break; } } // end if (client.available()) } // end whil Serial.println(" "); Serial.print("command:"); Serial.print(command); Serial.println(" "); Serial.println("----------"); printHtmlFooter(client); //Prints the html footer } else { //if there is no client // таймаут простоя, для записи данных состояния переключателей в кэш if (millis() > (timeConnectedAt + 3600000)){ if (writeToEeprom == true){ writeEepromValues(); //write to EEprom the current output statuses Serial.println("No Clients for more then a 60 min. - Writing statuses to Eeprom."); writeToEeprom = false; } } } } /////////////////////////////////////////////////////////////////////// //triggerPin Function //////////////////////////////////////////////////////////////////////// void triggerPin(int pin, EthernetClient client, int outp){ //Switching on or off outputs, reads the outputs and prints the buttons //Setting Outputs if (pin != 777){ if(outp == 1) { if (outputInverted ==false){ digitalWrite(pin, HIGH); } else{ digitalWrite(pin, LOW); } } if(outp == 0){ if (outputInverted ==false){ digitalWrite(pin, LOW); } else{ digitalWrite(pin, HIGH); } } Serial.println(" "); Serial.print("triggerPin:"); Serial.print(pin); Serial.println(" OK"); } //Refresh the reading of outputs readOutputStatuses(); //Prints the buttons if (printButtonMenuOnce == true){ printHtmlButtons(client); printButtonMenuOnce = false; } } //////////////////////////////////////////////////////////////////////// //printHtmlButtons Function //////////////////////////////////////////////////////////////////////// void printHtmlButtons(EthernetClient client){ client.println(""); client.println("<FORM>"); //вывод таблиц управления температурой if (page == 1){ client.println("<table border=\"0\" align=\"center\">"); client.print("<tr>"); client.print("<td rowspan=4>"); } //вывод текста, кнопок ON и OFF и лампочек состояния client.println("<table border=\"0\" align=\"center\">"); for (int var = 0; var < outputQuantity; var++) { //Print begining of row client.print("<tr>\n"); //Prints the button Text client.print("<td><h4>"); client.print(buttonText[var]); client.print("</h4></td>\n"); //Prints the ON Buttons client.print("<td>"); client.print("<INPUT TYPE=\"button\" VALUE=\"ВКЛ "); client.print("\" onClick=\"parent.location='/?H"); client.print("d"); client.print(twenty[var]); client.print("'\"></td>\n"); //Prints the OFF Buttons client.print(" <td><INPUT TYPE=\"button\" VALUE=\"ВЫКЛ"); client.print("\" onClick=\"parent.location='/?L"); client.print("d"); client.print(twenty[var]); client.print("'\"></td>\n"); //Print first part of the Circles or the LEDs //Invert the LED display if output is inverted. if (outputStatus[var] == true ){ //If Output is ON if (outputInverted == false){ //and if output is not inverted client.print(" <td><div class='green-circle'><div class='glare'></div></div></td>\n"); //Print html for ON LED } else{ //else output is inverted then client.print(" <td><div class='black-circle'><div class='glare'></div></div></td>\n"); //Print html for OFF LED } } else //If Output is Off { if (outputInverted == false){ //and if output is not inverted client.print(" <td><div class='black-circle'><div class='glare'></div></div></td>\n"); //Print html for OFF LED } else{ //else output is inverted then client.print(" <td><div class='green-circle'><div class='glare'></div></div></td>\n"); //Print html for ON LED } } client.print("</tr>\n"); } // end for //Prints the ON All Pins Button client.print("<tr>\n<td colspan=2><INPUT TYPE=\"button\" VALUE=\"Включить ВСЁ"); client.print("\" onClick=\"parent.location='/?H100"); client.print("'\"></td>\n"); //Prints the OFF All Pins Button client.print("<td colspan=2><INPUT TYPE=\"button\" VALUE=\"Выключить ВСЁ"); client.print("\" onClick=\"parent.location='/?L100"); client.print("'\"></td>\n<td></td>\n<td></td>\n</tr>\n"); //Prints save Button client.print("<tr>\n<td colspan=2><INPUT TYPE=\"button\" VALUE=\"Записать"); client.print("\" onClick=\"parent.location='/?save"); client.print("'\"></td>\n"); //Prints reset Button client.print("<td colspan=2><INPUT TYPE=\"button\" VALUE=\"Сбросить"); client.print("\" onClick=\"parent.location='/?reset"); client.print("'\"></td>\n<td></td>\n<td></td>\n</tr>\n"); client.println("</table>"); if (page == 1){ client.print("</td>"); client.print("<td height=\"86\">"); } client.println("<table border=\"0\" align=\"center\">"); client.print("<tr>"); client.print("<td></td>"); client.print("<td><h3>текущая</h3></td>"); client.print("<td><h3>обогрев</h3></td>"); client.print("<td><h3>желаемая</h3></td>"); // client.print("<td><h3>влажность</h3></td>"); client.print("</tr>"); client.print("<tr>"); client.print("<td><h4>"); client.print("Первый этаж:"); client.print("</h4></td>"); client.print("<td align=\"center\">"); client.println(chartemp1); //текущая температура client.print(" °C</td>"); if ( digitalRead(PinSSR1) == LOW ) { client.println("<td align=\"center\"><font color=green><b>ВКЛ</b></font></td>"); } // вкл или выкл else { client.println("<td align=\"center\"><font color=red><b>ВЫКЛ</b></font></td>"); } client.println("<td align=\"center\">"); client.println(TargetTemp1); //отображение желаемой температуры client.println(" °C</td>"); // client.println("<td align=\"center\">"); // client.println(Humidity1); //отображение влажности // client.println("%</td>"); client.print("</tr>"); client.print("<tr>"); client.print("<td><h4>"); client.print("Установить:"); //выбор желаемой температуры client.print("</h4></td>"); client.print(" <td colspan=3><table border=\"0\"><tr><td><INPUT TYPE=\"button\" VALUE=\"0" "\" onClick=\"parent.location='/?T1=0""'\"></td>"); client.print(" <td><INPUT TYPE=\"button\" VALUE=\"5" "\" onClick=\"parent.location='/?T1=5""'\"></td>"); client.print(" <td><INPUT TYPE=\"button\" VALUE=\"10" "\" onClick=\"parent.location='/?T1=10""'\"></td>"); client.print(" <td><INPUT TYPE=\"button\" VALUE=\"20" "\" onClick=\"parent.location='/?T1=20""'\"></td>"); client.print(" <td><INPUT TYPE=\"button\" VALUE=\"22" "\" onClick=\"parent.location='/?T1=22""'\"></td>"); client.print(" <td><INPUT TYPE=\"button\" VALUE=\"24" "\" onClick=\"parent.location='/?T1=24""'\"></td></tr></table></td>"); client.print("</tr>"); client.print("<tr>"); client.print("<td><h4>"); client.print("Точно:"); //выбор желаемой температуры точно client.print("</h4></td>"); client.print("<td></td>"); client.print(" <td colspan=2>"); client.print("<form><input type=text name=T1 size=10> <input type=submit value=ОК> </form></td>"); client.print("</tr>"); client.println("</table>"); //t1=5 if (page == 1){ client.print("</td>"); client.print("</tr>"); client.print("<tr>"); client.print("<td height=\"86\">"); } client.println("<table border=\"0\" align=\"center\">"); client.print("<tr>"); client.print("<td></td>"); client.print("<td><h3>текущая</h3></td>"); client.print("<td><h3>обогрев</h3></td>"); client.print("<td><h3>желаемая</h3></td>"); client.print("</tr>"); client.print("<tr>"); client.print("<td><h4>"); client.print("Второй этаж:"); client.print("</h4></td>"); client.print("<td align=\"center\">"); client.println(chartemp2); //текущая температура client.print(" °C</td>"); if ( digitalRead(PinSSR2) == LOW ) { client.println("<td align=\"center\"><font color=green><b>ВКЛ</b></font></td>"); } // вкл или выкл else { client.println("<td align=\"center\"><font color=red><b>ВЫКЛ</b></font></td>"); } client.println("<td align=\"center\">"); client.println(TargetTemp2); //отображение желаемой температуры client.println(" °C</td>"); client.print("</tr>"); client.print("<tr>"); client.print("<td><h4>"); client.print("Установить:"); //выбор желаемой температуры client.print("</h4></td>"); client.print(" <td colspan=3><table border=\"0\"><tr><td><INPUT TYPE=\"button\" VALUE=\"0" "\" onClick=\"parent.location='/?T2=0""'\"></td>"); client.print(" <td><INPUT TYPE=\"button\" VALUE=\"5" "\" onClick=\"parent.location='/?T2=5""'\"></td>"); client.print(" <td><INPUT TYPE=\"button\" VALUE=\"10" "\" onClick=\"parent.location='/?T2=10""'\"></td>"); client.print(" <td><INPUT TYPE=\"button\" VALUE=\"20" "\" onClick=\"parent.location='/?T2=20""'\"></td>"); client.print(" <td><INPUT TYPE=\"button\" VALUE=\"22" "\" onClick=\"parent.location='/?T2=22""'\"></td>"); client.print(" <td><INPUT TYPE=\"button\" VALUE=\"24" "\" onClick=\"parent.location='/?T2=24""'\"></td></tr></table></td>"); client.print("</tr>"); client.print("<tr>"); client.print("<td><h4>"); client.print("Точно:"); //выбор желаемой температуры точно client.print("</h4></td>"); client.print("<td></td>"); client.print(" <td colspan=2>"); client.print("<form><input type=text name=T2 size=10> <input type=submit value=ОК> </form></td>"); client.print("</tr>"); client.println("</table>"); if (page == 1){ client.print("</td>"); client.print("</tr>"); client.print("<tr>"); client.print("<td height=\"86\">"); } client.println("<table border=\"0\" align=\"center\">"); client.print("<tr>"); client.print("<td></td>"); client.print("<td><h3>текущая</h3></td>"); client.print("<td><h3>обогрев</h3></td>"); client.print("<td><h3>желаемая</h3></td>"); client.print("</tr>"); client.print("<tr>"); client.print("<td><h4>"); client.print("Кухня:"); client.print("</h4></td>"); client.print("<td align=\"center\">"); client.println(chartemp3); //текущая температура client.print(" °C</td>"); if ( digitalRead(PinSSR3) == LOW ) { client.println("<td align=\"center\"><font color=green><b>ВКЛ</b></font></td>"); } // вкл или выкл else { client.println("<td align=\"center\"><font color=red><b>ВЫКЛ</b></font></td>"); } client.println("<td align=\"center\">"); client.println(TargetTemp3); //отображение желаемой температуры client.println(" °C</td>"); client.print("</tr>"); client.print("<tr>"); client.print("<td><h4>"); client.print("Установить:"); //выбор желаемой температуры client.print("</h4></td>"); client.print(" <td colspan=3><table border=\"0\"><tr><td><INPUT TYPE=\"button\" VALUE=\"0" "\" onClick=\"parent.location='/?T3=0""'\"></td>"); client.print(" <td><INPUT TYPE=\"button\" VALUE=\"5" "\" onClick=\"parent.location='/?T3=5""'\"></td>"); client.print(" <td><INPUT TYPE=\"button\" VALUE=\"10" "\" onClick=\"parent.location='/?T3=10""'\"></td>"); client.print(" <td><INPUT TYPE=\"button\" VALUE=\"20" "\" onClick=\"parent.location='/?T3=20""'\"></td>"); client.print(" <td><INPUT TYPE=\"button\" VALUE=\"22" "\" onClick=\"parent.location='/?T3=22""'\"></td>"); client.print(" <td><INPUT TYPE=\"button\" VALUE=\"24" "\" onClick=\"parent.location='/?T3=24""'\"></td></tr></table></td>"); client.print("</tr>"); client.print("<tr>"); client.print("<td><h4>"); client.print("Точно:"); //выбор желаемой температуры точно client.print("</h4></td>"); client.print("<td></td>"); client.print(" <td colspan=2>"); client.print("<form><input type=text name=T3 size=10> <input type=submit value=ОК> </form></td>"); client.print("</tr>"); client.println("</table>"); if (page == 1){ client.print("</td>"); client.print("</tr>"); client.print("<tr>"); client.print("<td height=\"86\">"); } client.println("<table border=\"0\" align=\"center\">"); client.print("<tr>"); client.print("<td></td>"); client.print("<td><h3>1 этаж</h3></td>"); client.print("<td><h3>2 этаж</h3</td>"); client.print("<td><h3>кухня</h3</td>"); client.print("<td><h3>баня</h3</td>"); client.print("</tr>"); client.print("<tr>"); client.print("<td><h4>"); client.print("Влажность:"); client.print("</h4></td>"); client.println("<td align=\"center\">"); client.println(Humidity1+24); //отображение влажности client.println("%</td>"); client.println("<td align=\"center\">"); client.println(Humidity2+7); //отображение влажности client.println("%</td>"); client.println("<td align=\"center\">"); client.println(Humidity2+38); //отображение влажности client.println("%</td>"); client.println("<td align=\"center\">"); client.println(Humidity1+63); //отображение влажности client.println("%</td>"); client.print("</tr>"); client.println("</table>"); if (page == 1){ client.print("</td>"); client.print("</tr>"); client.println("</table>"); } client.println("</FORM>"); } //////////////////////////////////////////////////////////////////////// //readOutputStatuses Function //////////////////////////////////////////////////////////////////////// //Reading the Output Statuses void readOutputStatuses(){ for (int var = 0; var < outputQuantity; var++) { outputStatus[var] = digitalRead(outputAddress[var]); // Serial.print(outputStatus[var]); } } //////////////////////////////////////////////////////////////////////// //readEepromValues Function //////////////////////////////////////////////////////////////////////// //Read EEprom values and save to outputStatus void readEepromValues(){ for (int adr = 0; adr < outputQuantity; adr++) { outputStatus[adr] = EEPROM.read(adr+10); Serial.println(" "); Serial.print("read adr::"); Serial.print(adr); Serial.println(" OK"); Serial.println(" "); Serial.print("outputStatus[adr]::"); Serial.print(outputStatus[adr]); Serial.println(" OK"); } } //////////////////////////////////////////////////////////////////////// //writeEepromValues Function //////////////////////////////////////////////////////////////////////// void writeEepromValues(){ for (int adr = 0; adr < outputQuantity+0; adr++) { EEPROM.write(adr+10, outputStatus[adr]); Serial.println(" "); Serial.print("write adr::"); Serial.print(adr); Serial.println(" OK"); Serial.println(" "); Serial.print("outputStatus[adr]::"); Serial.print(outputStatus[adr]); Serial.println(" OK"); } } //////////////////////////////////////////////////////////////////////// //resetEepromValues Function //////////////////////////////////////////////////////////////////////// void resetEepromValues(){ for (int adr = 0; adr < outputQuantity+0; adr++) { EEPROM.write(adr+10, 0); Serial.println(" "); Serial.print("reset adr::"); Serial.print(adr); Serial.println(" OK"); Serial.println(" "); Serial.print("outputStatus[adr]::"); Serial.print(outputStatus[adr]); Serial.println(" OK"); } } //////////////////////////////////////////////////////////////////////// //initEepromValues Function //////////////////////////////////////////////////////////////////////// //Initialiaze EEprom values //if eeprom values are not the correct format ie not euqual to 0 or 1 (thus greater then 1) initialize by putting 0 void initEepromValues(){ for (int adr = 0; adr < outputQuantity; adr++){ if (EEPROM.read(adr+10) > 1){ EEPROM.write(adr+10, 0); } } } //////////////////////////////////////////////////////////////////////// //htmlHeader Function //////////////////////////////////////////////////////////////////////// void printHtmlHeader(EthernetClient client){ Serial.print("Serving html Headers at ms -"); timeConnectedAt = millis(); //Record the time when last page was served. Serial.println(timeConnectedAt); // Print time for debbugging purposes writeToEeprom = true; // page loaded so set to action the write to eeprom // send a standard http response header client.println(F("HTTP/1.1 200 OK")); client.println(F("Content-Type: text/html; charset=utf-8")); client.println(F("Connnection: close")); client.println(); client.println(F("<!DOCTYPE HTML>")); client.println(F("<head>")); // заголовок страницы client.println(F("<title>Контроль и управление домом</title>")); client.println(F("<meta name=\"description\" content=\"Контроль и управление домом\"/>")); // время обновления страницы client.print(F("<meta http-equiv=\"refresh\" content=\"")); client.print(refreshPage); client.println(F("; url=/\">")); // конфигурация браузера client.println(F("<meta name=\"apple-mobile-web-app-capable\" content=\"yes\">")); client.println(F("<meta name=\"apple-mobile-web-app-status-bar-style\" content=\"default\">")); client.println(F("<meta name=\"viewport\" content=\"width=device-width, user-scalable=no\">")); // вставка данных стилей CSS client.println(F("<style type=\"text/css\">")); client.println(F("")); // как будет выглядеть страница графически client.println(F("html { height:100%; }")); client.println(F(" body {")); client.println(F(" height: 100%;")); client.println(F(" margin: 0;")); client.println(F(" font-family: helvetica, sans-serif;")); client.println(F(" -webkit-text-size-adjust: none;")); client.println(F(" }")); client.println(F("")); client.println(F("body {")); client.println(F(" -webkit-background-size: 100% 21px;")); client.println(F(" background-color: #c5ccd3;")); client.println(F(" background-image:")); client.println(F(" -webkit-gradient(linear, left top, right top,")); client.println(F(" color-stop(.75, transparent),")); client.println(F(" color-stop(.75, rgba(255,255,255,.1)) );")); client.println(F(" -webkit-background-size: 7px;")); client.println(F(" }")); client.println(F("")); client.println(F(".view {")); client.println(F(" min-height: 100%;")); client.println(F(" overflow: auto;")); client.println(F(" }")); client.println(F("")); client.println(F(".header-wrapper {")); client.println(F(" height: 64px;")); client.println(F(" font-weight: bold;")); client.println(F(" text-shadow: rgba(0,0,0,0.7) 0 -1px 0;")); client.println(F(" border-top: solid 1px rgba(255,255,255,0.6);")); client.println(F(" border-bottom: solid 1px rgba(0,0,0,0.6);")); client.println(F(" color: #fff;")); client.println(F(" background-color: #8195af;")); client.println(F(" background-image:")); client.println(F(" -webkit-gradient(linear, left top, left bottom,")); client.println(F(" from(rgba(255,255,255,.4)),")); client.println(F(" to(rgba(255,255,255,.05)) ),")); client.println(F(" -webkit-gradient(linear, left top, left bottom,")); client.println(F(" from(transparent),")); client.println(F(" to(rgba(0,0,64,.1)) );")); client.println(F(" background-repeat: no-repeat;")); client.println(F(" background-position: top left, bottom left;")); client.println(F(" -webkit-background-size: 100% 21px, 100% 22px;")); client.println(F(" -webkit-box-sizing: border-box;")); client.println(F(" }")); client.println(F("")); client.println(F(".header-wrapper h1 {")); client.println(F(" text-align: center;")); client.println(F(" font-size: 20px;")); client.println(F(" line-height: 44px;")); client.println(F(" margin: 0;")); client.println(F(" }")); client.println(F("")); client.println(F(".group-wrapper {")); client.println(F(" margin: 9px;")); client.println(F(" aling: center;")); client.println(F(" }")); client.println(F("")); client.println(F(".group-wrapper h2 {")); client.println(F(" color: #4c566c;")); client.println(F(" font-size: 17px;")); client.println(F(" line-height: 0.8;")); client.println(F(" font-weight: bold;")); client.println(F(" text-shadow: #fff 0 1px 0;")); client.println(F(" margin: 20px 10px 12px;")); client.println(F(" }")); client.println(F("")); client.println(F(".group-wrapper h3 {")); client.println(F(" color: #4c566c;")); client.println(F(" font-size: 12px;")); client.println(F(" line-height: 1;")); client.println(F(" font-weight: bold;")); client.println(F(" text-shadow: #fff 0 1px 0;")); client.println(F(" margin: 20px 10px 12px;")); client.println(F(" }")); client.println(F("")); client.println(F(".group-wrapper h4 {")); //Text for description client.println(F(" color: #212121;")); client.println(F(" font-size: 14px;")); client.println(F(" line-height: 1;")); client.println(F(" font-weight: bold;")); client.println(F(" text-shadow: #aaa 1px 1px 3px;")); client.println(F(" margin: 5px 5px 5px;")); client.println(F(" }")); client.println(F("")); client.println(F(".group-wrapper table {")); client.println(F(" background-color: #fff;")); client.println(F(" -webkit-border-radius: 10px;")); client.println(F(" -moz-border-radius: 10px;")); client.println(F(" -khtml-border-radius: 10px;")); client.println(F(" border-radius: 10px;")); client.println(F(" font-size: 17px;")); client.println(F(" line-height: 20px;")); // ширина строк таблицы client.println(F(" margin: 5px 0 5px;")); // отступ строк таблицы client.println(F(" border: solid 1px #a9abae;")); client.println(F(" padding: 11px 3px 12px 3px;")); client.println(F(" margin-left:auto;")); client.println(F(" margin-right:auto;")); client.println(F(" -moz-transform :scale(1);")); //Code for Mozilla Firefox client.println(F(" -moz-transform-origin: 0 0;")); client.println(F(" }")); //how the green (ON) LED will look client.println(F(".green-circle {")); client.println(F(" display: block;")); client.println(F(" height: 23px;")); client.println(F(" width: 23px;")); client.println(F(" background-color: #0f0;")); client.println(F(" -moz-border-radius: 11px;")); client.println(F(" -webkit-border-radius: 11px;")); client.println(F(" -khtml-border-radius: 11px;")); client.println(F(" border-radius: 11px;")); client.println(F(" margin-left: 1px;")); client.println(F(" background-image: -webkit-gradient(linear, 0% 0%, 0% 90%, from(rgba(46, 184, 0, 0.8)), to(rgba(148, 255, 112, .9)));@")); client.println(F(" border: 2px solid #ccc;")); client.println(F(" -webkit-box-shadow: rgba(11, 140, 27, 0.5) 0px 10px 16px;")); client.println(F(" -moz-box-shadow: rgba(11, 140, 27, 0.5) 0px 10px 16px; /* FF 3.5+ */")); client.println(F(" box-shadow: rgba(11, 140, 27, 0.5) 0px 10px 16px; /* FF 3.5+ */")); client.println(F(" }")); client.println(F("")); //how the black (off)LED will look client.println(F(".black-circle {")); client.println(F(" display: block;")); client.println(F(" height: 23px;")); client.println(F(" width: 23px;")); client.println(F(" background-color: #040;")); client.println(F(" -moz-border-radius: 11px;")); client.println(F(" -webkit-border-radius: 11px;")); client.println(F(" -khtml-border-radius: 11px;")); client.println(F(" border-radius: 11px;")); client.println(F(" margin-left: 1px;")); client.println(F(" -webkit-box-shadow: rgba(11, 140, 27, 0.5) 0px 10px 16px;")); client.println(F(" -moz-box-shadow: rgba(11, 140, 27, 0.5) 0px 10px 16px; /* FF 3.5+ */")); client.println(F(" box-shadow: rgba(11, 140, 27, 0.5) 0px 10px 16px; /* FF 3.5+ */")); client.println(F(" }")); client.println(F("")); //this will add the glare to both of the LEDs client.println(F(" .glare {")); client.println(F(" position: relative;")); client.println(F(" top: 1;")); client.println(F(" left: 5px;")); client.println(F(" -webkit-border-radius: 10px;")); client.println(F(" -moz-border-radius: 10px;")); client.println(F(" -khtml-border-radius: 10px;")); client.println(F(" border-radius: 10px;")); client.println(F(" height: 1px;")); client.println(F(" width: 13px;")); client.println(F(" padding: 5px 0;")); client.println(F(" background-color: rgba(200, 200, 200, 0.25);")); client.println(F(" background-image: -webkit-gradient(linear, 0% 0%, 0% 95%, from(rgba(255, 255, 255, 0.7)), to(rgba(255, 255, 255, 0)));")); client.println(F(" }")); client.println(F("")); //and finally this is the end of the style data and header client.println(F("</style>")); client.println(F("</head>")); //now printing the page itself client.println(F("<body>")); client.println(F("<div class=\"view\">")); client.println(F(" <div class=\"header-wrapper\">")); // client.println(F(" <h1>СМАРТ ДАЧА</h1>")); client.print(F("<table border=\"0\" align=\"center\"><tr><td><h4>Стиль страницы:</h4></td><td><INPUT TYPE=\"button\" VALUE=\"широкая" "\" onClick=\"parent.location='/?page1""'\"></td>")); client.print(F("<td><INPUT TYPE=\"button\" VALUE=\" узкая " "\" onClick=\"parent.location='/?page0""'\"></td></tr></table>")); client.println(F(" </div>")); } //end of htmlHeader //////////////////////////////////////////////////////////////////////// //htmlFooter Function //////////////////////////////////////////////////////////////////////// void printHtmlFooter(EthernetClient client){ //Set Variables Before Exiting printLastCommandOnce = false; printButtonMenuOnce = false; client.println(F("\n<h3 align=\"center\">©- Plagiary - <br> 774 KM - 2016 - ")); client.println(rev); client.println(F("</h3></div>\n</div>\n</body>\n</html>")); delay(1); // give the web browser time to receive the data client.stop(); // close the connection: Serial.println(" - Done, Closing Connection."); delay (2); //delay so that it will give time for client buffer to clear and does not repeat multiple pages. } //end of htmlFooter //////////////////////////////////////////////////////////////////////// //printHtmlButtonTitle Function //////////////////////////////////////////////////////////////////////// void printHtmlButtonTitle(EthernetClient client){ client.println(F("<div class=\"group-wrapper\">")); client.println(F("<h2 align=\"center\" >Температура на улице")); client.println(chartemp4); client.print(F(" °C </h2>")); client.println(); } ///////////////// DS18B20 float tempread(byte sensoraddr[]) // error codes: // -1 no sensors found // -2 invalid CRC // -3 not a DS1820 { byte i; byte present = 0; byte data[12]; byte addr[8]; //int HighByte, LowByte, TReading, SignBit, Tc_100, Tf_100, Whole, Fract; for ( i = 0; i < 8; i++) { addr[i]=sensoraddr[i]; } ds.reset(); // pulse the pins and wait for a response to reset the DS1820 ds.select(addr); // 0x55 (MATCH_ROM) followed by the address of the 1820 to talk to. // ds.write(0x44,1); // start conversion, with parasite power on at the end ds.write(0x44,0); //PARASITE POWER OFF // delay(800); present = ds.reset(); ds.select(addr); ds.write(0xBE); // Read Scratchpad for ( i = 0; i < 9; i++) { // we need 9 bytes data[i] = ds.read(); } int16_t raw = (data[1] << 8) | data[0]; float temp = (float)raw / 16.0; return temp; }html:
<!DOCTYPE HTML> <head> <title>Контроль и управление домом</title> <meta name="description" content="Контроль и управление домом"/> <meta http-equiv="refresh" content="15; url=/"> <meta name="apple-mobile-web-app-capable" content="yes"> <meta name="apple-mobile-web-app-status-bar-style" content="default"> <meta name="viewport" content="width=device-width, user-scalable=no"> <style type="text/css"> html { height:100%; } body { height: 100%; margin: 0; font-family: helvetica, sans-serif; -webkit-text-size-adjust: none; } body { -webkit-background-size: 100% 21px; background-color: #c5ccd3; background-image: -webkit-gradient(linear, left top, right top, color-stop(.75, transparent), color-stop(.75, rgba(255,255,255,.1)) ); -webkit-background-size: 7px; } .view { min-height: 100%; overflow: auto; } .header-wrapper { height: 64px; font-weight: bold; text-shadow: rgba(0,0,0,0.7) 0 -1px 0; border-top: solid 1px rgba(255,255,255,0.6); border-bottom: solid 1px rgba(0,0,0,0.6); color: #fff; background-color: #8195af; background-image: -webkit-gradient(linear, left top, left bottom, from(rgba(255,255,255,.4)), to(rgba(255,255,255,.05)) ), -webkit-gradient(linear, left top, left bottom, from(transparent), to(rgba(0,0,64,.1)) ); background-repeat: no-repeat; background-position: top left, bottom left; -webkit-background-size: 100% 21px, 100% 22px; -webkit-box-sizing: border-box; } .header-wrapper h1 { text-align: center; font-size: 20px; line-height: 44px; margin: 0; } .group-wrapper { margin: 9px; aling: center; } .group-wrapper h2 { color: #4c566c; font-size: 17px; line-height: 0.8; font-weight: bold; text-shadow: #fff 0 1px 0; margin: 20px 10px 12px; } .group-wrapper h3 { color: #4c566c; font-size: 12px; line-height: 1; font-weight: bold; text-shadow: #fff 0 1px 0; margin: 20px 10px 12px; } .group-wrapper h4 { color: #212121; font-size: 14px; line-height: 1; font-weight: bold; text-shadow: #aaa 1px 1px 3px; margin: 5px 5px 5px; } .group-wrapper table { background-color: #fff; -webkit-border-radius: 10px; -moz-border-radius: 10px; -khtml-border-radius: 10px; border-radius: 10px; font-size: 17px; line-height: 20px; margin: 5px 0 5px; border: solid 1px #a9abae; padding: 11px 3px 12px 3px; margin-left:auto; margin-right:auto; -moz-transform :scale(1); -moz-transform-origin: 0 0; } .green-circle { display: block; height: 23px; width: 23px; background-color: #0f0; -moz-border-radius: 11px; -webkit-border-radius: 11px; -khtml-border-radius: 11px; border-radius: 11px; margin-left: 1px; background-image: -webkit-gradient(linear, 0% 0%, 0% 90%, from(rgba(46, 184, 0, 0.8)), to(rgba(148, 255, 112, .9)));@ border: 2px solid #ccc; -webkit-box-shadow: rgba(11, 140, 27, 0.5) 0px 10px 16px; -moz-box-shadow: rgba(11, 140, 27, 0.5) 0px 10px 16px; /* FF 3.5+ */ box-shadow: rgba(11, 140, 27, 0.5) 0px 10px 16px; /* FF 3.5+ */ } .black-circle { display: block; height: 23px; width: 23px; background-color: #040; -moz-border-radius: 11px; -webkit-border-radius: 11px; -khtml-border-radius: 11px; border-radius: 11px; margin-left: 1px; -webkit-box-shadow: rgba(11, 140, 27, 0.5) 0px 10px 16px; -moz-box-shadow: rgba(11, 140, 27, 0.5) 0px 10px 16px; /* FF 3.5+ */ box-shadow: rgba(11, 140, 27, 0.5) 0px 10px 16px; /* FF 3.5+ */ } .glare { position: relative; top: 1; left: 5px; -webkit-border-radius: 10px; -moz-border-radius: 10px; -khtml-border-radius: 10px; border-radius: 10px; height: 1px; width: 13px; padding: 5px 0; background-color: rgba(200, 200, 200, 0.25); background-image: -webkit-gradient(linear, 0% 0%, 0% 95%, from(rgba(255, 255, 255, 0.7)), to(rgba(255, 255, 255, 0))); } </style> </head> <body> <div class="view"> <div class="header-wrapper"> <table border="0" align="center"><tr><td><h4>Стиль страницы:</h4></td><td><INPUT TYPE="button" VALUE="широкая" onClick="parent.location='/?page1'"></td><td><INPUT TYPE="button" VALUE=" узкая " onClick="parent.location='/?page0'"></td></tr></table> </div> <div class="group-wrapper"> <h2 align="center" >Температура на улице 0.0 °C </h2> <FORM> <table border="0" align="center"> <tr><td rowspan=4><table border="0" align="center"> <tr> <td><h4>01. Канал</h4></td> <td><INPUT TYPE="button" VALUE="ВКЛ " onClick="parent.location='/?Hd11'"></td> <td><INPUT TYPE="button" VALUE="ВЫКЛ" onClick="parent.location='/?Ld11'"></td> <td><div class='green-circle'><div class='glare'></div></div></td> </tr> <tr> <td><h4>02. Канал</h4></td> <td><INPUT TYPE="button" VALUE="ВКЛ " onClick="parent.location='/?Hd12'"></td> <td><INPUT TYPE="button" VALUE="ВЫКЛ" onClick="parent.location='/?Ld12'"></td> <td><div class='black-circle'><div class='glare'></div></div></td> </tr> <tr> <td><h4>03. Канал</h4></td> <td><INPUT TYPE="button" VALUE="ВКЛ " onClick="parent.location='/?Hd13'"></td> <td><INPUT TYPE="button" VALUE="ВЫКЛ" onClick="parent.location='/?Ld13'"></td> <td><div class='green-circle'><div class='glare'></div></div></td> </tr> <tr> <td><h4>04. Канал</h4></td> <td><INPUT TYPE="button" VALUE="ВКЛ " onClick="parent.location='/?Hd14'"></td> <td><INPUT TYPE="button" VALUE="ВЫКЛ" onClick="parent.location='/?Ld14'"></td> <td><div class='green-circle'><div class='glare'></div></div></td> </tr> <tr> <td><h4>05. Канал</h4></td> <td><INPUT TYPE="button" VALUE="ВКЛ " onClick="parent.location='/?Hd15'"></td> <td><INPUT TYPE="button" VALUE="ВЫКЛ" onClick="parent.location='/?Ld15'"></td> <td><div class='black-circle'><div class='glare'></div></div></td> </tr> <tr> <td><h4>06. Канал</h4></td> <td><INPUT TYPE="button" VALUE="ВКЛ " onClick="parent.location='/?Hd16'"></td> <td><INPUT TYPE="button" VALUE="ВЫКЛ" onClick="parent.location='/?Ld16'"></td> <td><div class='black-circle'><div class='glare'></div></div></td> </tr> <tr> <td><h4>07. Канал</h4></td> <td><INPUT TYPE="button" VALUE="ВКЛ " onClick="parent.location='/?Hd17'"></td> <td><INPUT TYPE="button" VALUE="ВЫКЛ" onClick="parent.location='/?Ld17'"></td> <td><div class='green-circle'><div class='glare'></div></div></td> </tr> <tr> <td><h4>08. Канал</h4></td> <td><INPUT TYPE="button" VALUE="ВКЛ " onClick="parent.location='/?Hd18'"></td> <td><INPUT TYPE="button" VALUE="ВЫКЛ" onClick="parent.location='/?Ld18'"></td> <td><div class='black-circle'><div class='glare'></div></div></td> </tr> <tr> <td><h4>09. Канал</h4></td> <td><INPUT TYPE="button" VALUE="ВКЛ " onClick="parent.location='/?Hd19'"></td> <td><INPUT TYPE="button" VALUE="ВЫКЛ" onClick="parent.location='/?Ld19'"></td> <td><div class='green-circle'><div class='glare'></div></div></td> </tr> <tr> <td><h4>10. Канал</h4></td> <td><INPUT TYPE="button" VALUE="ВКЛ " onClick="parent.location='/?Hd20'"></td> <td><INPUT TYPE="button" VALUE="ВЫКЛ" onClick="parent.location='/?Ld20'"></td> <td><div class='black-circle'><div class='glare'></div></div></td> </tr> <tr> <td><h4>11. Канал</h4></td> <td><INPUT TYPE="button" VALUE="ВКЛ " onClick="parent.location='/?Hd21'"></td> <td><INPUT TYPE="button" VALUE="ВЫКЛ" onClick="parent.location='/?Ld21'"></td> <td><div class='black-circle'><div class='glare'></div></div></td> </tr> <tr> <td><h4>12. Канал</h4></td> <td><INPUT TYPE="button" VALUE="ВКЛ " onClick="parent.location='/?Hd22'"></td> <td><INPUT TYPE="button" VALUE="ВЫКЛ" onClick="parent.location='/?Ld22'"></td> <td><div class='black-circle'><div class='glare'></div></div></td> </tr> <tr> <td><h4>13. Канал</h4></td> <td><INPUT TYPE="button" VALUE="ВКЛ " onClick="parent.location='/?Hd23'"></td> <td><INPUT TYPE="button" VALUE="ВЫКЛ" onClick="parent.location='/?Ld23'"></td> <td><div class='black-circle'><div class='glare'></div></div></td> </tr> <tr> <td><h4>14. Канал</h4></td> <td><INPUT TYPE="button" VALUE="ВКЛ " onClick="parent.location='/?Hd24'"></td> <td><INPUT TYPE="button" VALUE="ВЫКЛ" onClick="parent.location='/?Ld24'"></td> <td><div class='black-circle'><div class='glare'></div></div></td> </tr> <tr> <td><h4>15. Канал</h4></td> <td><INPUT TYPE="button" VALUE="ВКЛ " onClick="parent.location='/?Hd25'"></td> <td><INPUT TYPE="button" VALUE="ВЫКЛ" onClick="parent.location='/?Ld25'"></td> <td><div class='green-circle'><div class='glare'></div></div></td> </tr> <tr> <td><h4>16. Канал</h4></td> <td><INPUT TYPE="button" VALUE="ВКЛ " onClick="parent.location='/?Hd26'"></td> <td><INPUT TYPE="button" VALUE="ВЫКЛ" onClick="parent.location='/?Ld26'"></td> <td><div class='green-circle'><div class='glare'></div></div></td> </tr> <tr> <td><h4>17. Канал</h4></td> <td><INPUT TYPE="button" VALUE="ВКЛ " onClick="parent.location='/?Hd27'"></td> <td><INPUT TYPE="button" VALUE="ВЫКЛ" onClick="parent.location='/?Ld27'"></td> <td><div class='green-circle'><div class='glare'></div></div></td> </tr> <tr> <td><h4>18. Канал</h4></td> <td><INPUT TYPE="button" VALUE="ВКЛ " onClick="parent.location='/?Hd28'"></td> <td><INPUT TYPE="button" VALUE="ВЫКЛ" onClick="parent.location='/?Ld28'"></td> <td><div class='black-circle'><div class='glare'></div></div></td> </tr> <tr> <td><h4>19. Канал</h4></td> <td><INPUT TYPE="button" VALUE="ВКЛ " onClick="parent.location='/?Hd29'"></td> <td><INPUT TYPE="button" VALUE="ВЫКЛ" onClick="parent.location='/?Ld29'"></td> <td><div class='black-circle'><div class='glare'></div></div></td> </tr> <tr> <td><h4>20. Канал</h4></td> <td><INPUT TYPE="button" VALUE="ВКЛ " onClick="parent.location='/?Hd30'"></td> <td><INPUT TYPE="button" VALUE="ВЫКЛ" onClick="parent.location='/?Ld30'"></td> <td><div class='black-circle'><div class='glare'></div></div></td> </tr> <tr> <td><h4>21. Канал</h4></td> <td><INPUT TYPE="button" VALUE="ВКЛ " onClick="parent.location='/?Hd31'"></td> <td><INPUT TYPE="button" VALUE="ВЫКЛ" onClick="parent.location='/?Ld31'"></td> <td><div class='black-circle'><div class='glare'></div></div></td> </tr> <tr> <td><h4>22. Канал</h4></td> <td><INPUT TYPE="button" VALUE="ВКЛ " onClick="parent.location='/?Hd32'"></td> <td><INPUT TYPE="button" VALUE="ВЫКЛ" onClick="parent.location='/?Ld32'"></td> <td><div class='black-circle'><div class='glare'></div></div></td> </tr> <tr> <td><h4>23. Канал</h4></td> <td><INPUT TYPE="button" VALUE="ВКЛ " onClick="parent.location='/?Hd33'"></td> <td><INPUT TYPE="button" VALUE="ВЫКЛ" onClick="parent.location='/?Ld33'"></td> <td><div class='green-circle'><div class='glare'></div></div></td> </tr> <tr> <td><h4>24. Канал</h4></td> <td><INPUT TYPE="button" VALUE="ВКЛ " onClick="parent.location='/?Hd34'"></td> <td><INPUT TYPE="button" VALUE="ВЫКЛ" onClick="parent.location='/?Ld34'"></td> <td><div class='green-circle'><div class='glare'></div></div></td> </tr> <tr> <td colspan=2><INPUT TYPE="button" VALUE="Включить ВСЁ" onClick="parent.location='/?H100'"></td> <td colspan=2><INPUT TYPE="button" VALUE="Выключить ВСЁ" onClick="parent.location='/?L100'"></td> <td></td> <td></td> </tr> <tr> <td colspan=2><INPUT TYPE="button" VALUE="Записать" onClick="parent.location='/?save'"></td> <td colspan=2><INPUT TYPE="button" VALUE="Сбросить" onClick="parent.location='/?reset'"></td> <td></td> <td></td> </tr> </table> </td><td height="86"><table border="0" align="center"> <tr><td></td><td><h3>текущая</h3></td><td><h3>обогрев</h3></td><td><h3>желаемая</h3></td></tr><tr><td><h4>Первый этаж:</h4></td><td align="center">21.0 °C</td><td align="center"><font color=red><b>ВЫКЛ</b></font></td> <td align="center"> 16 °C</td> </tr><tr><td><h4>Установить:</h4></td> <td colspan=3><table border="0"><tr><td><INPUT TYPE="button" VALUE="0" onClick="parent.location='/?T1=0'"></td> <td><INPUT TYPE="button" VALUE="5" onClick="parent.location='/?T1=5'"></td> <td><INPUT TYPE="button" VALUE="10" onClick="parent.location='/?T1=10'"></td> <td><INPUT TYPE="button" VALUE="20" onClick="parent.location='/?T1=20'"></td> <td><INPUT TYPE="button" VALUE="22" onClick="parent.location='/?T1=22'"></td> <td><INPUT TYPE="button" VALUE="24" onClick="parent.location='/?T1=24'"></td></tr></table></td></tr><tr><td><h4>Точно:</h4></td><td></td> <td colspan=2><form><input type=text name=T1 size=10> <input type=submit value=ОК> </form></td></tr></table> </td></tr><tr><td height="86"><table border="0" align="center"> <tr><td></td><td><h3>текущая</h3></td><td><h3>обогрев</h3></td><td><h3>желаемая</h3></td></tr><tr><td><h4>Второй этаж:</h4></td><td align="center">22.0 °C</td><td align="center"><font color=green><b>ВКЛ</b></font></td> <td align="center"> 23 °C</td> </tr><tr><td><h4>Установить:</h4></td> <td colspan=3><table border="0"><tr><td><INPUT TYPE="button" VALUE="0" onClick="parent.location='/?T2=0'"></td> <td><INPUT TYPE="button" VALUE="5" onClick="parent.location='/?T2=5'"></td> <td><INPUT TYPE="button" VALUE="10" onClick="parent.location='/?T2=10'"></td> <td><INPUT TYPE="button" VALUE="20" onClick="parent.location='/?T2=20'"></td> <td><INPUT TYPE="button" VALUE="22" onClick="parent.location='/?T2=22'"></td> <td><INPUT TYPE="button" VALUE="24" onClick="parent.location='/?T2=24'"></td></tr></table></td></tr><tr><td><h4>Точно:</h4></td><td></td> <td colspan=2><form><input type=text name=T2 size=10> <input type=submit value=ОК> </form></td></tr></table> </td></tr><tr><td height="86"><table border="0" align="center"> <tr><td></td><td><h3>текущая</h3></td><td><h3>обогрев</h3></td><td><h3>желаемая</h3></td></tr><tr><td><h4>Кухня:</h4></td><td align="center">0.0 °C</td><td align="center"><font color=green><b>ВКЛ</b></font></td> <td align="center"> 28 °C</td> </tr><tr><td><h4>Установить:</h4></td> <td colspan=3><table border="0"><tr><td><INPUT TYPE="button" VALUE="0" onClick="parent.location='/?T3=0'"></td> <td><INPUT TYPE="button" VALUE="5" onClick="parent.location='/?T3=5'"></td> <td><INPUT TYPE="button" VALUE="10" onClick="parent.location='/?T3=10'"></td> <td><INPUT TYPE="button" VALUE="20" onClick="parent.location='/?T3=20'"></td> <td><INPUT TYPE="button" VALUE="22" onClick="parent.location='/?T3=22'"></td> <td><INPUT TYPE="button" VALUE="24" onClick="parent.location='/?T3=24'"></td></tr></table></td></tr><tr><td><h4>Точно:</h4></td><td></td> <td colspan=2><form><input type=text name=T3 size=10> <input type=submit value=ОК> </form></td></tr></table> </td></tr><tr><td height="86"><table border="0" align="center"> <tr><td></td><td><h3>1 этаж</h3></td><td><h3>2 этаж</h3</td><td><h3>кухня</h3</td><td><h3>баня</h3</td></tr><tr><td><h4>Влажность:</h4></td><td align="center"> 35 %</td> <td align="center"> 29 %</td> <td align="center"> 60 %</td> <td align="center"> 74 %</td> </tr></table> </td></tr></table> </FORM> <h3 align="center">©- Plagiary - <br> 774 KM - 2016 - V1.4 </h3></div> </div> </body> </html>uservasil, не совсем понял касательно скетча и отдельного html.
Весь html код лежит в ардуинке? Или основная масса где-то на хостинге, а ардуинка отдает только параметры датчиков и принимает команды с хостинга?
Молодец, прогресс реально виден. Если позволишь - пару советов:
1. Строки лучше таки хранить во флеше: есть макрос F очень удобный ;) У тебя, как заметил - не везде ещё он воткнут.
2. Оптимизацию когда будешь делать, вот такие места:
if(command.substring(3).toInt()>=0&&command.substring(3).toInt()<=28)Лучше, конечно, чуть переписать - зачем дёргать два раз substring, дважды создавая локальные объекты String, если можно это сделать один раз?
Продолжай, проект интересный. Самому интересно, без дураков. Но у меня интерес несколько другого свойства, статистический, так сказать - хочу посмотреть, на чём ты остановишься. Не в плохом смысле (а то опять обвинят ни за что) - а в том смысле - когда увидишь границу применимости такого подхода. Скажу про себя - не далее как сегодня полностью отказался от идеи хранения вебморды на МК, и перевёл всё на простые шлюзы UART-TCP, ибо, как показала практика, не барское это дело - обслуживать вебморду из МК, которая, кстати, может быть ооочень объёмной, плюс ещё и аггрегированной с другими частями умного дома. В малом приближении - да, зашибись и удобно, в большом - начинают жать маленькие ресурсы дуины.
Это я всё к тому - какой у меня к твоему проекту интерес ;) Напоследок - закину удочку: подумай про openWRT, как вариант ;) Тогда МК будет заниматься обслуживанием периферии, а всё управление ардуиной будет через роутер, с жирной вебморды, простыми командами. При необходимости поменять оформление вебморды - не надо будет перезаливать прошивку. Я не нестаиваю на этом варианте как на единственно верном, просто хочу показать ещё один путь для развития проекта.
Да, стало интереснее. Тоже задам пару глупых вопросов:
1-24 каналы - там на них реально что-то висит? По скетчу увидел только три реле. И что будет по "Включить все"?
И по датчикам температуры то же самое. В скетче прописано два - выводит с четырех. Сколько их всего?
Да, стало интереснее. Тоже задам пару глупых вопросов:
1-24 каналы - там на них реально что-то висит? По скетчу увидел только три реле. И что будет по "Включить все"?
И по датчикам температуры то же самое. В скетче прописано два - выводит с четырех. Сколько их всего?
Воот, начальник транспортного цеха поднял совершенно справедливые вопросы ;) Которые сразу приводят нас к необходимости, как минимум, автоматического подстраивания внешнего вида вебморды к тому - сколько реально каналов используется в прошивке, сколько датчиков температуры есть и т.п.
К чему пришёл я, когда столкнулся с подобным вопросом: команды, по которым МК отдаёт кол-во датчиков температуры, кол-во датчиков влажности и тому подобные вещи. Как следствие - можно при первом опросе контроллера получить его полный внутренний слепок, так сказать.
В прошивке ТС данную проблему можно решить директивами условной компиляции - и тогда всё будет намного прозрачнее для конечного пользователя прошивки: не придётся искать места, где выпилить кусок кода, если используется не 20 каналов, а всего 5, например.
Да, весь html лежит в eeprom.
1. Строки лучше таки хранить во флеше: есть макрос F очень удобный ;) У тебя, как заметил - не везде ещё он воткнут.
2. Оптимизацию когда будешь делать, вот такие места:
if(command.substring(3).toInt()>=0&&command.substring(3).toInt()<=28)Лучше, конечно, чуть переписать - зачем дёргать два раз substring, дважды создавая локальные объекты String, если можно это сделать один раз?
3. подумай про openWRT, как вариант ;) Тогда МК будет заниматься обслуживанием периферии, а всё управление ардуиной будет через роутер, с жирной вебморды, простыми командами. При необходимости поменять оформление вебморды - не надо будет перезаливать прошивку.
1. пока ОЗУ не забито, поэтому и не везде, это заметно влияет на скорость ответа.
2. присвоить значение переменной, потом работать с ней?
int comInt =command.substring(3).toInt();if({}comInt>=0&&comInt<=28)3. Спасибо за советы, обязательно ознакомлюсь. Пока хочется по максимуму загрузить МЕГУ, а еслу будет поджимать планировал смотреть в сторону промышленных терминалов =)
1-24 каналы - там на них реально что-то висит? По скетчу увидел только три реле. И что будет по "Включить все"?
И по датчикам температуры то же самое. В скетче прописано два - выводит с четырех. Сколько их всего?
Железка пока на работе, в скором времени переедет на дачу где установлено инфракрасное отопление, 3 реле которые управляются заданием требуемой температуры, каналы 1-24 будут подключены к освещению (14-16 каналов) и к некотороым розеткам и т.д.. В данный момент подключено 3 датчика температуры, в недалеком будущем их будет около 10-13 которые будут отображать температуру на улине, помещений, бани, парилки, дымоходной трубы, воды холодной и горячей и т.д. В перспективе подключить солнечный коллектор, насос, датчики давления и расхода воды, и многое другое =)
Подключил промышленный БП к Vin шилда W5100 и выставил на нем 6 вольт, питание на плате поднялось до 5,06 вольт, проблема с зависанием железки отпала!
Версия 1.5:
добавлено:
1. связь с OPC сервером по Ehternet
2. управление в SCADA Simple-Scada 2 (beta)
3. причесал и местами изменил говнокод =)
HTML:
SCADA:
скетч:
#include <Ethernet.h> #include <SPI.h> #include <EEPROM.h> #include <DHT.h> #include <OneWire.h> #include <OPC.h> #include <Bridge.h> //////////////////////////////////////////////////////////////////////// //CONFIGURATION //////////////////////////////////////////////////////////////////////// //IP manual settings byte ip[] = { 10, 16, 30, 2 }; //Manual setup only byte gateway[] = { 10, 16, 30, 3 }; //Manual setup only byte subnet[] = { 255, 255, 255, 0 }; //Manual setup only // if need to change the MAC address (Very Rare) byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; //Ethernet Port EthernetServer server = EthernetServer(80); //default html port 80 //The number of outputs going to be switched. int outputQuantity = 24; //should not exceed 10 //Invert the output of the leds boolean outputInverted = false; //true or false // This is done in case the relay board triggers the relay on negative, rather then on positive supply //Html page refresh int refreshPage = 15; //default is 10sec. int outputAddress[24] = { 3,5,6,7,8,9,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31}; //Allocate 10 spaces and name the output pin address. //PS pin addresses 10, 11, 12 and 13 on the Duemilanove are used for the ethernet shield, therefore cannot be used. //PS pin addresses 10, 50, 51 and 52 and 53 on the Mega are used for the ethernet shield, therefore cannot be used. //PS pin addresses 4, are used for the SD card, therefore cannot be used. //PS. pin address 2 is used for interrupt-driven notification, therefore could not be used. // Write the text description of the output channel String buttonText[24] = { "01. Канал","02. Канал","03. Канал","04. Канал","05. Канал","06. Канал","07. Канал","08. Канал","09. Канал","10. Канал","11. Канал","12. Канал","13. Канал","14. Канал","15. Канал","16. Канал","17. Канал","18. Канал","19. Канал","20. Канал","21. Канал","22. Канал","23. Канал","24. Канал"}; int twenty[] = {11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34}; int outp = 0; boolean printLastCommandOnce = false; boolean printButtonMenuOnce = false; boolean initialPrint = true; boolean reading = false; boolean outputStatus[24]; //Create a boolean array for the maximum ammount. String rev = "V1.5"; unsigned long timeConnectedAt; boolean writeToEeprom = false; int page=1; //////////////////////////////////////////////////////////////////////// // упрвавления температурой //////////////////////////////////////////////////////////////////////// const byte PinSSR1 = 44; // Реле Pin for SSR 1 const byte PinSSR2 = 45; // Реле Pin for SSR 2 const byte PinSSR3 = 46; // Реле Pin for SSR 3 char chartemp1[10]; char chartemp2[10]; char chartemp3[10]; char chartemp4[10]; int TargetTemp1; int TargetTemp2; int TargetTemp3; int Humidity1; int Humidity2; float temp1; float temp2; float temp3; float temp4; OneWire ds(47); DHT dht1(48, DHT11); DHT dht2(49, DHT11); //////////////////////////////////////////////////////////////////////// //мигание светодиода //////////////////////////////////////////////////////////////////////// const int ledPin = 33; // номер выхода, подключенного к светодиоду // Variables will change: int ledState = LOW; // этой переменной устанавливаем состояние светодиода long previousMillis = 0; // храним время последнего переключения светодиода long interval = 1000; // интервал между включение/выключением светодиода (1 секунда) //////////////////////////////////////////////////////////////////////// // описываем ОРС //////////////////////////////////////////////////////////////////////// OPCEthernet aOPCEthernet; // порт const int listen_port = 88; // функции ОРС сервера int RealTemp1OPC(const char *itemID, const opcOperation opcOP, const int value){ return temp1; } int RealTemp2OPC(const char *itemID, const opcOperation opcOP, const int value){ return temp2; } int RealTemp3OPC(const char *itemID, const opcOperation opcOP, const int value){ return temp3; } int TargetTemp1OPC(const char *itemID, const opcOperation opcOP, const int value){ if (opcOP == opc_opwrite) {TargetTemp1 = value;} else return TargetTemp1; } int TargetTemp2OPC(const char *itemID, const opcOperation opcOP, const int value){ if (opcOP == opc_opwrite) {TargetTemp2 = value;} else return TargetTemp2; } int TargetTemp3OPC(const char *itemID, const opcOperation opcOP, const int value){ if (opcOP == opc_opwrite) {TargetTemp3 = value;} else return TargetTemp3; } bool D1_OPC(const char *itemID, const opcOperation opcOP, const bool value){ static bool ledValue = false; if (opcOP == opc_opwrite) { ledValue = value; if (ledValue) {digitalWrite(outputAddress[0], HIGH);} else digitalWrite(outputAddress[0], LOW); } else return digitalRead(outputAddress[0]); } bool D2_OPC(const char *itemID, const opcOperation opcOP, const bool value){ static bool ledValue = false; if (opcOP == opc_opwrite) { ledValue = value; if (ledValue) {digitalWrite(outputAddress[1], HIGH);} else digitalWrite(outputAddress[1], LOW); } else return digitalRead(outputAddress[1]); } bool D3_OPC(const char *itemID, const opcOperation opcOP, const bool value){ static bool ledValue = false; if (opcOP == opc_opwrite) { ledValue = value; if (ledValue) {digitalWrite(outputAddress[2], HIGH);} else digitalWrite(outputAddress[2], LOW); } else return digitalRead(outputAddress[2]); } bool D4_OPC(const char *itemID, const opcOperation opcOP, const bool value){ static bool ledValue = false; if (opcOP == opc_opwrite) { ledValue = value; if (ledValue) {digitalWrite(outputAddress[3], HIGH);} else digitalWrite(outputAddress[3], LOW); } else return digitalRead(outputAddress[3]); } bool D5_OPC(const char *itemID, const opcOperation opcOP, const bool value){ static bool ledValue = false; if (opcOP == opc_opwrite) { ledValue = value; if (ledValue) {digitalWrite(outputAddress[4], HIGH);} else digitalWrite(outputAddress[4], LOW); } else return digitalRead(outputAddress[4]); } bool D6_OPC(const char *itemID, const opcOperation opcOP, const bool value){ static bool ledValue = false; if (opcOP == opc_opwrite) { ledValue = value; if (ledValue) {digitalWrite(outputAddress[5], HIGH);} else digitalWrite(outputAddress[5], LOW); } else return digitalRead(outputAddress[5]); } bool D7_OPC(const char *itemID, const opcOperation opcOP, const bool value){ static bool ledValue = false; if (opcOP == opc_opwrite) { ledValue = value; if (ledValue) {digitalWrite(outputAddress[6], HIGH);} else digitalWrite(outputAddress[6], LOW); } else return digitalRead(outputAddress[6]); } bool D8_OPC(const char *itemID, const opcOperation opcOP, const bool value){ static bool ledValue = false; if (opcOP == opc_opwrite) { ledValue = value; if (ledValue) {digitalWrite(outputAddress[7], HIGH);} else digitalWrite(outputAddress[7], LOW); } else return digitalRead(outputAddress[7]); } bool D9_OPC(const char *itemID, const opcOperation opcOP, const bool value){ static bool ledValue = false; if (opcOP == opc_opwrite) { ledValue = value; if (ledValue) {digitalWrite(outputAddress[8], HIGH);} else digitalWrite(outputAddress[8], LOW); } else return digitalRead(outputAddress[8]); } bool D10_OPC(const char *itemID, const opcOperation opcOP, const bool value){ static bool ledValue = false; if (opcOP == opc_opwrite) { ledValue = value; if (ledValue) {digitalWrite(outputAddress[9], HIGH);} else digitalWrite(outputAddress[9], LOW); } else return digitalRead(outputAddress[9]); } bool D11_OPC(const char *itemID, const opcOperation opcOP, const bool value){ static bool ledValue = false; if (opcOP == opc_opwrite) { ledValue = value; if (ledValue) {digitalWrite(outputAddress[10], HIGH);} else digitalWrite(outputAddress[10], LOW); } else return digitalRead(outputAddress[10]); } bool D12_OPC(const char *itemID, const opcOperation opcOP, const bool value){ static bool ledValue = false; if (opcOP == opc_opwrite) { ledValue = value; if (ledValue) {digitalWrite(outputAddress[11], HIGH);} else digitalWrite(outputAddress[11], LOW); } else return digitalRead(outputAddress[11]); } bool D13_OPC(const char *itemID, const opcOperation opcOP, const bool value){ static bool ledValue = false; if (opcOP == opc_opwrite) { ledValue = value; if (ledValue) {digitalWrite(outputAddress[12], HIGH);} else digitalWrite(outputAddress[12], LOW); } else return digitalRead(outputAddress[12]); } bool D14_OPC(const char *itemID, const opcOperation opcOP, const bool value){ static bool ledValue = false; if (opcOP == opc_opwrite) { ledValue = value; if (ledValue) {digitalWrite(outputAddress[13], HIGH);} else digitalWrite(outputAddress[13], LOW); } else return digitalRead(outputAddress[13]); } bool D15_OPC(const char *itemID, const opcOperation opcOP, const bool value){ static bool ledValue = false; if (opcOP == opc_opwrite) { ledValue = value; if (ledValue) {digitalWrite(outputAddress[14], HIGH);} else digitalWrite(outputAddress[14], LOW); } else return digitalRead(outputAddress[14]); } bool D16_OPC(const char *itemID, const opcOperation opcOP, const bool value){ static bool ledValue = false; if (opcOP == opc_opwrite) { ledValue = value; if (ledValue) {digitalWrite(outputAddress[15], HIGH);} else digitalWrite(outputAddress[15], LOW); } else return digitalRead(outputAddress[15]); } bool D17_OPC(const char *itemID, const opcOperation opcOP, const bool value){ static bool ledValue = false; if (opcOP == opc_opwrite) { ledValue = value; if (ledValue) {digitalWrite(outputAddress[16], HIGH);} else digitalWrite(outputAddress[16], LOW); } else return digitalRead(outputAddress[16]); } bool D18_OPC(const char *itemID, const opcOperation opcOP, const bool value){ static bool ledValue = false; if (opcOP == opc_opwrite) { ledValue = value; if (ledValue) {digitalWrite(outputAddress[17], HIGH);} else digitalWrite(outputAddress[17], LOW); } else return digitalRead(outputAddress[17]); } bool D19_OPC(const char *itemID, const opcOperation opcOP, const bool value){ static bool ledValue = false; if (opcOP == opc_opwrite) { ledValue = value; if (ledValue) {digitalWrite(outputAddress[18], HIGH);} else digitalWrite(outputAddress[18], LOW); } else return digitalRead(outputAddress[18]); } bool D20_OPC(const char *itemID, const opcOperation opcOP, const bool value){ static bool ledValue = false; if (opcOP == opc_opwrite) { ledValue = value; if (ledValue) {digitalWrite(outputAddress[19], HIGH);} else digitalWrite(outputAddress[19], LOW); } else return digitalRead(outputAddress[19]); } bool D21_OPC(const char *itemID, const opcOperation opcOP, const bool value){ static bool ledValue = false; if (opcOP == opc_opwrite) { ledValue = value; if (ledValue) {digitalWrite(outputAddress[20], HIGH);} else digitalWrite(outputAddress[20], LOW); } else return digitalRead(outputAddress[20]); } bool D22_OPC(const char *itemID, const opcOperation opcOP, const bool value){ static bool ledValue = false; if (opcOP == opc_opwrite) { ledValue = value; if (ledValue) {digitalWrite(outputAddress[21], HIGH);} else digitalWrite(outputAddress[21], LOW); } else return digitalRead(outputAddress[21]); } bool D23_OPC(const char *itemID, const opcOperation opcOP, const bool value){ static bool ledValue = false; if (opcOP == opc_opwrite) { ledValue = value; if (ledValue) {digitalWrite(outputAddress[22], HIGH);} else digitalWrite(outputAddress[22], LOW); } else return digitalRead(outputAddress[22]); } bool D24_OPC(const char *itemID, const opcOperation opcOP, const bool value){ static bool ledValue = false; if (opcOP == opc_opwrite) { ledValue = value; if (ledValue) {digitalWrite(outputAddress[23], HIGH);} else digitalWrite(outputAddress[23], LOW); } else return digitalRead(outputAddress[23]); } //////////////////////////////////////////////////////////////////////// //RUN ONCE //////////////////////////////////////////////////////////////////////// //Beginning of Program void setup(){ // мигаем светодиодом pinMode(ledPin, OUTPUT); Serial.begin(9600); initEepromValues(); readEepromValues(); //Set pins as Outputs boolean currentState = false; for (int var = 0; var < outputQuantity; var++){ pinMode(outputAddress[var], OUTPUT); //Switch all outputs to either on or off on Startup if(outputInverted == true) { //digitalWrite(outputAddress[var], HIGH); if(outputStatus[var] == 0){currentState = true;}else{currentState = false;} //check outputStatus if off, switch output accordingly digitalWrite(outputAddress[var], currentState); } else{ //digitalWrite(outputAddress[var], LOW); if(outputStatus[var] == 0){currentState = false;}else{currentState = true;}//check outputStatus if off, switch output accordingly digitalWrite(outputAddress[var], currentState); } } //Setting up the IP address. Comment out the one you dont need. //Ethernet.begin(mac); //for DHCP address. (Address will be printed to serial.) Ethernet.begin(mac, ip, gateway, subnet); //for manual setup. (Address is the one configured above.) server.begin(); Serial.print("Server started at "); Serial.println(Ethernet.localIP()); ////////////////управление температурой pinMode(PinSSR1, OUTPUT); pinMode(PinSSR2, OUTPUT); pinMode(PinSSR3, OUTPUT); TargetTemp1 = EEPROM.read(1000); TargetTemp2 = EEPROM.read(1002); TargetTemp3 = EEPROM.read(1004); dht1.begin(); dht2.begin(); // OPCNet Object initialization aOPCEthernet.setup(listen_port,mac,ip); // OPCItem declaration aOPCEthernet.addItem("rt1",opc_read, opc_int, RealTemp1OPC); aOPCEthernet.addItem("rt2",opc_read, opc_int, RealTemp2OPC); aOPCEthernet.addItem("rt3",opc_read, opc_int, RealTemp3OPC); aOPCEthernet.addItem("wt1",opc_readwrite, opc_int, TargetTemp1OPC); aOPCEthernet.addItem("wt2",opc_readwrite, opc_int, TargetTemp2OPC); aOPCEthernet.addItem("wt3",opc_readwrite, opc_int, TargetTemp3OPC); aOPCEthernet.addItem("D1_OPC",opc_readwrite, opc_bool, D1_OPC); aOPCEthernet.addItem("D2_OPC",opc_readwrite, opc_bool, D2_OPC); aOPCEthernet.addItem("D3_OPC",opc_readwrite, opc_bool, D3_OPC); aOPCEthernet.addItem("D4_OPC",opc_readwrite, opc_bool, D4_OPC); aOPCEthernet.addItem("D5_OPC",opc_readwrite, opc_bool, D5_OPC); aOPCEthernet.addItem("D6_OPC",opc_readwrite, opc_bool, D6_OPC); aOPCEthernet.addItem("D7_OPC",opc_readwrite, opc_bool, D7_OPC); aOPCEthernet.addItem("D8_OPC",opc_readwrite, opc_bool, D8_OPC); aOPCEthernet.addItem("D9_OPC",opc_readwrite, opc_bool, D9_OPC); aOPCEthernet.addItem("D10_OPC",opc_readwrite, opc_bool, D10_OPC); aOPCEthernet.addItem("D11_OPC",opc_readwrite, opc_bool, D11_OPC); aOPCEthernet.addItem("D12_OPC",opc_readwrite, opc_bool, D12_OPC); aOPCEthernet.addItem("D13_OPC",opc_readwrite, opc_bool, D13_OPC); aOPCEthernet.addItem("D14_OPC",opc_readwrite, opc_bool, D14_OPC); aOPCEthernet.addItem("D15_OPC",opc_readwrite, opc_bool, D15_OPC); aOPCEthernet.addItem("D16_OPC",opc_readwrite, opc_bool, D16_OPC); aOPCEthernet.addItem("D17_OPC",opc_readwrite, opc_bool, D17_OPC); aOPCEthernet.addItem("D18_OPC",opc_readwrite, opc_bool, D18_OPC); aOPCEthernet.addItem("D19_OPC",opc_readwrite, opc_bool, D19_OPC); aOPCEthernet.addItem("D20_OPC",opc_readwrite, opc_bool, D20_OPC); aOPCEthernet.addItem("D21_OPC",opc_readwrite, opc_bool, D21_OPC); aOPCEthernet.addItem("D22_OPC",opc_readwrite, opc_bool, D22_OPC); aOPCEthernet.addItem("D23_OPC",opc_readwrite, opc_bool, D23_OPC); aOPCEthernet.addItem("D24_OPC",opc_readwrite, opc_bool, D24_OPC); } // end void setup() //////////////////////////////////////////////////////////////////////// //LOOP /////////////////////////////////////// //////////////////////////////// void loop(){ // мигаем светодиодом unsigned long currentMillis = millis(); //проверяем не прошел ли нужный интервал, если прошел то if(currentMillis - previousMillis > interval) { // сохраняем время последнего переключения previousMillis = currentMillis; // если светодиод не горит, то зажигаем, и наоборот if (ledState == LOW) ledState = HIGH; else ledState = LOW; // устанавливаем состояния выхода, чтобы включить или выключить светодиод digitalWrite(ledPin, ledState); } // listen for incoming clients, and process requests. checkForClient(); ///////////////////////управление температурой byte sensor1[8] = {0x28, 0xFF, 0x34, 0x2C, 0x50, 0x15, 0x01, 0x87}; // Адрес сенсора byte sensor2[8] = {0x28, 0xDF, 0x7E, 0xDC, 0x06, 0x00, 0x00, 0xF3}; // Адрес сенсора //DHT temp1 = dht1.readTemperature(); dtostrf(temp1, 3, 1, chartemp1); Humidity1=dht1.readHumidity(); temp2 = dht2.readTemperature(); dtostrf(temp2, 3, 1, chartemp2); Humidity2=dht2.readHumidity(); //DS18B20 temp3 = tempread(sensor1); dtostrf(temp3, 3, 1, chartemp3); temp4 = tempread(sensor2); dtostrf(temp4, 3, 1, chartemp4); if (TargetTemp1==0) { digitalWrite(PinSSR1, HIGH); } else { if (temp1<TargetTemp1-0.5) { digitalWrite(PinSSR1, LOW); } else if (temp1>TargetTemp1+0.5) { digitalWrite(PinSSR1, HIGH); } } if (TargetTemp2==0) { digitalWrite(PinSSR2, HIGH); } else { if (temp2<TargetTemp2-0.5) { digitalWrite(PinSSR2, LOW); } else if (temp2>TargetTemp2+0.5) { digitalWrite(PinSSR2, HIGH); } } if (TargetTemp3==0) { digitalWrite(PinSSR3, HIGH); } else { if (temp3<TargetTemp3-0.5) { digitalWrite(PinSSR3, LOW); } else if (temp3>TargetTemp3+0.5) { digitalWrite(PinSSR3, HIGH); } } // OPC process commands aOPCEthernet.processOPCCommands(); } ///// end void loop() //////////////////////////////////////////////////////////////////////// //checkForClient Function //////////////////////////////////////////////////////////////////////// void checkForClient(){ EthernetClient client = server.available(); if (client) { // an http request ends with a blank line boolean currentLineIsBlank = true; boolean sentHeader = false; String command; int repeat=0; //String tcommand; while (client.connected()) { if (client.available()) { //read user input char c = client.read(); if(c == '*'){ printHtmlHeader(client); //call for html header and css printHtmlFooter(client); //sentHeader = true; break; } if(!sentHeader){ printHtmlHeader(client); //call for html header and css printHtmlButtonTitle(client); //print the button title //This is for the arduino to construct the page on the fly. sentHeader = true; } //if there was reading but is blank there was no reading if(reading && c == ' '){ reading = false; } //http://10.16.30.2/?t1-10 //if there is a ? there was user input if(c == '?') { reading = true; //found the ?, begin reading the info command = F(""); // clear current command // tcommand = F(""); // clear current command } // if there was user input switch the relevant output if(reading){ //if user input is H set output to 1 if(c == 'H') { outp = 1; } //if user input is L set output to 0 if(c == 'L') { outp = 0; } if(c!='?'&&c!='H'&&c!='L') {command +=c;} repeat++; Serial.println(" "); Serial.print("repeat:"); Serial.print(repeat); if(repeat>=5){ if(command.substring(0,3) == "T1=") { if(command.substring(3).toInt()>=0&&command.substring(3).toInt()<=28) { TargetTemp1=command.substring(3).toInt();EEPROM.write(1000, TargetTemp1);Serial.println(" "); Serial.print("T1:"); Serial.print(TargetTemp1); } } if(command.substring(0,3) == "T2=") { if(command.substring(3).toInt()>=0&&command.substring(3).toInt()<=28) { TargetTemp2=command.substring(3).toInt();EEPROM.write(1002, TargetTemp2);Serial.println(" "); Serial.print("T2:"); Serial.print(TargetTemp2); } } if(command.substring(0,3) == "T3=") { if(command.substring(3).toInt()>=0&&command.substring(3).toInt()<=28) { TargetTemp3=command.substring(3).toInt();EEPROM.write(1004, TargetTemp3);Serial.println(" "); Serial.print("T3:"); Serial.print(TargetTemp3); } } if(command == "d11") {triggerPin(outputAddress[0], client, outp); Serial.println(" "); Serial.println("case 1 OK"); } if(command == "d12") {triggerPin(outputAddress[1], client, outp); Serial.println(" "); Serial.println("case 2 OK"); } if(command == "d13") {triggerPin(outputAddress[2], client, outp); Serial.println(" "); Serial.println("case 3 OK"); } if(command == "d14") {triggerPin(outputAddress[3], client, outp); Serial.println(" "); Serial.println("case 4 OK"); } if(command == "d15") {triggerPin(outputAddress[4], client, outp); Serial.println(" "); Serial.println("case 5 OK"); } if(command == "d16") {triggerPin(outputAddress[5], client, outp); Serial.println(" "); Serial.println("case 6 OK"); } if(command == "d17") {triggerPin(outputAddress[6], client, outp); Serial.println(" "); Serial.println("case 7 OK"); } if(command == "d18") {triggerPin(outputAddress[7], client, outp); Serial.println(" "); Serial.println("case 8 OK"); } if(command == "d19") {triggerPin(outputAddress[8], client, outp); Serial.println(" "); Serial.println("case 9 OK"); } if(command == "d20") {triggerPin(outputAddress[9], client, outp); Serial.println(" "); Serial.println("case 10 OK"); } if(command == "d21") {triggerPin(outputAddress[10], client, outp); Serial.println(" "); Serial.println("case 11 OK"); } if(command == "d22") {triggerPin(outputAddress[11], client, outp); Serial.println(" "); Serial.println("case 12 OK"); } if(command == "d23") {triggerPin(outputAddress[12], client, outp); Serial.println(" "); Serial.println("case 13 OK"); } if(command == "d24") {triggerPin(outputAddress[13], client, outp); Serial.println(" "); Serial.println("case 14 OK"); } if(command == "d25") {triggerPin(outputAddress[14], client, outp); Serial.println(" "); Serial.println("case 15 OK"); } if(command == "d26") {triggerPin(outputAddress[15], client, outp); Serial.println(" "); Serial.println("case 16 OK"); } if(command == "d27") {triggerPin(outputAddress[16], client, outp); Serial.println(" "); Serial.println("case 17 OK"); } if(command == "d28") {triggerPin(outputAddress[17], client, outp); Serial.println(" "); Serial.println("case 18 OK"); } if(command == "d29") {triggerPin(outputAddress[18], client, outp); Serial.println(" "); Serial.println("case 19 OK"); } if(command == "d30") {triggerPin(outputAddress[19], client, outp); Serial.println(" "); Serial.println("case 20 OK"); } if(command == "d31") {triggerPin(outputAddress[20], client, outp); Serial.println(" "); Serial.println("case 21 OK"); } if(command == "d32") {triggerPin(outputAddress[21], client, outp); Serial.println(" "); Serial.println("case 22 OK"); } if(command == "d33") {triggerPin(outputAddress[22], client, outp); Serial.println(" "); Serial.println("case 23 OK"); } if(command == "d34") {triggerPin(outputAddress[23], client, outp); Serial.println(" "); Serial.println("case 24 OK"); } if(command == "100"){ for (int var = 0; var < outputQuantity; var++) { triggerPin(outputAddress[var], client, outp); } } if(command == "page1") {page=1; Serial.println(" "); Serial.println("page 1 OK"); } if(command == "page0") {page=0; Serial.println(" "); Serial.println("page 0 OK"); } if(command == "save") {writeEepromValues(); Serial.println(" "); Serial.println("save"); } if(command == "reset") {resetEepromValues(); Serial.println(" "); Serial.println("reset"); } }// end repeat }//end if(reading) //if user input was blank if (c == '\n' && currentLineIsBlank){ printLastCommandOnce = true; printButtonMenuOnce = true; triggerPin(777, client, outp); //Call to read input and print menu. 777 is used not to update any outputs break; } } // end if (client.available()) } // end whil Serial.println(" "); Serial.print("command:"); Serial.print(command); Serial.println(" "); Serial.println("----------"); printHtmlFooter(client); //Prints the html footer } else { //if there is no client // таймаут простоя, для записи данных состояния переключателей в кэш if (millis() > (timeConnectedAt + 3600000)){ if (writeToEeprom == true){ writeEepromValues(); //write to EEprom the current output statuses Serial.println("No Clients for more then a 60 min. - Writing statuses to Eeprom."); writeToEeprom = false; } } } } /////////////////////////////////////////////////////////////////////// //triggerPin Function //////////////////////////////////////////////////////////////////////// void triggerPin(int pin, EthernetClient client, int outp){ //Switching on or off outputs, reads the outputs and prints the buttons //Setting Outputs if (pin != 777){ if(outp == 1) { if (outputInverted ==false){ digitalWrite(pin, HIGH); } else{ digitalWrite(pin, LOW); } } if(outp == 0){ if (outputInverted ==false){ digitalWrite(pin, LOW); } else{ digitalWrite(pin, HIGH); } } Serial.println(" "); Serial.print("triggerPin:"); Serial.print(pin); Serial.println(" OK"); } //Refresh the reading of outputs readOutputStatuses(); //Prints the buttons if (printButtonMenuOnce == true){ printHtmlButtons(client); printButtonMenuOnce = false; } } //////////////////////////////////////////////////////////////////////// //printHtmlButtons Function //////////////////////////////////////////////////////////////////////// void printHtmlButtons(EthernetClient client){ client.println(""); client.println("<FORM>"); //вывод таблиц управления температурой if (page == 1){ client.println("<table border=\"0\" align=\"center\">"); client.print("<tr>"); client.print("<td rowspan=4>"); } //вывод текста, кнопок ON и OFF и лампочек состояния client.println("<table border=\"0\" align=\"center\">"); for (int var = 0; var < outputQuantity; var++) { //Print begining of row client.print("<tr>\n"); //Prints the button Text client.print("<td><h4>"); client.print(buttonText[var]); client.print("</h4></td>\n"); //Prints the ON Buttons client.print("<td>"); client.print("<INPUT TYPE=\"button\" VALUE=\"ВКЛ "); client.print("\" onClick=\"parent.location='/?H"); client.print("d"); client.print(twenty[var]); client.print("'\"></td>\n"); //Prints the OFF Buttons client.print(" <td><INPUT TYPE=\"button\" VALUE=\"ВЫКЛ"); client.print("\" onClick=\"parent.location='/?L"); client.print("d"); client.print(twenty[var]); client.print("'\"></td>\n"); //Print first part of the Circles or the LEDs //Invert the LED display if output is inverted. if (outputStatus[var] == true ){ //If Output is ON if (outputInverted == false){ //and if output is not inverted client.print(" <td><div class='green-circle'><div class='glare'></div></div></td>\n"); //Print html for ON LED } else{ //else output is inverted then client.print(" <td><div class='black-circle'><div class='glare'></div></div></td>\n"); //Print html for OFF LED } } else //If Output is Off { if (outputInverted == false){ //and if output is not inverted client.print(" <td><div class='black-circle'><div class='glare'></div></div></td>\n"); //Print html for OFF LED } else{ //else output is inverted then client.print(" <td><div class='green-circle'><div class='glare'></div></div></td>\n"); //Print html for ON LED } } client.print("</tr>\n"); } // end for //Prints the ON All Pins Button client.print("<tr>\n<td colspan=2><INPUT TYPE=\"button\" VALUE=\"Включить ВСЁ"); client.print("\" onClick=\"parent.location='/?H100"); client.print("'\"></td>\n"); //Prints the OFF All Pins Button client.print("<td colspan=2><INPUT TYPE=\"button\" VALUE=\"Выключить ВСЁ"); client.print("\" onClick=\"parent.location='/?L100"); client.print("'\"></td>\n<td></td>\n<td></td>\n</tr>\n"); //Prints save Button client.print("<tr>\n<td colspan=2><INPUT TYPE=\"button\" VALUE=\"Записать"); client.print("\" onClick=\"parent.location='/?save"); client.print("'\"></td>\n"); //Prints reset Button client.print("<td colspan=2><INPUT TYPE=\"button\" VALUE=\"Сбросить"); client.print("\" onClick=\"parent.location='/?reset"); client.print("'\"></td>\n<td></td>\n<td></td>\n</tr>\n"); client.println("</table>"); if (page == 1){ client.print("</td>"); client.print("<td height=\"86\">"); } client.println("<table border=\"0\" align=\"center\">"); client.print("<tr>"); client.print("<td></td>"); client.print("<td><h3>текущая</h3></td>"); client.print("<td><h3>обогрев</h3></td>"); client.print("<td><h3>желаемая</h3></td>"); // client.print("<td><h3>влажность</h3></td>"); client.print("</tr>"); client.print("<tr>"); client.print("<td><h4>"); client.print("Первый этаж:"); client.print("</h4></td>"); client.print("<td align=\"center\">"); client.println(chartemp1); //текущая температура client.print(" °C</td>"); if ( digitalRead(PinSSR1) == LOW ) { client.println("<td align=\"center\"><font color=green><b>ВКЛ</b></font></td>"); } // вкл или выкл else { client.println("<td align=\"center\"><font color=red><b>ВЫКЛ</b></font></td>"); } client.println("<td align=\"center\">"); client.println(TargetTemp1); //отображение желаемой температуры client.println(" °C</td>"); // client.println("<td align=\"center\">"); // client.println(Humidity1); //отображение влажности // client.println("%</td>"); client.print("</tr>"); client.print("<tr>"); client.print("<td><h4>"); client.print("Установить:"); //выбор желаемой температуры client.print("</h4></td>"); client.print(" <td colspan=3><table border=\"0\"><tr><td><INPUT TYPE=\"button\" VALUE=\"0" "\" onClick=\"parent.location='/?T1=0""'\"></td>"); client.print(" <td><INPUT TYPE=\"button\" VALUE=\"5" "\" onClick=\"parent.location='/?T1=5""'\"></td>"); client.print(" <td><INPUT TYPE=\"button\" VALUE=\"10" "\" onClick=\"parent.location='/?T1=10""'\"></td>"); client.print(" <td><INPUT TYPE=\"button\" VALUE=\"20" "\" onClick=\"parent.location='/?T1=20""'\"></td>"); client.print(" <td><INPUT TYPE=\"button\" VALUE=\"22" "\" onClick=\"parent.location='/?T1=22""'\"></td>"); client.print(" <td><INPUT TYPE=\"button\" VALUE=\"24" "\" onClick=\"parent.location='/?T1=24""'\"></td></tr></table></td>"); client.print("</tr>"); client.print("<tr>"); client.print("<td><h4>"); client.print("Точно:"); //выбор желаемой температуры точно client.print("</h4></td>"); client.print("<td></td>"); client.print(" <td colspan=2>"); client.print("<form><input type=text name=T1 size=10> <input type=submit value=ОК> </form></td>"); client.print("</tr>"); client.println("</table>"); //t1=5 if (page == 1){ client.print("</td>"); client.print("</tr>"); client.print("<tr>"); client.print("<td height=\"86\">"); } client.println("<table border=\"0\" align=\"center\">"); client.print("<tr>"); client.print("<td></td>"); client.print("<td><h3>текущая</h3></td>"); client.print("<td><h3>обогрев</h3></td>"); client.print("<td><h3>желаемая</h3></td>"); client.print("</tr>"); client.print("<tr>"); client.print("<td><h4>"); client.print("Второй этаж:"); client.print("</h4></td>"); client.print("<td align=\"center\">"); client.println(chartemp2); //текущая температура client.print(" °C</td>"); if ( digitalRead(PinSSR2) == LOW ) { client.println("<td align=\"center\"><font color=green><b>ВКЛ</b></font></td>"); } // вкл или выкл else { client.println("<td align=\"center\"><font color=red><b>ВЫКЛ</b></font></td>"); } client.println("<td align=\"center\">"); client.println(TargetTemp2); //отображение желаемой температуры client.println(" °C</td>"); client.print("</tr>"); client.print("<tr>"); client.print("<td><h4>"); client.print("Установить:"); //выбор желаемой температуры client.print("</h4></td>"); client.print(" <td colspan=3><table border=\"0\"><tr><td><INPUT TYPE=\"button\" VALUE=\"0" "\" onClick=\"parent.location='/?T2=0""'\"></td>"); client.print(" <td><INPUT TYPE=\"button\" VALUE=\"5" "\" onClick=\"parent.location='/?T2=5""'\"></td>"); client.print(" <td><INPUT TYPE=\"button\" VALUE=\"10" "\" onClick=\"parent.location='/?T2=10""'\"></td>"); client.print(" <td><INPUT TYPE=\"button\" VALUE=\"20" "\" onClick=\"parent.location='/?T2=20""'\"></td>"); client.print(" <td><INPUT TYPE=\"button\" VALUE=\"22" "\" onClick=\"parent.location='/?T2=22""'\"></td>"); client.print(" <td><INPUT TYPE=\"button\" VALUE=\"24" "\" onClick=\"parent.location='/?T2=24""'\"></td></tr></table></td>"); client.print("</tr>"); client.print("<tr>"); client.print("<td><h4>"); client.print("Точно:"); //выбор желаемой температуры точно client.print("</h4></td>"); client.print("<td></td>"); client.print(" <td colspan=2>"); client.print("<form><input type=text name=T2 size=10> <input type=submit value=ОК> </form></td>"); client.print("</tr>"); client.println("</table>"); if (page == 1){ client.print("</td>"); client.print("</tr>"); client.print("<tr>"); client.print("<td height=\"86\">"); } client.println("<table border=\"0\" align=\"center\">"); client.print("<tr>"); client.print("<td></td>"); client.print("<td><h3>текущая</h3></td>"); client.print("<td><h3>обогрев</h3></td>"); client.print("<td><h3>желаемая</h3></td>"); client.print("</tr>"); client.print("<tr>"); client.print("<td><h4>"); client.print("Кухня:"); client.print("</h4></td>"); client.print("<td align=\"center\">"); client.println(chartemp3); //текущая температура client.print(" °C</td>"); if ( digitalRead(PinSSR3) == LOW ) { client.println("<td align=\"center\"><font color=green><b>ВКЛ</b></font></td>"); } // вкл или выкл else { client.println("<td align=\"center\"><font color=red><b>ВЫКЛ</b></font></td>"); } client.println("<td align=\"center\">"); client.println(TargetTemp3); //отображение желаемой температуры client.println(" °C</td>"); client.print("</tr>"); client.print("<tr>"); client.print("<td><h4>"); client.print("Установить:"); //выбор желаемой температуры client.print("</h4></td>"); client.print(" <td colspan=3><table border=\"0\"><tr><td><INPUT TYPE=\"button\" VALUE=\"0" "\" onClick=\"parent.location='/?T3=0""'\"></td>"); client.print(" <td><INPUT TYPE=\"button\" VALUE=\"5" "\" onClick=\"parent.location='/?T3=5""'\"></td>"); client.print(" <td><INPUT TYPE=\"button\" VALUE=\"10" "\" onClick=\"parent.location='/?T3=10""'\"></td>"); client.print(" <td><INPUT TYPE=\"button\" VALUE=\"20" "\" onClick=\"parent.location='/?T3=20""'\"></td>"); client.print(" <td><INPUT TYPE=\"button\" VALUE=\"22" "\" onClick=\"parent.location='/?T3=22""'\"></td>"); client.print(" <td><INPUT TYPE=\"button\" VALUE=\"24" "\" onClick=\"parent.location='/?T3=24""'\"></td></tr></table></td>"); client.print("</tr>"); client.print("<tr>"); client.print("<td><h4>"); client.print("Точно:"); //выбор желаемой температуры точно client.print("</h4></td>"); client.print("<td></td>"); client.print(" <td colspan=2>"); client.print("<form><input type=text name=T3 size=10> <input type=submit value=ОК> </form></td>"); client.print("</tr>"); client.println("</table>"); if (page == 1){ client.print("</td>"); client.print("</tr>"); client.print("<tr>"); client.print("<td height=\"86\">"); } client.println("<table border=\"0\" align=\"center\">"); client.print("<tr>"); client.print("<td></td>"); client.print("<td><h3>1 этаж</h3></td>"); client.print("<td><h3>2 этаж</h3</td>"); client.print("<td><h3>кухня</h3</td>"); client.print("<td><h3>баня</h3</td>"); client.print("</tr>"); client.print("<tr>"); client.print("<td><h4>"); client.print("Влажность:"); client.print("</h4></td>"); client.println("<td align=\"center\">"); client.println(Humidity1+24); //отображение влажности client.println("%</td>"); client.println("<td align=\"center\">"); client.println(Humidity2+7); //отображение влажности client.println("%</td>"); client.println("<td align=\"center\">"); client.println(Humidity2+38); //отображение влажности client.println("%</td>"); client.println("<td align=\"center\">"); client.println(Humidity1+63); //отображение влажности client.println("%</td>"); client.print("</tr>"); client.println("</table>"); if (page == 1){ client.print("</td>"); client.print("</tr>"); client.println("</table>"); } client.println("</FORM>"); } //////////////////////////////////////////////////////////////////////// //readOutputStatuses Function //////////////////////////////////////////////////////////////////////// //Reading the Output Statuses void readOutputStatuses(){ for (int var = 0; var < outputQuantity; var++) { outputStatus[var] = digitalRead(outputAddress[var]); // Serial.print(outputStatus[var]); } } //////////////////////////////////////////////////////////////////////// //readEepromValues Function //////////////////////////////////////////////////////////////////////// //Read EEprom values and save to outputStatus void readEepromValues(){ for (int adr = 0; adr < outputQuantity; adr++) { outputStatus[adr] = EEPROM.read(adr+10); Serial.println(" "); Serial.print("read adr::"); Serial.print(adr); Serial.println(" OK"); Serial.println(" "); Serial.print("outputStatus[adr]::"); Serial.print(outputStatus[adr]); Serial.println(" OK"); } } //////////////////////////////////////////////////////////////////////// //writeEepromValues Function //////////////////////////////////////////////////////////////////////// void writeEepromValues(){ for (int adr = 0; adr < outputQuantity+0; adr++) { EEPROM.write(adr+10, outputStatus[adr]); Serial.println(" "); Serial.print("write adr::"); Serial.print(adr); Serial.println(" OK"); Serial.println(" "); Serial.print("outputStatus[adr]::"); Serial.print(outputStatus[adr]); Serial.println(" OK"); } } //////////////////////////////////////////////////////////////////////// //resetEepromValues Function //////////////////////////////////////////////////////////////////////// void resetEepromValues(){ for (int adr = 0; adr < outputQuantity+0; adr++) { EEPROM.write(adr+10, 0); Serial.println(" "); Serial.print("reset adr::"); Serial.print(adr); Serial.println(" OK"); Serial.println(" "); Serial.print("outputStatus[adr]::"); Serial.print(outputStatus[adr]); Serial.println(" OK"); } } //////////////////////////////////////////////////////////////////////// //initEepromValues Function //////////////////////////////////////////////////////////////////////// //Initialiaze EEprom values //if eeprom values are not the correct format ie not euqual to 0 or 1 (thus greater then 1) initialize by putting 0 void initEepromValues(){ for (int adr = 0; adr < outputQuantity; adr++){ if (EEPROM.read(adr+10) > 1){ EEPROM.write(adr+10, 0); } } } //////////////////////////////////////////////////////////////////////// //htmlHeader Function //////////////////////////////////////////////////////////////////////// void printHtmlHeader(EthernetClient client){ Serial.print("Serving html Headers at ms -"); timeConnectedAt = millis(); //Record the time when last page was served. Serial.println(timeConnectedAt); // Print time for debbugging purposes writeToEeprom = true; // page loaded so set to action the write to eeprom // send a standard http response header client.println(F("HTTP/1.1 200 OK")); client.println(F("Content-Type: text/html; charset=utf-8")); client.println(F("Connnection: close")); client.println(); client.println(F("<!DOCTYPE HTML>")); client.println(F("<head>")); // заголовок страницы client.println(F("<title>Контроль и управление домом</title>")); client.println(F("<meta name=\"description\" content=\"Контроль и управление домом\"/>")); // время обновления страницы client.print(F("<meta http-equiv=\"refresh\" content=\"")); client.print(refreshPage); client.println(F("; url=/\">")); // конфигурация браузера client.println(F("<meta name=\"apple-mobile-web-app-capable\" content=\"yes\">")); client.println(F("<meta name=\"apple-mobile-web-app-status-bar-style\" content=\"default\">")); client.println(F("<meta name=\"viewport\" content=\"width=device-width, user-scalable=no\">")); // вставка данных стилей CSS client.println(F("<style type=\"text/css\">")); client.println(F("")); // как будет выглядеть страница графически client.println(F("html { height:100%; }")); client.println(F(" body {")); client.println(F(" height: 100%;")); client.println(F(" margin: 0;")); client.println(F(" font-family: helvetica, sans-serif;")); client.println(F(" -webkit-text-size-adjust: none;")); client.println(F(" }")); client.println(F("")); client.println(F("body {")); client.println(F(" -webkit-background-size: 100% 21px;")); client.println(F(" background-color: #c5ccd3;")); client.println(F(" background-image:")); client.println(F(" -webkit-gradient(linear, left top, right top,")); client.println(F(" color-stop(.75, transparent),")); client.println(F(" color-stop(.75, rgba(255,255,255,.1)) );")); client.println(F(" -webkit-background-size: 7px;")); client.println(F(" }")); client.println(F("")); client.println(F(".view {")); client.println(F(" min-height: 100%;")); client.println(F(" overflow: auto;")); client.println(F(" }")); client.println(F("")); client.println(F(".header-wrapper {")); client.println(F(" height: 64px;")); client.println(F(" font-weight: bold;")); client.println(F(" text-shadow: rgba(0,0,0,0.7) 0 -1px 0;")); client.println(F(" border-top: solid 1px rgba(255,255,255,0.6);")); client.println(F(" border-bottom: solid 1px rgba(0,0,0,0.6);")); client.println(F(" color: #fff;")); client.println(F(" background-color: #8195af;")); client.println(F(" background-image:")); client.println(F(" -webkit-gradient(linear, left top, left bottom,")); client.println(F(" from(rgba(255,255,255,.4)),")); client.println(F(" to(rgba(255,255,255,.05)) ),")); client.println(F(" -webkit-gradient(linear, left top, left bottom,")); client.println(F(" from(transparent),")); client.println(F(" to(rgba(0,0,64,.1)) );")); client.println(F(" background-repeat: no-repeat;")); client.println(F(" background-position: top left, bottom left;")); client.println(F(" -webkit-background-size: 100% 21px, 100% 22px;")); client.println(F(" -webkit-box-sizing: border-box;")); client.println(F(" }")); client.println(F("")); client.println(F(".header-wrapper h1 {")); client.println(F(" text-align: center;")); client.println(F(" font-size: 20px;")); client.println(F(" line-height: 44px;")); client.println(F(" margin: 0;")); client.println(F(" }")); client.println(F("")); client.println(F(".group-wrapper {")); client.println(F(" margin: 9px;")); client.println(F(" aling: center;")); client.println(F(" }")); client.println(F("")); client.println(F(".group-wrapper h2 {")); client.println(F(" color: #4c566c;")); client.println(F(" font-size: 17px;")); client.println(F(" line-height: 0.8;")); client.println(F(" font-weight: bold;")); client.println(F(" text-shadow: #fff 0 1px 0;")); client.println(F(" margin: 20px 10px 12px;")); client.println(F(" }")); client.println(F("")); client.println(F(".group-wrapper h3 {")); client.println(F(" color: #4c566c;")); client.println(F(" font-size: 12px;")); client.println(F(" line-height: 1;")); client.println(F(" font-weight: bold;")); client.println(F(" text-shadow: #fff 0 1px 0;")); client.println(F(" margin: 20px 10px 12px;")); client.println(F(" }")); client.println(F("")); client.println(F(".group-wrapper h4 {")); //Text for description client.println(F(" color: #212121;")); client.println(F(" font-size: 14px;")); client.println(F(" line-height: 1;")); client.println(F(" font-weight: bold;")); client.println(F(" text-shadow: #aaa 1px 1px 3px;")); client.println(F(" margin: 5px 5px 5px;")); client.println(F(" }")); client.println(F("")); client.println(F(".group-wrapper table {")); client.println(F(" background-color: #fff;")); client.println(F(" -webkit-border-radius: 10px;")); client.println(F(" -moz-border-radius: 10px;")); client.println(F(" -khtml-border-radius: 10px;")); client.println(F(" border-radius: 10px;")); client.println(F(" font-size: 17px;")); client.println(F(" line-height: 20px;")); // ширина строк таблицы client.println(F(" margin: 5px 0 5px;")); // отступ строк таблицы client.println(F(" border: solid 1px #a9abae;")); client.println(F(" padding: 11px 3px 12px 3px;")); client.println(F(" margin-left:auto;")); client.println(F(" margin-right:auto;")); client.println(F(" -moz-transform :scale(1);")); //Code for Mozilla Firefox client.println(F(" -moz-transform-origin: 0 0;")); client.println(F(" }")); //how the green (ON) LED will look client.println(F(".green-circle {")); client.println(F(" display: block;")); client.println(F(" height: 23px;")); client.println(F(" width: 23px;")); client.println(F(" background-color: #0f0;")); client.println(F(" -moz-border-radius: 11px;")); client.println(F(" -webkit-border-radius: 11px;")); client.println(F(" -khtml-border-radius: 11px;")); client.println(F(" border-radius: 11px;")); client.println(F(" margin-left: 1px;")); client.println(F(" background-image: -webkit-gradient(linear, 0% 0%, 0% 90%, from(rgba(46, 184, 0, 0.8)), to(rgba(148, 255, 112, .9)));@")); client.println(F(" border: 2px solid #ccc;")); client.println(F(" -webkit-box-shadow: rgba(11, 140, 27, 0.5) 0px 10px 16px;")); client.println(F(" -moz-box-shadow: rgba(11, 140, 27, 0.5) 0px 10px 16px; /* FF 3.5+ */")); client.println(F(" box-shadow: rgba(11, 140, 27, 0.5) 0px 10px 16px; /* FF 3.5+ */")); client.println(F(" }")); client.println(F("")); //how the black (off)LED will look client.println(F(".black-circle {")); client.println(F(" display: block;")); client.println(F(" height: 23px;")); client.println(F(" width: 23px;")); client.println(F(" background-color: #040;")); client.println(F(" -moz-border-radius: 11px;")); client.println(F(" -webkit-border-radius: 11px;")); client.println(F(" -khtml-border-radius: 11px;")); client.println(F(" border-radius: 11px;")); client.println(F(" margin-left: 1px;")); client.println(F(" -webkit-box-shadow: rgba(11, 140, 27, 0.5) 0px 10px 16px;")); client.println(F(" -moz-box-shadow: rgba(11, 140, 27, 0.5) 0px 10px 16px; /* FF 3.5+ */")); client.println(F(" box-shadow: rgba(11, 140, 27, 0.5) 0px 10px 16px; /* FF 3.5+ */")); client.println(F(" }")); client.println(F("")); //this will add the glare to both of the LEDs client.println(F(" .glare {")); client.println(F(" position: relative;")); client.println(F(" top: 1;")); client.println(F(" left: 5px;")); client.println(F(" -webkit-border-radius: 10px;")); client.println(F(" -moz-border-radius: 10px;")); client.println(F(" -khtml-border-radius: 10px;")); client.println(F(" border-radius: 10px;")); client.println(F(" height: 1px;")); client.println(F(" width: 13px;")); client.println(F(" padding: 5px 0;")); client.println(F(" background-color: rgba(200, 200, 200, 0.25);")); client.println(F(" background-image: -webkit-gradient(linear, 0% 0%, 0% 95%, from(rgba(255, 255, 255, 0.7)), to(rgba(255, 255, 255, 0)));")); client.println(F(" }")); client.println(F("")); //and finally this is the end of the style data and header client.println(F("</style>")); client.println(F("</head>")); //now printing the page itself client.println(F("<body>")); client.println(F("<div class=\"view\">")); client.println(F(" <div class=\"header-wrapper\">")); // client.println(F(" <h1>СМАРТ ДАЧА</h1>")); client.print(F("<table border=\"0\" align=\"center\"><tr><td><h4>Стиль страницы:</h4></td><td><INPUT TYPE=\"button\" VALUE=\"широкая" "\" onClick=\"parent.location='/?page1""'\"></td>")); client.print(F("<td><INPUT TYPE=\"button\" VALUE=\" узкая " "\" onClick=\"parent.location='/?page0""'\"></td></tr></table>")); client.println(F(" </div>")); } //end of htmlHeader //////////////////////////////////////////////////////////////////////// //htmlFooter Function //////////////////////////////////////////////////////////////////////// void printHtmlFooter(EthernetClient client){ //Set Variables Before Exiting printLastCommandOnce = false; printButtonMenuOnce = false; client.println(F("\n<h3 align=\"center\">©- Plagiary - <br> 774 KM - 2016 - ")); client.println(rev); client.println(F("</h3></div>\n</div>\n</body>\n</html>")); delay(1); // give the web browser time to receive the data client.stop(); // close the connection: Serial.println(" - Done, Closing Connection."); delay (2); //delay so that it will give time for client buffer to clear and does not repeat multiple pages. } //end of htmlFooter //////////////////////////////////////////////////////////////////////// //printHtmlButtonTitle Function //////////////////////////////////////////////////////////////////////// void printHtmlButtonTitle(EthernetClient client){ client.println(F("<div class=\"group-wrapper\">")); client.println(F("<h2 align=\"center\" >Температура на улице")); client.println(chartemp4); client.print(F(" °C </h2>")); client.println(); } ///////////////// DS18B20 float tempread(byte sensoraddr[]) // error codes: // -1 no sensors found // -2 invalid CRC // -3 not a DS1820 { byte i; byte present = 0; byte data[12]; byte addr[8]; //int HighByte, LowByte, TReading, SignBit, Tc_100, Tf_100, Whole, Fract; for ( i = 0; i < 8; i++) { addr[i]=sensoraddr[i]; } ds.reset(); // pulse the pins and wait for a response to reset the DS1820 ds.select(addr); // 0x55 (MATCH_ROM) followed by the address of the 1820 to talk to. // ds.write(0x44,1); // start conversion, with parasite power on at the end ds.write(0x44,0); //PARASITE POWER OFF // delay(800); present = ds.reset(); ds.select(addr); ds.write(0xBE); // Read Scratchpad for ( i = 0; i < 9; i++) { // we need 9 bytes data[i] = ds.read(); } int16_t raw = (data[1] << 8) | data[0]; float temp = (float)raw / 16.0; return temp; }uservasil
Как поменять местами в узком хтмл , кнопки с низу а температуру с верху
uservasil
Как поменять местами в узком хтмл , кнопки с низу а температуру с верху
сейчас точно сказать не смогу, т.к. нет времени совсем, быть может на следующей неделе, а так эксперементируйте сами)
попробуйте например вырезать это :
1169 client.print(F("<table border=\"0\" align=\"center\"><tr><td><h4>Стиль страницы:</h4></td><td><INPUT TYPE=\"button\" VALUE=\"широкая" "\" onClick=\"parent.location='/?page1""'\"></td>")); 1170 client.print(F("<td><INPUT TYPE=\"button\" VALUE=\" узкая " "\" onClick=\"parent.location='/?page0""'\"></td></tr></table>"));и вставить в строку 1191
а что у вас до строки 1191 и после нее я пробую вашу версию 1.4
а что у вас до строки 1191 и после нее я пробую вашу версию 1.4
Я эту версию и имел ввиду, пробуйте не бойтесь, это помогает понять как все устроено ;)
а что у вас до строки 1191 и после нее я пробую вашу версию 1.4
эт мы кнопки переставим в низ страницы, а я хотел в узком читоба показания были с верху а управление пинами снизу как в вашем первом посте.
И еще вопрос вы не пробовали эт все впихнуть в ардуино уно?
И еще вопрос вы не пробовали эт все впихнуть в ардуино уно?
в УНО можно и больше впихнуть если писать не в arduino ide, а в atmel studio на Си. Только это подразумевает другой уровень познаний
в среде ардуино при использовании ethernet на уно можно сделать совсем чуть чуть
Всем Привет, я еще не остановился на достигнутом и вот некоторые изменения в версии 1.6 =)
1. добавлены два всплывающих окна управления освещением и нагрузками.
2. добавлен модуль sim900, управление теперь и постредством SMS (свет, нагрузки, опопление)
в смарфоне установлено приложение GsmContrAll, которое позволяет создать интерфейс для быстрой отправки нужных SMS команд одним нажатием.
3. добавлены RTC(часы реального времени), датчики отвещенности, давления, напряжения и тока.
4. причесал код, разложил все по вкладкам оптимизировал CSS и HTML.
5. начал собирать шкаф управления.
приложение для Андройд:
скетч:
//пин 2 используется прирыванием //пин 3 свободен //пин 4 используется для SD карты //пины 5-9 свободны //пины 10-13 используются шилдом W5100 //пины 14-17 свободны //пины 18-19 используются шилдом Sim900 //пины 20-21 используются 1-Ware //пины 22-35 используются для управления освещением //пины 36-45 используются для управления розетками //пины 46-49 используются для управления обогревателями //пины 50-53 используются шилдом W5100 //пины A0-A1 используются для контроля температуты и влажности DHT 21 //пины A2 используется для контроля температуты ds18b20 //пины A3 используется для контроля уровня газа в воздухе //пины A4-A6 используется для контроля напряжения и тока //пины A7-A16 свободны //ethernet #include <Ethernet.h> #include <SPI.h> //eeprom #include <EEPROM.h> //dht #include <DHT.h> #include <OneWire.h> //OPS SCADA #include <OPC.h> #include <Bridge.h> //BMP185 #include <Wire.h> #include <Adafruit_BMP085.h> //rtc #include "RTClib.h" //BH1750 #include <BH1750.h> //////////////////////////////////////////////////////////////////////// // WEB //////////////////////////////////////////////////////////////////////// byte ip[] = { 10, 16, 30, 2 }; //Manual setup only byte gateway[] = { 10, 16, 30, 3 }; //Manual setup only byte subnet[] = { 255, 255, 255, 0 }; //Manual setup only byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; EthernetServer server = EthernetServer(80); //default html port 80 //The number of outputs going to be switched. int outputQuantity = 24; //should not exceed 10 //Invert the output of the leds boolean outputInverted = true; //true or false //Html page refresh int refreshPage = 60; //default is 10sec. int outputAddress[24] = { 22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45}; //Allocate 10 spaces and name the output pin address. // Write the text description of the output channel String buttonText[24] = { "Дом 1 этаж","Дом 2 этаж","Кухня","Ванная","Баня 1 этаж","Баня 2 этаж","Калитка","Лестница","Веранда","Балкон","Причал","Кладовка","Гирлянда-1","Гирлянда-2","Дом 1 этаж","Дом 2 этаж","Кухня","Плита","у Входа","Ванная","Насосная","Улица","Баня","Кладовка"}; int twenty[] = {11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34}; int outp = 0; boolean printLastCommandOnce = false; boolean printButtonMenuOnce = false; boolean reading = false; boolean outputStatus[24]; //Create a boolean array for the maximum ammount. String rev = "V1.6"; unsigned long timeConnectedAt; boolean writeToEeprom = false; int page=1; //////////////////////////////////////////////////////////////////////// // упрвавления температурой //////////////////////////////////////////////////////////////////////// const byte PinSSR1 = 46; // Реле Pin for SSR 1 const byte PinSSR2 = 47; // Реле Pin for SSR 2 const byte PinSSR3 = 48; // Реле Pin for SSR 3 const byte PinSSR4 = 49; // Реле Pin for SSR 4 char chartemp1[10]; char chartemp2[10]; char chartemp3[10]; char chartemp4[10]; int TargetTemp1; int TargetTemp2; int TargetTemp3; int TargetTemp4; int Humidity1; int Humidity2; float temp1; float temp2; float temp3; float temp4; float temp5; float temp6; float temp7; float temp8; float temp9; float temp10; float temp11; float temp12; OneWire ds(A2); DHT dht1(A0, DHT11); DHT dht2(A1, DHT11); //////////////////////////////////////////////////////////////////////// // описываем ОРС //////////////////////////////////////////////////////////////////////// OPCEthernet aOPCEthernet; // порт const int listen_port = 88; //////////////////////////////////////////////////////////////////////// // описываем SIM900 //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// // описываем часы DS1307 //////////////////////////////////////////////////////////////////////// /*const int kCePin = 5; // Chip Enable const int kIoPin = 6; // Input/Output const int kSclkPin = 7; // Serial Clock char buf[50]; // Create a object. DS1302 rtc(kCePin, kIoPin, kSclkPin); String dayAsString(const Time::Day day) { switch (day) { case Time::kSunday: return "Вс"; case Time::kMonday: return "Пн"; case Time::kTuesday: return "Вт"; case Time::kWednesday: return "Ср"; case Time::kThursday: return "Чт"; case Time::kFriday: return "Пт"; case Time::kSaturday: return "Сб"; } return "(unknown day)"; } */ char buf[50]; RTC_DS1307 rtc; char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"}; //DateTime now = rtc.now(); //////////////////////////////////////////////////////////////////////// // описываем барометр BMP185 //////////////////////////////////////////////////////////////////////// Adafruit_BMP085 bmp; //////////////////////////////////////////////////////////////////////// // описываем люксомер BH1750 //////////////////////////////////////////////////////////////////////// BH1750 lightMeter; //////////////////////////////////////////////////////////////////////// //RUN ONCE //////////////////////////////////////////////////////////////////////// void setup(){ Serial.begin(9600); initEepromValues(); readEepromValues(); //Set pins as Outputs for (int var = 0; var < outputQuantity; var++){ pinMode(outputAddress[var], OUTPUT); if(outputStatus[var] == 0) { if (outputInverted ==false){ digitalWrite(outputAddress[var], HIGH); } else{ digitalWrite(outputAddress[var], LOW); } } if(outputStatus[var] == 1){ if (outputInverted ==false){ digitalWrite(outputAddress[var], LOW); } else{ digitalWrite(outputAddress[var], HIGH); } } } // end for //Setting up the IP address. Comment out the one you dont need. Ethernet.begin(mac, ip, gateway, subnet); server.begin(); Serial.print("Server started at "); Serial.println(Ethernet.localIP()); //управление температурой pinMode(PinSSR1, OUTPUT); pinMode(PinSSR2, OUTPUT); pinMode(PinSSR3, OUTPUT); pinMode(PinSSR4, OUTPUT); TargetTemp1 = EEPROM.read(1000); TargetTemp2 = EEPROM.read(1002); TargetTemp3 = EEPROM.read(1004); TargetTemp4 = EEPROM.read(1006); dht1.begin(); dht2.begin(); // OPCItem declaration aOPCEthernet.setup(listen_port,mac,ip); aOPCEthernet.addItem("rt1",opc_read, opc_int, RealTemp1OPC); aOPCEthernet.addItem("rt2",opc_read, opc_int, RealTemp2OPC); aOPCEthernet.addItem("rt3",opc_read, opc_int, RealTemp3OPC); aOPCEthernet.addItem("wt1",opc_readwrite, opc_int, TargetTemp1OPC); aOPCEthernet.addItem("wt2",opc_readwrite, opc_int, TargetTemp2OPC); aOPCEthernet.addItem("wt3",opc_readwrite, opc_int, TargetTemp3OPC); aOPCEthernet.addItem("D1_OPC",opc_readwrite, opc_bool, D1_OPC); aOPCEthernet.addItem("D2_OPC",opc_readwrite, opc_bool, D2_OPC); aOPCEthernet.addItem("D3_OPC",opc_readwrite, opc_bool, D3_OPC); aOPCEthernet.addItem("D4_OPC",opc_readwrite, opc_bool, D4_OPC); aOPCEthernet.addItem("D5_OPC",opc_readwrite, opc_bool, D5_OPC); aOPCEthernet.addItem("D6_OPC",opc_readwrite, opc_bool, D6_OPC); aOPCEthernet.addItem("D7_OPC",opc_readwrite, opc_bool, D7_OPC); aOPCEthernet.addItem("D8_OPC",opc_readwrite, opc_bool, D8_OPC); aOPCEthernet.addItem("D9_OPC",opc_readwrite, opc_bool, D9_OPC); aOPCEthernet.addItem("D10_OPC",opc_readwrite, opc_bool, D10_OPC); aOPCEthernet.addItem("D11_OPC",opc_readwrite, opc_bool, D11_OPC); aOPCEthernet.addItem("D12_OPC",opc_readwrite, opc_bool, D12_OPC); aOPCEthernet.addItem("D13_OPC",opc_readwrite, opc_bool, D13_OPC); aOPCEthernet.addItem("D14_OPC",opc_readwrite, opc_bool, D14_OPC); aOPCEthernet.addItem("D15_OPC",opc_readwrite, opc_bool, D15_OPC); aOPCEthernet.addItem("D16_OPC",opc_readwrite, opc_bool, D16_OPC); aOPCEthernet.addItem("D17_OPC",opc_readwrite, opc_bool, D17_OPC); aOPCEthernet.addItem("D18_OPC",opc_readwrite, opc_bool, D18_OPC); aOPCEthernet.addItem("D19_OPC",opc_readwrite, opc_bool, D19_OPC); aOPCEthernet.addItem("D20_OPC",opc_readwrite, opc_bool, D20_OPC); aOPCEthernet.addItem("D21_OPC",opc_readwrite, opc_bool, D21_OPC); aOPCEthernet.addItem("D22_OPC",opc_readwrite, opc_bool, D22_OPC); aOPCEthernet.addItem("D23_OPC",opc_readwrite, opc_bool, D23_OPC); aOPCEthernet.addItem("D24_OPC",opc_readwrite, opc_bool, D24_OPC); // SIM900 Object initialization delay(2000); //время на инициализацию модуля Serial.println("GSM start:"); Serial1.begin(38400); //Serial1.println("ATI"); //delay(100); //Serial1.println("AT+IPR=38400"); //установка скорости работы шилда(один раз) delay(100); Serial1.println("AT+CLIP=1"); //включаем АОН delay(100); Serial1.println("AT+CMGF=1"); //режим кодировки СМС - обычный (для англ.) delay(100); Serial1.println("AT+CSCS=\"GSM\""); //режим кодировки текста delay(100); Serial1.println("AT+CNMI=2,2"); //информирование о полученных СМС delay(500); Serial.println("bmp.begin();"); // BPM185 Object initialization bmp.begin(); Serial.println("lightMeter.begin();"); // Luxmeter Object initialization lightMeter.begin(); Serial.println("rtc.begin()"); // RTC Object initialization rtc.begin(); //rtc.isrunning(); // установка времени //rtc.adjust(DateTime(2016, 4, 20, 15, 13, 0)); } // end void setup() //////////////////////////////////////////////////////////////////////// //LOOP /////////////////////////////////////////////////////////////////////// void loop(){ // Serial.println("void loop()"); // управление температурой temp_set(); // listen for incoming clients, and process requests. checkForClient(); // SIM900 process commands sim(); // OPC process commands // aOPCEthernet.processOPCCommands(); // вывод времени вызывается в web при обновлении страницы // printTime(); // вывод давления // bmp185(); // вывод люксомера // bh1755(); } ///// end void loop() //////////////////////////////////////////////////////////////////////// //for bh1755 //////////////////////////////////////////////////////////////////////// void bh1755(){ uint16_t lux = lightMeter.readLightLevel(); Serial.print("Light: "); Serial.print(lux); Serial.println(" lx"); delay(1000); } //////////////////////////////////////////////////////////////////////// //for bmp185 //////////////////////////////////////////////////////////////////////// void bmp185(){ Serial.print("Temperature = "); Serial.print(bmp.readTemperature()); Serial.println(" *C"); Serial.print("Pressure = "); Serial.print(bmp.readPressure()); Serial.println(" Pa"); // Calculate altitude assuming 'standard' barometric // pressure of 1013.25 millibar = 101325 Pascal Serial.print("Altitude = "); Serial.print(bmp.readAltitude()); Serial.println(" meters"); /* Serial.print("Pressure at sealevel (calculated) = "); Serial.print(bmp.readSealP()); Serial.println(" Pa"); */ // you can get a more precise measurement of altitude // if you know the current sea level pressure which will // vary with weather and such. If it is 1015 millibars // that is equal to 101500 Pascals. Serial.print("Real altitude = "); Serial.print(bmp.readAltitude(101500)); Serial.println(" meters"); Serial.println(); delay(500); } //////////////////////////////////////////////////////////////////////// //readEepromValues Function //////////////////////////////////////////////////////////////////////// //Read EEprom values and save to outputStatus void readEepromValues(){ for (int adr = 0; adr < outputQuantity; adr++) { outputStatus[adr] = EEPROM.read(adr+10); Serial.println(" "); Serial.print("read adr::"); Serial.print(adr); Serial.println(" OK"); Serial.println(" "); Serial.print("outputStatus[adr]::"); Serial.print(outputStatus[adr]); Serial.println(" OK"); } } //////////////////////////////////////////////////////////////////////// //writeEepromValues1 Function //////////////////////////////////////////////////////////////////////// void writeEepromValues1(){ for (int adr = 0; adr < 14; adr++) { EEPROM.write(adr+10, outputStatus[adr]); Serial.println(" "); Serial.print("write adr::"); Serial.print(adr); Serial.println(" OK"); Serial.println(" "); Serial.print("outputStatus[adr]::"); Serial.print(outputStatus[adr]); Serial.println(" OK"); } } //////////////////////////////////////////////////////////////////////// //writeEepromValues2 Function //////////////////////////////////////////////////////////////////////// void writeEepromValues2(){ for (int adr = 14; adr < outputQuantity; adr++) { EEPROM.write(adr+10, outputStatus[adr]); Serial.println(" "); Serial.print("write adr::"); Serial.print(adr); Serial.println(" OK"); Serial.println(" "); Serial.print("outputStatus[adr]::"); Serial.print(outputStatus[adr]); Serial.println(" OK"); } } //////////////////////////////////////////////////////////////////////// //resetEepromValues1 Function //////////////////////////////////////////////////////////////////////// void resetEepromValues1(){ for (int adr = 0; adr < 14; adr++) { EEPROM.write(adr+10, 1); Serial.println(" "); Serial.print("reset adr::"); Serial.print(adr); Serial.println(" OK"); Serial.println(" "); Serial.print("outputStatus[adr]::"); Serial.print(outputStatus[adr]); Serial.println(" OK"); } } //////////////////////////////////////////////////////////////////////// //resetEepromValues2 Function //////////////////////////////////////////////////////////////////////// void resetEepromValues2(){ for (int adr = 14; adr < outputQuantity; adr++) { EEPROM.write(adr+10, 1); Serial.println(" "); Serial.print("reset adr::"); Serial.print(adr); Serial.println(" OK"); Serial.println(" "); Serial.print("outputStatus[adr]::"); Serial.print(outputStatus[adr]); Serial.println(" OK"); } } //////////////////////////////////////////////////////////////////////// //initEepromValues Function //////////////////////////////////////////////////////////////////////// //Initialiaze EEprom values //if eeprom values are not the correct format ie not euqual to 0 or 1 (thus greater then 1) initialize by putting 0 void initEepromValues(){ for (int adr = 0; adr < outputQuantity; adr++){ if (EEPROM.read(adr+10) > 1){ EEPROM.write(adr+10, 1); } } } //////////////////////////////////////////////////////////////////////// // описываем ОРС //////////////////////////////////////////////////////////////////////// // функции ОРС сервера int RealTemp1OPC(const char *itemID, const opcOperation opcOP, const int value){ return temp1; } int RealTemp2OPC(const char *itemID, const opcOperation opcOP, const int value){ return temp2; } int RealTemp3OPC(const char *itemID, const opcOperation opcOP, const int value){ return temp3; } int TargetTemp1OPC(const char *itemID, const opcOperation opcOP, const int value){ if (opcOP == opc_opwrite) {TargetTemp1 = value;} else return TargetTemp1; } int TargetTemp2OPC(const char *itemID, const opcOperation opcOP, const int value){ if (opcOP == opc_opwrite) {TargetTemp2 = value;} else return TargetTemp2; } int TargetTemp3OPC(const char *itemID, const opcOperation opcOP, const int value){ if (opcOP == opc_opwrite) {TargetTemp3 = value;} else return TargetTemp3; } bool D1_OPC(const char *itemID, const opcOperation opcOP, const bool value){ static bool ledValue = false; if (opcOP == opc_opwrite) { ledValue = value; if (ledValue) {digitalWrite(outputAddress[0], HIGH);} else digitalWrite(outputAddress[0], LOW); } else return digitalRead(outputAddress[0]); } bool D2_OPC(const char *itemID, const opcOperation opcOP, const bool value){ static bool ledValue = false; if (opcOP == opc_opwrite) { ledValue = value; if (ledValue) {digitalWrite(outputAddress[1], HIGH);} else digitalWrite(outputAddress[1], LOW); } else return digitalRead(outputAddress[1]); } bool D3_OPC(const char *itemID, const opcOperation opcOP, const bool value){ static bool ledValue = false; if (opcOP == opc_opwrite) { ledValue = value; if (ledValue) {digitalWrite(outputAddress[2], HIGH);} else digitalWrite(outputAddress[2], LOW); } else return digitalRead(outputAddress[2]); } bool D4_OPC(const char *itemID, const opcOperation opcOP, const bool value){ static bool ledValue = false; if (opcOP == opc_opwrite) { ledValue = value; if (ledValue) {digitalWrite(outputAddress[3], HIGH);} else digitalWrite(outputAddress[3], LOW); } else return digitalRead(outputAddress[3]); } bool D5_OPC(const char *itemID, const opcOperation opcOP, const bool value){ static bool ledValue = false; if (opcOP == opc_opwrite) { ledValue = value; if (ledValue) {digitalWrite(outputAddress[4], HIGH);} else digitalWrite(outputAddress[4], LOW); } else return digitalRead(outputAddress[4]); } bool D6_OPC(const char *itemID, const opcOperation opcOP, const bool value){ static bool ledValue = false; if (opcOP == opc_opwrite) { ledValue = value; if (ledValue) {digitalWrite(outputAddress[5], HIGH);} else digitalWrite(outputAddress[5], LOW); } else return digitalRead(outputAddress[5]); } bool D7_OPC(const char *itemID, const opcOperation opcOP, const bool value){ static bool ledValue = false; if (opcOP == opc_opwrite) { ledValue = value; if (ledValue) {digitalWrite(outputAddress[6], HIGH);} else digitalWrite(outputAddress[6], LOW); } else return digitalRead(outputAddress[6]); } bool D8_OPC(const char *itemID, const opcOperation opcOP, const bool value){ static bool ledValue = false; if (opcOP == opc_opwrite) { ledValue = value; if (ledValue) {digitalWrite(outputAddress[7], HIGH);} else digitalWrite(outputAddress[7], LOW); } else return digitalRead(outputAddress[7]); } bool D9_OPC(const char *itemID, const opcOperation opcOP, const bool value){ static bool ledValue = false; if (opcOP == opc_opwrite) { ledValue = value; if (ledValue) {digitalWrite(outputAddress[8], HIGH);} else digitalWrite(outputAddress[8], LOW); } else return digitalRead(outputAddress[8]); } bool D10_OPC(const char *itemID, const opcOperation opcOP, const bool value){ static bool ledValue = false; if (opcOP == opc_opwrite) { ledValue = value; if (ledValue) {digitalWrite(outputAddress[9], HIGH);} else digitalWrite(outputAddress[9], LOW); } else return digitalRead(outputAddress[9]); } bool D11_OPC(const char *itemID, const opcOperation opcOP, const bool value){ static bool ledValue = false; if (opcOP == opc_opwrite) { ledValue = value; if (ledValue) {digitalWrite(outputAddress[10], HIGH);} else digitalWrite(outputAddress[10], LOW); } else return digitalRead(outputAddress[10]); } bool D12_OPC(const char *itemID, const opcOperation opcOP, const bool value){ static bool ledValue = false; if (opcOP == opc_opwrite) { ledValue = value; if (ledValue) {digitalWrite(outputAddress[11], HIGH);} else digitalWrite(outputAddress[11], LOW); } else return digitalRead(outputAddress[11]); } bool D13_OPC(const char *itemID, const opcOperation opcOP, const bool value){ static bool ledValue = false; if (opcOP == opc_opwrite) { ledValue = value; if (ledValue) {digitalWrite(outputAddress[12], HIGH);} else digitalWrite(outputAddress[12], LOW); } else return digitalRead(outputAddress[12]); } bool D14_OPC(const char *itemID, const opcOperation opcOP, const bool value){ static bool ledValue = false; if (opcOP == opc_opwrite) { ledValue = value; if (ledValue) {digitalWrite(outputAddress[13], HIGH);} else digitalWrite(outputAddress[13], LOW); } else return digitalRead(outputAddress[13]); } bool D15_OPC(const char *itemID, const opcOperation opcOP, const bool value){ static bool ledValue = false; if (opcOP == opc_opwrite) { ledValue = value; if (ledValue) {digitalWrite(outputAddress[14], HIGH);} else digitalWrite(outputAddress[14], LOW); } else return digitalRead(outputAddress[14]); } bool D16_OPC(const char *itemID, const opcOperation opcOP, const bool value){ static bool ledValue = false; if (opcOP == opc_opwrite) { ledValue = value; if (ledValue) {digitalWrite(outputAddress[15], HIGH);} else digitalWrite(outputAddress[15], LOW); } else return digitalRead(outputAddress[15]); } bool D17_OPC(const char *itemID, const opcOperation opcOP, const bool value){ static bool ledValue = false; if (opcOP == opc_opwrite) { ledValue = value; if (ledValue) {digitalWrite(outputAddress[16], HIGH);} else digitalWrite(outputAddress[16], LOW); } else return digitalRead(outputAddress[16]); } bool D18_OPC(const char *itemID, const opcOperation opcOP, const bool value){ static bool ledValue = false; if (opcOP == opc_opwrite) { ledValue = value; if (ledValue) {digitalWrite(outputAddress[17], HIGH);} else digitalWrite(outputAddress[17], LOW); } else return digitalRead(outputAddress[17]); } bool D19_OPC(const char *itemID, const opcOperation opcOP, const bool value){ static bool ledValue = false; if (opcOP == opc_opwrite) { ledValue = value; if (ledValue) {digitalWrite(outputAddress[18], HIGH);} else digitalWrite(outputAddress[18], LOW); } else return digitalRead(outputAddress[18]); } bool D20_OPC(const char *itemID, const opcOperation opcOP, const bool value){ static bool ledValue = false; if (opcOP == opc_opwrite) { ledValue = value; if (ledValue) {digitalWrite(outputAddress[19], HIGH);} else digitalWrite(outputAddress[19], LOW); } else return digitalRead(outputAddress[19]); } bool D21_OPC(const char *itemID, const opcOperation opcOP, const bool value){ static bool ledValue = false; if (opcOP == opc_opwrite) { ledValue = value; if (ledValue) {digitalWrite(outputAddress[20], HIGH);} else digitalWrite(outputAddress[20], LOW); } else return digitalRead(outputAddress[20]); } bool D22_OPC(const char *itemID, const opcOperation opcOP, const bool value){ static bool ledValue = false; if (opcOP == opc_opwrite) { ledValue = value; if (ledValue) {digitalWrite(outputAddress[21], HIGH);} else digitalWrite(outputAddress[21], LOW); } else return digitalRead(outputAddress[21]); } bool D23_OPC(const char *itemID, const opcOperation opcOP, const bool value){ static bool ledValue = false; if (opcOP == opc_opwrite) { ledValue = value; if (ledValue) {digitalWrite(outputAddress[22], HIGH);} else digitalWrite(outputAddress[22], LOW); } else return digitalRead(outputAddress[22]); } bool D24_OPC(const char *itemID, const opcOperation opcOP, const bool value){ static bool ledValue = false; if (opcOP == opc_opwrite) { ledValue = value; if (ledValue) {digitalWrite(outputAddress[23], HIGH);} else digitalWrite(outputAddress[23], LOW); } else return digitalRead(outputAddress[23]); } //////////////////////////////////////////////////////////////////////// // описываем SIM*900 //////////////////////////////////////////////////////////////////////// void sim() { #define MASTER "+71234567890" //укажите телефон хозяина int ch = 0; String val = ""; int led = 13; pinMode(led, OUTPUT); digitalWrite(led, LOW); if (Serial1.available()) { //есть данные от GSM модуля delay(200); //выждем, чтобы строка успела попасть в порт целиком раньше чем будет считана while (Serial1.available()) { //сохраняем входную строку в переменную val ch = Serial1.read(); val += char(ch); delay(10); } Serial.println(val); //печатаем в монитор порта пришедшую строку ///////////////////////////////////////////////////////////////////////// //----------------------- определение факта приема звонка и сравнение номера ///////////////////////////////////////////////////////////////////////// if (val.indexOf("RING") > -1) { //если звонок обнаружен, то проверяем номер if (val.indexOf("71234567890") > -1) { //если номер звонящего наш. Укажите свой номер без "+" Serial.println("--- MASTER RING DETECTED ---"); delay(100); Serial1.println("ATH0"); //разрываем связь delay(100); digitalWrite(led, HIGH); //включаем светодиод на 3 сек delay(3000); digitalWrite(led, LOW); //выключаем реле } else { Serial1.println("ATH0"); //разрываем связь Serial.println("--- Unknown RING DETECTED ---"); } } //////////////////////////////////////////////////////////////////////////////////////// //----------------------- проверка номера /////////////////////////////////////////////////////////////////////////////////////////// if (val.indexOf("+CMT") > -1) { //если обнаружен СМС (для определения звонка вместо "+CMT" вписать "RING", трубку он не берет, но реагировать на факт звонка можно) if (val.indexOf(MASTER) > -1) { //если СМС от хозяина Serial.println("--- MASTER SMS DETECTED ---"); //////////////////////////////////////////////////////////////////////////////////////// //----------------------- отправка температур /////////////////////////////////////////////////////////////////////////////////////////// //----------------------- поиск кодового слова в СМС (вообще эту часть надо поместить внутрь предыдущей, но если использовать кодовое слово не совпадающее с сообщениями модема, то не обязательно) if (val.indexOf("Temp") > -1) { // если обнаружено кодовое слово Serial.println("Good command"); // сообщаем об этом в терминал (если нужно) smstemp(MASTER); } //////////////////////////////////////////////////////////////////////////////////////// //----------------------- отправка состояний DO /////////////////////////////////////////////////////////////////////////////////////////// //----------------------- поиск кодового слова в СМС (вообще эту часть надо поместить внутрь предыдущей, но если использовать кодовое слово не совпадающее с сообщениями модема, то не обязательно) if (val.indexOf("Dostatus") > -1) { // если обнаружено кодовое слово Serial.println("Good command"); // сообщаем об этом в терминал (если нужно) smsDO(MASTER); } //////////////////////////////////////////////////////////////////////////////////////// //----------------------- управление DO /////////////////////////////////////////////////////////////////////////////////////////// if(val.substring(48,50) == "DO") { int D=val.substring(50,52).toInt(); Serial.print("D:"); Serial.print(D); int S=val.substring(52,53).toInt(); Serial.print("S:"); Serial.print(S); if(D>=0&&D<=28&&S>=0&&S<=1) { smstriggerPin(outputAddress[D], S); } } //////////////////////////////////////////////////////////////////////////////////////// //----------------------- задание требуемой температуры /////////////////////////////////////////////////////////////////////////////////////////// if(val.substring(48,51) == "T1=") { int T=val.substring(51).toInt(); if(T>=0&&T<=28) { TargetTemp1=T;EEPROM.write(1000, TargetTemp1);Serial.println(" "); Serial.print("SMS_T1:"); Serial.print(TargetTemp1); temp_set(); } } if(val.substring(48,51) == "T2=") { int T=val.substring(51).toInt(); if(T>=0&&T<=28) { TargetTemp2=T;EEPROM.write(1002, TargetTemp2);Serial.println(" "); Serial.print("SMS_T2:"); Serial.print(TargetTemp2); temp_set(); } } if(val.substring(48,51) == "T3=") { int T=val.substring(51).toInt(); if(T>=0&&T<=28) { TargetTemp3=T;EEPROM.write(1004, TargetTemp3);Serial.println(" "); Serial.print("SMS_T3:"); Serial.print(TargetTemp3); temp_set(); } } if(val.substring(48,51) == "T4=") { int T=val.substring(51).toInt(); if(T>=0&&T<=28) { TargetTemp4=T;EEPROM.write(1006, TargetTemp4);Serial.println(" "); Serial.print("SMS_T4:"); Serial.print(TargetTemp4); temp_set(); } } } else { Serial.println("NO MASTER SMS"); } } val = ""; } } void sms(String text, String phone) //процедура отправки СМС { Serial.println("SMS send started"); Serial1.println("AT+CMGS=\"" + phone + "\""); delay(500); Serial1.print(text); delay(200); Serial1.print((char)26); delay(200); Serial.println("SMS send complete"); delay(2000); } void smstemp(String phone) //процедура отправки СМС { Serial.println("SMS TEMP send started"); Serial1.println("AT+CMGS=\"" + phone + "\""); delay(500); Serial1.print("T1:"); delay(200); Serial1.print(chartemp1); delay(200); Serial1.print(">>"); delay(200); Serial1.println(TargetTemp1); delay(200); Serial1.print(" T2:"); delay(200); Serial1.print(chartemp2); delay(200); Serial1.print(">>"); delay(200); Serial1.println(TargetTemp2); delay(200); Serial1.print(" T3:"); delay(200); Serial1.print(chartemp3); delay(200); Serial1.print(">>"); delay(200); Serial1.println(TargetTemp3); delay(200); Serial1.print(" T4:"); delay(200); Serial1.print(chartemp4); delay(200); Serial1.print(">>"); delay(200); Serial1.println(TargetTemp4); delay(200); Serial1.print(" G1:"); delay(200); Serial1.print(Humidity1+24); delay(200); Serial1.print("%"); delay(200); Serial1.print(" G2:"); delay(200); Serial1.print(Humidity1+46); delay(500); Serial1.print("%"); delay(200); Serial1.print(" G3:"); delay(200); Serial1.print(Humidity2+13); delay(200); Serial1.print("%"); delay(200); Serial1.print(" G4:"); delay(200); Serial1.print(Humidity2+49); delay(200); Serial1.print("%"); delay(200); Serial1.print((char)26); delay(200); Serial.println("SMS send complete"); delay(2000); Serial1.println("AT+CMGD=1"); //стираем память смс delay(100); } void smsDO(String phone) //процедура отправки СМС { Serial.println("SMS DO send started"); Serial1.println("AT+CMGS=\"" + phone + "\""); delay(500); for (int var = 0; var < outputQuantity; var++) { delay(100); delay(100); Serial1.print(var); Serial.print(var); delay(100); Serial1.print("::"); Serial.print("::"); delay(100); if (outputStatus[var] == true ){ if (outputInverted == false){ Serial1.print("1"); } else{ Serial1.print("0"); Serial.println("0"); } } else { if (outputInverted == false){ Serial1.print("0"); } else{ Serial1.print("1"); Serial.println("1"); } } Serial1.print(" "); } delay(200); Serial1.print((char)26); delay(200); Serial.println("SMS send complete"); delay(2000); Serial1.println("AT+CMGD=1"); //стираем память смс delay(100); } void smstriggerPin(int smspin, int smsoutp){ //Switching on or off outputs, reads the outputs and prints the buttons //Setting Outputs if(smsoutp == 1) { if (outputInverted ==false){ digitalWrite(smspin, HIGH); } else{ digitalWrite(smspin, LOW); } } if(smsoutp == 0){ if (outputInverted ==false){ digitalWrite(smspin, LOW); } else{ digitalWrite(smspin, HIGH); } } Serial.println(" "); Serial.print("smstriggerPin:"); Serial.print(smspin); Serial.print(" = "); Serial.println(smsoutp); } //////////////////////////////////////////////////////////////////////// ///////////////// управление температурой //////////////////////////////////////////////////////////////////////// void temp_set(){ byte sensor1[8] = {0x28, 0xFF, 0x48, 0x47, 0x34, 0x16, 0x04, 0x9E}; // Адрес сенсора byte sensor2[8] = {0x28, 0xFF, 0xB8, 0x25, 0x34, 0x16, 0x04, 0xAF}; // Адрес сенсора byte sensor3[8] = {0x28, 0xFF, 0x6C, 0x27, 0x34, 0x16, 0x04, 0xE9}; // Адрес сенсора byte sensor4[8] = {0x28, 0xFF, 0x1C, 0x1F, 0x34, 0x16, 0x03, 0x53}; // Адрес сенсора byte sensor5[8] = {0x28, 0xFF, 0xF2, 0x2F, 0x34, 0x16, 0x03, 0x63}; // Адрес сенсора byte sensor6[8] = {0x28, 0xFF, 0x7E, 0x46, 0x34, 0x16, 0x03, 0x8A}; // Адрес сенсора byte sensor7[8] = {0x28, 0xFF, 0x01, 0x46, 0x34, 0x16, 0x04, 0x0B}; // Адрес сенсора byte sensor8[8] = {0x28, 0xFF, 0x39, 0x4A, 0x34, 0x16, 0x04, 0xA3}; // Адрес сенсора byte sensor9[8] = {0x28, 0xFF, 0x0D, 0x32, 0x34, 0x16, 0x04, 0x8C}; // Адрес сенсора byte sensor10[8] = {0x28, 0xFF, 0x9D, 0x49, 0x34, 0x16, 0x04, 0x07}; // Адрес сенсора //DHT temp1 = dht1.readTemperature(); dtostrf(temp1, 3, 1, chartemp1); Humidity1=dht1.readHumidity(); temp2 = dht2.readTemperature(); dtostrf(temp2, 3, 1, chartemp2); Humidity2=dht2.readHumidity(); //DS18B20 /*Dallas Temperature IC Control Library Demo Locating devices...Found 10 devices. Parasite power is: OFF Found device 0 with address: 28FF48473416049E Found device 1 with address: 28FFB825341604AF Found device 2 with address: 28FF6C27341604E9 Found device 3 with address: 28FF1C1F34160353 Found device 4 with address: 28FFF22F34160363 Found device 5 with address: 28FF7E463416038A Found device 6 with address: 28FF01463416040B Found device 7 with address: 28FF394A341604A3 Found device 8 with address: 28FF0D323416048C Found device 9 with address: 28FF9D4934160407 */ temp3 = tempread(sensor1); dtostrf(temp3, 3, 1, chartemp3); temp4 = tempread(sensor2); dtostrf(temp4, 3, 1, chartemp4); temp5 = tempread(sensor3); temp6 = tempread(sensor4); temp7 = tempread(sensor5); temp8 = tempread(sensor6); temp9 = tempread(sensor7); temp10 = tempread(sensor8); temp11 = tempread(sensor9); temp12 = tempread(sensor10); if (TargetTemp1==0) { digitalWrite(PinSSR1, HIGH); } else { if (temp1<TargetTemp1-0.5) { digitalWrite(PinSSR1, LOW); } else if (temp1>TargetTemp1+0.5) { digitalWrite(PinSSR1, HIGH); } } if (TargetTemp2==0) { digitalWrite(PinSSR2, HIGH); } else { if (temp2<TargetTemp2-0.5) { digitalWrite(PinSSR2, LOW); } else if (temp2>TargetTemp2+0.5) { digitalWrite(PinSSR2, HIGH); } } if (TargetTemp3==0) { digitalWrite(PinSSR3, HIGH); } else { if (temp3<TargetTemp3-0.5) { digitalWrite(PinSSR3, LOW); } else if (temp3>TargetTemp3+0.5) { digitalWrite(PinSSR3, HIGH); } } if (TargetTemp4==0) { digitalWrite(PinSSR4, HIGH); } else { if (temp4<TargetTemp4-0.5) { digitalWrite(PinSSR4, LOW); } else if (temp4>TargetTemp4+0.5) { digitalWrite(PinSSR4, HIGH); } } } //////////////////////////////////////////////////////////////////////// ///////////////// DS18B20 //////////////////////////////////////////////////////////////////////// float tempread(byte sensoraddr[]) // error codes: // -1 no sensors found // -2 invalid CRC // -3 not a DS1820 { byte i; byte present = 0; byte data[12]; byte addr[8]; //int HighByte, LowByte, TReading, SignBit, Tc_100, Tf_100, Whole, Fract; for ( i = 0; i < 8; i++) { addr[i]=sensoraddr[i]; } ds.reset(); // pulse the pins and wait for a response to reset the DS1820 ds.select(addr); // 0x55 (MATCH_ROM) followed by the address of the 1820 to talk to. // ds.write(0x44,1); // start conversion, with parasite power on at the end ds.write(0x44,0); //PARASITE POWER OFF // delay(800); present = ds.reset(); ds.select(addr); ds.write(0xBE); // Read Scratchpad for ( i = 0; i < 9; i++) { // we need 9 bytes data[i] = ds.read(); } int16_t raw = (data[1] << 8) | data[0]; float temp = (float)raw / 16.0; return temp; } //////////////////////////////////////////////////////////////////////// //for 1307 //////////////////////////////////////////////////////////////////////// void printTime() { DateTime now = rtc.now(); snprintf(buf, sizeof(buf), "%02d:%02d %02d-%02d-%04d ", now.hour(), now.minute(), now.day(), now.month(), now.year() ); } //////////////////////////////////////////////////////////////////////// //checkForClient Function //////////////////////////////////////////////////////////////////////// void checkForClient(){ EthernetClient client = server.available(); if (client) { // an http request ends with a blank line boolean currentLineIsBlank = true; boolean sentHeader = false; String command; int repeat=0; //String tcommand; while (client.connected()) { if (client.available()) { //read user input char c = client.read(); if(c == '*'){ printHtmlHeader(client); //call for html header and css printHtmlFooter(client); //sentHeader = true; break; } if(!sentHeader){ printHtmlHeader(client); //call for html header and css printHtmlButtonTitle(client); //print the button title //This is for the arduino to construct the page on the fly. sentHeader = true; } //if there was reading but is blank there was no reading if(reading && c == ' '){ reading = false; } //http://10.16.30.2/?t1-10 //if there is a ? there was user input if(c == '?') { reading = true; //found the ?, begin reading the info command = F(""); // clear current command // tcommand = F(""); // clear current command } // if there was user input switch the relevant output if(reading){ //if user input is H set output to 1 if(c == 'H') { outp = 1; } //if user input is L set output to 0 if(c == 'L') { outp = 0; } if(c!='?'&&c!='H'&&c!='L') {command +=c;} repeat++; Serial.println(" "); Serial.print("repeat:"); Serial.print(repeat); if(repeat>=5){ if(command.substring(0,3) == "T1=") { int T=command.substring(3).toInt(); if(T>=0&&T<=28) { TargetTemp1=T;EEPROM.write(1000, TargetTemp1);Serial.println(" "); Serial.print("T1:"); Serial.print(TargetTemp1); temp_set(); } } if(command.substring(0,3) == "T2=") { int T=command.substring(3).toInt(); if(T>=0&&T<=28) { TargetTemp2=T;EEPROM.write(1002, TargetTemp2);Serial.println(" "); Serial.print("T2:"); Serial.print(TargetTemp2); temp_set(); } } if(command.substring(0,3) == "T3=") { int T=command.substring(3).toInt(); if(T>=0&&T<=28) { TargetTemp3=T;EEPROM.write(1004, TargetTemp3);Serial.println(" "); Serial.print("T3:"); Serial.print(TargetTemp3); temp_set(); } } if(command.substring(0,3) == "T4=") { int T=command.substring(3).toInt(); if(T>=0&&T<=28) { TargetTemp4=T;EEPROM.write(1006, TargetTemp4);Serial.println(" "); Serial.print("T4:"); Serial.print(TargetTemp4); temp_set(); } } if(command == "d11") {triggerPin(outputAddress[0], client, outp); Serial.println(" "); Serial.println("case 1 OK"); } if(command == "d12") {triggerPin(outputAddress[1], client, outp); Serial.println(" "); Serial.println("case 2 OK"); } if(command == "d13") {triggerPin(outputAddress[2], client, outp); Serial.println(" "); Serial.println("case 3 OK"); } if(command == "d14") {triggerPin(outputAddress[3], client, outp); Serial.println(" "); Serial.println("case 4 OK"); } if(command == "d15") {triggerPin(outputAddress[4], client, outp); Serial.println(" "); Serial.println("case 5 OK"); } if(command == "d16") {triggerPin(outputAddress[5], client, outp); Serial.println(" "); Serial.println("case 6 OK"); } if(command == "d17") {triggerPin(outputAddress[6], client, outp); Serial.println(" "); Serial.println("case 7 OK"); } if(command == "d18") {triggerPin(outputAddress[7], client, outp); Serial.println(" "); Serial.println("case 8 OK"); } if(command == "d19") {triggerPin(outputAddress[8], client, outp); Serial.println(" "); Serial.println("case 9 OK"); } if(command == "d20") {triggerPin(outputAddress[9], client, outp); Serial.println(" "); Serial.println("case 10 OK"); } if(command == "d21") {triggerPin(outputAddress[10], client, outp); Serial.println(" "); Serial.println("case 11 OK"); } if(command == "d22") {triggerPin(outputAddress[11], client, outp); Serial.println(" "); Serial.println("case 12 OK"); } if(command == "d23") {triggerPin(outputAddress[12], client, outp); Serial.println(" "); Serial.println("case 13 OK"); } if(command == "d24") {triggerPin(outputAddress[13], client, outp); Serial.println(" "); Serial.println("case 14 OK"); } if(command == "d25") {triggerPin(outputAddress[14], client, outp); Serial.println(" "); Serial.println("case 15 OK"); } if(command == "d26") {triggerPin(outputAddress[15], client, outp); Serial.println(" "); Serial.println("case 16 OK"); } if(command == "d27") {triggerPin(outputAddress[16], client, outp); Serial.println(" "); Serial.println("case 17 OK"); } if(command == "d28") {triggerPin(outputAddress[17], client, outp); Serial.println(" "); Serial.println("case 18 OK"); } if(command == "d29") {triggerPin(outputAddress[18], client, outp); Serial.println(" "); Serial.println("case 19 OK"); } if(command == "d30") {triggerPin(outputAddress[19], client, outp); Serial.println(" "); Serial.println("case 20 OK"); } if(command == "d31") {triggerPin(outputAddress[20], client, outp); Serial.println(" "); Serial.println("case 21 OK"); } if(command == "d32") {triggerPin(outputAddress[21], client, outp); Serial.println(" "); Serial.println("case 22 OK"); } if(command == "d33") {triggerPin(outputAddress[22], client, outp); Serial.println(" "); Serial.println("case 23 OK"); } if(command == "d34") {triggerPin(outputAddress[23], client, outp); Serial.println(" "); Serial.println("case 24 OK"); } if(command == "100"){ for (int var = 0; var < 14; var++){triggerPin(outputAddress[var], client, outp);} } if(command == "200"){ for (int var = 14; var < outputQuantity; var++){triggerPin(outputAddress[var], client, outp);} } if(command == "page1") {page=1; Serial.println(" "); Serial.println("page 1 OK"); } if(command == "page0") {page=0; Serial.println(" "); Serial.println("page 0 OK"); } if(command == "save1") {writeEepromValues1(); Serial.println(" "); Serial.println("save1"); } if(command == "reset1") {resetEepromValues1(); Serial.println(" "); Serial.println("reset1"); } if(command == "save2") {writeEepromValues2(); Serial.println(" "); Serial.println("save2"); } if(command == "reset2") {resetEepromValues2(); Serial.println(" "); Serial.println("reset2"); } }// end repeat }//end if(reading) //if user input was blank if (c == '\n' && currentLineIsBlank){ printLastCommandOnce = true; printButtonMenuOnce = true; triggerPin(777, client, outp); //Call to read input and print menu. 777 is used not to update any outputs break; } } // end if (client.available()) } // end whil Serial.println(" "); Serial.print("command:"); Serial.print(command); Serial.println(" "); Serial.println("----------"); printHtmlFooter(client); //Prints the html footer } else { //if there is no client // таймаут простоя, для записи данных состояния переключателей в кэш if (millis() > (timeConnectedAt + 3600000)){ if (writeToEeprom == true){ writeEepromValues1(); //write to EEprom the current output statuses writeEepromValues2(); //write to EEprom the current output statuses Serial.println("No Clients for more then a 60 min. - Writing statuses to Eeprom."); writeToEeprom = false; } } } } /////////////////////////////////////////////////////////////////////// //triggerPin Function //////////////////////////////////////////////////////////////////////// void triggerPin(int pin, EthernetClient client, int outp){ //Switching on or off outputs, reads the outputs and prints the buttons //Setting Outputs if (pin != 777){ if(outp == 1) { if (outputInverted ==false){ digitalWrite(pin, HIGH); } else{ digitalWrite(pin, LOW); } } if(outp == 0){ if (outputInverted ==false){ digitalWrite(pin, LOW); } else{ digitalWrite(pin, HIGH); } } Serial.println(" "); Serial.print("triggerPin:"); Serial.print(pin); Serial.print(" = "); Serial.println(outp); } //Refresh the reading of outputs readOutputStatuses(); //Prints the buttons if (printButtonMenuOnce == true){ printHtmlButtons(client); printButtonMenuOnce = false; } } //////////////////////////////////////////////////////////////////////// //readOutputStatuses Function //////////////////////////////////////////////////////////////////////// //Reading the Output Statuses void readOutputStatuses(){ for (int var = 0; var < outputQuantity; var++) { outputStatus[var] = digitalRead(outputAddress[var]); // Serial.print(outputStatus[var]); } } //////////////////////////////////////////////////////////////////////// //printHtmlButtons Function //////////////////////////////////////////////////////////////////////// void printHtmlButtons(EthernetClient client){ client.println(F("")); client.println(F("<FORM>")); //вывод таблиц узкая или широкая, page == 1 широкая if (page == 1){ client.println(F("<table border=\"0\" align=\"center\">")); client.println(F("<tr>")); client.println(F(" <td colspan=2>")); } //////////////////////////////////////////////////////////////////////////////// // всплывающие окна //////////////////////////////////////////////////////////////////////////////// //выыод первого окна client.println(F("<div id=\"parent_popup_click\">")); client.println(F(" <div id=\"popup_click\">")); client.println(F(" <h2>Управление овещением</h2>")); //client.println(F(" <p><center>")); //начало текста в окне client.println(F("<table>\n")); for (int var = 0; var < 14; var++) { //Print begining of row client.print(F("<tr>\n")); //Prints the button Text client.print(F(" <td><h5>")); client.print(buttonText[var]); client.print(F("</h5></td>\n")); //Prints the ON Buttons client.print(F(" <td><INPUT TYPE=\"button\" VALUE=\"ВКЛ ")); client.print(F("\" onClick=\"parent.location='/?H")); client.print(F("d")); client.print(twenty[var]); client.print(F("'\"></td>\n")); //Prints the OFF Buttons client.print(F(" <td><INPUT TYPE=\"button\" VALUE=\"ВЫКЛ")); client.print(F("\" onClick=\"parent.location='/?L")); client.print(F("d")); client.print(twenty[var]); client.print(F("'\"></td>\n")); //Print first part of the Circles or the LEDs //Invert the LED display if output is inverted. if (outputStatus[var] == true ){ //If Output is ON if (outputInverted == false){ //and if output is not inverted client.print(F(" <td><div class='green-circle'><div class='glare'></div></div></td>\n")); //Print html for ON LED } else{ //else output is inverted then client.print(F(" <td><div class='black-circle'><div class='glare'></div></div></td>\n")); //Print html for OFF LED } } else //If Output is Off { if (outputInverted == false){ //and if output is not inverted client.print(F(" <td><div class='black-circle'><div class='glare'></div></div></td>\n")); //Print html for OFF LED } else{ //else output is inverted then client.print(F(" <td><div class='green-circle'><div class='glare'></div></div></td>\n")); //Print html for ON LED } } client.print(F("\n")); } // end for //Prints the ON All Pins Button client.print(F("<tr>\n <td colspan=2><INPUT TYPE=\"button\" VALUE=\"Включить ВСЁ")); client.print(F("\" onClick=\"parent.location='/?H100")); client.print(F("'\"></td>\n")); //Prints the OFF All Pins Button client.print(F(" <td colspan=2><INPUT TYPE=\"button\" VALUE=\"Выключить ВСЁ")); client.print(F("\" onClick=\"parent.location='/?L100")); client.print(F("'\"></td>\n <td></td>\n <td></td>\n</tr>\n")); //Prints save Button client.print(F("<tr>\n <td colspan=2><INPUT TYPE=\"button\" VALUE=\"Записать")); client.print(F("\" onClick=\"parent.location='/?save1")); client.print(F("'\"></td>\n")); //Prints reset Button client.print(F(" <td colspan=2><INPUT TYPE=\"button\" VALUE=\"Сбросить")); client.print(F("\" onClick=\"parent.location='/?reset1")); client.print(F("'\"></td>\n <td></td>\n <td></td>\n</tr>\n")); client.println(F("</table>\n")); //конец текста в вервом окне //client.println(F(" </center>")); client.println(F(" <a class=\"close\" title=\"Закрыть\" onclick=\"document.getElementById('parent_popup_click').style.display='none';\">X</a>")); client.println(F(" </div>")); client.println(F(" </div>")); client.println(F("")); //вывод второго окна client.println(F(" <div id=\"parent_popup2_click\">")); client.println(F(" <div id=\"popup2_click\">")); client.println(F(" <h2>Управление нагрузками:</h2>")); //client.println(F(" <p><center>Тут может быть абсолютно любой html или даже скрипты</center>")); //начало текста во втором окне client.println(F("<table>\n")); for (int var = 14; var < outputQuantity; var++) { //Print begining of row client.print(F("<tr>\n")); //Prints the button Text client.print(F(" <td><h5>")); client.print(buttonText[var]); client.print(F(" </h5></td>\n")); //Prints the ON Buttons client.print(F(" <td><INPUT TYPE=\"button\" VALUE=\"ВКЛ ")); client.print(F("\" onClick=\"parent.location='/?H")); client.print(F("d")); client.print(twenty[var]); client.print(F("'\"></td>\n")); //Prints the OFF Buttons client.print(F(" <td><INPUT TYPE=\"button\" VALUE=\"ВЫКЛ")); client.print(F("\" onClick=\"parent.location='/?L")); client.print(F("d")); client.print(twenty[var]); client.print(F("'\"></td>\n")); //Print first part of the Circles or the LEDs //Invert the LED display if output is inverted. if (outputStatus[var] == true ){ //If Output is ON if (outputInverted == false){ //and if output is not inverted client.print(F(" <td><div class='green-circle'><div class='glare'></div></div></td>\n")); //Print html for ON LED } else{ //else output is inverted then client.print(F(" <td><div class='black-circle'><div class='glare'></div></div></td>\n")); //Print html for OFF LED } } else //If Output is Off { if (outputInverted == false){ //and if output is not inverted client.print(F(" <td><div class='black-circle'><div class='glare'></div></div></td>\n")); //Print html for OFF LED } else{ //else output is inverted then client.print(F(" <td><div class='green-circle'><div class='glare'></div></div></td>\n")); //Print html for ON LED } } client.print(F("</tr>\n")); } // end for //Prints the ON All Pins Button client.print(F("<tr>\n <td colspan=2><INPUT TYPE=\"button\" VALUE=\"Включить ВСЁ")); client.print(F("\" onClick=\"parent.location='/?H200")); client.print(F("'\"></td>\n")); //Prints the OFF All Pins Button client.print(F(" <td colspan=2><INPUT TYPE=\"button\" VALUE=\"Выключить ВСЁ")); client.print(F("\" onClick=\"parent.location='/?L200")); client.print(F("'\"></td>\n <td></td>\n <td></td>\n</tr>\n")); //Prints save Button client.print(F("<tr>\n <td colspan=2><INPUT TYPE=\"button\" VALUE=\"Записать")); client.print(F("\" onClick=\"parent.location='/?save2")); client.print(F("'\"></td>\n")); //Prints reset Button client.print(F(" <td colspan=2><INPUT TYPE=\"button\" VALUE=\"Сбросить")); client.print(F("\" onClick=\"parent.location='/?reset2")); client.print(F("'\"></td>\n <td></td>\n <td></td>\n</tr>\n")); client.println(F("</table>\n")); //конец текста во втором окне client.println(F(" <a class=\"close\" title=\"Закрыть\" onclick=\"document.getElementById('parent_popup2_click').style.display='none';\">X</a>")); client.println(F(" </div>")); client.println(F(" </div>")); client.println(F("")); // таблица кнопок управления client.println(F(" <table border=\"0\" align=\"center\" style=\"background-color:#f5f5f5\">")); //Prints window1 Button client.print(F(" <tr>\n <td colspan=2><INPUT TYPE=\"button\" VALUE=\"Управление освещением")); client.print(F("\" onclick=\"document.getElementById('parent_popup_click').style.display='block';\">")); client.print(F("</td>\n")); //Prints window2 Button client.print(F(" <td colspan=2><INPUT TYPE=\"button\" VALUE=\"Управление нагрузками")); client.print(F("\" onclick=\"document.getElementById('parent_popup2_click').style.display='block';\">")); client.print(F("</td>\n <td></td>\n <td></td>\n ")); client.println(F("</table>")); client.println(F("")); //вывод таблиц узкая или широкая, page == 1 широкая if (page == 1){ client.println(F("</td>")); client.println(F("</tr>")); client.println(F("<tr>")); client.println(F("<td height=\"86\">")); client.println(F("")); } client.println(F("<table border=\"0\" align=\"center\">")); client.println(F("<tr>")); client.println(F(" <td></td>")); client.println(F(" <td><h3>текущая</h3></td>")); client.println(F(" <td><h3>обогрев</h3></td>")); client.println(F(" <td><h3>желаемая</h3></td>")); client.println(F("</tr>")); client.println(F("<tr>")); client.print(F(" <td><h4>")); client.print(F("Первый этаж:")); client.println(F("</h4></td>")); client.print(F(" <td align=\"center\">")); client.print(chartemp1); //текущая температура client.println(F(" °C</td>")); if ( digitalRead(PinSSR1) == LOW ) { client.println(F(" <td align=\"center\"><font color=green><b>ВКЛ</b></font></td>")); } // вкл или выкл else { client.println(F(" <td align=\"center\"><font color=red><b>ВЫКЛ</b></font></td>")); } client.print(F(" <td align=\"center\">")); client.print(TargetTemp1); //отображение желаемой температуры client.println(F(" °C</td>")); client.println(F("</tr>")); client.println(F("<tr>")); client.print(F(" <td><h4>")); client.print(F("Установить:")); //выбор желаемой температуры client.println(F("</h4></td>")); client.println(F(" <td colspan=3><table border=\"0\" style=\"background-color:#f5f5f5\"><tr><td><INPUT TYPE=\"button\" VALUE=\"0" "\" onClick=\"parent.location='/?T1=0""'\"></td>")); client.println(F(" <td><INPUT TYPE=\"button\" VALUE=\"5" "\" onClick=\"parent.location='/?T1=5""'\"></td>")); client.println(F(" <td><INPUT TYPE=\"button\" VALUE=\"10" "\" onClick=\"parent.location='/?T1=10""'\"></td>")); client.println(F(" <td><INPUT TYPE=\"button\" VALUE=\"20" "\" onClick=\"parent.location='/?T1=20""'\"></td>")); client.println(F(" <td><INPUT TYPE=\"button\" VALUE=\"22" "\" onClick=\"parent.location='/?T1=22""'\"></td>")); client.println(F(" <td><INPUT TYPE=\"button\" VALUE=\"24" "\" onClick=\"parent.location='/?T1=24""'\"></td></tr></table></td>")); client.println(F("</tr>")); client.println(F("<tr>")); client.print(F(" <td><h4>")); client.print(F("Точно:")); //выбор желаемой температуры точно client.println(F("</h4></td>")); client.println(F(" <td></td>")); client.print(F(" <td colspan=2>")); client.print(F("<form><input type=text name=T1 size=10> <input type=submit value=ОК> </form></td>")); client.println(F("</tr>")); client.println(F("</table>")); client.println(F("")); if (page == 1){ client.println(F("</td>")); client.println(F("<td height=\"86\">")); client.println(F("")); } client.println(F("<table border=\"0\" align=\"center\">")); client.println(F("<tr>")); client.println(F(" <td></td>")); client.println(F(" <td><h3>текущая</h3></td>")); client.println(F(" <td><h3>обогрев</h3></td>")); client.println(F(" <td><h3>желаемая</h3></td>")); client.println(F("</tr>")); client.println(F("<tr>")); client.print(F(" <td><h4>")); client.print(F("Второй этаж:")); client.println(F("</h4></td>")); client.print(F(" <td align=\"center\">")); client.print(chartemp2); //текущая температура client.println(F(" °C</td>")); if ( digitalRead(PinSSR2) == LOW ) { client.println(F(" <td align=\"center\"><font color=green><b>ВКЛ</b></font></td>")); } // вкл или выкл else { client.println(F(" <td align=\"center\"><font color=red><b>ВЫКЛ</b></font></td>")); } client.print(F(" <td align=\"center\">")); client.print(TargetTemp2); //отображение желаемой температуры client.println(F(" °C</td>")); client.println(F("</tr>")); client.println(F("<tr>")); client.print(F(" <td><h4>")); client.print(F("Установить:")); //выбор желаемой температуры client.println(F("</h4></td>")); client.println(F(" <td colspan=3><table border=\"0\" style=\"background-color:#f5f5f5\"><tr><td><INPUT TYPE=\"button\" VALUE=\"0" "\" onClick=\"parent.location='/?T2=0""'\"></td>")); client.println(F(" <td><INPUT TYPE=\"button\" VALUE=\"5" "\" onClick=\"parent.location='/?T2=5""'\"></td>")); client.println(F(" <td><INPUT TYPE=\"button\" VALUE=\"10" "\" onClick=\"parent.location='/?T2=10""'\"></td>")); client.println(F(" <td><INPUT TYPE=\"button\" VALUE=\"20" "\" onClick=\"parent.location='/?T2=20""'\"></td>")); client.println(F(" <td><INPUT TYPE=\"button\" VALUE=\"22" "\" onClick=\"parent.location='/?T2=22""'\"></td>")); client.println(F(" <td><INPUT TYPE=\"button\" VALUE=\"24" "\" onClick=\"parent.location='/?T2=24""'\"></td></tr></table></td>")); client.println(F("</tr>")); client.println(F("<tr>")); client.print(F(" <td><h4>")); client.print(F("Точно:")); //выбор желаемой температуры точно client.println(F("</h4></td>")); client.println(F(" <td></td>")); client.print(F(" <td colspan=2>")); client.print(F("<form><input type=text name=T2 size=10> <input type=submit value=ОК> </form></td>")); client.println(F("</tr>")); client.println(F("</table>")); client.println(F("")); if (page == 1){ client.println(F("</td>")); client.println(F("</tr>")); client.println(F("<tr>")); client.println(F("<td height=\"86\">")); client.println(F("")); } client.println(F("<table border=\"0\" align=\"center\">")); client.println(F("<tr>")); client.println(F(" <td></td>")); client.println(F(" <td><h3>текущая</h3></td>")); client.println(F(" <td><h3>обогрев</h3></td>")); client.println(F(" <td><h3>желаемая</h3></td>")); client.println(F("</tr>")); client.println(F("<tr>")); client.print(F(" <td><h4>")); client.print(F("Кухня:")); client.println(F("</h4></td>")); client.print(F(" <td align=\"center\">")); client.print(chartemp3); //текущая температура client.println(F(" °C</td>")); if ( digitalRead(PinSSR3) == LOW ) { client.println(F(" <td align=\"center\"><font color=green><b>ВКЛ</b></font></td>")); } // вкл или выкл else { client.println(F(" <td align=\"center\"><font color=red><b>ВЫКЛ</b></font></td>")); } client.print(F(" <td align=\"center\">")); client.print(TargetTemp3); //отображение желаемой температуры client.println(F(" °C</td>")); client.println(F("</tr>")); client.println(F("<tr>")); client.print(F(" <td><h4>")); client.print(F("Установить:")); //выбор желаемой температуры client.println(F("</h4></td>")); client.println(F(" <td colspan=3><table border=\"0\" style=\"background-color:#f5f5f5\"><tr><td><INPUT TYPE=\"button\" VALUE=\"0" "\" onClick=\"parent.location='/?T3=0""'\"></td>")); client.println(F(" <td><INPUT TYPE=\"button\" VALUE=\"5" "\" onClick=\"parent.location='/?T3=5""'\"></td>")); client.println(F(" <td><INPUT TYPE=\"button\" VALUE=\"10" "\" onClick=\"parent.location='/?T3=10""'\"></td>")); client.println(F(" <td><INPUT TYPE=\"button\" VALUE=\"20" "\" onClick=\"parent.location='/?T3=20""'\"></td>")); client.println(F(" <td><INPUT TYPE=\"button\" VALUE=\"22" "\" onClick=\"parent.location='/?T3=22""'\"></td>")); client.println(F(" <td><INPUT TYPE=\"button\" VALUE=\"24" "\" onClick=\"parent.location='/?T3=24""'\"></td></tr></table></td>")); client.println(F("</tr>")); client.println(F("<tr>")); client.print(F(" <td><h4>")); client.print(F("Точно:")); //выбор желаемой температуры точно client.println(F("</h4></td>")); client.println(F(" <td></td>")); client.print(F(" <td colspan=2>")); client.print(F("<form><input type=text name=T3 size=10> <input type=submit value=ОК> </form></td>")); client.println(F("</tr>")); client.println(F("</table>")); client.println(F("")); if (page == 1){ client.println(F("</td>")); client.println(F("<td height=\"86\">")); client.println(F("")); } client.println(F("<table border=\"0\" align=\"center\">")); client.println(F("<tr>")); client.println(F(" <td></td>")); client.println(F(" <td><h3>текущая</h3></td>")); client.println(F(" <td><h3>обогрев</h3></td>")); client.println(F(" <td><h3>желаемая</h3></td>")); client.println(F("</tr>")); client.println(F("<tr>")); client.print(F(" <td><h4>")); client.print(F("Ванная:")); client.println(F("</h4></td>")); client.print(F(" <td align=\"center\">")); client.print(chartemp4); //текущая температура client.println(F(" °C</td>")); if ( digitalRead(PinSSR4) == LOW ) { client.println(F(" <td align=\"center\"><font color=green><b>ВКЛ</b></font></td>")); } // вкл или выкл else { client.println(F(" <td align=\"center\"><font color=red><b>ВЫКЛ</b></font></td>")); } client.print(F(" <td align=\"center\">")); client.print(TargetTemp4); //отображение желаемой температуры client.println(F(" °C</td>")); client.println(F("</tr>")); client.println(F("<tr>")); client.print(F(" <td><h4>")); client.print(F("Установить:")); //выбор желаемой температуры client.println(F("</h4></td>")); client.println(F(" <td colspan=3><table border=\"0\" style=\"background-color:#f5f5f5\"><tr><td><INPUT TYPE=\"button\" VALUE=\"0" "\" onClick=\"parent.location='/?T4=0""'\"></td>")); client.println(F(" <td><INPUT TYPE=\"button\" VALUE=\"5" "\" onClick=\"parent.location='/?T4=5""'\"></td>")); client.println(F(" <td><INPUT TYPE=\"button\" VALUE=\"10" "\" onClick=\"parent.location='/?T4=10""'\"></td>")); client.println(F(" <td><INPUT TYPE=\"button\" VALUE=\"20" "\" onClick=\"parent.location='/?T4=20""'\"></td>")); client.println(F(" <td><INPUT TYPE=\"button\" VALUE=\"22" "\" onClick=\"parent.location='/?T4=22""'\"></td>")); client.println(F(" <td><INPUT TYPE=\"button\" VALUE=\"24" "\" onClick=\"parent.location='/?T4=24""'\"></td></tr></table></td>")); client.println(F("</tr>")); client.println(F("<tr>")); client.print(F(" <td><h4>")); client.print(F("Точно:")); //выбор желаемой температуры точно client.println(F("</h4></td>")); client.println(F(" <td></td>")); client.print(F(" <td colspan=2>")); client.print(F("<form><input type=text name=T4 size=10> <input type=submit value=ОК> </form></td>")); client.println(F("</tr>")); client.println(F("</table>")); client.println(F("")); if (page == 1){ client.println(F("</td>")); client.println(F("</tr>")); client.println(F("<tr>")); client.println(F("<td height=\"86\" colspan=2>")); client.println(F("")); } client.println(F("<table border=\"0\" align=\"center\" style=\"background-color:#f5f5f5\">")); client.println(F("<tr>")); client.println(F(" <td></td>")); client.println(F(" <td><h3>улица</h3></td>")); client.println(F(" <td><h3>1 этаж</h3></td>")); client.println(F(" <td><h3>2 этаж</h3></td>")); client.println(F(" <td><h3>кухня</h3></td>")); client.println(F(" <td><h3>ванная</h3></td>")); client.println(F(" <td><h3>баня 1эт.</h3></td>")); client.println(F(" <td><h3>баня 2эт.</h3></td>")); client.println(F(" <td><h3>парилка</h3></td>")); client.println(F(" <td><h3>труба</h3></td>")); client.println(F(" <td><h3>шкаф упр.</h3></td>")); client.println(F("</tr>")); client.println(F("<tr>")); client.print(F(" <td><h4>")); client.print(F("Температура:")); client.println(F("</h4></td>")); client.print(F(" <td align=\"center\">")); client.print(temp1); //отображение температуры client.println(F("°C</td>")); client.print(F(" <td align=\"center\">")); client.print(temp2); //отображение температуры client.println(F("°C</td>")); client.print(F(" <td align=\"center\">")); client.print(temp3); //отображение температуры client.println(F("°C</td>")); client.print(F(" <td align=\"center\">")); client.print(temp4); //отображение температуры client.println(F("°C</td>")); client.print(F(" <td align=\"center\">")); client.print(temp5); //отображение температуры client.println(F("°C</td>")); client.print(F(" <td align=\"center\">")); client.print(temp6); //отображение температуры client.println(F("°C</td>")); client.print(F(" <td align=\"center\">")); client.print(temp7); //отображение температуры client.println(F("°C</td>")); client.print(F(" <td align=\"center\">")); client.print(temp8); //отображение температуры client.println(F("°C</td>")); client.print(F(" <td align=\"center\">")); client.print(temp9); //отображение температуры client.println(F("°C</td>")); client.print(F(" <td align=\"center\">")); client.print(temp10); //отображение температуры client.println(F("°C</td>")); client.println(F("</tr>")); client.println(F("</table>")); client.println(F("")); if (page == 1){ client.println(F("</td>")); client.println(F("</tr>")); client.println(F("<tr>")); client.println(F("<td height=\"86\" colspan=2>")); client.println(F("")); } client.println(F("<table border=\"0\" style=\"background-color:#f5f5f5\">")); client.println(F("<tr>")); client.println(F(" <td><h3>Напряжение:</h3></td>")); client.println(F(" <td><h3>Ток 1:</h3></td>")); client.println(F(" <td><h3>Ток 2:</h3></td>")); client.println(F(" <td><h3>Яркость:</h3></td>")); client.println(F(" <td><h3>Давление:</h3></td>")); client.println(F(" <td><h3>Газ/воздух:</h3></td>")); client.println(F("</tr>")); client.println(F("<tr>")); client.print(F(" <td align=\"center\">")); client.print(analogRead(A4)); client.println(F(" V</td>")); client.print(F(" <td align=\"center\">")); client.print(analogRead(A5)); client.println(F(" A</td>")); client.print(F(" <td align=\"center\">")); client.print(analogRead(A6)); client.println(F(" A</td>")); client.print(F(" <td align=\"center\">")); client.print(lightMeter.readLightLevel()); client.println(F(" lux</td>")); client.print(F(" <td align=\"center\">")); client.print(bmp.readPressure()); client.println(F(" Pa</td>")); client.print(F(" <td align=\"center\">")); client.print(analogRead(A3)); client.println(F("</td>")); client.println(F("</tr>")); client.println(F("</table>")); client.println(F("")); if (page == 1){ client.println(F("</td>")); client.println(F("</tr>")); client.println(F("<tr>")); client.println(F("<td height=\"86\" colspan=2>")); client.println(F("")); } client.println(F("<table border=\"0\" align=\"center\" style=\"background-color:#f5f5f5\">")); client.println(F("<tr>")); client.println(F(" <td></td>")); client.println(F(" <td><h3>Кухня</h3></td>")); client.println(F(" <td><h3>Ванная</h3></td>")); client.println(F(" <td><h3>Баня</h3></td>")); client.println(F("</tr>")); client.println(F("<tr>")); client.print(F(" <td><h4>")); client.print(F("Влажность:")); client.println(F("</h4></td>")); client.print(F(" <td align=\"center\">")); client.print(Humidity2+38); //отображение влажности client.println(F("%</td>")); client.print(F(" <td align=\"center\">")); client.print(Humidity1+63); //отображение влажности client.println(F("%</td>")); client.print(F(" <td align=\"center\">")); client.print(Humidity1+87); //отображение влажности client.println(F("%</td>")); client.println(F("</tr>")); client.println(F("</table>")); client.println(F("")); if (page == 1){ client.println(F("</td>")); client.println(F("</tr>")); client.println(F("</table>")); } client.println(F("</FORM>")); } // end printHtmlButtons //////////////////////////////////////////////////////////////////////// //htmlHeader Function //////////////////////////////////////////////////////////////////////// void printHtmlHeader(EthernetClient client){ Serial.print("Serving html Headers at ms -"); timeConnectedAt = millis(); //Record the time when last page was served. Serial.println(timeConnectedAt); // Print time for debbugging purposes writeToEeprom = true; // page loaded so set to action the write to eeprom // send a standard http response header client.println(F("HTTP/1.1 200 OK")); client.println(F("Content-Type: text/html; charset=utf-8")); client.println(F("Connnection: close")); client.println(); client.println(F("<!DOCTYPE HTML>")); client.println(F("<head>")); // заголовок страницы client.println(F("<title>Контроль и управление домом</title>")); client.println(F("<meta name=\"description\" content=\"Контроль и управление домом\"/>")); // время обновления страницы client.print(F("<meta http-equiv=\"refresh\" content=\"")); client.print(refreshPage); client.println(F("; url=/\">")); // конфигурация браузера client.println(F("<meta name=\"apple-mobile-web-app-capable\" content=\"yes\">")); client.println(F("<meta name=\"apple-mobile-web-app-status-bar-style\" content=\"default\">")); client.println(F("<meta name=\"viewport\" content=\"width=device-width, user-scalable=no\">")); // вставка данных стилей CSS client.println(F("<style type=\"text/css\">")); client.println(F("")); // как будет выглядеть страница графически client.println(F("html { height:100%; }")); client.println(F(" body {")); client.println(F(" height: 100%;")); client.println(F(" margin: 0;")); client.println(F(" font-family: helvetica, sans-serif;")); client.println(F(" -webkit-text-size-adjust: none;")); client.println(F(" }")); client.println(F("")); client.println(F("body {")); client.println(F(" -webkit-background-size: 100% 21px;")); client.println(F(" background-color: #c5ccd3;")); client.println(F(" background-image:")); client.println(F(" -webkit-gradient(linear, left top, right top,")); client.println(F(" color-stop(.75, transparent),")); client.println(F(" color-stop(.75, rgba(255,255,255,.1)) );")); client.println(F(" -webkit-background-size: 7px;")); client.println(F(" }")); client.println(F("")); client.println(F(".view {")); client.println(F(" min-height: 100%;")); client.println(F(" overflow: auto;")); client.println(F(" }")); client.println(F("")); client.println(F(".header-wrapper {")); //шапка страницы client.println(F(" height: 40px;")); client.println(F(" font-weight: bold;")); client.println(F(" text-shadow: rgba(0,0,0,0.7) 0 -1px 0;")); client.println(F(" border-top: solid 1px rgba(255,255,255,0.6);")); client.println(F(" border-bottom: solid 1px rgba(0,0,0,0.6);")); client.println(F(" color: #fff;")); client.println(F(" background-color: #8195af;")); client.println(F(" background-image:")); client.println(F(" -webkit-gradient(linear, left top, left bottom,")); client.println(F(" from(rgba(255,255,255,.4)),")); client.println(F(" to(rgba(255,255,255,.05)) ),")); client.println(F(" -webkit-gradient(linear, left top, left bottom,")); client.println(F(" from(transparent),")); client.println(F(" to(rgba(0,0,64,.1)) );")); client.println(F(" background-repeat: no-repeat;")); client.println(F(" background-position: top left, bottom left;")); client.println(F(" -webkit-background-size: 100% 21px, 100% 22px;")); client.println(F(" -webkit-box-sizing: border-box;")); client.println(F(" }")); client.println(F("")); client.println(F(".group-wrapper {")); // серый текст client.println(F(" color: #19191c;")); client.println(F(" font-weight: bold;")); client.println(F(" line-height: 1;")); client.println(F(" text-shadow: #fff 0 1px 0;")); // client.println(F(" margin: 9px;")); client.println(F(" margin: 5px 5px 5px;")); client.println(F(" aling: center;")); client.println(F(" }")); client.println(F("")); client.println(F(".group-wrapper h2 {")); //крупный серый текст client.println(F(" font-size: 17px;")); client.println(F(" line-height: 0.8;")); client.println(F(" margin: 20px 10px 12px;")); client.println(F(" }")); client.println(F("")); client.println(F(".group-wrapper h3 {")); //мелкий серый текст client.println(F(" color: #4c566c;")); client.println(F(" font-size: 12px;")); client.println(F(" margin: 20px 10px 12px;")); client.println(F(" }")); client.println(F("")); client.println(F(".group-wrapper h4 {")); //крупный черный текст client.println(F(" color: #212121;")); client.println(F(" font-size: 14px;")); client.println(F(" text-shadow: #aaa 1px 1px 3px;")); client.println(F(" margin: 5px 5px 5px;")); client.println(F(" }")); client.println(F("")); client.println(F(".group-wrapper table {")); //таблицы client.println(F(" background-color: #fff;")); client.println(F(" -webkit-border-radius: 10px;")); client.println(F(" -moz-border-radius: 10px;")); client.println(F(" -khtml-border-radius: 10px;")); client.println(F(" border-radius: 10px;")); client.println(F(" font-size: 14px;")); client.println(F(" line-height: 10px;")); // ширина строк таблицы client.println(F(" margin: 5px 0 5px;")); // отступ строк таблицы client.println(F(" border: solid 1px #a9abae;")); client.println(F(" padding: 5px 3px 10px 3px;")); // отступ текста верх-права-низ-лево client.println(F(" margin-left:auto;")); client.println(F(" margin-right:auto;")); client.println(F(" -moz-transform :scale(1);")); //Code for Mozilla Firefox client.println(F(" -moz-transform-origin: 0 0;")); client.println(F(" }")); //how the green (ON) LED will look client.println(F(".green-circle {")); client.println(F(" display: block;")); client.println(F(" height: 23px;")); client.println(F(" width: 23px;")); client.println(F(" background-color: #0f0;")); client.println(F(" -moz-border-radius: 11px;")); client.println(F(" -webkit-border-radius: 11px;")); client.println(F(" -khtml-border-radius: 11px;")); client.println(F(" border-radius: 11px;")); client.println(F(" margin-left: 1px;")); client.println(F(" background-image: -webkit-gradient(linear, 0% 0%, 0% 90%, from(rgba(46, 184, 0, 0.8)), to(rgba(148, 255, 112, .9)));@")); client.println(F(" border: 2px solid #ccc;")); client.println(F(" -webkit-box-shadow: rgba(11, 140, 27, 0.5) 0px 10px 16px;")); client.println(F(" -moz-box-shadow: rgba(11, 140, 27, 0.5) 0px 10px 16px; /* FF 3.5+ */")); client.println(F(" box-shadow: rgba(11, 140, 27, 0.5) 0px 10px 16px; /* FF 3.5+ */")); client.println(F(" }")); client.println(F("")); //how the black (off)LED will look client.println(F(".black-circle {")); client.println(F(" display: block;")); client.println(F(" height: 23px;")); client.println(F(" width: 23px;")); client.println(F(" background-color: #040;")); client.println(F(" -moz-border-radius: 11px;")); client.println(F(" -webkit-border-radius: 11px;")); client.println(F(" -khtml-border-radius: 11px;")); client.println(F(" border-radius: 11px;")); client.println(F(" margin-left: 1px;")); client.println(F(" -webkit-box-shadow: rgba(11, 140, 27, 0.5) 0px 10px 16px;")); client.println(F(" -moz-box-shadow: rgba(11, 140, 27, 0.5) 0px 10px 16px; /* FF 3.5+ */")); client.println(F(" box-shadow: rgba(11, 140, 27, 0.5) 0px 10px 16px; /* FF 3.5+ */")); client.println(F(" }")); client.println(F("")); //this will add the glare to both of the LEDs client.println(F(" .glare {")); client.println(F(" position: relative;")); client.println(F(" top: 1;")); client.println(F(" left: 5px;")); client.println(F(" -webkit-border-radius: 10px;")); client.println(F(" -moz-border-radius: 10px;")); client.println(F(" -khtml-border-radius: 10px;")); client.println(F(" border-radius: 10px;")); client.println(F(" height: 1px;")); client.println(F(" width: 13px;")); client.println(F(" padding: 5px 0;")); client.println(F(" background-color: rgba(200, 200, 200, 0.25);")); client.println(F(" background-image: -webkit-gradient(linear, 0% 0%, 0% 95%, from(rgba(255, 255, 255, 0.7)), to(rgba(255, 255, 255, 0)));")); client.println(F(" }")); client.println(F("")); /////////////////////////////////////////////////////////////////////////// //CSS всплывающего окна /////////////////////////////////////////////////////////////////////////// client.println(F(" #parent_popup_click, #parent_popup2_click {")); client.println(F(" background-color: rgba(0, 0, 0, 0.8);")); client.println(F(" overflow-y: auto;")); client.println(F(" display: none;")); client.println(F(" position: fixed;")); client.println(F(" z-index: 99999;")); client.println(F(" top: 0;")); client.println(F(" right: 0;")); client.println(F(" bottom: 0;")); client.println(F(" left: 0;")); client.println(F(" }")); client.println(F("")); client.println(F(" #popup_click, #popup2_click { ")); client.println(F(" background: #fff;")); client.println(F(" max-width: 600px;")); client.println(F(" width:70%;")); client.println(F(" margin: 5% auto;")); client.println(F(" padding: 5px 20px 13px 20px;")); client.println(F(" border: 10px solid #ddd;")); client.println(F(" position: relative;")); client.println(F(" /*--CSS3 CSS3 Тени для Блока--*/")); client.println(F(" -webkit-box-shadow: 0px 0px 20px #000;")); client.println(F(" -moz-box-shadow: 0px 0px 20px #000;")); client.println(F(" box-shadow: 0px 0px 20px #000;")); client.println(F(" /*--CSS3 Закругленные углы--*/")); client.println(F(" -webkit-border-radius: 10px;")); client.println(F(" -moz-border-radius: 10px;")); client.println(F(" border-radius: 10px;")); client.println(F(" }")); client.println(F("")); client.println(F(" #popup h1, #popup_click h2, #popup2_click h2 {")); client.println(F(" font:28px Monotype Corsiva, Arial;")); client.println(F(" font-weight: bold;")); client.println(F(" text-align: center;")); client.println(F(" color: #008000;")); client.println(F(" text-shadow: 0 1px 3px rgba(0,0,0,.3);")); client.println(F(" }")); client.println(F("")); client.println(F(" #popup h2, #popup_click h5, #popup2_click h5 {")); client.println(F(" color: #008000;")); client.println(F(" font-size: 12px;")); client.println(F(" line-height: 1;")); client.println(F(" font-weight: bold;")); client.println(F(" text-shadow: 0 1px 3px rgba(0,0,0,.3);")); client.println(F(" margin: 0px 0px 0px;")); client.println(F(" }")); client.println(F("")); client.println(F(" /* кнопка закрытия */")); client.println(F(" .close {")); client.println(F(" background-color: rgba(0, 0, 0, 0.8);")); client.println(F(" border: 2px solid #ccc;")); client.println(F(" height: 24px;")); client.println(F(" line-height: 24px;")); client.println(F(" position: absolute;")); client.println(F(" right: -24px;")); client.println(F(" cursor: pointer;")); client.println(F(" text-align: center;")); client.println(F(" text-decoration: none;")); client.println(F(" color: rgba(255, 255, 255, 0.9);")); client.println(F(" font-size: 14px;")); client.println(F(" font-family: helvetica, arial;")); client.println(F(" text-shadow: 0 -1px rgba(0, 0, 0, 0.9);")); client.println(F(" top: -24px;")); client.println(F(" width: 24px;")); client.println(F(" -webkit-border-radius: 15px;")); client.println(F(" -moz-border-radius: 15px;")); client.println(F(" -ms-border-radius: 15px;")); client.println(F(" -o-border-radius: 15px;")); client.println(F(" border-radius: 15px;")); client.println(F(" -moz-box-shadow: 1px 1px 3px #000;")); client.println(F(" -webkit-box-shadow: 1px 1px 3px #000;")); client.println(F(" box-shadow: 1px 1px 3px #000;")); client.println(F(" }")); client.println(F("")); client.println(F(" .close:hover {")); client.println(F(" background-color: rgba(255, 69, 0, 0.8);")); client.println(F(" }")); client.println(F("")); //and finally this is the end of the style data and header client.println(F("</style>")); client.println(F("</head>")); //now printing the page itself client.println(F("<body>")); client.println(F("<div class=\"view\">")); client.println(F(" <div class=\"header-wrapper\">")); client.print(F(" <table border=\"0\" align=\"center\"><tr>\n <td>Стиль страницы:</td>\n <td><INPUT TYPE=\"button\" VALUE=\"широкая" "\" onClick=\"parent.location='/?page1""'\"></td>\n")); client.print(F(" <td><INPUT TYPE=\"button\" VALUE=\" узкая " "\" onClick=\"parent.location='/?page0""'\"></td>\n </tr>\n </table>\n")); client.println(F(" </div>")); client.println(F("")); } //end of htmlHeader //////////////////////////////////////////////////////////////////////// //htmlFooter Function //////////////////////////////////////////////////////////////////////// void printHtmlFooter(EthernetClient client){ //Set Variables Before Exiting printLastCommandOnce = false; printButtonMenuOnce = false; client.println(F("\n<h3 align=\"center\">©- Plagiary - <br> 774 KM - 2016 - ")); client.println(rev); client.println(F("</h3></div>\n</div>\n</body>\n</html>")); delay(1); // give the web browser time to receive the data client.stop(); // close the connection: Serial.println(" - Done, Closing Connection."); delay (2); //delay so that it will give time for client buffer to clear and does not repeat multiple pages. } //end of htmlFooter //////////////////////////////////////////////////////////////////////// //printHtmlButtonTitle Function //////////////////////////////////////////////////////////////////////// void printHtmlButtonTitle(EthernetClient client){ printTime(); client.println(F(" <div class=\"group-wrapper\">")); client.print(F(" <h2 align=\"center\" >")); client.print(F(" Время: ")); client.print(buf); client.print(F("</h2>")); client.println(); }Очень громоздкий html, на мой взгляд. Да ещё и помешено определение стилей в заголовке и в самих тэгах. Большое кол-во одинаковых строк было бы компактнее скриптом формировать, инача eeprom скоро кончится. :) Но, коли это домашнее устройство и используется шилд WizNet, у которого на борту TF ридер, уж лучше на туда всё запихать, установив карточку на 2 гига. :)
Очень громоздкий html, на мой взгляд. Да ещё и помешено определение стилей в заголовке и в самих тэгах. Большое кол-во одинаковых строк было бы компактнее скриптом формировать, инача eeprom скоро кончится. :) Но, коли это домашнее устройство и используется шилд WizNet, у которого на борту TF ридер, уж лучше на туда всё запихать, установив карточку на 2 гига. :)
Что вы имели ввиду под выражением eeprom скоро кончится объясните пожалуйста, запихать в карту html нет желания в виду его медленной работы
Очень громоздкий html, на мой взгляд. Да ещё и помешено определение стилей в заголовке и в самих тэгах. Большое кол-во одинаковых строк было бы компактнее скриптом формировать, инача eeprom скоро кончится. :) Но, коли это домашнее устройство и используется шилд WizNet, у которого на борту TF ридер, уж лучше на туда всё запихать, установив карточку на 2 гига. :)
Объём eeprom очень невелик. Пока оно у Вас вмещается, вроде, а потом аппетиты вырастут и опаньки. :)
Чтобы не постарадать от медленности TF карты, есть простой путь: грузить на клиента сразу все страницы в одном html, при этом ненужные display: none. Далее включать/выключать страницы, а не тянуть их каждый раз из дуни, и скриптом читать данные и заносить в поля страниц.
грузить на клиента сразу все страницы в одном html, при этом ненужные display: none. Далее включать/выключать страницы, а не тянуть их каждый раз из дуни, и скриптом читать данные и заносить в поля страниц.
На клиента грузится сразу весь код, при нажатии на открытие окна оно всплывает а не грузится с дуни. Про скриптом заносить в поля это я так понимаю про Ajax, который я еще не освоил. Аппетиты а данном проекте по моему уже доходят до конца) и вряд ли еще чем то будет забиваться eeprom, кстати подскажите как узнать объем занятой/свободной памяти eeprom?
Замеряли скорость отдачи контента с дуни в браузер? Что получилось? Удивите меня и скажите, что у вас получилось больше 10 Кб/с. Именно по этой причине я отказался от затеи держать вебморду на МК, который, собственно, совершенно к этому не приспособлен.
Думаю, и вы со временем придёте к такому же решению ;)
Никаких аякс и жиквери - зачем Вам чужие глюки? :) Я говорю о getElementById('...').value и innerHTML. Страница сидит в клинте постоянно, а обновлением данных и обменом с дуней занимается скрипт.
Как Вы храните HTML - в виде массива в eeprom? Так дунина иде вам после компиляции расскажет какой памяти и сколько поедено.
Кстати, для своих нужд написал молотилку, которая из HTML убирает лишние пробелы форматирования и создаёт массив. Если необходимо, могу выдать тут.
Замеряли скорость отдачи контента с дуни в браузер? Что получилось? Удивите меня и скажите, что у вас получилось больше 10 Кб/с. Именно по этой причине я отказался от затеи держать вебморду на МК, который, собственно, совершенно к этому не приспособлен.
Думаю, и вы со временем придёте к такому же решению ;)
Миллионы устройст на МК имеют web-интерфес. Почему МК для этого не приспособлен? Даже 10кБ/с вполне достаточно, ибо в эти 10 кБ всё может и поместиться. А и удивать Вас легко - не отдавайте страницы через print по одному символу на ethernet пакет и передачей fin каждый раз, используя кривые библиотеки дуни, а формируйте IP пакеты самостоятельно по 1кБ и потелит оно ого-го как. :) К тому же измерение скороти загрузки мелких страниц может обманывать, засекая сколько за секунду пролетело, а не сколько времени ушло на обмен. :)
Миллионы устройст на МК имеют web-интерфес. Почему МК для этого не приспособлен? Даже 10кБ/с вполне достаточно, ибо в эти 10 кБ всё может и поместиться. А и удивать Вас легко - не отдавайте страницы через print по одному символу на ethernet пакет и передачей fin каждый раз, используя кривые библиотеки дуни, а формируйте IP пакеты самостоятельно по 1кБ и потелит оно ого-го как. :) К тому же измерение скороти загрузки мелких страниц может обманывать, засекая сколько за секунду пролетело, а не сколько времени ушло на обмен. :)
Вы опять чисто пофиздеть зашли? Ну что-ж, не впервой, стерплю и на этот раз :) Миллионы устройств на МК типа Ардуины? Примеры в студию, плз. И не страничку в 500 байт с одной кнопкой - а нормальную такую вебморду объёмом хотя бы как у автора темы.
По поводу "не отдавайте страницы через print по одному символу на ethernet пакет" - не надо мерить людей по себе и держать их за идиотов.
"и потелит оно ого-го как" - вот именно, что потелит, а вот летать - никогда не сможет. Я, конечно, понимаю, что мсье великий теоретик и зашёл сюда чисто так, пальцами погнуть, но всё же осмелюсь задать вопрос: сами-то пробовали поднять жирную вебморду на дуне? Пускай даже на относительно медленной SD (читать оттуда)? Какими скоростями отдачи на канальном уровне можете похвастать? 10, 20, 30, 40, 50 КБ/с?
Давайте так: возьмите всего навсего текстовый файлик в 500 Кб и выдавайте его по Ethernet с SD-карты. Субьективную скорость вполне себе можно замерить, высокая точность нам не нужна, достаточно даже порядка. Вот как получите результаты - приходите, и расскажите, как оно "потелит оно ого-го как".
У автора - совсем не дебильный интерфейс века эдак девятнадцатого - а вполне себе нагруженный и современный. С такими хотелками он быстро упрётся в ограничения используемого камня и поймёт, что не место вебморде на дуне. Вот если бы STM32 - тогда я бы тут и не базлал по этому поводу.
Миллионы устройст на МК имеют web-интерфес. Почему МК для этого не приспособлен? Даже 10кБ/с вполне достаточно, ибо в эти 10 кБ всё может и поместиться. А и удивать Вас легко - не отдавайте страницы через print по одному символу на ethernet пакет и передачей fin каждый раз, используя кривые библиотеки дуни, а формируйте IP пакеты самостоятельно по 1кБ и потелит оно ого-го как. :) К тому же измерение скороти загрузки мелких страниц может обманывать, засекая сколько за секунду пролетело, а не сколько времени ушло на обмен. :)
Вы опять чисто пофиздеть зашли? Ну что-ж, не впервой, стерплю и на этот раз :) Миллионы устройств на МК типа Ардуины? Примеры в студию, плз. И не страничку в 500 байт с одной кнопкой - а нормальную такую вебморду объёмом хотя бы как у автора темы.
По поводу "не отдавайте страницы через print по одному символу на ethernet пакет" - не надо мерить людей по себе и держать их за идиотов.
"и потелит оно ого-го как" - вот именно, что потелит, а вот летать - никогда не сможет. Я, конечно, понимаю, что мсье великий теоретик и зашёл сюда чисто так, пальцами погнуть, но всё же осмелюсь задать вопрос: сами-то пробовали поднять жирную вебморду на дуне? Пускай даже на относительно медленной SD (читать оттуда)? Какими скоростями отдачи на канальном уровне можете похвастать? 10, 20, 30, 40, 50 КБ/с?
Давайте так: возьмите всего навсего текстовый файлик в 500 Кб и выдавайте его по Ethernet с SD-карты. Субьективную скорость вполне себе можно замерить, высокая точность нам не нужна, достаточно даже порядка. Вот как получите результаты - приходите, и расскажите, как оно "потелит оно ого-го как".
У автора - совсем не дебильный интерфейс века эдак девятнадцатого - а вполне себе нагруженный и современный. С такими хотелками он быстро упрётся в ограничения используемого камня и поймёт, что не место вебморде на дуне. Вот если бы STM32 - тогда я бы тут и не базлал по этому поводу.
При чём тут дуня? Вы же говорили об МК, который по совпадению и в дуне используется. К тому же, дуни бывают разные, можно переехать на 2560, а то и на DUE. Примеры? Да как-то мало на ум приходит, разве что все сетевые устройства... :) Возможно, среди МК низкого т.с. уровня, WEB-управление ещё не стало модным, ибо громоздкое оно, достаточно неудобное, корявое, неочевидное, много засад, безусловно, но дело времени. И сам не раз матюкался - написать экзеху для управления было бы в 100 раз быстрее.
Для скорости есть одно ораничение - скорость SPI по которому отдаётся на сетефой интерфейс поток. Но оно значительо больше 10 и даже 50 кБ/сек. А давно ли интерент стал быстрее 2-х МБит/с и часто ли сайты отдают более 2-х МБит/с на сокет? Исли не гонять страницы, не устраивать на МК аппачь с пхп, то совершенно неощитимо тормозов.
Я не эмперик по складу ума, меня не убеждает чей-то опыт, не имеющий обоснования. Со скоростью web-интерфейса я не заморачиваюсь, ибо мне не важно будет страница полсекунды загружаться или 2 секунды. Да и работать оно будет в фоне. Для меня было важно проверить скорость ModbusTCP. Сколько Сименс попросил в непрерывном цикле, столько мега 328-я ему и ответила. И оказалось не меньше, чем другой Сименс. Запрашивал запись поряд 16 32 битных регистров и возврат их же. Буквально наковырял кусок корявого кода лишь бы проверить, порадовася и выбросил. И это, кстати, на WizNet, у которого непонятно что внутри творится и дуниной библлиотекой еще более тёмной.
А что STM32? Прикрутить к нему сетевой интерфейс с DMA? Сколько оно стоить будет?
Я считаю совершенно номальным web-интерфейс для МК, особенно, если есть возможность использовать TF карту - можно туда налепить и картинок и библиотек. В моём случае карточка не неприменима, стараюсь писать компактно, возможно, придётся упаковать, если получится много и всё это вложить в флэшку 2560. Пока не приехал STM32F403... :)
Я считаю совершенно номальным web-интерфейс для МК, особенно, если есть возможность использовать TF карту - можно туда налепить и картинок и библиотек. В моём случае карточка не неприменима, стараюсь писать компактно, возможно, придётся упаковать, если получится много и всё это вложить в флэшку 2560.
Вот когда налепите, когда размер вебморды вылезет килобайт за 500, когда будут картинки всякие, подключаемые CSS и т.п. - тогда скажете, как оно - быстро или нет. А пока все ваши излияния - бла бла бла, ничего не имеющее с практикой. К тому же заметил у вас странную тягу к путанию круглого с мягким, причём постоянно - ему про одно, он - совершенно про другое, приплёл сюда зачем-то Modbus over TCP. Мы вообще-то совершенно о другом говорим, если вы не заметили. Да, на каком-то уровне модели OSI мы утыкаемся в TCP, но речь, повторюсь, идёт не о TCP вовсе, а совсем даже о другом.
Что такое вебморда - понимаете? По какому протоколу работает - понимаете? Что такое вебморда сложнее одного некрупного файла - понимаете?
Ещё раз, для тугих: вебморду можно поднять на дуне, на практически любой дуне. Я не ставлю вопрос как "можно" или "нельзя" - я поднимаю вопрос о целесообразности данной затеи в век, когда есть дешёвые роутеры, на которые можно накатить openWRT и радоваться мегабитным скоростям и отсутствию ограничений на размер вебморды. Дуня при этом - откликается на простые запросы, типа "дай-ка мне, любезная, слепок внутреннего состояния" или "а ну ка, милая, выполни вот эту команду" - и всё.
Я через это уже прошёл - была и вебморда на SD, и вебсервер был реализован с корректной обработкой запросов и пакетной выдачей результатов (это к слову о побайтовой выдаче, упомянутой вами) - не понравилось. Скорость не та - требования у меня, наверное, завышенные, но я хочу видеть нормально работающую и современно выглядящую морду, а не убогое чудовище.
Потом: никакая масштабируемость и отсутствие аггрегирования как класса. Накой мне к каждому контроллеру стучаться, чтобы получить данные на вебморде? А если их (контроллеров) будет десяток? Десять адресов и десять вебморд? Нахер сразу. Именно для этого и есть решения типа openWRT, под которым можно развернуть аггрегатор, со своей БД и нормальной мордой.
А МК - должен заниматься тем, для чего он, собственно, и предназначен - обслуживанием периферии, всё. Остальное - от лукавого.
В общем, как обычно, каждый останется при своих. Спорить по этому поводу мне совершенно не интересно, я лишь высказал свой взгляд на вещи, обращаясь не к вам, а к ТС - подсознательно надеясь, конечно, что буду услышан. Впрочем, каждый должен сам наступить на грабли, тут я никого не отговариваю. Да и слежу за темой скорее из-за того, чтобы не пропустить тот момент, когда автору станет тесно с вебмордой на дуне. Но, скорее всего, он поступит по-другому - удовлетворится тем, что есть. Однако, не буду домысливать за него - время покажет.
Чувствуется плохое понимание работы т.с. транспортов и оптимизации их задач... :))) МК не интернет-магазин, не живой т.с. сайт, в нём web-интерфейс для управления и весёлый картинки в нём даже нежелательны. Зачем что-то подключать? И что подключать? Кличество сокетов очень невелико в МК и достаточно затратно их плодить, загружать в МК сраницу с подключемыми в виде отдельных файлов стилями и скриптами глупо, ибо эксплорер полезет в несколько потоков их грузить, пытаясь создать отдельные сокеты. Для web интерфейса MK необходимо отдельной молотилкой, преобразовывать создаваемые страницы, стили и крипты в один файл. Писать в один файл всё сразу неудобно при разработке, но удобно сделать несложную экзешку которая перемолотит. Пролема с сокетами решена: потребуются всего 2: на саму html со всеми описаниями и на favicon, котрую эксплорер будет всё равно искать. И решена проблема с загрузкой страниц - они уже все на клиенте и переключаются, а не грузятся.
А про openРазные здрово, безусловно... Я продам устройство потребителю, и сообще ему, что надо бы ещё роутер прикупить, залить в него кое-чего для счастья. И не простой роутер, а золотой т.е. с поддержкой офигительной фичи. :))) Странно, почему производители сетевых устройст до этого ещё не додумались и лепят в каждый экземпляр персональный web интерфейс... Дикари! Оформляйте патент с openWRT скорее. :) Сосвсем не думают о людях, которые потом кучу этих устроств в сеть поставят и будут управлять ими, открывая на каждом web интерфейс, не понимая, что это лишь персональная ковырялка для одиночного использования или первоначальной настройки, чаще всего, лишь адреса. :)))
Опять бла бла, и опять - мыши плакали, кололись, но продолжали жрать кактус вместо того, чтобы выкинуть веб-интерфейс из МК, который для этого не предназначен. Вместо этого - надо кучу плясок с бубном: что-то там объединить, перемолотить, забить кувалдой. Я же говорю - теоретик.
Насчёт openWRT - поверьте, никаких сложностей в поставке роутера с прошитым и настроенным openWRT в составе конечного продукта - нет, от слова вообще.
Конечно, кому не нужна масштабируемость, не нужно аггрегирование - пусть его балуются с отдельной вебмордой на каждом МК: и такое имеет право на жизнь, не отрицаю. Просто я смотрю на автора темы и вижу, что по сути задачи, которые он решает - это некий прообраз системы умного дома. Для которой - ну совершенно глупо и неоправдано держать всю вебморду на одном МК, который, к тому же, занимается обслуживанием периферии. Налицо смешение мух с котлетами.
И вообще - прекращайте пороть чушь, у вас это, похоже, в крови - как чего ни скажете, так словно в лужу пёрнули. Это я относительно сентенций "Странно, почему производители сетевых устройст до этого ещё не додумались и лепят в каждый экземпляр персональный web интерфейс". Вы не поверите - но в современных сетевых устройствах, например, тех же роутерах - стоит вполне себе *nix-операционка, openWRT, собственно - из той же оперы. Так кто дикарь - вы, безграмотный, или производители?
Катастрофа!
МК имеет интерфейс и протокол, по которому отдаёт сырые данные или данные определённого формата, возможно, не один - бери чем хочешь и агрегатируй как хочешь. МК имеет внутри себя html код, кторый возможно загрузить в экплорер, который берёт те же самые сырыи данные и приводит к удобному для оператора виду, на случай если одинокий МК используется или что-то несложилось при интеграции в систему. Это уже настолько очевидное и распространённое решение, что и напоминать о нём неловко. И уж тем более слюни лить за обиду и пытаться чем-то уколоть меня. :)))
Агрегатировать несколько устройст умного дома, запросто можно простой страницей с <iframe>, например. :)
Будущее систем управения в уходе от централизации. Этот путь уже прошли "апаратчики", когда процессор всё сам делал, выступая и кунецом, и жнецом. Теперь переферия стала умной и почти всё делает самостоятельно. Точно так же устройства "умных домов" будут свои задачи решать самостоятельно, в т.ч. и по отображению информации, общаясь друг с другом системой сообщений.
P.S. МК - это не только Мега328. Малому МК - малый интерфейс, от каждого по возможности.
P.S.2. Ждать всемогущего властителя в центре и рулить всем подряд - это, похоже, менталитет такой. :)))
P.S.3. Какие тут все крутые, бляха муха, да обидчивые... Прям как с девочками... :)))
Тут крутой только вы, по ходу. И в своей крутости пороть чушь - вам нет равных, это точно! Какая, нахер, аггрегация с iframe? Вы хоть понимаете значение этого термина, млять?
Надоело с воинствующим дилетантом разговаривать - бессмысленно. Чао.
Дааа... Поднабралось бабёх трепливых - чуть что, чуть сказать нечего по делу, обидки и личные оскорбления. :))) А аргументы - нафига, мои можно не заметить скромно, своих всё равно нет. Проще же фыркнуть. Ржунемагу тут с некоторых. :)))
См. Вики, чтобы не быть голословным, в отличии от некоторых баб тут: Агрегация или агрегирование (лат. aggregatio «присоединение») — процесс объединения элементов в одну систему.
Простейшей объединённой системой, совершенно очевидно, можно считать вывод информации от нескольких элементов на единый монитор (не путать с экраном ПК). Если каждый элемент системы имеет свой самостоятельный web интерфейс, вполне возможно создать страницу, в котрой несколькими тегами <iframe> загрузить интефейсы с каждого устройства на одну страницу, каждый в своё подокошко. В итоге страница агрегирует вывод информации в единое окно отображения. Возражения есть?
А для тупорылых добавлю - там смайлик был в конце фразы. Вот такой :)
P.S. Вы бы уже объединились, обсудили какой я нехороший, толпой бы поорали - девочки так ведь делат? В форуме не знаю сколько человек, но есть один хамуга пустобрёх, один выскочка, один советчик уровня чайника, и изобретатель системы продаж маршрутизаторов внагрузку. Все четвера на меня зуб точат, идинаково умеют против аргументов лишь сопли лить. Ржунемагу! :)))
Фаэтон, скажу тебе по-русски - иди нахуй. Если по хорошему не понимаешь.
такой вопрос, делаю управление освещением с помощью кнопок которые будут раскиданы по дому вместо выключателей, будет 10 кнопок подключеных к одному аналоговому входу через разное сопротивления, скетч обработки написал, но вот быстродействие и факт нажатия огорчает) подскажите как это связать с внешним прерыванием, проблема в том для прерывания нужен дистретный сигнал, а для отпределения кнопки аналоговый, тянуть отдельные провода для прерывания не вариант, и просьба не советовать свякую по-русски говоря хуйню
Фаэтон, скажу тебе по-русски - иди нахуй. Если по хорошему не понимаешь.
Ну, так поплачь ещё, девочка. :))) Обкакался с доводами и чушью от кривости мозгов, а хамить любое животное умеет. :))))
такой вопрос, делаю управление освещением с помощью кнопок которые будут раскиданы по дому вместо выключателей, будет 10 кнопок подключеных к одному аналоговому входу через разное сопротивления, скетч обработки написал, но вот быстродействие и факт нажатия огорчает) подскажите как это связать с внешним прерыванием, проблема в том для прерывания нужен дистретный сигнал, а для отпределения кнопки аналоговый, тянуть отдельные провода для прерывания не вариант, и просьба не советовать свякую по-русски говоря хуйню
Давайте скетч. Быстродействия аналогового входа (АЦП), скорее всего, тут совершенно не при чём. Факт нажатия, предполагаю, портится помехами.
P.S. Лучше создайте отдельную тему в разделе "Программирование".
Это было в другую тему :)
как раз таки быстродействие АЦП не успевает прочитать импульс 100-200 мс, потому что занята другими задачами, поэтому и решено использовать прерывание, собрал вот такую схему, но дребезг вызывает прерывание 3-5 раз за одно нажатие. В функции которое вызывает прерывание не работает ни delay ни millis, поэтому программно убить дребезг не выходит, вот и не знаю как это реализовать... =)
как раз таки быстродействие АЦП не успевает прочитать импульс 100-200 мс, потому что занята другими задачами, поэтому и решено использовать прерывание, собрал вот такую схему, но дребезг вызывает прерывание 3-5 раз за одно нажатие. В функции которое вызывает прерывание не работает ни delay ни millis, поэтому программно убить дребезг не выходит, вот и не знаю как это реализовать... =)
Это кто у Вас там кнопки так быстро нажимает? :)
Создайте внешнюю переменную - флаг времени вызова предыдущего прерывания.
На прерывании таймера эту переменную декриментируйте, если она больше нуля.
На прерывании от кнопки, если флаг не равен нулю - ничего не делать и вывалиться из прерывания, иначе записать в флаг значение времени нечувствительности и прочитать значение.
Кроме того, не забывайте, что прерывания имеют разные варианты: по фронтам, по низкому/высокому уровню и по изменению состояния. Если прерывание от кнопок будет настроено как по низкому/высокому уровню, то оно будет постоянно вызываться, пока нажата/отпущена кнопка.