Здравствуйте! За ранее извернуться если создал тему не в том разделе. Начал изучать 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?
Добрый человек)) $fp =fopen("/dev/ttyACM0", "w"); fwrite($fp, chr(1)); close($fp); это и есть отправка значения в ком порт)) ок, как пример могу на прямую через терминал Linux отправить echo 1>/dev/ttyACM0 тем самым отправлю 1 на com0, но это не решает проблему. А проблема в том что arduino (железка) не хочет работать самостоятельно без монитора порта в arduino IDE
Попробую, сначало только разберусть о чем ты говоришь, у меня ардуино 7 день), пойду гуглить о каком резете ты говоришь
У контроллера есть нога сброса - ресет. Когда на ней низкий уровень, контроль сброшен и не работает. Сигнал DTR из COM-порта заведен на эту ногу, чтобы с компа перезагружать контроллер при прошивке. Из пхп попробуйте установить DTR в высокий уровень, чтобы контроллер не находился в состоянии сброса.
Могу ошибаться, но исходя из ситуации -- при активном мониторе работает, а без него не реботает -- можно предположить, что PHP как-то криво настраивает порт, если вообще настраивает (при активном мониторе -- монитор конфигурирует порт /dev/ttyACM0). Попробуйте явно указать параметры порта: PHP: $device = "/dev/ttyACM0"; // настройка порта -- задаем скорость 9600 exec('stty -F '.$device.' 9600'); $fp = fopen($device, "w");
Ардуина какая?? Если уно, то возможно такое объяснение поведения. Уна при подключении по последовательному порту через USB перезагружается. Это не ошибка. Так было задумано авторами. Когда открыт монитор порта, то он "держит" соединение. Соответственно, в момент подключения монитора ардуина рестартует и дальше работает нормально. Если же монитор порта закрыт, то когда выполняются короткие сеансы из открытия, записи и закрытия, то при каждом открытии (установление соединения) ардуина рестартует. На рестарт требуется некоторое время. Вполне возможно, что запись в порт осуществляется до завершения рестарта ардуины, т.е. до того, как она сможет что-то из порта прочитать (до выполнения Serial.begin). Можно попробовать вставить между открытием порта и записью какую-либо задержку на пару секунд. В теории, если предположение о причинах описанного ТС поведения ардуины верно, ардуина должна будет корректно отработать прием данных и реакцию на него, но каждая такая посылка из-за рестарта в момент подключения будет обрабатываться как первый раз, без учета предыдущих воздействий. Возможные решения: 1. Использовать Softwareserial и преобразователь USB-Serial TTL. Такой дополнительный последовательный порт не будет вызывать рестартов по поводу и без повода. 2. Физически заблокировать рестарт. Если не путаю, ресет нужно соединить конденсатором на 10 мкф с землей. Для перепрошивки, естественно, кодденсатор придется снимать. 3. Держать постоянно открытым соединение для последовательного порта.
Ага, въехал я что он ребутиться). Когда ардуино работает диод горит как только отправляю данные сразу же перестает гореть и потом опять загорается. geher большое тебе спасибо! за подробное описание, но решения которые ты написал 1-й вариант не могу использовать просто нет USB-Serial TTL (потом как нибудь попробую). 2-й вариант по любому накосячу с электрикой у меня пока провалы в знаниях. 3-й держать открытым порт через php не выйдет, сильно геморойно). И да, кстати geher у меня arduino uno + набор всякой всячены (набор Тони Старка ыыыы) Megakoteyka хочу копнуть в твою мысль, я как понимаю ты предлагаешь отключить ребут платы без кардинального подхода. Но повысить DTR из php нельзя это не системный язык программирования, или может я что то не понимаю. А нельзя просто какой нибудь перемычкой запретить ребубиться плате? На плате есть 9 пеньков которые можно закоротить перемычкой, там ничего такого нет?)))
Так там всего электрики - вставить конденсатор одной ногой (+, если конденсатор электролитический) в пин, помеченный на ардуине как RESET, и другой в GND. В теории конденсатор, установленный вышеописанным образом, и является такой "перемычкой". А девять "пеньков" где? Шесть "пеньков" может быть у короткой стороны, противоположной той, на которой разъемы USB и питания - это разъем ICSP, через который можно шить бутлоадер. Еще шесть "пеньков" может быть возле пина AREF (вдоль длинной стороны, на которой цифровые пины). Это ICSP разъем встроенного в ардуину преобразователя USB-Serial. И это добро лучше не закорачивать.
ВСЕ ПОЛУЧИЛОСЬ! geher прости ошибся 12 пеньков. Щас опишу все от а до я как все делал, мало ли кому понадобиться
Итак пишу все под 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 Ну и далее сам код на 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); } } } Всех благодарю за участие!
на самом arduino не получилось, все что я нашел так это watchdog но и там не все идеально в общем данная библеотека wdt.h работает со счетчиком перезагрузки, но, с помощью ее фукнций можно только играть с таймером отсрочки резета. Т.е. она мне не подошла. Еще вариан был перепрошивка но на кой она нужна))). А вот из под самого линкса держать сериал порт открытым можно с помошью утилиты screen или cu, но для php это не подходит т.к. он выполняет единожды по запрсу юзера, он не может висеть в процессах, даже если сделать ожидание то apache убъет php через 30 сек (в зависимости от настройки), т.к. подумает что php срипт завис. По этому для меня идельным вариантом было искать решение при котором открывалось бы соединение php бегом все выполнил и закрыл соединение.
1. Я пробовал конденсатор между землей и ресетом. И оно работает. В смысле с конденсатором между ресетом и землей не рестартует при подключении к последовательному порту и не дает прошивать. В теорию функционирования такой схемы не вникал, но, насколько я понимаю, это просто не позволяет отразиться на состоянии пина Reset быстрым изменениям. Главное, что оно работает (и описано в сети именно в таком виде). Возможно, конденсатор между ресет и +5 работает схожим образом. 2. В приведенной схеме между ресетом и +5 не конденсатор, а резистор 120 Ом. Когнитивный диссонанс при сопоставлении текста и картинки.
А я ведь говорил что я не шарю в электронике), правельно говоришь главное все работает)) У меня на землю не работает