Обсуждаем контроллеры компании Atmel.
Ответить

AVR+W5500+MQTT

Вт ноя 24, 2020 20:11:01

Приветствую всех!
У меня вопрос по Ethernet модулю на чипе W5500. Кто ни будь уже с ним работал?

А вопрос вот в чем. Делаю 4 устройства которые общаются по протоколу MQTT. Хотел написать код на C, даже нашел пример кода как это было реализовано (На Ютуб канале "Электроника в объективе") но у меня этот код работать не хочет. Он ОЧЕНЬ громоздкий и я потратил 2 дня что бы разобраться. Но не особо у меня получилось.

Решил реализовать задумку используя Arduino IDE с библиотека. Все получилось. Но работает минут 15-20. Дальше может отвалиться Ethernet или MQTT и не факт что поднимется вновь. В общем пока не знаю как быть.

Что можете сказать про W5500+MQTT? Кто ни будь программировал такое?

Re: AVR+W5500+MQTT

Ср ноя 25, 2020 10:41:38

вопрос по Ethernet модулю на чипе W5500. Кто ни будь уже с ним работал?

Работаем с ним постоянно... Делали на нем и радиоуправление и Умный Дом...
Осторожно ! Много букав ! ))
https://www.radiokot.ru/forum/viewtopic ... &start=452
MQTT мы больше не используем. Перешли на технологию Xiaomi. Всё работает по UDP. ))

Re: AVR+W5500+MQTT

Пн ноя 30, 2020 21:09:24

Мдааа..... Ребята..... это еще то занятие......

В общем кое как разобрался с W5500 и библиотекой которая идет от производителя. В целом работает.
Добавил поддержку DHCP (от производителя) вроде тоже заработало. Но если кто то соображает в этом то я бы взял консультацию.... Хоть и работает но выглядит код как костыль.

С MQTT *опа...... Контроллер сам по себе зависает.... Может чуток поработать и зависнуть. Мне кажется что 328p по памяти не вывозит...

Re: AVR+W5500+MQTT

Чт дек 03, 2020 21:38:00

Есть небольшая информация.

1) МК 328р не справляется. Все непонятные ошибки за за неё (не хватка памяти). Поставил 1284р и все работает как часы.
2) Библиотека W5500 в целом нормальная.
3) Библиотека MQTT мне не очень нравится. А именно а) Почти везде тип данных int32 (Это забивает место только так.) б) функция MQTTYield(Client* c, int32_t timeout_ms) вообще не работает. Зависает, не может принять топики....

Re: AVR+W5500+MQTT

Сб дек 26, 2020 12:47:01

Так ребята. Раз никто ничего не знает. Или знает, но не говорит. Тогда я сам вам поведую рассказ о том, что удалось выяснить за 3 недели.

Сразу скажу! Текст пишу для себя (Мало ли забуду какие нюансы). Комментариев к коду нет, так что придется разбираться.

Поехали! :tea:

Техническое задание: Нужно 4-ре выключателя с 4-мя кнопками и 4-мя светодиодами состояния. У каждого выключателя есть реле которое управляет нагрузкой (лампочкой). Все выключатели объединены в сеть. И каждый выключатель может управлять релюшкой другого выключателя передавая команды по сети. В ответ получая состояние реле.

Первая версия проекта состояла из Arduino+nrf24l01(с усилителем). Работала 2 года. Выявлены конструктивные недочеты. А именно: 1) Я сделал сенсорные кнопки - перестали нормально работать через год. (Вывод: Больше не буду использовать сенсоры. Работают иногда не предсказуемо. Нет тактильной обратной связи. В общем ерунда при практическом использовании) 2) Модуль nrf24l01 постоянно теряет пакеты и из за этого связь. (Думаю из за того, что модуль подделка. (Читал о таком явлении с поддельными модулями)).

Решил развивать проводную сеть и заодно переделать эти выключатели на ethernet кабель. Выбор пал на модуль W5500 от Wiznet.
Физически модуль выглядит так.
Изображение

ГЛАВА 1.

ARDUINO(328p) + W5500<Ethernet2.h> + MQTT<PubSubClient.h>

Брокером MQTT служил mosquitto. Установленный на ПК Windows. Видеоинструкция по установке и настройке + Просмотрщик пакетов.

