изменился IP

salik
Offline
Зарегистрирован: 12.12.2018

Посоветуйте, куда смотреть...

Есть проект Мега2560, W5500 (библиотека ethernet2), библиотека MODBUS TCP  (https://github.com/siamect/mudbus). IP задается статический 192.168.1.25. Вообщем modbus TCP slave устройство. Все работает, но пару раз проявился такой момент: через некоторое время (дней 7-10, примерно) беспрерывной работы устройство перестало отвечать на запросы. Адрес 192.168.1.25 не пингуется. НО, устройство стало пинговаться по адресу 192.168.1.15.

Как такое возможно? Как обойти эти грабли и куда смотреть?

Спасибо.

sadman41
Offline
Зарегистрирован: 19.10.2016

Само по себе у меня такое ни разу не происходило, но допускать вероятность того, что в чип полетела наводке, которая была распознана как команда переконфигурирования со случайным адресом, совпавшим до некоторой степени с оригинальным, - могу. 

Что скрывается под словом"обойти" - не понимаю пока, но могу предложить раз в N секунд сличать хотя бы localIP() с заданным. Разняться - переконфигурировать.

Jeka_M
Jeka_M аватар
Offline
Зарегистрирован: 06.07.2014

Видимо роутер всё таки присваивает динамический IP. В роутере можно зарезервировать динамический IP адрес для конкретного устройства по MAC-адресу.

salik
Offline
Зарегистрирован: 12.12.2018

Неее, роутера нет. Сеть - это само устройство, ПЛК и ноутбук. У всех статические адреса. Что поменялся IP адрес случайно обнаружил - запустил Advanced IP scaner.

salik
Offline
Зарегистрирован: 12.12.2018

sadman41 пишет:

 

Что скрывается под словом"обойти" - не понимаю пока, но могу предложить раз в N секунд сличать хотя бы localIP() с заданным. Разняться - переконфигурировать.

В идеале найти причину 

salik
Offline
Зарегистрирован: 12.12.2018

sadman41 пишет:

Само по себе у меня такое ни разу не происходило, но допускать вероятность того, что в чип полетела наводке, которая была распознана как команда переконфигурирования со случайным адресом, совпавшим до некоторой степени с оригинальным, - могу. 

я запущу на тест устройство, понаблюдаю. Если будет тот же адрес - значит другая причина  ....

negavoid
Offline
Зарегистрирован: 09.07.2016

sadman41 пишет:
допускать вероятность того, что в чип полетела наводке, которая была распознана как команда переконфигурирования со случайным адресом, совпавшим до некоторой степени с оригинальным

Это очень вряд ли. Чтобы получить адрес от dhcp, нужно четыре чётко структурированных пакета, по два в обе стороны, это очень уж умная наводка должна быть :)

sadman41
Offline
Зарегистрирован: 19.10.2016

negavoid пишет:

Это очень вряд ли. Чтобы получить адрес от dhcp, нужно четыре чётко структурированных пакета, по два в обе стороны, это очень уж умная наводка должна быть :)

У него нет DHCP, так что не умная, но достаточно сообразительная. А вероятность - она всегда ненулевая.

__Alexander
Offline
Зарегистрирован: 24.10.2012

IP же в W5500 прописывается только раз, по SPI. Может всё таки была перезагрузка?

salik
Offline
Зарегистрирован: 12.12.2018

__Alexander пишет:

IP же в W5500 прописывается только раз, по SPI. Может всё таки была перезагрузка?

я логировал modbus, вот что в логах

[1553856923] 29.03.2019 15:55:23 [0]    MODBUS OK: RESPONSE_SUCCESS
[1553864147] 29.03.2019 17:55:47 [0]    MODBUS OK: RESPONSE_SUCCESS
[1553864446] 29.03.2019 18:00:46 [74784]        RESPONSE_INVALID_DATA
[1553864446] 29.03.2019 18:00:46 [74788]        MODBUS OK: RESPONSE_SUCCESS
[1553864577] 29.03.2019 18:02:57 [107442]       RESPONSE_TIMEOUT
[1553864577] 29.03.2019 18:02:57 [107445]       MODBUS OK: RESPONSE_SUCCESS
[1553864579] 29.03.2019 18:02:59 [108016]       RESPONSE_INVALID_DATA
[1553864579] 29.03.2019 18:02:59 [108020]       MODBUS OK: RESPONSE_SUCCESS
[1553864658] 29.03.2019 18:04:18 [127808]       RESPONSE_TIMEOUT
[1553864658] 29.03.2019 18:04:18 [127818]       MODBUS OK: RESPONSE_SUCCESS
[1553864936] 29.03.2019 18:08:56 [197301]       RESPONSE_TIMEOUT
[1553864936] 29.03.2019 18:08:56 [197304]       MODBUS OK: RESPONSE_SUCCESS
[1553865258] 29.03.2019 18:14:18 [277841]       RESPONSE_INVALID_HEADER
[1553865259] 29.03.2019 18:14:19 [277845]       MODBUS OK: RESPONSE_SUCCESS
[1553865665] 29.03.2019 18:21:05 [379401]       RESPONSE_WRONG_SLAVE
[1553865665] 29.03.2019 18:21:05 [379405]       MODBUS OK: RESPONSE_SUCCESS
[1553866587] 29.03.2019 18:36:27 [610077]       RESPONSE_TIMEOUT
[1553866589] 29.03.2019 18:36:29 [610577]       TCP_COMMUNICATION_ERROR
[1553866590] 29.03.2019 18:36:30 [610832]       RESPONSE_TIMEOUT
[1553866592] 29.03.2019 18:36:32 [611332]       TCP_COMMUNICATION_ERROR
[1553866617] 29.03.2019 18:36:57 [617438]       MODBUS OK: RESPONSE_SUCCESS
[1553866745] 29.03.2019 18:39:05 [649402]       RESPONSE_TIMEOUT
[1553866747] 29.03.2019 18:39:07 [649902]       TCP_COMMUNICATION_ERROR

