Обработка данных через COM порт

Тема в разделе "Arduino & Shields", создана пользователем OmanDebian, 25 окт 2015.

  1. OmanDebian

    OmanDebian Нуб

    Здравствуйте! За ранее извернуться если создал тему не в том разделе. Начал изучать Arduono, столкнулся с проблемой: Я отпровляю значение через php на com порт:

    $fp =fopen("/dev/ttyACM0", "w");
    fwrite($fp, chr(1));
    close($fp);


    Все делаю на linux ubuntu, php работает под apache2.
    С начало была проблема с правами но этот я вопрос легко решил sudo chmod 777 /dev/ttyACM0.


    Serial на ардуино работает и через монитор я вижу что он принимает значение 1.
    Все работает все прекрасно но... Сейчас приведу код на ардуино


    int incomingByte = 0;
    void setup() {
    Serial.begin(9600);
    pinMode(12, OUTPUT);
    }

    void loop() {
    if (Serial.available() > 0)
    {
    incomingByte = Serial.read();
    Serial.print("I received: ");
    Serial.println(incomingByte, DEC);
    if(incomingByte == 2)
    {
    digitalWrite(12, HIGH);
    }
    if(incomingByte == 1)
    {
    digitalWrite(12, LOW);
    }
    }
    }



    На 12 пин у меня подключен светодиод. Когда запущен монитор порта arduino IDE все работает отлично я на php отсылаю 1 диод гаснет отсылаю 2 диод загорается. Но когда выключаю монитор порта arduino IDE ничего не происходит. С чем связно это добрые люди подскажите. Можно ли отпровлять на ардуино данные без запущенного монитора порта на arduino IDE?
     
  2. Mestniy

    Mestniy Гуру

    Ппрограмму напишите ввода в com-порт значений!!!!
     
  3. Mestniy

    Mestniy Гуру

    Ну вы же ничего не отправляете, вот у Вас ничего и не происходит!:confused:
     
  4. Megakoteyka

    Megakoteyka Оракул Модератор

    Попробуйте поднять сигнал DTR, он на ресет контроллера заведен.
     
  5. OmanDebian

    OmanDebian Нуб

    Добрый человек))
    $fp =fopen("/dev/ttyACM0", "w");
    fwrite($fp, chr(1));
    close($fp);
    это и есть отправка значения в ком порт))
    ок, как пример могу на прямую через терминал Linux отправить
    echo 1>/dev/ttyACM0
    тем самым отправлю 1 на com0, но это не решает проблему. А проблема в том что arduino (железка) не хочет работать самостоятельно без монитора порта в arduino IDE
     
  6. OmanDebian

    OmanDebian Нуб

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

    Megakoteyka Оракул Модератор

    У контроллера есть нога сброса - ресет. Когда на ней низкий уровень, контроль сброшен и не работает. Сигнал DTR из COM-порта заведен на эту ногу, чтобы с компа перезагружать контроллер при прошивке. Из пхп попробуйте установить DTR в высокий уровень, чтобы контроллер не находился в состоянии сброса.
     
    OmanDebian нравится это.
  8. AlexU

    AlexU Гуру

    Могу ошибаться, но исходя из ситуации -- при активном мониторе работает, а без него не реботает -- можно предположить, что PHP как-то криво настраивает порт, если вообще настраивает (при активном мониторе -- монитор конфигурирует порт /dev/ttyACM0).
    Попробуйте явно указать параметры порта:
    PHP:
    $device = "/dev/ttyACM0";
    // настройка порта -- задаем скорость 9600
    exec('stty -F '.$device.' 9600');
    $fp = fopen($device, "w");
     
     
  9. geher

    geher Гуру

    Ардуина какая??
    Если уно, то возможно такое объяснение поведения.
    Уна при подключении по последовательному порту через USB перезагружается. Это не ошибка. Так было задумано авторами.
    Когда открыт монитор порта, то он "держит" соединение. Соответственно, в момент подключения монитора ардуина рестартует и дальше работает нормально.
    Если же монитор порта закрыт, то когда выполняются короткие сеансы из открытия, записи и закрытия, то при каждом открытии (установление соединения) ардуина рестартует.
    На рестарт требуется некоторое время. Вполне возможно, что запись в порт осуществляется до завершения рестарта ардуины, т.е. до того, как она сможет что-то из порта прочитать (до выполнения Serial.begin).
    Можно попробовать вставить между открытием порта и записью какую-либо задержку на пару секунд. В теории, если предположение о причинах описанного ТС поведения ардуины верно, ардуина должна будет корректно отработать прием данных и реакцию на него, но каждая такая посылка из-за рестарта в момент подключения будет обрабатываться как первый раз, без учета предыдущих воздействий.

    Возможные решения:
    1. Использовать Softwareserial и преобразователь USB-Serial TTL. Такой дополнительный последовательный порт не будет вызывать рестартов по поводу и без повода.
    2. Физически заблокировать рестарт. Если не путаю, ресет нужно соединить конденсатором на 10 мкф с землей. Для перепрошивки, естественно, кодденсатор придется снимать.
    3. Держать постоянно открытым соединение для последовательного порта.
     
    OmanDebian нравится это.
  10. OmanDebian

    OmanDebian Нуб

    Ага, въехал я что он ребутиться). Когда ардуино работает диод горит как только отправляю данные сразу же перестает гореть и потом опять загорается.
    geher большое тебе спасибо! за подробное описание, но решения которые ты написал 1-й вариант не могу использовать просто нет USB-Serial TTL (потом как нибудь попробую). 2-й вариант по любому накосячу с электрикой у меня пока провалы в знаниях. 3-й держать открытым порт через php не выйдет, сильно геморойно). И да, кстати geher у меня arduino uno + набор всякой всячены (набор Тони Старка ыыыы)

    Megakoteyka хочу копнуть в твою мысль, я как понимаю ты предлагаешь отключить ребут платы без кардинального подхода. Но повысить DTR из php нельзя это не системный язык программирования, или может я что то не понимаю. А нельзя просто какой нибудь перемычкой запретить ребубиться плате? На плате есть 9 пеньков которые можно закоротить перемычкой, там ничего такого нет?)))
     
  11. geher

    geher Гуру

    Так там всего электрики - вставить конденсатор одной ногой (+, если конденсатор электролитический) в пин, помеченный на ардуине как RESET, и другой в GND.

    В теории конденсатор, установленный вышеописанным образом, и является такой "перемычкой".
    А девять "пеньков" где?
    Шесть "пеньков" может быть у короткой стороны, противоположной той, на которой разъемы USB и питания - это разъем ICSP, через который можно шить бутлоадер.
    Еще шесть "пеньков" может быть возле пина AREF (вдоль длинной стороны, на которой цифровые пины). Это ICSP разъем встроенного в ардуину преобразователя USB-Serial.
    И это добро лучше не закорачивать.
     
  12. OmanDebian

    OmanDebian Нуб

    ВСЕ ПОЛУЧИЛОСЬ!
    geher прости ошибся 12 пеньков. Щас опишу все от а до я как все делал, мало ли кому понадобиться
     
  13. OmanDebian

    OmanDebian Нуб

    Итак пишу все под linux ubuntu
    Для php устанавливаем модуль dio он нужен для работы с сериал портами на php
    sudo apt-get install php5-dev
    sudo pecl install dio-0.0.7
    Далее в /etc/php5/apache2/php.ini пишем
    extension=dio.so
    поле подключение dio.so нужно ребутнуть apache
    sudo service apache2 restart
    Настройка php готова!
    Далее подготавливал платку arduino uno
    Подключил как и сказал geher "пин reset конденсатором на 10 мкф к землей" НОООО! Ребят не к земле а к 5v пину для того что бы на пине reset не падало напряжение как писал Megakoteyka
    [​IMG]

    Ну и далее сам код на php
    PHP:

    $fd = dio_open('/dev/ttyACM0', O_RDWR | O_NOCTTY | O_NONBLOCK);
       dio_write($fd, chr(2));
       dio_close($fd);
     
    и для arduino
    Код (C++):

    void setup() {
     
           Serial.begin(9600);
           pinMode(12, OUTPUT);
    }

    void loop() {
      if (Serial.available() > 0) {
        Serial.print("I received: ");
     
        int inChar =  Serial.read();
        Serial.print(inChar);
     
        Serial.println();
     
        if(inChar == 2)
        {
          digitalWrite(12, HIGH);
        }
     
        if(inChar == 1)
        {
          digitalWrite(12, LOW);
        }
     
      }
    }
    Всех благодарю за участие!
     
  14. Megakoteyka

    Megakoteyka Оракул Модератор

    А программно не получилось ресет поднять? Или не пробовали?
     
  15. OmanDebian

    OmanDebian Нуб

    на самом arduino не получилось, все что я нашел так это watchdog но и там не все идеально в общем данная библеотека wdt.h работает со счетчиком перезагрузки, но, с помощью ее фукнций можно только играть с таймером отсрочки резета. Т.е. она мне не подошла. Еще вариан был перепрошивка но на кой она нужна))). А вот из под самого линкса держать сериал порт открытым можно с помошью утилиты screen или cu, но для php это не подходит т.к. он выполняет единожды по запрсу юзера, он не может висеть в процессах, даже если сделать ожидание то apache убъет php через 30 сек (в зависимости от настройки), т.к. подумает что php срипт завис. По этому для меня идельным вариантом было искать решение при котором открывалось бы соединение php бегом все выполнил и закрыл соединение.
     
  16. geher

    geher Гуру

    1. Я пробовал конденсатор между землей и ресетом.
    И оно работает. В смысле с конденсатором между ресетом и землей не рестартует при подключении к последовательному порту и не дает прошивать.
    В теорию функционирования такой схемы не вникал, но, насколько я понимаю, это просто не позволяет отразиться на состоянии пина Reset быстрым изменениям. Главное, что оно работает (и описано в сети именно в таком виде).
    Возможно, конденсатор между ресет и +5 работает схожим образом.
    2. В приведенной схеме между ресетом и +5 не конденсатор, а резистор 120 Ом. Когнитивный диссонанс при сопоставлении текста и картинки.
     
  17. OmanDebian

    OmanDebian Нуб

    А я ведь говорил что я не шарю в электронике), правельно говоришь главное все работает)) У меня на землю не работает