Комментарии по работе в среде ARDUINO: Код пишется быстро, сразу начинает работать MQTT. НО! Лично у меня работает первые 15 минут. Дальше пакеты перестают доходить до адресатов. Постоянно теряется соединение и не восстанавливается. В коде я проверяю коннект.
Код:
if (ethClient.connected() && MQTTclient.connected())
Так вот, иногда он работает иногда нет. Например: Если вытащить Ethernet кабель то все равно в логах соединение есть.
В общем библиотеки не доработанные на потерю и восстановление соединения. Пробовал другие библиотеки, но они работают ещё хуже.

Для информации. По библиотеки <PubSubClient.h> есть даже подробное описание!!!!

Прилагаю скетч. Пусть будет для истории. Может кому то пригодится.
Arduino_W5500_MQTT.rar
(2.95 KiB) Скачиваний: 321


Добавлено after 1 hour 22 minutes 19 seconds:
ГЛАВА 2.

После мытарств с ARDUINO решил плюнуть на это дело и написать уже код на С.

AVR(328p) + W5500 + DHCP + MQTT

Компания Wiznet снабдила свой Ethernet модель уже готовой библиотекой. НО! Не снабдила внятными примерами как с этим работать.
Так что для понимания смотрим 2 видео:
1) Электроника в объективе: Ethernet для МК. W5500 и ENC28J60. MQTT
2) Vladimir Medintsev: STM32 + Ethernet / Чип W5500 от WIZnet / Сокеты и простой рассказ о построении WEB сервера. Часть 2.
3) Статья: Микроконтроллеры STM32: выходим в сеть с Wiznet W5500
Все! Больше ничего вменяемого на русском языке про библиотеку от Wiznet НЕТ!

После изучения этих 3 ресурсов становится более менее понятно как работать с модулем. Дальше. Открываем код и изучаем что я там понаписал. :shock:
В дополнении расскажу о подводных камнях с которыми я сталкивался. Думаю будет полезно так как я убил на это ОЧЕНЬ! много времени.

1. Инициализация W5500.

Когда модуль прошел инициализацию, но уже отвечает на команду ping. Если этого нет, то что то идет не так.
Самое смешное, что изначально я брал файлы из библиотеки от WIZnet. И у меня ping не работал.
Потом я взял пример из видео от канала "Электроника в объективе" и использовал файлы оттуда. И все заработало! Решил сравнить файлы и там что то было дофига различий. Разбираться не стал. Библиотеки ОЧЕНЬ! мудреные и остановился на файлах из видео. Далее я использовал только их.
nadyrshin_ryu-w5500_mqtt_avr-77d65c58f0ef.rar
(783.34 KiB) Скачиваний: 348

Не забываем сконфигурировать SPI! Есть интересный файл "W5500_driver.с" Там много про инициализацию самого модуля.

PS. Есть интересная функция.
Код:
   
uint8_t PHYLINK_Status;
ctlwizchip(CW_GET_PHYLINK, (void*)&PHYLINK_Status);
printf("PHYLINK_Status= %d\n",PHYLINK_Status);

Показывает есть ли линк на модуле или нет.

2. DHCP.

Эта библиотека меня реально порадовала. Работает как часы, проста в настройке, поддерживает реконнект.
НО! :)) Таймаут на реконнект огромны! И есть выход!
Файл dhcp.с. Строчка
Код:
if ((dhcp_lease_time != INFINITE_LEASETIME) && ((dhcp_lease_time/36) < dhcp_tick_1s))

Изначально вместо 36 стояло значение 2. Вот меняя это значение можно менять реакцию, например на отключение кабеля.

Также в инструкции говорится что нужно вызывать функцию DHCP_time_handler(); раз в секунду. Этот счетчик времени для библиотеки. Он у меня вызывается раз в 100 миллисекунд и все равно таймаюут пришлось поделить на 36.

3. MQTT.

Самая жирная из библиотек и самая бестолковая. В идеальных условиях она работает стабильно. НО! Пропала сеть, выключился брокер или ещё что ни будь произошло. МК зависает. А точнее застревает в как то из циклов внутри библиотеки. Помогает только перезагрузка МК. Кроме того библиотека не оптимизированная. Все типы данных 32 разрядные. Даже там где можно применить 8 разрядов. Все равно используется 32. Я пробовал оптимизировать 2 файла. Выиграл 1,5Кб места. Но это не выход. Вся библиотека в целом не очень.

