mega +ethernet shield + raspberry(mysql,php,apache,phpmyadmin)
- Войдите на сайт для отправки комментариев
Добрый день товарищи! Ситуация такая:
есть мега 2560 с эзернет шилдом сверху. Есть отдельно малинка с установленной на ней mysql,php,apache,phpmyadmin
мега каждые 10 секунд лезет внутри сети на скл, проверяет что запись с таким "мак адресом" в базе скл есть. вторым запросом берет данные с скл о настройках оборудования (максимальная температура,влажность и так далее).
третим запросом записывает данные с датчиков в СКЛ.
крутится это все примерно 3-4 часа и отваливается. может отвалиться раньше, может позже.
1) соединение с скл проверяю каждый раз перед запросом в скл,таким способом:
void connectToSQL() { if (SQL_Connect.connected()) { //@lnSerial.println("SQL already connected!"); //sql_fails_count = 0; return; } else { SQL_Connect.close(); //@lnSerial.println("Connect to SQL..."); if (SQL_Connect.connect(server_addr, SQL_port, user, password)) { delay(500); //@lnSerial.println("SQL Connection success."); return; } else { //@lnSerial.println("SQL Connection failed."); connectToSQL(); } }}
2) после каждого запроса очищаю память :
delete SQL_Cursor;
Полный код запроса,место где отваливается отметил. Собственно у меня все действия набиты выводами в сериал, только там я могу более-менее поймать место где отваливается. Запускал два оборудования одновременно, различие лишь в мак адресе, один отвалился через 3 часа, второй часов через 5-6... Так же сделал вывод свободной памяти ардуино, вдруго переполняется какими то данными или еще что то, всегда в лупе стабильное значение 5391. 2 варианта, либо ошибка в коде, либо отваливается соединение, может не напрямую в СКЛ лезть а через get запросы? Аля : ардуино отправляет info.php? на малине запускается пхп и он делает все то что сейчас делает моя ардуинка? суть проблемы: ардуино будет работать 24-7-365 и такие отваливания могут плохо закончится. Нужна стабильная работа =(((((
byte checkWeIsActive() { lnSerial.println(""); lnSerial.println("-----Check Arduino Active-----"); ПОСЛЕ ЭТОЙ ЗАПИСИ ОТВАЛИВАЕТСЯ!!!!!!!!!!!!!!!!! bool weAreActive = false; row_values *row = NULL; long head_count = 0; String queryDefault = "SELECT isActive FROM grower.clients WHERE mac = '" + mac + "'"; int queryDefault_len = queryDefault.length() + 1; char query[queryDefault_len]; queryDefault.toCharArray(query, queryDefault_len); // Подключение к SQL и проверка оборудования в базе ***************************************************************** connectToSQL(); // Подключение к SQL и проверка оборудования в базе ***************************************************************** MySQL_Cursor *SQL_Cursor = new MySQL_Cursor(&SQL_Connect); // Execute the query SQL_Cursor->execute(query); // Fetch the columns (required) but we don't use them. column_names *columns = SQL_Cursor->get_columns(); //Если есть хотя бы одна строка, то после нее почему то попадает в пустую строку и идет регистрация оборудования!!! bool weHaveRows = false; // Read the row (we are only expecting the one) do { row = SQL_Cursor->get_next_row(); if (row != NULL) { weHaveRows = true; weAreActive = String(row->values[0]) == "1"; if (weAreActive) { //@lnSerial.println("Arduino is Active. OK!"); } else { //@lnSerial.println("Arduino registered but not active!"); } } else { //НАС НЕТ В БАЗЕ if (!weHaveRows) { //@lnSerial.println("Arduino NOT registered!"); //ПОПРАВИТЬ ПЕРЕБОР МАК АДРЕСА!!!! //registerMyArduino(); } } } while (row != NULL); // Deleting the cursor also frees up memory used delete SQL_Cursor; lnSerial.println("-----Check Arduino Active-----"); lnSerial.println(""); return weAreActive; }
Ну и заодно напишите - какой помощи ждете. Совета? Совет - делайте всё, что придумали. Бродить по закоулкам вашего воображения и пытаться понять, как устроена ваша непростая система наврядли кто-то будет.
Если срочно надо вопрос решить - я бы для начала добавил WDT и тупо например раз в час перезагружал МК принудительно.
Нет не срочно, хочу найти причину и решить ее. Что бы работало как часы =)
без полного скетча и всей задачи сложно что то советовать
Если кто то сталкивался с обращением к скл в короткие сроки (каждые 5-10 секунд) и ему было необходимо делать это 24-7-365 и у него все работало - получить подтверждение, что это работает и нужно искать ошибку. А то мне кажется что данный метод не эффективен и нужно идти по схеме:
ардуино вызывает php на малине которая делает запись либо возвращает данные в ардуино.
ардуино -> малина -> скл
а не
ардуино -> скл
Просто не хочу верить что спам каждые 5 секунд в скл селектами или инсертами может через какое то время отлетать... это же не 1с :D :D :D
Просто не хочу верить что спам каждые 5 секунд в скл селектами или инсертами может через какое то время отлетать... это же не 1с :D :D :D
и не надо, правильный SQL сервер тысячи запросов может обслужить в секунды и не подавиться
сейчас пробегусь по всему коду, расставлю комментарии, что бы понятно было что происходит. Если будет время и желание - буду признателен.
Проблема на стороне SQL отслеживается по логам. Но сразу могу сказать, что держать SQL-базу, работающую в режиме записи, на SD-карте - идея не очень здравая.
В строках №№ 12, 14, 21, 25, 32, 36, может, ещё где, имеются явные или неявные запросы памяти, но нигде (от слова совсем) нет проверки, успешно ли выделилась память. Вы, видимо, принципиально работаете с памятью, не прверяя, выделилась она или нет?
Поставьте везде проверки, глядишь и вылезет чего-нибудь.
варианты решения? покупать сервак на digitalocean? :)
Можете и на DigitalOcean. Или думаете, что от того, что вы с'иронизировали, SD карта начнет лучше переносить ковровые бомбардировки SQL-ем по одним и тем же секторам?
Честно говоря, даже не задумывался об этом. Считал что 4 раза в минуту записывать данные в СКЛ это не страшно для сд карты...
Вы пишете 4 раза в минуту, сам SQL ведет журнал транзакций, индексы, логи, всякую такую муть. Делает вакуумы, реиндексы. Через месяцок система просто не загрузится и всё. Или сам SQL будет падать, так как база уже не читается, и рушить всё под собой.
Но это через месяц. У ТС валится гораздо раньше. Мне кажется начать надо с проверок, о которых я написал в #9.
А если не хватает памяти то ардуино просто отлетает и все? может быть на каждую функцию вешать try catch ? Просто очень сложно отловить то что вылетает не понятно когда =((((((((( буду пробовать пробивать память под переменные... спасибо!
try-catch в ардуино из коробки не работает.
Если не хочется разводить большую простыню, то можно поступить так:
1. Всю память под String проверять в одном месте, там где на запрашивается (она запрашивается в единственном месте в WString.cpp) и там печатать сообщение или ещё как тревогу поднимать.
2. Память для SQL операций также проверять там, где она непосредственно запрашивается. Где она запрашивается я не знаю, но если иметь библиотеку, то найти можно.
Мне просто задача непонятна. Наврядли она нова. Скорее всего нужно просто пересмотреть подход.
Мой запасной мониторинг висит уже который год на CubeTruck с ноутбучным винтом. Хранение-графики-управление-оповещение - все на опенсорце. В пару к нему ИБП-тысячник. Если даже электрики все нажрутся и попадают на рубильники, система еще сутки сохраняет работоспособность и сообщает, что изменилось. А за сутки уж можно пофиксить... Все эти линупсы на системных фрешках, всунутых в тонкие терминалы я проходил тоже. В самый ответственный момент ты теряешь управление хостом, приходишь к нему и видишь непроходящий кернел паник.
Есть две,три,четыре ардуино, которые управляют климатом в разных комнатах. Все ардуино соединены между собой в локальной сети (езернет шилды)
Далее будет их n-ое количество...
база скл хранит данные настроек каждого оборудования, уникальность по мак адресу. А так же ардуино записывают данные со своих датчиков + могут получать задания через скл.
Далее веб сайт, который берет все данные из скл и рисует красивые картинки и графики + в дальнейшем какие то кнопки на отправку заданий на оборудования.
т.к. у меня валялась малинка, я решил на ней сделать сервак (все прошло успешно и он отлично работает без остановки месяц) и ардуино мега 2560 5 штук + эзернет шилды. Дальше буду реле которыми буду управлять остальным оборудованием...
Вот такая задача и она не новая, но решений в интернете как обычно, вопросы позадавали, написали и ничего не описывают... =) поэтому все с нуля и сам по себе =))))
Как бы я поступил на вашем месте без кардинального перекроя:
1) искал что-то с нормальным винтом (даже SSD). Но на Raspberry не стал вешать USB винт - на этом интерфейсе уже сетевуха висит. Сейчас, как мне кажется, достаточно платформ с нативным или выделенными под SATA портом. Искал что-то типа кубитрека. Да, дороже. Но работать будет и быстрее и дольше на порядки. Особенно, если планируется масштабирование системы.
2) Перенес всю кашеварню с SQL на серверную сторону. Простой диспетчер на питоне, перловке, том же пхп, умеющий в простой TCP-сессии выдавать то, что нужно ардуине - самое то. Все, что будет использовано на ардуине - EthernetClient.
3) удаленные модули меняются с Мег на что попроще (по желанию, впрочем).
Остальное требует более глубокого пересмотра архитектуры.
Ну или искать какие-нить уже готовые системы... наверняка уже парочка точно написана.
Ах, да, забыл. MQTT - вот еще на чем любят такую мелкоту подымать.
Спасибо за развернутый ответ! Буду ковырять и думать... Просто уже было все так близко... осталось только прикрутить работу реле и сайт запилить за вечер... а тут на тебе... все заново =(
Я же вас по рукам не бью - можете заканчивать свою задумку. Половите сначала баги во всех этиз sql-ных либах, потом начнете на новую SD накатывать систему...
имхо, вместо малинки под сервер отвести любой старый системник под управлением Линукс. Ну или собрать новый на низкобюджетной платформе. Я как лет 10 назад собрал домашний сервер на проце Атом - так он до сих пор отлично трудится, хотя морально давным-давно устарел...
да я тоже задумался на какой бы комп нацепить сервак. идея рабочая, согласен. сд карта хреновая идея... я пока попробую убрать все принты в сериал, а то у меня их тонна и коннект сделать на внешний сервак диджитал оушен у друга, протестю и отпишу. Может реально проблема в срущем сериале либо в сдкарте... хоть бы это было так))))) а то совсем руки опустились =(
имхо, вместо малинки под сервер отвести любой старый системник под управлением Линукс. Ну или собрать новый на низкобюджетной платформе. Я как лет 10 назад собрал домашний сервер на проце Атом - так он до сих пор отлично трудится, хотя морально давным-давно устарел...
Атом - не тру )), вот VIA - это реальный эконом по тем временам. У меня такая файлсервером служила, пока порты под HDD не закончились. Тогда пришлось менять мать и искать интеловский проц с индексом T. Вот это стало тру. Даже кулер на процессор не ставил - одним радиатором обходится и корпусным вентилятором.
В общем, перешел на сервер на рег.ру (крутится домен, там и база есть, что бы не платить на сторонний сервак)
крутилась ардуино 17 часов (вместо 5 обычных) и подвисла на том же месте, при первой проверки скл соединения идет селект, вот после проверки что соединение в порядке, я так понимаю на моменте execute в базу.
Сейчас скомпоновал программу, из трех селектов сделал один большой, что бы меньше коннектов было и убрал все выводы в сериал, протестирую, отпишу... Судя по логике, после проверки скл соединения есть вероятность что оно отваливается...
По памяти: память не проседает ниже 4900. За 17 часов нет поведения ухода памяти "потихоньку" в минус. 17 часов данные записывались в СКЛ, вместе с количеством свободной памяти. Нижний порок 4900, верхний 5300. 4900 при заполненных переменных, 5300 при освобождении памяти...
Давайте формализуем ошибку, иначе непонятно где искать. Необходимо ответить на вопрос "что такое подвисла?": зависла сама Arduino; завис сетевой модуль; не выделяется сокет; не производится соединение; нет ответа от удаленной стороны; ... ?
Сейчас обьясню =)
1) Сериал пишет -----Ceck Arduino Active and Properties-------
2) Потом попадает в процедуру get_free_memory() и выводит количество свободной памяти
3) Потом попадает в функцию connectToSQL(); и выводит на экран SQL already connected!
4)Далее делается execute запроса на котором все отваливается без надписей ошибок и тд и адруино перестает работать, не бежит сериал, потому что у меня на каждое действие стоит вывод в сериал
SQL_Cursor на NULL анализы сдавал?
при выделении памяти проверить его на NULL? а то немного не понял твоего вопроса...
в конце, память освобождаю так : delete SQL_Cursor;
SQL_Cursor на NULL анализы сдавал?
По-моему, об этом ТС ещё с пятницы талдычим (#9) - игнор полный :(
Да тупанул, я зациклился переносом сервера и забыл про то что вы говорили. Сейчас поставлю проверку и запущу. Отпишу как будет результат. Извиняюсь =)
Ну, вобщем, я тут вижу такие потенциальные проблемы (без чтения библиотеки и остального кода):
1) Вызов execute из неизвестного указателя;
2) Странную рекурсию в строке #61;
3) Неправильно написанную процедуру connectToSQL;
По моему мнению таковая процедура должна возвратить или true/false или return code. На основании его main loop делает вывод - начинать обмен данными или повторить его через три оборота или N msec. M раз неудачно "законнектились" - подожгли светодиод "тревога".
А сейчас получается какое-то насилование непрерывное с торможением остальных процессов и обмене данными даже в случае неопределенности с установлением сессии.
Огромное спасибо за советы!!!!!!!
1) поставил проверку
2) рекурсия - если не получилось сделать скл подключение то пробуем подключиться опять. А как иначе в лупе не идти дальше если нужно сделать скл подключение перед выполнением запроса? И пока подключения нет то ничего не делать... ?
Вылетает как раз после надписи что коннект уже установлен, все ок. Как раз на экзекуте вылетает, судя по сериалам. Видимо он в какой то момент равен NULL...
т.е. в идеале если курсор равен null значит, при этом можно продолжать луп но запрещать выполнение execute. Логика правильная? или тут надо разобраться почему курсор становится null ?
2)А как иначе в лупе не идти дальше если нужно сделать скл подключение перед выполнением запроса? И пока подключения нет то ничего не делать... ?
Именно так - ничего не делать определенное время. Если вы кому-то звоните и там занято, то вы что, бесконечно на трубке висите или чай попьете и перезвоните? А с рекурсиями вы завязывайте. Тут вам не ПК, все нужно ювелирно делать.
т.е. в идеале если курсор равен null значит, при этом можно продолжать луп но запрещать выполнение execute. Логика правильная? или тут надо разобраться почему курсор становится null ?
В идеале - надо разобраться, конечно. Вопрос, конечно, может ли он в принципе быть NULL. ...либу ковырять.
Но чтобы не вешаться - достаточно проверок и пропусков. Но, опять же - возможно либа сама какие-то return code возвращает из методов и не дает делать глупости.
А то, что в Serial выводится... были у меня случаи, когда в Serial Monitor не успевала прилететь диагностическая строка, т.е. проблемная точка была в другом месте. Так что Serial - для грубого прицеливания.
Спасибо большое! Буду переделывать
Пока вестей нет. почему то оборудование отказывается работать от розетки если это 12В 1А либо 9В 1А. Сейчас поставил от 5В 1А и начались записи в СКЛ. Очень странно, ардуино мега 2560 + езернет шилд. Работает либо от юсб компа либо от 5В 1А (пишет данные в СКЛ) иначе отказывается писать... Буду разбираться, а пока поставил одно оборудование на проверку стабильной работы...
А вы это... на ресет жмакните после подключения к БП 12V - пойдет? Или delay(500) в начале сетапа... Так-то встречаются случаи, когда W5100 не успевает инициализацию пройти , а ему уже begin суют в морду.
сейчас попробую =) век живи, век учись)))
и 12 вольт многовато, 9 за глаза
Помогло!! УРА Товарищи)))))
P.S. 9В 1А заработало а 12В 1А не заработало. Собственно меня и 9В 1А хватает. Просто думал кулер запитать 12В но и 9В тоже пойдет, немного потише крутить будет))))
Конечно теперь придется мутить отдельное питание 12В под помпу для полива =( но я 2 недели не мог завести ардуино от розетки, благо тут написал!!!!! Спасибо!!!
Да, выше подсказали делей в сетапе поставить что бы шилд успевал стартануть, с 9В 1А ардуино начала писать данные с СКЛ, уже радует... Единственное,в мануале написано 7В-12В, я поэтому и взял мегу, что бы от нее питать помпу на воду(она 12В) попробую от 9В сделать питание, по идее, насос будет работать не в полную мощность но главное что бы из-за этого ардуинка не грелась =(
Странно, конечно, что 12V не тянет. Суть-то проблемы не в напряжении, а в том, что при подключении через USB система дольше чухается и сетевой чип успевает привести себя в порядок. А когда БП подключаешь - не успевает. Ресет жмешь - МК заново начинает прошивку исполнять и begin() применяется к уже инициализированному чипу. Вобщем, колдовство там еще то. Еще вроде конденсатор суют куда-то в район ресета... не помню сейчас. С отдельными модулями W5100 (Mini Red) проблем не испытываю. Но у меня и драйвер подфикшенный.
От меги советую питать только мегу и шилд, а помпу пускать таки в обход. А то сюрпризов еще получите.
Странно, конечно, что 12V не тянет. Суть-то проблемы не в напряжении, а в том, что при подключении через USB система дольше чухается и сетевой чип успевает привести себя в порядок. А когда БП подключаешь - он не успевает. Ресет жмешь - МК заново начинает прошивку исполнять и begin() применяется к уже инициализированному чипу. Вобщем, колдовство там еще то. Еще вроде конденсатор суют куда-то в район ресета... не помню сейчас. С отдельными модулями W5100 (Mini Red) проблем не испытываю. Но у меня и драйвер подфикшенный.
чего тут странного, для тутошнего стабилизатора оптимальное напряжение на входе 7.5 -8.8 вольт, а всё остальное от лукавого, я не думаю, что схемотехника за 30 лет изменилась )))
я даже делай 10 сек поставил в сетапе в начале, не помогло =(
конденсатор - хорошее решение, но колхозить не хочется, все таки хорошо, когда без рукоприкладства работает :P
Оптимальное, не оптимальное, но я и от 12V Уно с шилдом питал и от 9V - тоже все ок было. Ну, конечно, если знаешь как пнуть.
Вобщем, если что, версия драйвера от самих wiznet-овцев содержит такое в w5100.cpp
Так что можете повторить грязный хак.
Спасибо! Завтра попробую. Поставил 2 оборудования. Тест идёт полным ходом :)
Оптимальное, не оптимальное, но я и от 12V Уно с шилдом питал и от 9V - тоже все ок было. Ну, конечно, если знаешь как пнуть.
А Вы внимательно, под лупой посмотрите на микросхему стабилизатора (не все микросхемы одинаковые) )))