Между началом ошибок по связи и моментом когда устройство полностью перестало отвечать на запросы, прошло (с 18.00 до 18.39) 39 минут. 

Если была просто перезагрузка, почему адрес прописался другой ? 

sadman41
Offline
Зарегистрирован: 19.10.2016

Устанавливается адрес сколько угодно раз... Никаких ограничений на многократную запись в регистр SIPR нет.

void W5500Class::setIPAddress(uint8_t *_addr) {
  writeSIPR(_addr);
}

 

__Alexander
Offline
Зарегистрирован: 24.10.2012

sadman41 пишет:

Устанавливается адрес сколько угодно раз... Никаких ограничений на многократную запись в регистр SIPR нет.

void W5500Class::setIPAddress(uint8_t *_addr) {
  writeSIPR(_addr);
}

Я про то, что в данном случае он статический и прописывается один раз после подачи питания. Вот тут, помеха по SPI в момент записи вполне себе может быть.

ТС, я бы добавил задержку перед настройкой микрухи по SPI, пусть питание устаканится.

negavoid
Offline
Зарегистрирован: 09.07.2016

Да, так может, да :)

salik
Offline
Зарегистрирован: 12.12.2018

 

[/quote]

ТС, я бы добавил задержку перед настройкой микрухи по SPI, пусть питание устаканится.

[/quote]

Да, согласен, резонно... Реализую

salik
Offline
Зарегистрирован: 12.12.2018

вытащил на морду еще и  Ethernet.localIP(), тестирую

salik
Offline
Зарегистрирован: 12.12.2018

и все таки IP меняется... причину понять не могу. задержку поставил перед настройкой по SPI в случае перезагрузки... пока хочу обработать сам факт изменения и принудительно переконфигурить IP адрес. Вопрос такой: как правильно обрабатывать значение  Ethernet.localIP(). В конструкции display.println (Ethernet.localIP ( )) оно правильно отображается на экране в виде 192.168.1.25. А что с чем сравнивать, ведь это не строка? 

b707
Offline
Зарегистрирован: 26.05.2017

salik пишет:

В конструкции display.println (Ethernet.localIP ( )) оно правильно отображается на экране в виде 192.168.1.25. А что с чем сравнивать, ведь это не строка? 

так чего проще - откройте библиотеку Ethernet и посмотрите, в каком виде отдает адрес эта самая функция localIP( ).  Подозреваю, что она выводит как раз таки строку.

Сравнивать IP в виде строки не слишком эффективно - я бы покопался в библиотеке, наверняка из нее можно получить адрес и в виде 4х байт. что было бы удобнее для сравнения.

 

sadman41
Offline
Зарегистрирован: 19.10.2016

Ethernet.localIP() возвращает объект IPAddress. Его можно сравнивать с таким же IPAddress или, например, с uint32_t. С первым более наглядно, наверно - ведь он задаётся в начале скетча. Типа IPAddress hostIp(192, 168, 1, 25);

b707
Offline
Зарегистрирован: 26.05.2017

sadman41 пишет:

Ethernet.localIP() возвращает объект IPAddress.

а как же оно печатается функцией print() ?

sadman41
Offline
Зарегистрирован: 19.10.2016

b707 пишет:

sadman41 пишет:

Ethernet.localIP() возвращает объект IPAddress.

а как же оно печатается функцией print() ?

/** The Printable class provides a way for new classes to allow themselves to be printed.
    By deriving from Printable and implementing the printTo method, it will then be possible
    for users to print out instances of this class by passing them into the usual
    Print::print and Print::println methods.
*/
class Printable
{
  public:
    virtual size_t printTo(Print& p) const = 0;  // Фокус тут готовится
};

...
class IPAddress : public Printable 
...

size_t IPAddress::printTo(Print& p) const
{
    size_t n = 0;
    for (int i =0; i < 3; i++)
    {
        n += p.print(_address.bytes[i], DEC);
        n += p.print('.');
    }
    n += p.print(_address.bytes[3], DEC);
    return n;
}


 

b707
Offline
Зарегистрирован: 26.05.2017

вот ты не ленивый :) Спасибо, понятно

salik
Offline
Зарегистрирован: 12.12.2018

Спасибо большое

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

b707 пишет:

вот ты не ленивый :) Спасибо, понятно

он программист докапывающийся до сути )))