Помогите подружить ардуино с php
- Войдите на сайт для отправки комментариев
Пнд, 12/06/2017 - 20:24
В общем хочу попробовать управлять светодиодом через php передавая данные на компорт. Если открыть монитор порта в arduino ide тоВозникают следующие ошибки:
Warning: fopen(COM3) [function.fopen]: failed to open stream: Permission denied in C:\OpenServer\domains\server\index.php on line 10
Warning: fwrite(): supplied argument is not a valid stream resource in C:\OpenServer\domains\server\index.php on line 11
Warning: fclose(): supplied argument is not a valid stream resource in C:\OpenServer\domains\server\index.php on line 12
А если монитор порта закрыт то ничего не происходит. Вот собственно код
arduino
int ledPin1 = 7;
int ledPin2 = 8;
char tmp;
void setup() {
Serial.begin(9600);
pinMode(ledPin2, OUTPUT);
}
void loop() {
if (Serial.available() > 0) {
tmp = Serial.read();
if (tmp == 1) {
digitalWrite(ledPin2, HIGH);
}
else {
digitalWrite(ledPin2, LOW);
}
}
}
php
<html>
<head>
<meta charset="utf-8">
<title>Сервер Arduino</title>
</head>
<body>
<?
if(isset($_POST['tmp'])){
$f = fopen("COM3","w");
fwrite($f,chr(49));
fclose($f);
}
if(isset($_POST['btn2'])){
$f = fopen("COM3","w");
fwrite($f,chr(50));
fclose($f);
}
?>
<form action="" method="post">
<input type="submit" name="tmp" value="ВКЛЮЧИТЬ"/>
<input type="submit" name="btn2" value="ВЫКЛЮЧИТЬ"/>
</form>
</body>
</html>
Вы посылаете в порт символы 49 и 50, а проверяете получение
if(tmp == 1), это выглядит странно, ведь переменная объявлена какchartmp.Если последовательный порт открыт монитором, то он занят для прочих процессов, поэтому получаете Permission denied. Кто первый порт открыл, тот и хозяин его )))
С монитором порта понятно.
Заменил символы 49 и 50 на 1 и 2, что соответствует написанному в скетче арды. Ничего не изменилось..
Посылаем в сериал единичку.
Если char tmp - сравниваем с '1', если int tmp - сравниваем с 1.
Вот здесь http://pashkevich.me/article/6.html вроде бы неплохо разжёвано.
Ничего не изменилось, к сожалению, на долю секунды загорается индикатор tx на плате и все.
Выложите-ка ещё разок актуальные коды для Arduino и PHP.
Дорогой автор,
Если у тебя получится , - прошу мне сообщить.
Я когда то пытался работать с ком-портом через пхп - у меня не получилось.
dmitron1036, всё работает, светодиод RX радостно моргает раз в секунду.
<?php $f = fopen("COM3","w"); while(1) { fwrite($f, chr(50)); sleep(1); } // fclose($f);Зачем пыхой писать в файл???
GETом не проще?
<html> <head> <meta charset="utf-8"> <title>Сервер Arduino</title> </head> <body> <?php if(isset($_GET['tmp'])){ echo trim($_GET['tmp']); } ?> <form action="" method="get"> <input type="submit" name="tmp" value="1" /> <input type="submit" name="tmp" value="2" /> </form> </body> </html>Раз у вас все работает, подскажите мне что не так?
int ledPin1 = 7; int ledPin2 = 8; int tmp; void setup() { Serial.begin(9600); pinMode(ledPin2, OUTPUT); } void loop() { if (Serial.available()) { tmp = Serial.read(); if (tmp == 'h') { digitalWrite(ledPin2, HIGH); } if (tmp == 'g') { digitalWrite(ledPin2, LOW); } } }<html> <head> <meta charset="utf-8"> <title>Сервер Arduino</title> </head> <body> <? if(isset($_POST['tmp'])){ $f = fopen("COM3","w"); fwrite($f,chr(`1`)); fclose($f); } if(isset($_POST['btn2'])){ $f = fopen("COM3","w"); fwrite($f,chr(`2`)); fclose($f); } ?> <form action="" method="post"> <input type="submit" name="tmp" value="ВКЛЮЧИТЬ"/> <input type="submit" name="btn2" value="ВЫКЛЮЧИТЬ"/> </form> </body> </html>if(isset($_POST['tmp'])){ // Если пришел пост и это именно tmp то есть нажата ваша кнопка "ВКЛЮЧИТЬ" $f = fopen("COM3","w"); // Открываем файл с именем "COM3" в режиме "w" // Файл "COM3" находится в той же директории с файле с этим исполняемым кодом // Режим "w" = открывает файл только для записи; помещает указатель в начало файла и обрезает файл до нулевой длинны. Если файл не существует - пробует его создать. // То есть режим "w" открывает файл, если его нет создает (если есть права в каталоге для создания файлов скриптами) если файл уже был то скрипт его полностью очищает и записывает вашу строку, если файла не было то создает пустой и записывает вашу строку. fwrite($f,chr("1")); // Пишем в файл "1" fclose($f); // Закрываем файл, то есть завершаем работу с ним, если не закрывать файл то он будет постоянно висеть открытым и занимать память... }Ничегоо не изменилооось.
Внесу дополнение, с монитора порта ардуино IDE отправляя 1, светодиод загорается...а если через php в баузере то нет
Что должно измениться?
Каким образом ардуина понимет что нужно включать светодиод?
Читает из файла значение или как?
Sanyaba, COM3 в данном случае это не файл, а COM-порт. Т.е. PHP открывает COM-порт COM3 и пишет в него, т.е. отправляет данные.
Так и должно быть, но этого не происходит...не понятно почемуууу
м.б. проблема в том что я на windows?
Sanyaba, COM3 в данном случае это не файл, а COM-порт. Т.е. PHP открывает COM-порт COM3 и пишет в него, т.е. отправляет данные.
Жесть, так как же все таки ардуина понимает что нужно открыть порт, наличием файла или его содержимым?
Он же с PHP создает файл с именем COM3...
м.б. проблема в том что я на windows?
COM-порты как раз на Windows. На Linux они по-другому обозначаются - /dev/ttyS0, /dev/ttyUSB0
Sanyaba, COM3 в данном случае это не файл, а COM-порт. Т.е. PHP открывает COM-порт COM3 и пишет в него, т.е. отправляет данные.
Жесть, так как же все таки ардуина понимает что нужно открыть порт, наличием файла или его содержимым?
Он же с PHP создает файл с именем COM3...
Ардуина слушает порт и ждет когда в него придет что то.
int ledPin1 = 7; int ledPin2 = 8; int tmp; void setup() { Serial.begin(9600); pinMode(ledPin2, OUTPUT); } void loop() { if (Serial.available()) { tmp = Serial.read(); if (tmp == '1') { digitalWrite(ledPin1, HIGH); } if (tmp == '2') { digitalWrite(ledPin1,LOW); } } }Проблема в том что php ниичего в этот com3 не отправляет
Он же с PHP создает файл с именем COM3...
Я не гуру PHP-программирования, но везде пишут что fopen("COM3","w") должно открывать именно COM-порт, а не файл.
Он же с PHP создает файл с именем COM3...
Я не гуру PHP-программирования, но везде пишут что fopen("COM3","w") должно открывать именно COM-порт, а не файл.
http://php.net/manual/ru/function.fopen.php
Проблема в том что php ниичего в этот com3 не отправляет
смешно и немноооожко обидно)
Не, действительно не работает, я скопипастил повторил, светодиод на ардуине моргает и сразу же выключается при обращениях из php, что с браузера, что с консоли.
Ну тады - https://github.com/Xowap/PHP-Serial
Пример - http://www.instructables.com/id/Control-Arduino-using-PHP/
sava4aev,
А может надо сначала на винде параметры порта выставить? - в вашем скрипте этого не вижу. Это как-то так (взято из первого попавшегося php-скрипта в гугле)
exec("mode COM3: BAUD=9600 PARITY=n DATA=8 STOP=1 to=off dtr=off rts=off");Этот класс нужно закинуть в папку с index.php или куда ?
я не знаю, я в php ни черта не смыслю :) Просто Вы писали, что видели в гугле куча примеров с открытием ком-порта в php, я решил глянуть эти примеры - и почти в каждом есть эта строчка.
Вот, например
https://stackoverflow.com/questions/5920600/open-com-port-in-php
В принципе, логично, что прежде чем что-то посылать в порт, у него надо хотя бы скорость выставить.
Желаю sava4aev победить PHP и уточняю по скетчу :
// Если int tmp; // то if (tmp == 1) { // и if (tmp == 2) { // А если char tmp; // то if (tmp == '1') { // и if (tmp == '2') { // Оба варианта равнозначны и имеют место быть ))http://php.net/manual/ru/function.fopen.php
Всё так, но есть нюанс. В Windows есть зарезервированные имена, которыми нельзя называть файлы. По этой же ссылке приводят цитату с MSDN: "Do not use the following reserved device names for the name of a file: CON, PRN, AUX, NUL, COM1, COM2, COM3, COM4, COM5, COM6, COM7, COM8, COM9, LPT1, LPT2, LPT3, LPT4, LPT5, LPT6, LPT7, LPT8, and LPT9." Предполагаю, что при попытке писать в файл с таким именем (например COM1), на самом деле запись будет осуществляться в COM-порт. Походу это реализовано на уровне ОС.
Сейчас вспомнил, что делал подобное на LUA:
os.execute("mode COM3:9600,n,8,1") wserial=io.open("COM3","w") // this opens the COM wserial:write("Test") // fills the serial buffer wserial:flush() // send the serial buffer wserial:close("COM3") // this closes the COMИ это работало. Хотя по документации это работа с файлами (как и в случае с PHP) - https://www.lua.org/pil/21.2.html , http://www.lua.ru/doc/5.7.html
Вот на Stackoverflow предлагают такой вариант для PHP:
exec("mode COM3 BAUD=9600 PARITY=N data=8 stop=1 xon=off"); $fp = fopen ("COM3", "w"); if (!$fp) { echo "Not open"; } else { echo "Open"; }Ещё ссыль - http://radiovibrations.com/php/com-port-access.php
http://php.net/manual/ru/function.fopen.php
Всё так, но есть нюанс. В Windows есть зарезервированные имена, которыми нельзя называть файлы. По этой же ссылке приводят цитату с MSDN: "Do not use the following reserved device names for the name of a file: CON, PRN, AUX, NUL, COM1, COM2, COM3, COM4, COM5, COM6, COM7, COM8, COM9, LPT1, LPT2, LPT3, LPT4, LPT5, LPT6, LPT7, LPT8, and LPT9." Предполагаю, что при попытке писать в файл с таким именем (например COM1), на самом деле запись будет осуществляться в COM-порт. Походу это реализовано на уровне ОС.
Сейчас вспомнил, что делал подобное на LUA:
os.execute("mode COM3:9600,n,8,1") wserial=io.open("COM3","w") // this opens the COM wserial:write("Test") // fills the serial buffer wserial:flush() // send the serial buffer wserial:close("COM3") // this closes the COMИ это работало. Хотя по документации это работа с файлами (как и в случае с PHP) - https://www.lua.org/pil/21.2.html , http://www.lua.ru/doc/5.7.html
Вот на Stackoverflow предлагают такой вариант для PHP:
exec("mode COM3 BAUD=9600 PARITY=N data=8 stop=1 xon=off"); $fp = fopen ("COM3", "w"); if (!$fp) { echo "Not open"; } else { echo "Open"; }Ещё ссыль - http://radiovibrations.com/php/com-port-access.php
Так я уже делал. Порт открывается.
Всем снова привет!)
В конечном итоге решить свой вопрос мне так и не удалось. Пошел другим путем. На C# написал программку, которая (на данный момент) умеет управлять светодиодами и принимает данные от датчика влаажности и температуры DTH11. Проект планирую развивать на сколько хватит интузиазма.
Всем спасибо за помощь! Кому интересно могу скинуть исходники на C# и собственно скетч Arduino.
Привет! Можешь скинуть исходники если остались ?
<?php header("HTTP/1.1 200 OK"); header("Content-Type:text/html; charset=UTF-8"); header("Access-Control-Allow-Origin:*"); //Команда MODE для последовательного порта COM: //https://ab57.ru/cmdlist/mode.html $port="com7";//номер com порта $baud=115200;//скорость передачи для последовательного порта $bits=8;//биты данных $stop=1;//стоп биты exec("mode ".$port.": baud=".$baud."data=".$bits." stop=".$stop." " ); //Отправка данных в порт function Write($Status){ global $port; $fp = fopen($port, "w+"); fwrite($fp, $Status); //$contents = fread($fp, filesize($port)); //echo $contents; fclose($fp); } if (isset($_GET['action'])) { $switch1 = $_GET['action']; switch ($switch1) { case "on": Write(chr(97)); //echo "ON"; break; case "off": Write(chr(98)); //echo "OFF"; break; }//switch }//if (isset($_GET['action'])) { ?>Скрипт передаёт данные в порт. Как получить ответ от порта?
fread() же написали вон...
Не работает, ругается на эту строку
А... Тут вот пишут, что у php под виндой вообще много проблем с серийными портами: https://forum.arduino.cc/index.php?topic=138335.0
Ага, проблем нет только на отправку.
нашла другую статью
https://lesson.iarduino.ru/page/upravlyaem-arduino-iz-php-cherez-com-port/
разбираюсь
Какой-то троллейбус из булки хлеба.
Цель-то какая преследуется этими манипуляциями?
Под относительно новой виндой имеется нативный PowerShell - достаточно гибкая штука. Практически Сишарп, но скриптовый.
Общаться с ардуино из браузера без использования интернет модуля
Без посредника - наврядли. Браузеры давно строят так, чтобы пользователь не смог выпрыгнуть в пользовательскую систему. Даже файлы с диска не особо почитаешь.
В 36 посте ссылка, там как раз таки организована передаче и приём через exe файл приложения. Работает.
Общаться с ардуино из браузера без использования интернет модуля
Вам именно PHP нужно? Хром может работать с COM-портом. Но опять же не понятно почему именно браузер? Если у вас Ардуино подключена непосредственно к этому компьютеру, почему не использовать просто программу на Сях/Бэйсиках/Паскалях?
Общаться с ардуино из браузера без использования интернет модуля
Вам именно PHP нужно? Хром может работать с COM-портом. Но опять же не понятно почему именно браузер? Если у вас Ардуино подключена непосредственно к этому компьютеру, почему не использовать просто программу на Сях/Бэйсиках/Паскалях?
С php html и css знакома, умею работать, легко создать графическую оболочку, так сказать.
Можно взять проект HTML сервера MiniWeb https://github.com/avih/miniweb (если нужно доработать для работы с СОМ портом, если встроенная-штаттная функциональность работы с СОМ портом не подойдёт)
и "общаться" с ним, например, на JavaScript. :)
Не думали о таком решении?
Меня устраивает обращение к exe файлу, всё прекрасно работает
Поясните что значит 2>&1 в конце настроек порта
Статья по ссылке
https://lesson.iarduino.ru/page/upravlyaem-arduino-iz-php-cherez-com-port/
https://qna.habr.com/q/391038
Не стоит опускаться до уровня "в гугле забаненных". Ранее за тобой такого не замечалось.
Что это такое я прочитала
2>&1- перенаправление stderr в stdout (который пойдет в /dev/null)Но для чего не поняла, поэтому попросила пояснить, надо ли (без нее работает)
stdout - это куда echo пишет, к примеру, "стандартное устройство вывода". Для исполняемых файлов это может быть консоль. В cmd наберите dir - получите вывод данных в stdout.
sderr - канал вывода сообщений об ошибках. /dev/null - устройство типа "нигде". Не хотите вывод команды dir видеть - отправляете его в null.
Спасибо
Подскажите люди знающие:
exec("программа.exe 2>&1",$param);
Отправляю запрос-получаю ответ от ардуино.
Но стоит ардуино отключить, получаю зависание php страницы или долгий ответ что порт занят или недоступен, так как программа.exe продолжает ждать ответа от ардуино.
Мне нужно убить процесс программа.exe который я запускаю через exec