Камень 1
По инструкции надо постоянно вызывать MQTTYield(&c, 0); Если вызвать функцию до подключения MQTT то это гарантированное зависание.
Так же в функции MQTTYield (файл MQTTClient.с) есть цикл while (!expired(&timer)). Надо его убрать. Бесполезный и по умолчанию в нем все зависает.
Камень 2
В файле MQTTClient.с в функции deliverMessage есть такое условие
Код:
if (c->messageHandlers[i].topicFilter != 0 && (MQTTPacket_equals(topicName, (char*)c->messageHandlers[i].topicFilter) || isTopicMatched((char*)c->messageHandlers[i].topicFilter, topicName)))

Его надо закомментировать. Это условие избыточное и из за него не происходит обработка принятых сообщений.

Общие замечания:
Код разделения сообщения для дальнейшей обработки:
Код:
   
char _topic_name[10] = "\0";
char _message[10] = "\0";
MQTTMessage* message = md->message;
MQTTString* topic = md->topicName;
strncpy(_topic_name, topic->lenstring.data, topic->lenstring.len);
strncpy(_message, message->payload, message->payloadlen);
printf("MQTT Sub: [%s] %s\n", _topic_name , _message);

Распознавать сообщения лучше сравнением. Кода будет больше, но стабильнее.
Код:
if (strcmp(_message,"10")==0)


Ну и сам проект всего этого безобразия.
AVR_W5500_DHCP_MQTT.rar
(602.28 KiB) Скачиваний: 323


Добавлено after 55 minutes 51 second:
ГЛАВА 3.

Как вы уже поняли, библиотека MQTT мне не понравилась. Если нет возможности реконнекта то это чушь а не библиотека.
Я конечно рассматривал и другие библиотеки, но они более непонятные + сопровождения и информации по ним нет вообще.

Долго думал что делать дальше..... На одном форуме сказали "Зачем тебе MQTT? Общайся с контроллером напрямую по TCP\IP. Так проще" Больше никакой информации не было, кроме библиотеки loopback.с от Wiznet.
Вот что получилось на данный момент.

AVR(328p) + TCP\IP

В первую очередь надо сказать.
1) TCP\IP это соединение клиент-сервер. Важно! Соединение всегда устанавливает клиент. Сервер просто ожидает соединения. После того как соединение состоялось данные можно слать в обе стороны из любого места в коде.
2) Сокет - это комбинация IP адреса и порта. Модуль W5500 имеет 1 адрес и 8 портов. Другими словами можем работать с 8 сокетами одновременно.

Мне понравилось использовать TCP\IP соединение. Очень просто, удобно и самое главное есть понятный алгоритм переподключения если что то пошло не так.
В общем лучше смотрите код. Он скажет намного больше чем я буду тут описывать.
AVR_TCP_IP.rar
(264.68 KiB) Скачиваний: 393

Когда соединение установлено. То всегда выполняется "case SOCK_ESTABLISHED :"

Подводные камни:
У меня кнопки управления были завязаны на прерывание (это все тянулось с лагучий библиотеки MQTT). Так вот. Иногда при нажатии что то шло не так и в буфер данных попадал мусор. Итак в нем оставался. Из за этого переставали обрабатываться команды.
Отказался от прерывания и все стало нормально работать.


Подводя итоги могу сказать следующее: 8)
На данный момент TCP\IP соединение самое выгодное по месту на МК и самое стабильно. + Можно организовать общение с ПК по сети!
В качестве программы для такого общение я пробовал TcpClientServer. Не помню откуда скачал. Но программа простая и видно как пересылаются пакеты.


По самому проекту:
Сейчас макетная плата проработало сутки и глюков не обнаружено. Отказался от DHCP - устройство стационарное. Раз настроил и все.
Осталось подкрутить watchdogs. И какую ни будь проверку на зависание самого модуля W5500. (Например считывать IP адрес и сравнивать с настройкой.)
Изображение

Re: AVR+W5500+MQTT

Чт дек 08, 2022 12:22:32

По просьбам трудящихся допишу небольшое дополнение.

