Официальный сайт компании Arduino по адресу arduino.cc
2560 зависает с LoRa
- Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии
Здравствуйте, коллеги, подскажите пожалуйста кто знает - есть проект в частный дом из двух аппаратных блоков (каждый на Mega2560). Один блок собирает данные с котельной и близлежащих помещений и по радиоканалу транслирует каждые 10 сек на другой блок. Изначально радиоканал создавался на nRF24L01+. Работало всё хорошо. Потом решил сделать радиоканал на модулях LoRa SX1278. Всё работает, но приёмная часть регулярно зависает. Может зависнуть через 20 минут, может через 8 часов.... Если убираю код (приведён ниже), который обрабатывает этот модуль - всё хорошо. Питание отфильтровано на самой переходной плате к SX1278 и танталовыми электролитами и керамикой. Код привожу. Может кто-то что-то подсказать?.....
Могу конечно сделать внешний аппартный WDT (и потом сделаю), но хотелось бы знать и устранить причину зависаний.
Библиотека используемая RadioHead, модули такие: https://sc02.alicdn.com/kf/HTB1DlmtSVXXXXaJXXXXq6xXFXXXS/SX1278-433MHz-LOra-Spreading-High-Sensitivity-Wireless.jpg
Приведённый код это обработка этого модуля, если его убрать /* */ то зависаний нет. Может что не так в этом коде? Писал его по видео из ютуба.....
Весь код не выкладываю - он 825 строк
// ------------------------------- приём данных на LoRa (SX1278) --------------------------------------- if (rf95.available()) { uint8_t buf[RH_RF95_MAX_MESSAGE_LEN]; uint8_t len = sizeof(buf); if (rf95.recv((uint8_t*)&data, &len)) { d1 = data[0]; d2 = data[1]; d3 = data[2]; d4 = data[3]; d5 = data[4]; d6 = data[5]; d7 = data[6]; d9 = data[7]; // отопл. d8 = data[8]; // водосн. d10 = data[9]; d11 = data[10]; d12 = data[11]; d13 = data[12]; d14 = data[13]; d15 = data[14]; olddata = millis(); SendDataP("q0.picc", 0); // удаляем надпись "Данные устарели!" } } if (millis() - olddata > 300000) { SendDataP("t6.font", 3); // пишем "Данные устарели!" через 5 минут }
Вас не смущает, что Вы:
Кстати, что там за data - ХЗ.
data - массив из 15 переменных int.
самый верхний кусок кода:
Евгений, подскажите пожалуйста как надо сделать, написать данную часть кода, - я электронщик, не программист....
Строка 04 задаёт buf (буфер), в скобках длина буфера? Какая она, что означает то что в скобках?
Ну, "как делать" я не знаю, т.к. не знаю, "что делать".
А так,
во-первых у Вас ошибка в размере массива. Вот смотрите: RH_RF95_MAX_MESSAGE_LEN - равна 259, а Вы в строке 5 присваиваете это число переменной uint8_t len, в которую больше, чем 255 не лезет. В итоге, len получает несколько неожиданное для Вас значение 3 - (выведите её в Serial и полюбуйтесь). В резудьтате Вы читаете только 3 байта.Виноват - это бред - я там сослепу минус за плюс принял.Во-вторых, судя по Вашей логике, читать Вы собиралиcь в buf, а не в data, иначе этот buf вообще ни для чего не нужен. Но это уже предположения - я не знаю, что Вы на самом деле хотели делать.
А зависает она скорее всего потому. что Вы пытаетесь читать не столько байтов, сколько реально пришло, а столько, сколько максимально возможно. А реально пришло меньше, вот она и ждёт пока остальные придут. Попробуйте читать столько, сколько пришло реально.
Я согласен с вами, но если я читаю в 6 строке не data, а buf, то получается каша какая-то....
Вывожу в монитор порта принятый массив - есть только половина значений, остальные нули, и действительные значения не по порядку, например data[0], data[3] и data[4] имеют нормальные значения (как передал), а остальные значения этого принятого массива нули..... как будто нумерация значений массива сбивается....
Код передатчика:
НУ, Вот смотрите, Вы передаёте значения типа int - пятнадцаь штук, т.е. 30 байтов.
Читаете же Вы (пытаетесь ситать) 251 байт, и более того, присваиваете прочитанное переменным d1, d2 и т.д., какого типа - ХЗ.
Наведите порядок. Читайте то, что передаёте.
Не, d1 d2 и т.д. в начале обозначены как переменные int.
Вот, Евгений, такой код также прекрасно работает, только на зависания конечно не проверял ещё....
Явно указал длину читаемого массива - 30 байт (15 int), поскольку размер массива не изменяем.
Вопрос - могли ли эти три вычеркнутые строчки повлиять на зависания?.... как-то сомневаюсь я..... Может задержка где какая нужна?..... Может пытался вычитать слишком много?....
Похоже опять завис.... опять что ли переходить на nRF.......
Нет, ну Вы же не слышаете. Вот смотрите, Вы передаёте int'ы. Так и лопишите Ваш buf как int - чего он у Вас uint8_t.
далее, сообщение всегда состоит из 15 int'ов, или возможны варианты? Если всегда, то опишите его как int [15] (как data) и спокойно используйте. Если возможны варианты, то это отдельный разговор.
Далее, что у Вас за библиотека? Потому, что если вот эта, то recv пишется не так, у него второй параметр - указатель, а не голимое число. Показывайте свою.
Шестую строку поставил так:
if (rf95.recv(int(data), 30)) {
работает, принимает, посмотрю дальше....
Спасибо!
Я не помню уже где брал библиотеку, архив с ней называется RadioHead-1.89.zip
Если в шестой строке указываю не 30, а 15 - читает половину массива..... Видимо указывается кол-во байт, а не int-ов
Если в шестой строке указываю не 30, а 15 - читает половину массива..... Видимо указывается кол-во байт, а не int-ов
Это да - вне всякого сомнения.
Нет..... виснет..... Буду эксперементировать с задержками.
У меня на SPI сидит три устройства - SD карта, SX1278 и W5500. Изначально шёл конфликт, поскольку аппартное разделение устройств присутствует, сделал переходные буферные платы на 74HC125. Конфликты ушли. С nRF24 всё было нормально... Чем отличается SX1278?... фиг знает... Я толком не знаю принцип работы этого модуля - может он отсылает обратно CRC, может библиотека подрабатывает после приёма и идёт конфликт по SPI... не пойму... Наводка с антенны? - так модуль на приём вроде работает, Другой блок, который работает на передачу инфы не виснет...
Может подскажет кто?... Работает от получаса до нескольких часов и... фсё... намертво, пока не перезагрузишь. Пробовал ставить метки по всей программе дабы найти место зависания - так оказалось виснет в разных частях программы.
А чего толку экспериментировать. Для начала надо понять в каком месте виснет и что при этом делает.
Понавставляйте везде по коду (хоть через строчку) печать всех меняющихся переменных в тот же сериал. Запустите, а когда завистет, посомотрите в каокм месте, чему переменные равны, ну и какие-то выводы сделаете.
Ну может ваша лора жрет больше, чем нрф. Чуть посильнее дало в эфир и готово.
А чего толку экспериментировать. Для начала надо понять в каком месте виснет и что при этом делает.
Понавставляйте везде по коду (хоть через строчку) печать всех меняющихся переменных в тот же сериал. Запустите, а когда завистет, посомотрите в каокм месте, чему переменные равны, ну и какие-то выводы сделаете.
Я примерно по этому пути и иду, Евгений.... Интуиция подсказывает - аппартная это проблема...
Ну может ваша лора жрет больше, чем нрф. Чуть посильнее дало в эфир и готово.
Уровень передачи выставлен минимальный - 5 (5-23). БП стоит 4 амперный, питание везде шунтировано, самая большая просадка по питанию это 0,15В в момент регистации в сети GSM модуля.
Вобщем, пошёл я, коллеги, таким путём.... Поскольку 4 десятка лет с паяльником в руках кое-чему научили решил поступить радикальным способом... ))) Весь проект предполагается в частный дом сестре, ну а человеческий интернет там не только скоро не появится, а есть подозрение что не появится вовсе. И, сделав над собой усилие и отодрав от себя часть живого я решил расстаться с сетевым модулем, который рисовал мне в браузере красивое ромашковое поле со сводкой погоды и всей телеметрией котельной... (((
Как только W5500 покинул проект всё заработало достойно..... ну, во всяком случае, почти сутки ни одного зависания, программка побежала шустрее, ну и вообще.... W5500 и так-то работал через пень-колоду, пусть отдохнёт. Тем более что засунул я его сюда практически из любви к исскуству, а не по необходимости.
Спасибо большое всем участвующим, особенно Евгению!
Наврядли сам по себе W5500 вис... Железка неплохая.
Согласен полностью - очень не плохая, но на SPI голышом три устройства не работали - MOSI, MISO, SCK - все сидят параллельно и кто-то подкорачивал линию. Только когда буферами все их разделил - заработали. Модуль SD карты работает всегда, как танк, W5500 в этом плане противоположность. Какие-то временнЫе косяки может быть... аппаратно буферы (на 74HC125) на все три модуля одинаковы, а стабильность работы этих модулей разная....
ЕвгенийП
Здравствуйте, Евгений, можно как-то с вами связаться - хочу код вам показать, момент есть который не могу понять.
хочу код вам показать
Показывайте.
851 строка.......
да и боюсь - тут начнутся всевозможные язвительные комментарии не по делу....
почты нет у вас?
Выкладывайте, только спойлером прикройте. А комментарии ... "жизнь такова, какова она есть, и больше никакова" :-)
Блок с 499-533 строки - если вставляю в другое место, не там где сейчас стоит, принимается всякая ерунда.
И если идёт приём на LoRa то результат измерения температуры celsius2 соскакивает на ноль. При следующем измерении - нормально - 25 градусов показывает. Как только LoRa ловит через 10 секунд новую инфу - опять celsius2 ноль.....
Код не сложный, но большой, а программист я начинающий....
Блок с 499-533 строки - если вставляю в другое место, не там где сейчас стоит, принимается всякая ерунда.
И если идёт приём на LoRa то результат измерения температуры celsius2 соскакивает на ноль. При следующем измерении - нормально - 25 градусов показывает. Как только LoRa ловит через 10 секунд новую инфу - опять celsius2 ноль.....
Второй абзац - это при коде "как сейчас"? А то я не понял Вашего "если вставляю в другое место"
Я завтра посмотрю, сейчас уже отключаюсь.
Наверное начинающему программисту машину кирпичей разгрузить, в принципе, несложно. Просто она большая, а так всё просто...
Блок с 499-533 строки - если вставляю в другое место, не там где сейчас стоит, принимается всякая ерунда.
И если идёт приём на LoRa то результат измерения температуры celsius2 соскакивает на ноль. При следующем измерении - нормально - 25 градусов показывает. Как только LoRa ловит через 10 секунд новую инфу - опять celsius2 ноль.....
Второй абзац - это при коде "как сейчас"? А то я не понял Вашего "если вставляю в другое место"
Я завтра посмотрю, сейчас уже отключаюсь.
Да, комментарий мой к этому коду, кот. выше
Наверное начинающему программисту машину кирпичей разгрузить, в принципе, несложно. Просто она большая, а так всё просто...
ну вот, о чём я и говорил..... )))
Блок с 499-533 строки - если вставляю в другое место, не там где сейчас стоит, принимается всякая ерунда.
ну совершенно неудивительно, если сравнить строчки 504 и 25...
Ладно, не буду дальше, оставлю удовольствие Евгению. Тут есть где разгуляться :)
А глядя на строчки 835 - 849 - сразу понимаешь, почему новички предпочитают Мегу. Разумное использование памяти? - А зачем...
ну вот, о чём я и говорил..... )))
если вы пишете огромные простыни "грязного" неэффективного кода - будьте готовы слышать язвительные замечания в свой адрес. Рассматривайте критику не как обиду и агрессию, а как попытку донести до вас новые знания и толчок к улучшению своего кода.
Блок с 499-533 строки - если вставляю в другое место, не там где сейчас стоит, принимается всякая ерунда.
ну совершенно неудивительно, если сравнить строчки 504 и 25...
Ладно, не буду дальше, оставлю удовольствие Евгению. Тут есть где разгуляться :)
А глядя на строчки 835 - 849 - сразу понимаешь, почему новички предпочитают Мегу. Разумное использование памяти? - А зачем...
504 и 25 - что не так? подскажите. Массив из пяти интов, 10 байт. Приём у лоры только 8-ми битные переменные, но компилятор не ругается. Если в 504 прямо указываю uint8_t то ничего не меняется.
Почитал ветку сначала - и хочу отметить.
alexbel620017 - вы систематически путаете int и байт. Они не равны друг другу, в int - 2 байта, а не один.
Именно из-за этого вам приходится делать сложные преобразования массивов, поэтому у вас оказываются после передачи заполнены только каждый второй элемент. Вы регулярно пишете данные за пределы массива либо передаете или принимаете пакеты неверного размера.
С вероятностью в 99% именно этим обьяснялись зависания программы год назад - а вовсе не "аппаратными проблемами". Ровно те же самые проблемы остались в вашем коде и сейчас. То что работоспособность кода зависит от взаимного положения частей и то, что запуск лоры портит значения температуры - обьясняются очень просто - записью за границы массива.
504 и 25 - что не так? подскажите. Массив из пяти интов, 10 байт. Приём у лоры только 8-ми битные переменные, но компилятор не ругается. Если в 504 прямо указываю uint8_t то ничего не меняется.
точнее не 504, а начиная со строки 505.
массив из пяти интов, говорите? - так с какой стати вы обращаетесь в этом массиве к элементам вплоть до девятого???
Я понимаю разницу, знаю что в инте 2 байта, но я перебрал такую кучу вариантов с указанием переменных... а толку нет
Я понимаю разницу, знаю что в инте 2 байта, но я перебрал такую кучу вариантов с указанием переменных... а толку нет
именно потому и перебирали, что вы этого не понимаете.
504 и 25 - что не так? подскажите. Массив из пяти интов, 10 байт. Приём у лоры только 8-ми битные переменные, но компилятор не ругается. Если в 504 прямо указываю uint8_t то ничего не меняется.
точнее не 504, а начиная со строки 505.
массив из пяти интов, говорите? - так с какой стати вы обращаетесь в этом массиве к элементам вплоть до девятого???
Передаётся массив из 5 интов, 10 байт. Видимо и приём ведётся также - последовательно 10 байт...... Что я не так делаю?
Вот код передатчика:
Я понимаю разницу, знаю что в инте 2 байта, но я перебрал такую кучу вариантов с указанием переменных... а толку нет
именно потому и перебирали, что вы этого не понимаете.
Скорее всего......
Едрить там кадавр! Без ящика водки - точно не разберёсси.
Передаётся массив из 5 интов, 10 байт. Видимо и приём ведётся также - последовательно 10 байт...... Что я не так делаю?
что вы не так делаете???
Вот код:
если в массиве только пять интов, то куда вы обращаетесь в строчках 9 и 10? Что такое элементы 6 и 8 ?
- вот вы и влезли в чужую область памяти, при этом знаете что бывает? - программа либо зависает (привет вопросам годичной давности) либо в ней портятся другие переменные - вот вам и обнуление температуры
Алекс, Вы реально путаете инты и байты. Обьявили массив из 5 интов, запомнили, что в нем 10 байт - но у вас в голове каша, поэтому когда вы начинаете обращаться к массиву - вы помните, что там "чего-то десять", а чего - забыли. Вот и вышло, что в массиве пять элементов, а вы обращаетесь к десяти и вылезаете в чужую область памяти.
"- вот вы и влезли в чужую область памяти, при этом знаете что бывает? - программа либо зависает (привет вопросам годичной давности) либо в ней портятся другие переменные - вот вам и обнуление температуры"
я вижу что это так и происходит, только не могу понять почему. При чтении
rf95.recv(
int
(bn), 10); мои данные содержатся в чётных байтах, потому и печатаю с нулевого по девятый. И вынимаю чётные.
Едрить там кадавр! Без ящика водки - точно не разберёсси.
"Код несложный, но большой". И бестолковый.
Типично новичковый, когда писать еще не умеем, а уже хочется "мега-прогу" :)))
Главное - штоп до управления газовым котлом дело не дошло.
Алекс, Вы реально путаете инты и байты. Обьявили массив из 5 интов, запомнили, что в нем 10 байт - но у вас в голове каша, поэтому когда вы начинаете обращаться к массиву - вы помните, что там "чего-то десять", а чего - забыли. Вот и вышло, что в массиве пять элементов, а вы обращаетесь к десяти и вылезаете в чужую область памяти.
Блин, подскажите как надо пожалуйста! Я понимаю что вы правы, но не знаю как на деле это написать.....
Если я отправляю 5 интов (10 байт), то и приняться должны 10 байт....
Что-то я не допонимаю или не знаю.....
При чтении
rf95.recv(
int
(bn), 10); мои данные содержатся в чётных байтах, потому и печатаю с нулевого по девятый. И вынимаю чётные.
Вы голову-то включите. Вы читаете четные инты, а не четные байты!
))))))) Не, система чисто информационная, не управляющая. Тот проект что я год назад делал уже давно в частном доме сестры стоит и работает. Это себе делаю.
Блин, подскажите как надо пожалуйста! Я понимаю что вы правы, но не знаю как на деле это написать.....
Если я отправляю 5 интов (10 байт), то и приняться должны 10 байт....
Оставьте вы байты, раз не понимаете. Если вы отправляете пять интов - то и принимайте пять интов. Ваши данные содержатся в элементах с bn[0] по bn[4], подряд, а не в четных
Завидую я вам, новичкам. Глаза горят, руки по клавиатуре бьют. У меня вот даже мысли не возникало все эти умные бани лепить, ибо геморрой это редкостный, когда знаешь, что в перспективе ожидает.
Тот проект что я год назад делал уже давно .... стоит и работает.
позвольте вам не поверить. Ваш стиль за год не изменился, в коде косяк на косяке. Сестру жалко.