Ethernet Library или почему в природе не существует серверов на Arduino

    image

    В этой статье я опишу ситуацию с которой столкнулся во время разработки проекта Arduino Mega Server. Суть дела заключается в том, что существует такая библиотека Arduino Ethernet Library, написанная для поддержки сетевой платы Ethernet Shield на чипе W5100. Это стандартная плата и стандартная библиотека, которая многие годы поставляется в комплекте со средой разработки Arduino.

    И эта библиотека является основой для всех проектов, использующих обмен информацией по проводной сети. Так вот, оказалось, что эта библиотека попросту профнепригодна. На ней в принципе невозможно построить нормальное сетевое взаимодействие. Можно только «баловаться» одиночными запросами и ответами. Ни о каком построении серверов на базе этой библиотеки речь не может идти. Почему?

    Потому, что эта библиотека имеет встроенный «баг», который подвешивает неодиночные запросы на время от трёх до десяти секунд и более. Баг именно встроенный и автор библиотеки об этом знал, о чём свидетельствует его пометки в исходниках (но об этом несколько позже).

    Тут нужно понимать, что библиотека, поставляемая с официальной средой разработки является неким стандартом и если у вас не работает проект, то вы будете искать дефект где угодно, только не в стандартной библиотеке, ведь ей много лет и ею пользуются сотни тысяч, если не миллионы людей. Не могут же они все ошибаться?

    Почему в природе не существует серверов на Arduino


    Разработка проекта шла своим чередом и дело, наконец, дошло до оптимизации кода и увеличения скорости работы сервера и тут я столкнулся с такой ситуацией: приходящие запросы от браузера принимались и «подвешивались» на время от трёх до десяти секунд, в среднем и до двадцати и более секунд при более интенсивном обмене. Вот скриншот, на котором видно, что аномальная задержка ответов сервера «гуляет» по различным запросам.

    аномальная задержка

    Когда я стал разбираться, то выяснилось, что серверу ничто не мешает ответить, но, тем не менее, запрос «висит» девять с лишним секунд, а при другой итерации этот же запрос висит уже около трёх секунд.

    Подобные наблюдения повергли меня в глубокую задумчивость и я перекопал весь код сервера (заодно размялся) но дефектов не обнаружил и вся логика вела к «святая святых» библиотеке Arduino Ethernet Library. Но крамольную мысль, что виновата стандартная библиотека я отбрасывал, как неадекватную. Ведь с библиотекой работают не только пользователи, но и огромное количество профессиональных разработчиков. Не могут же они все не видеть столь очевидных вещей?

    Забегая вперёд, скажу, что когда выяснилось, что дело именно в стандартной библиотеке, стало понятно почему в природе не существует (нормальных) серверов на Arduino. Потому, что на базе стандартной библиотеки (с которой работает большинство разработчиков) построить сервер в принципе невозможно. Задержка ответа в десять секунд и более выводит сервер из категории собственно серверов и делает его просто (тормозной) игрушкой.

    Промежуточный вывод. Это не Ардуино не подходит для построения серверов, а сетевая библиотека ставит крест на очень интересном классе устройств.

    Анатомия проблемы


    Теперь от лирики давайте перейдём к техническому описанию проблемы и её практическому решению. Для тех, кто не в курсе, стандартное место расположения библиотеки (в Windows):

    arduino\libraries\Ethernet

    И первое, что мы рассмотрим, это функция из файла EthernetServer.cpp

    EthernetClient EthernetServer::available() {
      accept();
    
      for (int sock = 0; sock < MAX_SOCK_NUM; sock++) {
        EthernetClient client(sock);
        if (EthernetClass::_server_port[sock] == _port &&
            (client.status() == SnSR::ESTABLISHED ||
             client.status() == SnSR::CLOSE_WAIT)) {
          if (client.available()) {
            // XXX: don't always pick the lowest numbered socket.
            return client;
          }
        }
      }
      return EthernetClient(MAX_SOCK_NUM);
    }

    Когда я преодолел психологический барьер (под давлением логики) и начал искать дефект в Ethernet Library я начал именно с этой функции. Заметил я и странный комментарий автора, но не придал ему значения. Перелопатив всю библиотеку, я опять, но уже через пару дней и сильно продвинувшись в сетевых технологиях, вернулся к этой функции потому, что логика подсказывала, что проблема именно здесь и более внимательно посмотрел на комментарий.

    
            // XXX: don't always pick the lowest numbered socket.
    
    

    Друзья, там всё написано открытым текстом. В вольном переводе это звучит примерно так «это работает, но не всегда». Подождите минуточку, что значит «не всегда»? У нас же не воскресный клуб по игре в лото. А когда не работает, то что? А вот когда «не работает» и начинаются проблемы с задержкой в десять секунд.

    И автор об этом определённо знал, о чём свидетельствует самооценка его творения — три икса. Без комментариев. Эта библиотека является основой для многих клонов и, внимание, эти три икса кочуют из одного проекта в другой. Если вы разработчик, то не заметить эту проблему можно только не разу не протестировав сетевой обмен. Тоже без комментариев.

    Для тех, кто плохо разбирается в коде поясню суть проблемы простыми словами. Цикл перебирает сокеты и, как только находит подходящий, возвращает клиента, а остальных просто игнорирует. И они висят по десять секунд, пока «карты благоприятно не лягут».

    Решение проблемы


    Поняв причину проблемы, мы конечно не остановимся на этом и попробуем её решить. Для начала давайте перепишем функцию таким образом, чтобы получение или не получение сокета не зависело от воли случая и происходило всегда, если есть свободный. Это решит две проблемы:

    • запросы не будут зависать
    • «последовательные» запросы превратятся в «параллельные», что значительно ускорит работу

    Итак, код новой функции:

    EthernetClient EthernetServer::available_(int sock) {
      accept_(sock);
      EthernetClient client(sock);
      if (EthernetClass::_server_port[sock] == _port &&
          (client.status() == SnSR::ESTABLISHED ||
           client.status() == SnSR::CLOSE_WAIT)) {
        if (client.available()) {
          return client;
        }
      }
      return EthernetClient(MAX_SOCK_NUM);
    }
    

    Убираем цикл, явным образом указываем сокет и ничего не теряем — если он свободен, то мы гарантированно получаем клиента (если он нам подходит).

    То же самое «по цепочке» проделываем с кодом функции accept, убираем цикл и явно указываем сокет.

    void EthernetServer::accept_(int sock) {
      int listening = 0;
      EthernetClient client(sock);
    
      if (EthernetClass::_server_port[sock] == _port) {
        if (client.status() == SnSR::LISTEN) {
          listening = 1;
        } 
        else if (client.status() == SnSR::CLOSE_WAIT && !client.available()) {
          client.stop();
        }
      } 
    
      if (!listening) {
        //begin();
        begin_(sock); // added
      }
    }
    

    И не забываем поправить файл EthernetServer.h

    class EthernetServer : 
    public Server {
    private:
      uint16_t _port;
      //void accept();
      void accept_(int sock);
    public:
      EthernetServer(uint16_t);
      //EthernetClient available();
      EthernetClient available_(int sock);
      virtual void begin();
      virtual void begin_(int sock);
      virtual size_t write(uint8_t);
      virtual size_t write(const uint8_t *buf, size_t size);
      using Print::write;
    };
    

    Вот, собственно и всё. Мы внесли изменения в стандартную библиотеку и поведение сервера кардинально изменилось. Если раньше всё работало очень медленно, за гранью любых представление о юзабилити, то теперь скорость загрузки страниц значительно возросла и стала вполне приемлемой для нормального использования.

    скорость загрузки возрасла

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

    Полный код изменённого EthernetServer.cpp
    /*
    Mod for Arduino Mega Server project
    fix bug delay answer server
    */

    #include «w5100.h»
    #include «socket.h»
    extern «C» {
    #include «string.h»
    }

    #include «Ethernet.h»
    #include «EthernetClient.h»
    #include «EthernetServer.h»

    EthernetServer::EthernetServer(uint16_t port) {
    _port = port;
    }

    void EthernetServer::begin() {
    for (int sock = 0; sock < MAX_SOCK_NUM; sock++) {
    EthernetClient client(sock);
    if (client.status() == SnSR::CLOSED) {
    socket(sock, SnMR::TCP, _port, 0);
    listen(sock);
    EthernetClass::_server_port[sock] = _port;
    break;
    }
    }
    }

    void EthernetServer::begin_(int sock) {
    EthernetClient client(sock);
    if (client.status() == SnSR::CLOSED) {
    socket(sock, SnMR::TCP, _port, 0);
    listen(sock);
    EthernetClass::_server_port[sock] = _port;
    }
    }

    /*

    void EthernetServer::accept() {
    int listening = 0;

    for (int sock = 0; sock < MAX_SOCK_NUM; sock++) {
    EthernetClient client(sock);

    if (EthernetClass::_server_port[sock] == _port) {
    if (client.status() == SnSR::LISTEN) {
    listening = 1;
    }
    else if (client.status() == SnSR::CLOSE_WAIT && !client.available()) {
    client.stop();
    }
    }
    }

    if (!listening) {
    begin();
    }
    }

    */

    void EthernetServer::accept_(int sock) {
    int listening = 0;
    EthernetClient client(sock);

    if (EthernetClass::_server_port[sock] == _port) {
    if (client.status() == SnSR::LISTEN) {
    listening = 1;
    }
    else if (client.status() == SnSR::CLOSE_WAIT && !client.available()) {
    client.stop();
    }
    }

    if (!listening) {
    //begin();
    begin_(sock); // added
    }
    }

    /*

    EthernetClient EthernetServer::available() {
    accept();

    for (int sock = 0; sock < MAX_SOCK_NUM; sock++) {
    EthernetClient client(sock);
    if (EthernetClass::_server_port[sock] == _port &&
    (client.status() == SnSR::ESTABLISHED ||
    client.status() == SnSR::CLOSE_WAIT)) {
    if (client.available()) {
    // XXX: don't always pick the lowest numbered socket.
    return client;
    }
    }
    }
    return EthernetClient(MAX_SOCK_NUM);
    }

    */

    EthernetClient EthernetServer::available_(int sock) {
    accept_(sock);
    EthernetClient client(sock);
    if (EthernetClass::_server_port[sock] == _port &&
    (client.status() == SnSR::ESTABLISHED ||
    client.status() == SnSR::CLOSE_WAIT)) {
    if (client.available()) {
    return client;
    }
    }
    return EthernetClient(MAX_SOCK_NUM);
    }

    size_t EthernetServer::write(uint8_t b) {
    return write(&b, 1);
    }

    size_t EthernetServer::write(const uint8_t *buffer, size_t size) {
    size_t n = 0;
    //accept();

    for (int sock = 0; sock < MAX_SOCK_NUM; sock++) {
    accept_(sock); // added
    EthernetClient client(sock);

    if (EthernetClass::_server_port[sock] == _port &&
    client.status() == SnSR::ESTABLISHED) {
    n += client.write(buffer, size);
    }
    }
    return n;
    }

    Полный код изменённого EthernetServer.h
    /*
    Mod for Arduino Mega Server project
    fix bug delay answer server
    */

    #ifndef ethernetserver_h
    #define ethernetserver_h

    #include «Server.h»

    class EthernetClient;

    class EthernetServer:
    public Server {
    private:
    uint16_t _port;
    //void accept();
    void accept_(int sock);
    public:
    EthernetServer(uint16_t);
    //EthernetClient available();
    EthernetClient available_(int sock);
    virtual void begin();
    virtual void begin_(int sock);
    virtual size_t write(uint8_t);
    virtual size_t write(const uint8_t *buf, size_t size);
    using Print::write;
    };

    #endif



    Оставшиеся проблемы


    В таком виде сервер из демонстрации идеи переходит в категорию вещей, которыми можно пользоваться в повседневной жизни, но остались некоторые проблемы. Как вы видите на скриншоте ещё присутствует не принципиальная, но неприятная задержка в три секунды, которой не должно быть. Библиотека написана так, что мест, где код работает не так, как нужно, очень много и если вы квалифицированный разработчик, то ваша помощь в установлении причины трёхсекундной задержки будет очень ценной. И для проекта Arduino Mega Server и для всех пользователей Arduino.

    Последний момент


    Поскольку мы изменили код стандартной библиотеки, то и вызывать её функции нужно несколько иным способом. Здесь я привожу код, который реально работает и который обеспечивал работу AMS на скриншоте выше.

      for (int sock = 0; sock < MAX_SOCK_NUM; sock++) {
        EthernetClient sclient = server.available_(sock);
        serverWorks2(sclient);
      }
    

    Здесь задача перебора сокетов перенесена на уровень клиентского скетча и, что самое главное, и в чём смысл всего вышесказанного, не происходит «подвисания» запросов. И функция собственно сервера:

    void serverWorks2(EthernetClient sclient) {
    ...
    }
    

    С полным кодом сервера вы можете ознакомиться, скачав дистрибутив с официального сайта проекта Arduino Mega Server. А задать возникшие вопросы можно на форуме. Осталось решить последнюю проблему трёхсекундной задержки и у нас будет настоящий, быстро работающий сервер на Ардуино. Кстати, скоро выйдет новая версия AMS со всеми исправлениями и улучшениями в которой решена одна из самых актуальных проблем — автономная работа без поддержки сервера MajorDoMo.

    Arduino Mega Server

    И возможным это стало во многом благодаря тем исправлениям стандартной библиотеки Arduino Ethernet Library о которых я вам сейчас рассказал.

    Дополнение. Открыт канал на Youtube и вот промо ролик Arduino Mega Server, который демонстрирует работу с реальной системой.
    Share post
    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More
    Ads

    Comments 74

      0
      Спасибо за работу! Как раз начинаем проект где будет задействован и чип и эта библиотека.
        0
        +1
        Полезная вещь, респект автору за работу!
          +4
          Сотни мух не могут ошибаться!!! (выбирая говно) Спасибо за работу!!!
            0
            на оффициальном сайте Ардуино есть и другие библиотеки реализующие или не весь функционал шилдов или с ошибками, хотя есть библиотеки на github.com с лучшим кодом, который охватывает больше функционала железа. Чтобы попасть на оффициальный сайт есть какие то трудности? Или просто никто не отслеживает на оффициальном сайте лучшие реализации библиотек?
              0
              Я совершенно не фанат официальной библиотеки, мне нужно, чтобы AMS работал и если есть нормальная библиотека то я с удовольствием ею воспользуюсь. Все, что я протестировал были не лучше.
              +9
              Ведь с библиотекой работают не только пользователи, но и огромное количество профессиональных разработчиков.

              Не холивара ради, а любопытства. А правда есть профессиональные разработчики на Ардуино? Пытался найти недавно примеры коммерческих Ардуино-продуктов, но как-то поиски не на что не навели…
              И по посту. Если все равно приходится ковыряться в библиотеках то не проще ли сразу перейти на обычную атмегу?
                +3
                Нет, что вы, это же адский ад, писать на атмеге или, не дай Бог, на любом другом микроконтроллере.
                  +1
                  Я вообще сейчас ужас напишу, нет не так… УЖАСЪ!!! Ассемблер.
                    +2
                    На всякий случай побрызгал святой водой на монитор.
                      0
                      Воистину, коллега!!!
                    +3
                    shpaker: Не холивара ради, а любопытства. А правда есть профессиональные велосипедисты на детских пластиковых трехколесных велосипедах?

                    aronsky: Нет, что вы, это же адский ад, велосипедисту велосипед использовать.
                    +1
                    Профессиональный — это в контексте ВУЗов с недостатком финансирования. Коммерческий проект в Ардуино — это сама Ардуино и шильды к ней. Например атмеловские чипы нельзя использовать в оборудовании медицинского направления — они вроде как отказались лицензировать.

                    Что касается самих веб серверов на атмеле, то проектов куча. Начиная с цепляния эзернетовской карточки на rtl8239, полноценного web с ftp на mega644 и закачнчивая микросервером на attiny2313.
                      +2
                      Как-то не убедительно. Сама Ардуина как пример успешного проекта на Ардуинке тоже не засчитано. Имхо преподов принимающих работы на дуинке не должно быть, только если на вводных дисциплинах.
                      пс: Вы не подумайте у меня у самого их три штуки, для целей быстрого прототипирования.
                        0
                        Не защитник Ардуино, но нам на экскурсии в Rice University, весьма небедном месте, показывали, что вообще все электронное прототипирование студентами ведется с использованием ардуино…
                          0
                          На сколько вижу по информации из поисковика, в этом универе ардуиной проповедуют с 2014 года. Зато прекрасно помню их страницу студенческих разработок под атмел с 2002 года. Да оно и сейчас не дурно отображается по запросе rise univeryity atmel.

                          Идея стандартизировать модуль разработки не нова и даже хорошо, что на это кто-то выделил денег под рекламу, чтоб сделать некий «стандарт», отметающий кучу самолепных велосипедов. Самый навоз идет от прилагаемого фреймворка, от которого у начинающих пучит мозг (что напрямую относится к данному топику). Благо для программирования можно не легко, но отказаться от фремворка.
                        0
                        Под профессионалами подразумевались люди хорошо разбирающиеся в сетях, авторы серверов на Ардуино (такие тоже есть) и разработчики библиотек, основанных на стандартном коде.

                        В библиотеке пришлось ковыряться по необходимости, до сих пор как-то обходилось без этого.
                          –1
                          Недавно я задал тот же вопрос Винфилду Хиллу, автору знаменитой книги «Искусство схемотехники». Он выслал схему своего недавнего проекта — драйвера электропорации — под управлением Arduino Nano. Удобство Arduino в том, что клиенту будет легко обновлять программный код.
                            +2
                            Удобство Arduino в том, что клиенту будет легко обновлять программный код


                            Это достигается заливкой в любую конструкцию бутлоадера от Ардуины, если вы хотите именно из Arduino IDE заливать прошивки (не представляю, зачем покупателю серийного коммерческого устройства этого хотеть). Во всех остальных случаях это будет очень странным решением.

                            Он выслал схему своего недавнего проекта — драйвера электропорации


                            Он его производит? Нет? Тогда, боюсь, лично он Arduino не использует.
                              –4
                              Авторы книги обедают с самыми продвинутыми схемотехниками Силиконовой Долины, создают приборы для научных лабораторий по всему США, поэтому я бы к их мнению прислушался. Я понимаю, что принято думать, что Ардуино — это такая игрушка для моргания светодиодами, но достаточно одного примера, чтобы это опровергнуть.
                                +1
                                Я рад за них, наверняка питаются хорошо.

                                Но не могли бы вы всё-таки пояснить, какой практический смысл в использовании Arduino в серийно производимом устройстве?
                                  +1
                                  В крупносерийном производстве использовать Ардуино смысла нет, но про это не было и речи. Вопрос был «используют ли Ардуино профессионалы». Ответ — используют, в частности — Arduino Nano. Удобный маленький модуль со смешной ценой.
                                    +1
                                    Вопрос был про коммерческие продукты. Коммерческий продукт — это серийный продукт.

                                    А профессионалы его используют как удобную вещь для быстрого прототипирования, чтобы на коленке быстренько что-то собрать. Иное, повторюсь, не имеет практического смысла.
                                      –2
                                      А если окажется что в серийное устройство дешевле и быстрее будет впаять плату-ардуину? Ключевое слово дешевле. особенно на малых сериях, где подготовка к производству с нуля существенно повысит стоимость конечного изделия.
                                        +3
                                        У вас ардуина куда впаивается? На некоторую плату, на которой нужная вам обвязка стоит?

                                        Ну так вам к производству её готовить что с атмегой на борту, что без неё — одинаково стоит.
                                        0
                                        Коммерческий продукт не всегда крупносерийный.
                                        Научные установки продаются, зачастую штучно, с адаптацией под конкретного заказчика. Использование технологий быстрого прототипирования в таких проектах вполне оправдано.

                                        PS: сам не использую ардуино и против его использования в проектах с сериями > 500 шт.
                                          +1
                                          Использование технологий быстрого прототипирования в таких проектах вполне оправдано


                                          Извините, полная чушь.

                                          У вас 90 % научной установки — это интерфейсы к датчикам, как правило, весьма специфическим, причём интерфейсы с максимально понятными характеристиками, линейностью, ошибками. У вас просто стоимость одних только нужных АЦП и ОУ (и да, на ардуиновских ширпотребных шилдах ничего близкого к ним не будет) запросто перекроет стоимость самой ардуины в разы, равно как и сложность разводки печатки под них по сравнению с печаткой под атмегу.

                                          P.S. Помнится, в начале нулевых мы в лабе делали себе на атмеге оптоэлектронный интерфейс к спектрометру, не то чтобы сильно страдали от отсутствия ардуины.
                                            0
                                            Ну фиг его знает. В моей установке обвеса примерно на 200$ датчиков и тому подобного. Но с этим прекрасно справляется Arduino Nano за 2.5$
                                              0
                                              Вы её себе на коленке делали, а не продавали сторонним людям.

                                              Себе — из чего угодно, хоть из соломы с глиной, никто, кроме вас, от этого не пострадает.
                                                0
                                                А в чём проблема для одиночных вещей? Сама плата сделана очень качественно, щтампуют их тоннами. Софт? Вероятно. Библиотеки Arduino могут содержать проблемы. Но в моих задачах это не проявляется. Где надо я руками запускал аналоговый коммутатор, который обычным фреймворком не охватывается. Мне остаётся только воткнуть готовую железяку в плату и работать. Меньше возни с разводкой. Какая мне разница — голый там чип или сразу с обвязкой и usb? В одиночных изделиях большая часть цены- моё время. Тупо дешевле не отвлекать меня совсем низким уровнем.
                                                  +1
                                                  Меньше возни с разводкой


                                                  Если разводка AVR8 для вас — это возня, которая заслуживает хоть какого-то отдельного упоминания, то на уровень разработчика электронных устройство вы вообще, совсем, никак не тянете. Для меня, например, развести на плате атмегу и её обвязку — это быстрее, чем рисовать библиотечный компонент с какой-либо ардуиной.

                                                  А если для вас разводка атмеги представляет собой какое-то значимое препятствие, то у меня, как потенциального покупателя научной аппаратуры вашего производства, возникает серьёзный вопрос о том, какой уровень понимания там вложен в куда более сложную часть этой аппаратуры.

                                                  Говоря проще, не набрана ли она таким же путём из готовых модулей с ебея — и не окажется ли, что разработчик про характеристики получившегося имеет весьма смутное представление, а все проблемы аппаратного характера мне придётся решать самому.

                                                  Для себя — повторюсь, хоть из соломы с глиной. Но если вы хотите на коммерческой основе мне это за несколько тысяч долларов продать — у меня будут вопросы.
                                                    0
                                                    Убедили, согласен. Я профессионал в другой области.
                                                      0
                                                      Ох уж эти специалисты, которые разводят цифровую схему за 5 минут…
                                                      У меня как раз сомнения возникают именно эти 5-минутные платы.
                                                      Потратить час времени на разводку платы — сколько говорите у вас стоит час времени?
                                                      Примерно столько времени уйдет чтобы развести плату уровня ардуины с учетом всех требований разводки а не скопировать уже готовое решение.
                                            +1
                                            Коммерческий продукт — это серийный продукт


                                            Откуда взято такое определение?
                                            Бывают индивидуальные проекты, для которых да же плату разводить не имеет смысла. Как пример — производство архитектурных макетов. Есть фирма (без имен, рекламой заниматься не буду), которая занимается именно этими макетами. В каждый макет втыкается ардуинка, которая мигает лампочками («ночная» подсветка, светофоры), крутит сервы (шлагбаумы, ворота, модельки машин), обрабатывает внешние запросы (в т.ч. сетевые) на запуск сценария. Каждый макет — индивидуальный проект под конкретного заказчика.

                                            В моем понимании «Коммерческий продукт» — это продукт, приносящий прибыль. Каждый макет — это продукт, за который платят достаточно что бы кормить небольшую фирму, которая их производит. Им важна скорость разработки (чем больше выполненных заказов, тем больше прибыль), а в этом ардуине нет равных.
                                              0
                                              Это фирма со всей очевидностью не занимается разработкой и производством электроники ни в каком виде. Она является потребителем готового изделия.

                                              Как только они захотят чего-то минимально большего и, например, придут с этим запросом к собственно разработчикам электроники, ардуина бодро пойдёт лесом.
                                                +1
                                                Я написал, что эта фирма занимается производством интерактивных архитектурных макетов. Вообще, как и любая коммерческая фирма, она занимается зарабатыванием денег, а не продвижением своей религии. Если производить универсальные блоки им покажется выгоднее, то она это сделает, а пока использует ардуино в своих вполне коммерческих проектах, не претендуя на инновации, не нанимая армию дорогих специалистов, не закупая дорогое ПО и аппаратуру. У них своя ниша и их это, видимо, устраивает.
                                                Напомню, что вопрос был про коммерческий продукт. И я поддерживаю ezh213b в его утверждении, что «Коммерческий продукт не всегда крупносерийный.». В приведенном примере продуктом, который фирма производит, является сам макет. Для его производства закупаются комплектующие, в составе которых Ардуина, которая используется как управляющий блок.
                                                  0
                                                  Типа чем Ардуина хуже, чем просто gps или wi-fi чип. Причём этот чип может содержать более сложную структуру и мощные мозги, чем центральный модуль.
                                  +1
                                  Тоже подумалось что професиионал скорее всего не возьмёт ардуионо для любого более-менее серьезного проекта.
                                    0
                                    Да вот берут (см. комментарий выше)
                                      +1
                                      У меня в лаборатории весьма успешно трудится. Контролирует процесс обработки органа перед засеванием стволовых клеток.
                                        +1
                                        Неужели, профессионально занимаетесь разработкой железок? Или всё же на хлеб зарабатываете другими навыками? ;)
                                          +2
                                          Хм. Уели. Но тем не менее, благодаря сниженному порогу вхождения, специалисты получили возможность использовать железо в профессиональных смежных областях.
                                            0
                                            А для питания ардуины можно взять батарею из картофелин.

                                            Вы бы всё же обозначили грань между профессиональным и студенческой поделкой. Верный признак второго — вы единственный носитель знаний о девайсе (и, как следствие, неремонтопригодность).

                                            А стоит ли опираться на студенческие поделки в проф. деятельности — большой воопрос.
                                              0
                                              Для небольших исследовательских групп это нормально. Естественно, подробная документация и все исходники доступны. Мои коллеги сами не смогут без меня, но любой технарь — без проблем.
                                                0
                                                Нет, батарея из картофелин — это не нормально для любых групп (кроме группы проекта исследования батарей из картофелин).

                                                На сколько я понял, у вас _макет_ трудится в _исследовательской_ деятельности. Но, это _макет_ — ему можно. Как только деятельность станет чуть масштабнее («профессиональнее») — начнёт жать. Профессиональность — она же не в buzzwords измеряется

                                                PS. Но за подробную документацию — лайк (хотя, если честно — не верю -_-)
                                                PPS. Не надо думать, что я Вас где-то дураком назвал
                                                  0
                                                  Я стараюсь все документировать. Знаю как тяжело чужую вещь исправлять. В науке нормально использование уникального единичного экземпляра. И иногда для одного эксперимента.
                                        0
                                        Тут еще вопрос, что вы называете ардуино. Официальные железки? Ардуино как прообраз ОС?
                                        Например, вот знаменитый ArduPilot — отточенный опенсорсный автопилот, под него сначала сделали свою железку, а позже портировали на PixHawk.
                                          0
                                          О да, профессионал обязательно пойдет в гараж, вытравит плату и будет пол года писать прошивку на ассемблере. Такие вот суровые профессионалы.
                                            +3
                                            Для макетирования пойдёт и wire-wrapped макетки, и девкиты. Да, и арудино тоже.
                                            Но неужели вы будете утверждать что делать продукт на девките это нормально?
                                            Прототипирование и разработка готового изделия — разные вещи.
                                          +2
                                          Пытался найти недавно примеры коммерческих Ардуино-продуктов, но как-то поиски не на что не навели…


                                          А смысл? Arduino — это фактически референсный дизайн атмеги, которая в применении проста настолько, что своя плата с нужным функционалом разводится за вечер студентом-третьекурсником. Результат будет значительно компактнее, надёжнее и дешевле.

                                          Ардуино в коммерческих разработках нужно использовать, если изделие — это какой-то конструктор, который покупатель сам собирать будет.
                                            +2
                                            Как только дело доходит до более-менее серьезной задачи, Arduino ни на что не годится. Хотя сам проц нормальный, библиотеки в проекте слишком уж универсальны, и иза-за этого очень неоптимальны для узких задач. Да и написаны абы как. С этим проектом работают в основном начинающие разработчики, и это сказывается на уровне кода, и от багов проект избавляется очень медленно.

                                            Но для старта он очень хорош. Начав освоение микропроцессоров с Ардуино, очень скоро я перешл в AVR studio и переписал нужные библиотеки под свой проект.
                                            +9
                                            Так вот, оказалось, что эта библиотека попросту профнепригодна. На ней в принципе невозможно построить нормальное сетевое взаимодействие. Можно только «баловаться» одиночными запросами и ответами.

                                            В принципе этим можно охарактеризовать Arduino в целом.
                                            • UFO just landed and posted this here
                                                0
                                                Конечно, и подробно описал в статье. Если кратко, то те запросы, которые игнорировались и просто отбрасывались стали обрабатываться, что кардинально (3 — 5 раз) уменьшило время загрузки файлов. Если бы я не разобрался в проблеме, то как бы я перекисал библиотеку и заставил всё работать как минимум в три раза быстрее?
                                                  0
                                                  Пардон, переписал, естественно.
                                                  • UFO just landed and posted this here
                                                      0
                                                      Я проверял закрытие сокетов и никаких проблем не нашёл, у меня складывается подозрение, что проблема глубже — в работе с буфером 2х8 килобайт в W5100. Было бы здорово, если кто-нибудь из действительно компетентных людей осветил этот вопрос.
                                                        0
                                                        Кстати, кто-нибудь может сказать почему именно 3 секунды? Не 2 и не 4, а именно 3. Или кратное этому значению 9 секунд? Здесь явно есть какой-то смысл и какая-то связь. Таймаутов я не обнаружил.
                                                        • UFO just landed and posted this here
                                                            0
                                                            Конечно пробовал. Ничего не меняется.
                                                          • UFO just landed and posted this here
                                                              0
                                                              Увеличивать нельзя. У W5100 аппаратное ограничение. А при уменьшении всё становится только хуже, что предсказуемо.
                                                              0
                                                              Похоже на дефолтовый таймаут tcp syn retry. Вообще, вам надо было начать с дампа траффика хотя бы тем же wireshark, а дальше уже разбираться, где именно не работает.
                                                                0
                                                                Да, мы эту проблему обсуждали на форуме АМС с дампами и графиками и пришли к выводу, что запросы уходят в ретрансмиссию на 3 секунды, затем на 6. Но всё равно, на мой взгляд, библиотека работает не на 100% корректно и там есть, что исправлять.

                                                                Сейчас мы вышли на минимально приемлемую задержку загрузки страницы в 4 секунды, но желательно всё-таки разобраться с этой проблемой до конца.
                                                        +1
                                                        > рассуждения на счет комментария и XXX

                                                        Осторожно, здесь какая-то порнография:
                                                        +3
                                                        Мне прислали ссылку forum.arduino.cc/index.php?topic=154157.0, оказывается не только я пытаюсь решить эту проблему. (Обсуждение на итальянском)

                                                        Ещё высказано предположение, что 3 секунды связаны с TCP retransmission. Это попытка повторной отправки пакета через определенный таймаут. 3 сек — это Default Retransmission Timeout в Windows msdn.microsoft.com/en-us/library/aa922362.aspx?f=255&MSPPError=-2147217396
                                                          0
                                                          У вас отлично получается, может посмотрите чип W5500?
                                                          Вот тут я про него писал полтора года назад. С тех пор шилдов на нем появилось изрядно.
                                                          geektimes.ru/post/255132
                                                            0
                                                            Скоро выйдет «отвязанная» версия в которой все принципиальные проблемы решены и типичное время загрузки страниц составляет 4 секунды, что вполне приемлемо. Но есть мелкие моменты с задержками и сокетами.

                                                            Я смотрю вы разбираетесь в теме — было бы неплохо если бы вы помогли разобраться. Скачав дистрибутив к себе или «теоретически» обсудив проблему на форуме АМС.
                                                              0
                                                              Коллеги к счастью уже давно сделали и сдали железку. Там было все на штатной библиотеке wiz-io на одном фиксированном сокете, а не на пуле сокетов. Задержки были минимальные просто по той причине, что TCP HTTP быстро открывалось и быстро закрывалось. Долгоживущие HTTP сокеты не поддерживались, даже на просьбу Connection: keep-alive. Параллельные соединения от броузера (например IMG SRC) теоретически могли бы мешать, но чип как-то корректно информировал клиента, что сокет уже занят (подробности не смотрел) и запросы приходили последовательно, но в хаотичном порядке, особенно при работе через proxy. Это что помню.
                                                            0
                                                            Вот именно поэтому я как правило пишу библиотеки сам на основе известных и популярных. Не люблю котов в мешках. Иногда их приходится практически переписывать заново. Сейчас пишу для Amazon S3. Стандартный SDK вполне рабочий, только во-первых там ноги переломаешь на коде, а во вторых столько абстракций просто не нужно. Все хорошо в меру. В итоге все необходимые функции для работы с файлами уместились в один файл. Один! Времени занимает много, соглашусь, я до сих пор ее пишу согласно нужным задачам, однако я более чем уверен, что она будет работать так, как мне надо, без подводных камней и каких-то сюрпризов, имеющих обыкновение появляться прямо на дедлайне. Ну и наконец это просто интересно и полезно для практики.
                                                              0
                                                              Поясните, пожалуйста, это место: «Цикл перебирает сокеты и, как только находит подходящий, возвращает клиента, а остальных просто игнорирует. И они висят по десять секунд, пока «карты благоприятно не лягут».» Что за проблема была в ходе перебора? В ходе перебора сокеты не закрывались должным образом?
                                                                0
                                                                Насколько я понял, когда перебор находил первый пригодный сокет, то прерывал цикл и остальные игнорировал. Там по цепочке ещё функция accept. Алгоритм «уходил» на обслуживание микроконтроллерных функций и когда «приходил» опять к этому циклу, опять выхватывал один сокет и опять «убегал», а те запросы, которые он не «выхватил» уходили в ретрансмиссию.

                                                                Большую часть проблемы я решил, но там еще далеко не всё в порядке.
                                                                0
                                                                Вопрос может немного не в тему, но все же спрошу:
                                                                Скажите пожалуйста, в чем вы собираете Ардуиновский проект, например свой MegaServer? В какой среде?
                                                                Мне пришлось из-за одного проекта внести в эту же библиотеку изменения касающиеся кол-ва сокетов и объема буфера у них, но в других проектах нужна стандартная версия. Я не знаю как передать компилятору дополнительный параметр, который бы определял какой вариант библиотеки собирать. Пробовал стандартную Ардуиновскую IDE и Code::Block.
                                                                  +1
                                                                  Собираю в стандартной Arduino IDE. Я тоже столкнулся с проблемой подключения разных библиотек к разным проектам. И решил её при помощи новой концепции директорий проекта. В частности, 0.13 версия AMS для Arduino Due поставляется с новой схемой директорий проекта. Подробнее об этом можно почитать на форуме проекта, а со структурой папок можно ознакомиться, скачав 0.13 версию AMS для Due.
                                                                    0
                                                                    Чтож, спасибо, попробую. Хотя я в тайне надеялся, что вам удалось раскопать тайны IDE, которые позволили бы поступать примерно так:
                                                                    1. определить в коде специальный литерал, например TX_RX_MAX_BUF_SIZE_4096
                                                                    2. в библиотечных файлах прописать соответствующие изменения в конструкцию типа:
                                                                    #if defined(TX_RX_MAX_BUF_SIZE_4096) // если определен литерал TX_RX_MAX_BUF_SIZE_4096
                                                                    #define TX_RX_MAX_BUF_SIZE 4096
                                                                    #else
                                                                    #define TX_RX_MAX_BUF_SIZE 2048
                                                                    #endif
                                                                    А компилятору передать дополнительный параметр -DTX_RX_MAX_BUF_SIZE_4096.

                                                                Only users with full accounts can post comments. Log in, please.