Первое на что хочу обратить внимание. W5500 - не переносит помехи по сети питания. Если вы подключаете устройство в тот же тройник что и (например) утюг, то при отключении утюга модуль обязательно зависнет. А точнее перезагрузится и все настройки IP будут сброшены.
Для решения этой проблемы я проверяю раз в секунду настройки на модуле.
Код:
//Проверка W5500 на зависание.
if(Millis()-Check_W5500>1000)
{
  Check_W5500=Millis();
  ctlnetwork(CN_GET_NETINFO,(void *)&conf);
  if(memcmp(&conf,&gWIZNETINFO,sizeof(wiz_NetInfo)) != 0)W5500_Init();
}

Если они не совпадают то переинициализирую модуль. Теперь проблем с помехами нет :)

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

И тут задали вопрос. Как организовывается общение по TCP.
Мой код основывается на примере из библиотека производителя, я ничего нового в коде не придумал.

Сервер:
1) Раз в 50 мс прослушивает сокеты по очереди "Loopback_TCP_Server(SOCK_Workshop,(uint8_t*)Message, PORT_Workshop);"
Перейдем в функцию "Loopback_TCP_Server".
В строке "switch(getSn_SR(sn))". Получаем статус сокета.
Далее начинает работать блок "switch". И первым отрабатывает "case SOCK_INIT:" Устанавливая соединение.
Из всего что есть в блоке "switch" нас интересует только эта часть "case SOCK_ESTABLISHED". Все остальные "case" трогать не нужно вообще.
Итак:
В блоке "if(getSn_IR(sn) & Sn_IR_CON)" мы можем вывести в консоль данные о текущем соединении.
(Это понятно по этой строчке "printf("%d:Connected - %d.%d.%d.%d : %d\r\n",sn, destip[0], destip[1], destip[2], destip[3], destport);")

В блоке "if((getSn_RX_RSR(sn)) > 0)" мы считываем сообщение что пришло нам от клиента. Сообщение хранится в переменной "buf".
Здесь же мы и обрабатываем сообщения. (Например в этой строчке "if((strcmp(buf,"B1\0")==0)) SETModuleStatus(1);")
Также можем и отправить сообщение (Например: "send(sn, "10\0", DATA_BUF_SIZE);")

Есть один момент в моем проекте! Когда устанавливается соединение оно НЕ РАЗРЫВАЕТСЯ!!!! Разрыв происходит только когда клиент не отвечает!
(Строчка кода: "if (Module.Update[sn]==9){close(sn);}") 9-это секунды (Инкремент в файле main: Блок "//Слежка за неотвечающими модулями")

Клиент:
Все тоже самое что и с сервером только различие в блоке "case SOCK_INIT:"

Дополню пост исходниками к рабочему проекту.
Проект простой: Это выключатели уличного освещения на 4 строениях. Любым выключателем можно включить или выключить освещение на любом из 4 строений.
Каждый выключатель представляет из себя коробку с 4 кнопками и 4 светодиодами-статусами. Статусы показывают включено ли освещение на строении и есть ли в принципе соединение с выключателем. + Web морда сервера. Можно включать и выключать освещение из Браузера на ПК.

Если резюмировать все вышесказанное, то самый важный блок это "case SOCK_ESTABLISHED :" В нем происходит все! Все остальные блоки трогать не нужно.
Вложения
Ethernet_Switch.zip
(238.01 KiB) Скачиваний: 115

Re: AVR+W5500+MQTT

Чт дек 08, 2022 13:13:41

LEVV2006 писал(а):Первое на что хочу обратить внимание. W5500 - не переносит помехи по сети питания. Если вы подключаете устройство в тот же тройник что и (например) утюг, то при отключении утюга модуль обязательно зависнет.

Уже несколько лет использую модуль W5500...
https://www.radiokot.ru/forum/viewtopic ... 8&t=185219
За несколько лет ни разу W5500 не завис... чтобы куда я не включал))

Это наверное потому что я не использую библиотек от производителя))

Re: AVR+W5500+MQTT

Чт дек 08, 2022 13:51:45

В библиотеке от Wiznet есть слабое место- это чтение какого-то статуса в цикле while(). Всё никак руки не дойдут добавить туда счётчик проходов, чтобы не было зависания.
="LEVV2006"На данный момент TCP\IP соединение самое выгодное по месту на МК и самое стабильно. + Можно организовать общение с ПК по сети!

Осталось добавить Modbus/TCP.

Re: AVR+W5500+MQTT

Чт дек 08, 2022 14:16:08

В библиотеке от Wiznet есть слабое место- это чтение какого-то статуса в цикле while(). Всё никак руки не дойдут добавить туда счётчик проходов, чтобы не было зависания.


Да. Там что такое есть. И если например линка нет (кабель не вставлен). То Прошивка застревает где то в библиотеке W5500.
Застревает правда ненадолго.... Но заметно. Реакция на кнопки заторможенная.

Re: AVR+W5500+MQTT

Чт дек 08, 2022 16:12:10

LEVV2006 писал(а):если например линка нет (кабель не вставлен). То Прошивка застревает где то в библиотеке W5500.

))
а прочитать статус регистра PHY не судьба ? ))

//////////////////////////////////////////////////////////////////W5500 PHY:
// перед настройкой PHY сделать программный Cброс PHY:
PORTB.0=0; // SS W5500
tx=0x00; SPI(); tx=0x2E; SPI(); tx=0x04; SPI(); // Address Registers + Control Registers
tx=0x00; SPI(); // Data -0x00
tx=0x00; SPI(); // Data -0x00
PORTB.0=1; // SS W5500
// пишем режим PHY:
// 1... .... RST - 1.
// .1.. .... программная настройка режима - 1
// ..0. .... 10BT Full-duplex, Auto-negotiation disabled / Power Down mode
// ...0 .... 10BT Full-duplex, Auto-negotiation disabled / Power Down mode
// .... 1... 10BT Full-duplex, Auto-negotiation disabled / Power Down mode
// .... .1.. Duplex Status
// .... ..0. Speed Status
// .... ...1 Link Status
PORTB.0=0; // SS W5500
tx=0x00; SPI(); tx=0x2E; SPI(); tx=0x04; SPI(); // Address Registers + Control Registers
tx=0xC8; SPI(); // Data -0xC8 (10 Мбит/с, Full-duplex)
tx=0x00; SPI(); // Data -0x00
PORTB.0=1; // SS W5500
////////////////////////////////////////////////////////////////////////////////

Если например линка нет (кабель не вставлен). То регистр 0x2E меняет значение.
Поэтому в моей программе идёт непрерывный опрос как статуса регистров TX... RX... так и статуса регистра линка PHY.
Если например линка нет (кабель не вставлен). То мой МК стразу прекращает выполнение программы и сообщает мне громким ПИК-ПИК-ПИК... (кабель не вставлен ! ).
:tea:

Re: AVR+W5500+MQTT

Вс дек 11, 2022 03:27:51

вот вы, роман... хитрый какой! лучше-бы поделились своей реализацией! :))
общество не будет против, обществу пригодиться! :beer:

Re: AVR+W5500+MQTT

Вс дек 11, 2022 11:44:28

LEVV2006 писал(а): И если например линка нет (кабель не вставлен). То Прошивка застревает где то в библиотеке W5500.

Ничего не застревает, всё нормально работает.

Re: AVR+W5500+MQTT

Вс фев 12, 2023 08:45:13

В библиотеке от Wiznet есть слабое место- это чтение какого-то статуса в цикле while(). Всё никак руки не дойдут добавить туда счётчик проходов, чтобы не было зависания.
="LEVV2006"На данный момент TCP\IP соединение самое выгодное по месту на МК и самое стабильно. + Можно организовать общение с ПК по сети!

Осталось добавить Modbus/TCP.


а чо его добавлять? 20 строк кода.

Re: AVR+W5500+MQTT

Вс фев 12, 2023 15:19:46

1.jpeg
(97.1 KiB) Скачиваний: 114

украли мою схему))
схема_1.jpg
(196.87 KiB) Скачиваний: 111

:))
мой AVR+W5500+MQTT на ПК...
AVR+W5500+MQTT.jpg
(125.98 KiB) Скачиваний: 95

:))

Re: AVR+W5500+MQTT

Вс фев 12, 2023 15:32:28

imsushka писал(а):а чо его добавлять? 20 строк кода.

Шутишь, imsushka? :)))

Re: AVR+W5500+MQTT

Вс фев 12, 2023 19:43:48

imsushka писал(а):а чо его добавлять? 20 строк кода.

Шутишь, imsushka? :)))


кроме шуток
даже меньше чем 20 строк (шучу)

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

Re: AVR+W5500+MQTT

Пн мар 13, 2023 10:17:37

украли мою схему))

:shock:
В первый раз вижу ваши картинки :)))
Ответить