Arduino UNO + PHP интерфейс

niksen
Offline
Зарегистрирован: 18.01.2012

Пытаюсь  обратиться к Arduino UNO через php_serial.class на локальном сервере osx. 

Ardhuino подключено через USB, подключиться через терминал к /dev/tty.usbmodemfd131 и отправлять команды - получается. А вот через PHP интерфейс - нет. Просто висит страничка.

Возможно причина в настройках моего apache, нужно дать пользователю доступ к serial портам? Кто сталкивался с похожим или знает как решить - пожалуйста, подскажите.

.c8r
.c8r аватар
Offline
Зарегистрирован: 15.11.2011

Я делал так:

php:

if (isset($_GET['param'])) {
$fp = fopen("com7", "w");
fwrite($fp, chr(1));
fclose($fp);
}

 

А в arduino слушл Serial порт

for(;;){

 if (Serial.available()){
   var p = Serial.read();
 }

}

 

 P/s апач у меня на винде

niksen
Offline
Зарегистрирован: 18.01.2012

 На osx все заработало - запустилось. Но поменялась задача - нужно запустить РНР скрипт на винде, который бы управлял Ардуино подключенной к этому же компьютеру. Тут мне ваш опыт будет очень полезен, поделитесь пожалуйста подробнее. Какую программу-прослойку для общения РНР с портом использовали?

Уточняющая информация по моей системе:

Windos 7 64bit, Arduino UNO, XAMPP (Апач запущен)

Проблема: не получается управлять Arduino через РНР.

Использую  serial2socket
порт 8080 там по дефолту dl.dropbox.com/u/15881557/Screen%20shot%202012-01-23%20at%202.26.42%20PM.png — вот так выгляди окно serial2proxy

код php:

<?php
$fp = fsockopen(«127.0.0.1», 8080, $errno, $errstr, 30);
if (!$fp) {
echo "$errstr ($errno)
\n";
} else {
fwrite($fp, «1»);

fclose($fp);
}
?>

 

На ардуино слушают 1 или 0 в зависимости от этого зажигаю 13 лед - но проблема в том что через прокси команда один раз проходит, а на второй запрос пишет Refused connection from 127.0.0.1 как показано в скрине выше, подскажите пожалуйста в чем может быть проблема? Или какой прокси использовать?

.c8r
.c8r аватар
Offline
Зарегистрирован: 15.11.2011

Через сервер апач на винде - работает на "ура", но тмы пользуемся com-портом, если хотите работать через сокеты на прямую - это интересно, можно поробовать через С++. Пусть программка слушает сокет, если подключились - создаем поток и коннектимся к дуине, тут можно обойтись и без пхп. Только нужен ip и проброшенный порт до компа, на котором програмулина и ардуина.

Завтра посмотрю.

.c8r
.c8r аватар
Offline
Зарегистрирован: 15.11.2011

А по-поводу проблеммы сокетов в пхп: может, после первого обращения с сокетом он "открыт"/"используется", из-за этого пхп и ругается? Я б попробовал закрывать сокет после общения.

.c8r
.c8r аватар
Offline
Зарегистрирован: 15.11.2011

Оу, вчитался еще разок и понял проблемму.

Чтоб подружить ардуину с компом через com порт, под управлением php установите denwer: www.denwer.ru/dis/Base/latest

После установки у вас будет полноценный php(и не только)-сервер, к которому Вы можете обращаться из вне и контролировать com порты.

В деррикторию www кладете ваш php скрипт, обращаетесь к нему, а он управляет дуиной. Необходимый код я выкладывал ранее.

rial2001
Offline
Зарегистрирован: 25.11.2011

Господа, подскажите код кнопки PHP для 8080 - отправка 0 или 1 на конкретный пин.  

leshak
Offline
Зарегистрирован: 29.09.2011

 Такого "кода кнопки" - не существует. Как и кода кнопки "что-бы все работало круто".

Нужно:

  1. Делаете html страницу, содержающую форму и кнопку, отправляющую эту форму скрипту.
  2. Делаете php скрипт который принимает данные этой формы (естественно с помощью web-сервера, например аппач).
  3. Далее этот php скрипт открывает serial port и шлет в него команду включения пина.
  4. Потом пишите скетч, для ардуины, который принимает эту команду из serial и в ключает нужный пин.

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

rial2001
Offline
Зарегистрирован: 25.11.2011

веб-сервер вкл. апач и php есть, установлен. пробовал с COM - все работает

недавно приобрел ethernet-шилд и хотелось поэкспериментировать без подключения к ПК

меня интересует сам код php, скрипт, да и сам принцип обмена инф. внутри локальной сети

Заранее спасибо

.c8r
.c8r аватар
Offline
Зарегистрирован: 15.11.2011

192.168.1.1 - айпишник апача на лок. машине. Обращайтесь по нему к вашему скрипту. Чтоб передать простейший параметр используйте get запрос к серверу.

leshak
Offline
Зарегистрирован: 29.09.2011

rial2001 пишет:

недавно приобрел ethernet-шилд и хотелось поэкспериментировать без подключения к ПК

меня интересует сам код php, скрипт, да и сам принцип обмена инф. внутри локальной сети

Ну тут встает вопрос что вы понимаете под "без подключения к ПК", то что ПК вообще может не быть, или "не подключен через USB".

То есть как браузер клиента будет общаться с ардуиной. Есть два пути: 

  • Браузер шлет данные сразу ардуине (в этом случае php вам вообще не нужен).
  • Браузер шлет данные web-серверу (php-скрипту), то их принимает, и дает команды ардуине (через serial или ethernet).

В любом случае нужно будет решить две задачи 

  1. Отдать клиенту html-форму с кнопкой
  2. Принять и обработать submit это формы

А дальше могут быть "комбинации". Первую задачу php, вторую ардуино. Или обе ардуино. Или обе php.

Так же стоит уточнить "каких кровей" ваш ethernet.  На каком чипе? ""Wiznet W5100" или enc28j60?

 

rial2001
Offline
Зарегистрирован: 25.11.2011

 "без подключения к ПК" - в смысле не подключен через USB

меня интересует сам вэб-сервер, сейчас код под ардуино настроил, если вбить в строке браузера команду - ардуино понимает. а вот с php под сервер пока проблемка...

по крови визнет5100

вот старый код под ком, рабочий:

<html> 
<head> 
<title>
</title> 
<meta name="viewport" content="width=240">
</head> 
<style>
body,table,td{font-family:Verdana,Arial,helv; font-size12px;}
</style>
<body> 
<h1>Киннопка</h1>
<?
if (isset($_REQUEST['send'])) {
$fp = fopen("com3", "w");
fwrite($fp, chr(1));
fclose($fp);
      
}           
?>
<form action="send.php" method="post">
<input type="hidden" name="send" value="1" />
<input type=image src="button.png">
</form>
</body> 
</html>

 

leshak
Offline
Зарегистрирован: 29.09.2011

 Ну что-бы все-таки можно было "что-то говорить дальше" вы, все-таки, должны сделать выбор. Кто же будет обрабатывать нажатие это формы?

  1. php (и дергать, в свою очередь ардуину, только уже не через serial, а "по сети").
  2. Или сразу "форма отправится ардуине" и "php-э об этом не узнает ;)".

Вообщем "что барин изволит?" ;)

>по крови визнет5100

Повезло. У меня enc28j60 там все грустней (правда, так как цель "поковырятся" было, то сильно не пугает).

 

vworld
vworld аватар
Offline
Зарегистрирован: 26.09.2011

почитал и решил тоже попробовать поработать с ардуино и пхп

до этого делал проект ардуино+питон питон стучал в гмыло и проверял почту, если новые сообщения были, то в сом порт писал "m", соответственно ардуино проверяло что в сом порте - если m, то мигало светодиодом...

Сейчас же поставил Денвер и сделал проект:

1) хтмл

<html> 
<head> 
<title>
</title> 
<meta name="viewport" content="width=240">
</head> 
<style>
body,table,td{font-family:Verdana,Arial,helv; font-size12px;}
</style>
<body> 
<h1>Кнопка1</h1>

<form action="send.php" method="post">
<input type="hidden" name="send" value="1" />
<input type=image src="button.png">
</form>
<h1>Кнопка2</h1>

<form action="send2.php" method="post">
<input type="hidden" name="send" value="1" />
<input type=image src="button.png">
</form>
</body> 
</html>

2) два пхп файла...send.php и send2.php

<?php
if (isset($_GET['param'])) {
$fp = fopen("com3", "m");
fwrite($fp, chr(1));
fclose($fp);
}
?>

В общем светодиод не горит...отмечу, что Денвер стоит на Вин7

rial2001
Offline
Зарегистрирован: 25.11.2011

Думаю второй вариант, чтоб отправлялась сразу...мне по сути что попроще и надежнее...

По поводу COM - буду дома, отпишу "мануал" как у меня все это зарабоатало в т.ч. скетч для ардуины, точно помню что были проблемки описанные выше (глюк при повторном нажатии киноппки).

vworld
vworld аватар
Offline
Зарегистрирован: 26.09.2011

в общем решил добить...

нашел класс для пхп - php_serial.class

код для пхп

<?php
include "php_serial.class.php";

// Let's start the class
$serial = new phpSerial;

// First we must specify the device. This works on both linux and windows (if
// your linux serial device is /dev/ttyS0 for COM1, etc)
$serial->deviceSet("COM3");

// Then we need to open it
$serial->deviceOpen();

// To write into
$serial->sendMessage("m");

// If you want to change the configuration, the device must be closed
$serial->deviceClose();

?>

буду дальше копать

leshak
Offline
Зарегистрирован: 29.09.2011

 

rial2001 пишет:

Думаю второй вариант, чтоб отправлялась сразу...мне по сути что попроще и надежнее...

Ну... если задача ограничится "включить led" то проще. А вот если возникнет желание потом "усложнить", "навести красоту" - через php проще. Хотя-бы потому что "красиво" может потребовать болше html-ля, картинок, а хранить их в ардуине -  места не шибко много, да и денвер берет на себя много "черновой работы" которую в ардуине нужно делать руками. Нужно тогде еще SD-карту подключать... Кстати для вашего Ethernet-чипа когда-то видел библиотечку-реализацию просто web-сервера который этим и занимается (хранит .html файлы на SD-карте, отдает их по запросу, парсит входные параметры и т.п.)

Ладно. Давайте рассмотрим вариант "напрямую". Тут тоже есть два варианта. Вначале рассмотрим  "тупой". Предположим, что ваша ардуина имеет адресс http://192.168.0.33 и включает led если передали param1=1. То есть если в браузере набрать "http://192.168.0.33?param1=1" то светодиод включится.

Тогда ваша "посылающая форма" должна выглядеть так (замена строчек 19-22 вашего скетча):

<form action="h t t p://192.168.0.33" method="get">
<input type="hidden" name="param" value="1" />
<input type="submit" value="Включить">
</form>

Если мы не хотим что-бы пользователь видел в url этот param1 - делает method="post", но и скетч, тогда, нужно поправить, что-бы он принимал еще и POST запросы, а не только GET.

Эта форма, при нажатии кнопки "Включить", как раз и пошлет браузер по адресу  "http://192.168.0.33?param1=1". То есть "идика ты в ардуину" :) В ответ ардуина, кроме включения светодиода, должна вернуть, как минимум http status 200 ("все ok") и html-ль типа

<html
<body>
   Светодиод включили.
</body>
</html>

Или, даже, может в ответ прислать "форму выключения" (форму где <input type="hidden" name="param" value="0" /> ). Тогда светик можно будет "включать/выключать". Но тогда встанет вопрос "а почему бы и изначальную форму "включения" тоже не получать от ардуины?

Если сделать так, то надобность в компьютере с php вообще отпадет. Арудино станет самостоятельным, автономным web-сервером. Хоть и примитивным ;)

Как возможный вариант (что-бы упростить скетч, и побольше переложить на PC) - ардуина может  возвращать не http 200 (все-ok), а перенаправить на ваш денвер (что-бы уже он рассказал пользователю что все хорошо). Делается это с помощью статуса http 303 и заголовка location. Ознакомится с кодами http статусов можно тут Список кодов состояний

 

 

 

leshak
Offline
Зарегистрирован: 29.09.2011

Если вспомнить что на дворе 2012 год. Пользователь любит web2.0, ajax и "что-бы страница не перезагружалась", то можно возложить миссию "общения с ардуиной" на javascript.

Проще всего это делать с помощью библиотеки jQuery (хотя можно и руками, но тогда с кросс-браузерностью танцевать прийдется).

Нужен ее методод ajax

Пишем что-то типа

 
<html>

<script type="text/javascript" src="js/jquery.js"></script> <!-- подключили библиотеку -->

<script language="javascript">
$(document).ready(function() { // когда html полностью загрузится
 $('#turnOnButton').click(function() { // вешаем обработчик события click на turnOnButton
  

   // по нажатию на линк, отсылаем ajax запрос.
   $.ajax({
            url: "h t t p://192.168.0.33?param1=1",
            success: function(data) {  alert('наслаждайтесь светом'); }
            error: function(){alert('что-то неладно в датском королевстве');}
});
    
 });
});
</script>

<body>
<a id="turnOnButton" href="#">Включить светик</a>
</body>
</html>

Естественно, кроме тупых alert(), можно менять html, css-классы, показывать прогресс бары и т.п. Вообщем насколько хватит "фантазии украшательства" (и знаний html/javascript).

Вообщем "все очень красиво", но есть "маленький" подводный камень. Сейчас точно не помню, но там,  есть какие-то секьюрные ограничения куда  ajax имеет право слать запросы. Типа "слать можно только на тот домен, с которого html загрузили". Из этого есть "два выхода". Первый - грузить этот html из арудины (тогда получает что домен html-ля и ajax запроса совпадут), либо использовать "исключение из этого правила". Если мне не изменяет память, то кросс-доменные запросы можно слать для данных типа JSON/JSONP

P.S. В 12-той строке нужно убрать пробелы в слове http, добавил их потому что без них нормально сюда не вставлялось. Парсер пытался оформить "как ссылку".

P.S.S.И, кстати,  в предыдущем посте в первой строке <form action="..." - тоже нужно убрать лишние пробелы.

.c8r
.c8r аватар
Offline
Зарегистрирован: 15.11.2011

ajax кроссдоменен, т.е. можно делать запросы с "домена" на "домен"

leshak
Offline
Зарегистрирован: 29.09.2011

.c8r пишет:

ajax кроссдоменен, т.е. можно делать запросы с "домена" на "домен"

Ага, конечно. Наберите в гугле "ajax cross domain". Если кросс-доменен, то покажите-ка, если не трудно, пример Html-ля с аджаксом, который грузится с 127.0.0.1, делает get запрос, хотя-бы на тот же http://www.google.com и вставляет полученный html в какой-нибудь div. И что-бы он работал не на каком-то "экзотическом браузере" (у которого напрочь отсутсвует секьюрность), а на популярных (FF, Chrome,IE).

Я в свое время побуцкался в это лбом. И приемлимого решения кроме делать простешие проксирование через свой web-сервер - не нашел (JSON мне не подходил, так как другой сервер мне был не подвластен, а отдавать он мог только html). Были другие, но "либо работают только в одном браузере", либо что-то в настройках браузера разрешить нужно... Может с тех пор что-то помянлось и появились более "прямые механизмы" - подскажите. буду благодарен. Но, в любом случае сомневаюсь что это будет "чистый ajax".

.c8r
.c8r аватар
Offline
Зарегистрирован: 15.11.2011

Без бубнов, естественно, никак, вот парочка примеров: http://vremenno.net/js/crossdomain-ajax/ и http://habrahabr.ru/blogs/webdev/135413/

leshak
Offline
Зарегистрирован: 29.09.2011

 Ну и что мы видим по этим линкам? Способы  того как обойти не кросс-доменность ajax-а (проксирование, JSONP и т.п.). То есть никаким

Цитата:

ajax кроссдоменен, т.е. можно делать запросы с "домена" на "домен""

и не пахнет.

Так я вроде сразу и сказал, что "не кроссдоменен", но потанцевав можно обойти. Я не говорил "невозможно", я сказал "есть подводный камень, про который нужно знать". В данном случае я бы использовал-бы либо отказ от кросдоменности (делал arduin-у полностью автономной), либо использовал JSONP, благо "что отвечает другой домен", в данном случае, тоже под нашим контролем.

 

vworld
vworld аватар
Offline
Зарегистрирован: 26.09.2011

vworld пишет:

нашел класс для пхп - php_serial.class

Поставил Денвер

в нем сделал соответственно поддомен и в нем хтмл, пхп + вышеуказанный класс

скетч

int val;
int ledPin =  13;      // the number of the LED pin

void setup()
{
Serial.begin(38400);
pinMode(ledPin, OUTPUT); 

}
void loop()
{
if (Serial.available())
{
val = Serial.read();
//Serial.println(val);
if (val == 110) // n = 110 in dec
{
digitalWrite(ledPin, HIGH);
//delay(1000); 
}
else if (val == 109) //109 = m in dec
{
digitalWrite(ledPin, LOW);
//delay(1000); 

}    
}
} 

При отправке из формы идет обращение к ардуине (моргает светодиод), НО как надо не отрабатывает...иду просто в монитор и отправляю - все работает как надо ...не могу понять в чем дело :(

Возможно в пхп нужно указать скорость работы порта...

добавил в send.php

$serial->confBaudRate(38400);

все равно не помогло :(

rial2001
Offline
Зарегистрирован: 25.11.2011

 По поводу общения по сети через вэб-сервер, ардуино подключен к серверу по СОМ.

Вот попробуйте, у меня вроде так было:

код index.php указан в моем сообщении выше

для ардуины:

int switchPin = 8;
int usbnumber = 0;
void setup() {
    pinMode(switchPin, OUTPUT);  
    Serial.begin(9600);
}
void loop() {
    if (Serial.available() > 0) {
        usbnumber = Serial.read();
    }
    if (usbnumber > 0) {

        digitalWrite(switchPin, HIGH);
        delay(300);
        digitalWrite(switchPin, LOW);
       delay(300);          //у меня тут задержка на 3 сек.!!!
         
        usbnumber = 0;
    }
}





 

leshak
Offline
Зарегистрирован: 29.09.2011

 

vworld пишет:

При отправке из формы идет обращение к ардуине (моргает светодиод), НО как надо не отрабатывает...иду просто в монитор и отправляю - все работает как надо ...не могу понять в чем дело :(

Очень рад за вас.

Не, ну вот подумайте. У вас есть минимум три составляющие (скетч, php, html).  На публику вы вынесли только скетч (который, к тому же работает, по вашим словам) и спрашиваете почему не работает система в целом. Да и что скрывается под словами "как надо не отрабатывает" тоже нужно, видимо, "протелепатить".

Вообщем непонятно что вы хотите, что-бы вам указали на возможную ошибку-проблему (если будет заметна) или просто хотите пожаловаться на тяжелую долю ардуино-разработчика?

vworld
vworld аватар
Offline
Зарегистрирован: 26.09.2011

данный скетч

int switchPin = 8;
int usbnumber = 0;
void setup() {
    pinMode(switchPin, OUTPUT);  
    Serial.begin(9600);
}
void loop() {
    if (Serial.available() > 0) {
        usbnumber = Serial.read();
    }
    if (usbnumber > 0) {

        digitalWrite(switchPin, HIGH);
        delay(300);
        digitalWrite(switchPin, LOW);
       delay(300);          //у меня тут задержка на 3 сек.!!!
         
        usbnumber = 0;
    }
}

и выше постами index.php - работает

я же бьюсь над тем, как отправить например вот команду на включение светодиода, а потом команду на выключение свтодиода...

перепробовал различные варианты - не получается...

вот например вот так пытаюсь

<?php
if (isset($_REQUEST['send'])) {
$fp = fopen("com3", "w");
fwrite($fp, dechex(110));
//fwrite($fp, 110);
fclose($fp);  
}           
?>

По коду - ардуино смотрит если в сом имеется 110, то должна включить светодиод, если отправлю 109, то выключить светодиод

 

leshak
Offline
Зарегистрирован: 29.09.2011

 Не, ну я не понимаю. Вы место на сервере экономите, что-ли? Или html-ль какой-то секретный у вас? Почему-же html-ль то не дать (тем более когда уже попросили в явном виде)? Что-бы все части мозаики было видно. Это гораздо продуктивней, чем еще раз написать "перепробовал различные варианты - не получается" (что не получается? В чем это проявляется?)

Может какая-то банальная опечатка, на которую у вас уже глаз замылился.

Про то, над чем вы приоткрыли завесу тайны:

В последнем скетче закоментируйте строчки 2 и 7. Дерните этот скрипт руками. Он должен послать команду включения в арудину, просто от самого факта своего вызова. Добейдесь вначали связки php->arduina, а потом уже будете разбиратся с форма->php.

Попробуйте вместо "fwrite($fp, dechex(110));", сделать "fwrite($fp, "n");" хотя, по идее это одно и тоже.  Просто непонятно зачем городить лишнюю функци. Можно еще попробовать "fwrite($fp, "n",1);" - что-бы быть уверенным что мы посылаем один байт (никаких концов строк и т.п.)

Только пробуйте все это по очереди, а не "все-сразу", возможно просто закоментировать if (строчки 2 и 7) - уже будет достаточно.

Я бы еще добавил, перед и после fwrite что-то типа echo, что-бы видить что происходит.

Вообщем сделал-бы что-то типа send.php

<?php
echo "Com3 opening....<br/>";
$fp = fopen("com3", "w");
echo "Done.<br/>";

echo "Sending data to Arduino...<br/>";
fwrite($fp, "n");
echo "Done.<br/>";

fclose($fp);  
}           
?>

Что-бы в браузере видить "что происходит".

 

 

 

 

leshak
Offline
Зарегистрирован: 29.09.2011

 Не, ну я не понимаю. Вы место на сервере экономите, что-ли? Или html-ль какой-то секретный у вас? Почему-же html-ль то не дать (тем более когда уже попросили в явном виде)? Что-бы все части мозаики было видно. Это гораздо продуктивней, чем еще раз написать "перепробовал различные варианты - не получается" (что не получается? В чем это проявляется?)

Может какая-то банальная опечатка, на которую у вас уже глаз замылился.

Про то, над чем вы приоткрыли завесу тайны:

В последнем скетче закоментируйте строчки 2 и 7. Дерните этот скрипт руками. Он должен послать команду включения в арудину, просто от самого факта своего вызова. Добейдесь вначали связки php->arduina, а потом уже будете разбиратся с форма->php.

Попробуйте вместо "fwrite($fp, dechex(110));", сделать "fwrite($fp, "n");" хотя, по идее это одно и тоже.  Просто непонятно зачем городить лишнюю функци. Можно еще попробовать "fwrite($fp, "n",1);" - что-бы быть уверенным что мы посылаем один байт (никаких концов строк и т.п.)

Только пробуйте все это по очереди, а не "все-сразу", возможно просто закоментировать if (строчки 2 и 7) - уже будет достаточно.

Я бы еще добавил, перед и после fwrite что-то типа echo, что-бы видить что происходит.

Вообщем сделал-бы что-то типа send.php

<html><body>
<?php
echo "Com3 opening....<br/>";
$fp = fopen("com3", "w");
echo "Done.<br/>";

echo "Sending data to Arduino...<br/>";
fwrite($fp, "n");
echo "Done.<br/>";

fclose($fp);        
?>
</body></html>


Что-бы в браузере видить "что происходит".

 

 

 

 

vworld
vworld аватар
Offline
Зарегистрирован: 26.09.2011

index.html

<html> 
<head> 
<title>
</title> 
<meta name="viewport" content="width=240">
</head> 
<style>
body,table,td{font-family:Verdana,Arial,helv; font-size12px;}
</style>
<body> 
<h1>Включить</h1>

<form action="sendN.php" method="post">
<input type="hidden" name="send" value="1" />
<input type=image src="button.png">
</form>
<h1>Выключить</h1>

<form action="sendM.php" method="post">
<input type="hidden" name="send" value="1" />
<input type=image src="button.png">
</form>
</body> 
</html>

sendN.php

<?php

if (isset($_REQUEST['send'])) {
$fp = fopen("com3", "w");
fwrite($fp, chr(110));
fclose($fp);     
}           
?>

sendM.php

<?php

if (isset($_REQUEST['send'])) {
$fp = fopen("com3", "w");
fwrite($fp, chr(109));
fclose($fp);    
}           
?>

 Скетч


int ledPin = 13;
//int usbnumber = 0;
int val;

void setup() {
    pinMode(ledPin, OUTPUT);  
    Serial.begin(38400);
}

void loop()
{
if (Serial.available())
{
val = Serial.read();
Serial.println(val);
if (val == 110) // n = 110 in dec
{
digitalWrite(ledPin, HIGH);
}
else if (val == 109) //109 = m in dec
{
digitalWrite(ledPin, LOW);

}    
}
}

 

leshak
Offline
Зарегистрирован: 29.09.2011
  1.  Ну, так как вы используете разные скрипты для sendN и sendM - проверки if (isset($_REQUEST['send'])) - явно лишние. "<input type="hidden" name="send" value="1" />" - получается тоже не нужны.
  2. Попробуйте вызвать эти скрипты (после того как уберете if) просто набрав в браузере sendM.php,sendN.php
  3. Добавте в php хотя-бы какой-то вывод сообщающий о том что скрипт отработал.
  4. И в чем-же, все-таки проявляется "не работа"?
  5. Попробуйте пока "попроще", вместо "<input type=image src="button.png">" сделайте  "<input type="submit" value="Послать" >" . Красоту потом наводить будете, когда заработает. 

 

vworld
vworld аватар
Offline
Зарегистрирован: 26.09.2011

сделал по Вашему примеру

sendN.php

<html><body>
<?php
echo "Com3 opening....<br/>";
$fp = fopen("com3", "w");
echo "Done.<br/>";

echo "Sending data to Arduino...<br/>";
fwrite($fp, "n");
echo "Done.<br/>";

fclose($fp);        
?>
</body></html>
<br><br>

Вывод

Com3 opening....
Done.
Sending data to Arduino...
Done.

п.4. "не работа" проявляет себя в том, что светодиод не загорается при исполнении скрипта sendN.php

п.5 исправил согласно Ваших рекомендаций

Добавлю...при использовании этого скетча

int ledPin = 13;
int usbnumber = 0;
int val;

void setup() {
    pinMode(ledPin, OUTPUT);  
    Serial.begin(38400);
}

void loop()
{
if (Serial.available())
{
val = Serial.read();
//Serial.println(val);
if (val == 110) // n = 110 in dec
{
digitalWrite(ledPin, HIGH);
}
else if (val == 109) //109 = m in dec
{
digitalWrite(ledPin, LOW);

}    
}
}

Отправляя в мониторе значения "n" или "m" все работает как надо...

leshak
Offline
Зарегистрирован: 29.09.2011

 Попробуйте, перед fclose() вызвать fflush($fp); Возможно оно "закешировало" и реальную запись не произвело.

Убедитесь что  используете правильный порт. Что он не занят монитором, ардуино IDE и т.п. (хотя в этом случае должно было-бы ошибками сыпать). 

Если на ардуино есть светодиодики на rx,tx пинах посмотрите моргают-ли они когда вы шлете данные (хотя один байт можно и не успеть увидитеть).

Пробуйте В СКЕТЧЕ выставить другую скорость. Попробуйте, хотя-бы 9600 и 115200. Неизвестно на какой скорости шлет fwrite. Скорее всего на той, что выставленая в "Диспетчере устройств" для этого com-порта.

Указание скорости через $serial->confBaudRate(38400); - не поможет. Если ее так устанавливать, тогда и всю работу с комп-портом через $serial делать, а не через функции файловой системы (fwrite). Возможно с этим $serial это даже проще будет (так как специально под это "заточен").

 

leshak
Offline
Зарегистрирован: 29.09.2011

 А вот такой скрипт как себя повдет??

<html><body>
<?php
include "php_serial.class.php";
$serial = new phpSerial;
echo "Try open com3...<br/>";
$serial->deviceSet("/dev/cuad2"); // предполагаю что это com3

$serial->deviceOpen();
$serial->confBaudRate(38400); // скорость должна быть такой как и в скетче
echo "Done.<br/><br/><br/>";


echo "Sending 'n' command to Arduino...<br/>";
$serial->sendMessage("n");
echo "Done";
$serial->deviceClose();
?></body></html>

 

.c8r
.c8r аватар
Offline
Зарегистрирован: 15.11.2011

/dev/cuad2 ... если апач на винде (а так вроде и есть), то и надо писать com3

leshak
Offline
Зарегистрирован: 29.09.2011

 

.c8r пишет:

/dev/cuad2 ... если апач на винде (а так вроде и есть), то и надо писать com3

Тоже так думал, как минимум "попробовать так" - точно не помешает. Но... В семпле на эту библиотеку написано так:

// First we must specify the device. This works on both linux and windows (if
// your linux serial device is /dev/ttyS0 for COM1, etc)
$serial->deviceSet("/dev/cuad0");

То есть для винды "cuadXXX", для linux "ttySXXX". По крайней мере я так понял этот комент.

.c8r
.c8r аватар
Offline
Зарегистрирован: 15.11.2011

С этой библиотекой не работал, приму к сведению.

leshak
Offline
Зарегистрирован: 29.09.2011

 При работе не через библиотеку, а fopen нашел еще такие упоминание.

Попробуйте сделать открытие не fopen("com3","w"); а fopen("com3:","w"); , где-то видел такой пример (хотя сомневаюсь в нем).

И еще, нашел как можно задать скорость. В коммандной строке выполнить что-то типа

"mode com3: BAUD=38400" или "mode com3: BAUD=38400 PARITY=N data=8 stop=1 xon=off"

Эта устновка будет действовать пока не ребутнете машину и fwrite будет писать на этой скорости.

Кстати, если выполнить просто mode, без параметров, то увидитие какая скорость у вас сейчас установлена на каком порту.

Вот эту скорость и нужно поставить, скорее всего, в скетч что-бы пользоватся fwrite без дополнительных "подстроек".

 З.Ы. На всяк случай. "Коммандная строка", это "Кнопка старт/выполнить, набрать cmd.exe<ENTER>". 

vworld
vworld аватар
Offline
Зарегистрирован: 26.09.2011

leshak пишет:

Попробуйте, перед fclose() вызвать fflush($fp); Возможно оно "закешировало" и реальную запись не произвело.

не помогло...

leshak пишет:

Если на ардуино есть светодиодики на rx,tx пинах посмотрите моргают-ли они когда вы шлете данные (хотя один байт можно и не успеть увидитеть).

RX успеваю увидить, что моргает, когда скрипт отрабатывает

Цитата:
Пробуйте В СКЕТЧЕ выставить другую скорость. Попробуйте, хотя-бы 9600 и 115200. Неизвестно на какой скорости шлет fwrite. Скорее всего на той, что выставленая в "Диспетчере устройств" для этого com-порта.

В "Диспетчере устройств" установлено 9600, скетч подправил на 9600 - эффекта не дало...

Цитата:
А вот такой скрипт как себя повдет??

Код, который Вы предложили привел при исполнении к ошибкам

Try open com3...

Warning: Specified serial port is not valid in Z:\home\test1.ru\www\php_serial.class.php on line 111

Warning: The device must be set before to be open in Z:\home\test1.ru\www\php_serial.class.php on line 137

Warning: Unable to set the baud rate : the device is either not set or opened in Z:\home\test1.ru\www\php_serial.class.php on line 204
Done.


Sending 'n' command to Arduino...

Warning: Device must be opened in Z:\home\test1.ru\www\php_serial.class.php on line 541
Done

Если поменять с $serial->deviceSet("/dev/cuad2"); // предполагаю что это com3

на $serial->deviceSet("COM3"); // предполагаю что это com3

то идет ошибка уже другая

Try open com3...

Warning: Unable to set the baud rate : the device is either not set or opened in Z:\home\test1.ru\www\php_serial.class.php on line 204
Done.


Sending 'n' command to Arduino...
Done

Цитата:
Попробуйте сделать открытие не fopen("com3","w"); а fopen("com3:","w"); , где-то видел такой пример (хотя сомневаюсь в нем).

не помогло....

По Вашему совету mode com3: BAUD=9600 PARITY=N data=8 stop=1 xon=off

выставил 9600

P.S. посидел и внимательно посомтрел функцию и попробовал все сделать согласно ее...

<html><body>
<?php
include "php_serial.class.php";
$serial = new phpSerial;
echo "Try open com3...<br/>";
$serial->deviceSet("COM3"); // предполагаю что это com3

$serial->confBaudRate(9600); // скорость должна быть такой как и в скетче
$serial->confParity("none");
$serial->confCharacterLength(8);
$serial->confStopBits(1);
$serial->confFlowControl("none");
$serial->deviceOpen();
echo "Done.<br/><br/><br/>";


echo "Sending 'n' command to Arduino...<br/>";
$serial->sendMessage("n");
echo "Done";
$serial->deviceClose();
?></body></html>

Тем самым интерпретировав вин команду - mode com3: BAUD=9600 PARITY=N data=8 stop=1 xon=off  ну или на сколько хватило моего понимания...

В итоге скрипт отрабатывает без ошибки, но светодиод все равно не загорается...
 

vworld
vworld аватар
Offline
Зарегистрирован: 26.09.2011

Путем долгих изысканий таки удалось отчасти победить связку ардуино+денвер+пхп

Ардуино

#include <LiquidCrystal_SR_LCD3.h>

const int PIN_LCD_STROBE         =  5;  // Out: LCD IC4094 shift-register strobe
const int PIN_LCD_DATA           =  6;  // Out: LCD IC4094 shift-register data
const int PIN_LCD_CLOCK          =  4;  // Out: LCD IC4094 shift-register clock
//const int PIN_LCD_BACKLIGHT      =  5;  // Out: LCD backlight (PWM)

// srdata / srclock / strobe
LiquidCrystal_SR_LCD3 lcd(PIN_LCD_DATA, PIN_LCD_CLOCK, PIN_LCD_STROBE);


int ledPin = 13;
int usbnumber = 0;
int val;

void setup() {
  lcd.begin(16, 2); 
    pinMode(ledPin, OUTPUT);  
    Serial.begin(57600);
}

void loop()
{
if (Serial.available())
{
val = Serial.read();
//Serial.println(val);
 lcd.setCursor ( 0, 0 );
    lcd.print(val);
if (val == 110) // n = 110 in dec
//if (val == 238) // n = 110 in dec
{
digitalWrite(ledPin, HIGH);
}
else if (val == 109) //109 = m in dec
//else if (val == 237) //109 = m in dec
{
digitalWrite(ledPin, LOW);

}    
}
}

Был вынужден еще подключить ЛСД - для того, чтобы отслеживать, приходит ли что-нибудь в сом порт...

PHP

<?php
if ($_POST['send_n']) {
include "php_serial.class.php";
$serial = new phpSerial;
$serial->deviceSet("COM3"); // предполагаю что это com3
$serial->deviceOpen("w+");
$serial->sendMessage("n");
$serial->deviceClose();
echo "Светодиод включен!<br/><br/><br/>";
}

if ($_POST['send_m']) {
{
include "php_serial.class.php";
$serial = new phpSerial;
$serial->deviceSet("COM3"); // предполагаю что это com3
$serial->deviceOpen("w+");
$serial->sendMessage("m");
$serial->deviceClose();
echo "Светодиод выключен!<br/><br/><br/>";
}
}
?> 
<form method="post" action="index333.php">
<input type="submit" value="Включить" name="send_n">
</form>
<form method="post" action="index333.php">
<input type="submit" value="Выключить" name="send_m">
</form> 

Из "нехорошего" сом порт почему то сам по себе меняет скорость...при включение машинки и mode com3 в командной строке показывает 1200, заливаю скетч скорость становится 57600 и спустя какое-то время возвращается к 1200

В диспетчере устройств стоит 9600...

Чем вызвана такая работа сом порта предполагаю, что дело в драйвере

Порылся в инете и нашел такую штуку - очень похоже на свежий дрйвер виртуального сом порта...кто знает подскжите можно ли использовать...и поможет ли?

leshak
Offline
Зарегистрирован: 29.09.2011

>Был вынужден еще подключить ЛСД - для того, чтобы отслеживать, приходит ли что-нибудь в сом порт...

Ну для проверки "что нибудь", проще было сам светодиод зажечь. Не по if(val == 110), а любому значению. LCD это если хочется смотреть "что именно пришло". Но, раз уж сделали, то хуже не будет. LCD конечно более удобен.

 

vworld пишет:

Из "нехорошего" сом порт почему то сам по себе меняет скорость...при включение машинки и mode com3 в командной строке показывает 1200,

Что-то "маловато". Не похоже на дефолтное значение.
> заливаю скетч скорость становится 57600

Это нормально. Это ардуина IDE его переключает, что-бы "нормально залить". Задана эта скорость в файле boards.txt. Но можно-ли ее безболезненно там менять, или бутлоадер ожидает "только ее" - не знаю нужно попробовать. Поставте 1200 и посмотрите будет-ли скетч заливатся.
> и спустя какое-то время возвращается к 1200

А вот это странно. Нужно искать "виновника". Кто именно "переключает ему скорость". Может-быть serial monitor? Вообщем любой софт который открывает com-port.

> В диспетчере устройств стоит 9600...

А.. $serial->confBaudRate(57600); не срабаывает?

 

> Чем вызвана такая работа сом порта предполагаю, что дело в драйвере

Сомневаюсь. Больше похоже как-раз что "его кто-то меняет". У вас какого-то телефонно софта не стоит? Может он "опрашивает ком-порты" (и случайно сбрасывает им скорость), может ArduinoIDE при старте это делает (по крайней мере при первом заходе в меню Tools, после запуска она точно ищет все com-порты в системе).

vworld
vworld аватар
Offline
Зарегистрирован: 26.09.2011

да задана в ардуино - atmega328.upload.speed=57600

стоял телефонный софт под самсуг - но давно уже удален, хотя может он что то и оставил в системе...

Сейчас есть только драйвер под телефон ZTE Skate, но он вряд ли с сом работает...

tip777
Offline
Зарегистрирован: 16.08.2011

интересно ,а как зделать что бы наоборот получать от ардуины инфу?

 

vworld
vworld аватар
Offline
Зарегистрирован: 26.09.2011

в классе php_serial.class.php есть функция readPort, но в винде она не работает :(

а так средствами пхп можно fread

хочу вот тоже попробовать реализовать...

пока вот такое работает...

<?php
if ($_POST['read']) {
$fp = fopen ("COM3:", "r+");
if (!$fp) {
    echo 'Не может быть прочитано из порта!';
}
else{
    echo '<br/>Порт открыт для чтения<br/><br/>';
    $buffer = fread($fp, 64 );
    echo $buffer;
    fclose ($fp);
}
echo "<br/><br/>";
echo "Готово!";
}
?> 
<form method="post" action="indexRead2.php">
<input type="submit" value="Считать" name="read">
</form>

 

morpeh
Offline
Зарегистрирован: 04.04.2012

Здраствйту хотел бы узнать получилось ли у вас считать данные с ардуино и передавать их в пхп фаил

Rimidalw
Offline
Зарегистрирован: 04.04.2012

morpeh пишет:

Здраствйту хотел бы узнать получилось ли у вас считать данные с ардуино и передавать их в пхп фаил

Я уже давно эту задачу решил) Используйте линукс например ту же Ubuntu, вебсервер и php_serial.class. Скоро допишу свою статью и выложу у себя в блоге. Пока здесь ничего кидать не буду.

fox7812
Offline
Зарегистрирован: 09.04.2012

Так и не получилось запустить под линуксом. Рушится с unable serial port. Не понимаю в чем беда. Может с правами че то не то. С нетерпением жду статью Rimidalw.

fox7812
Offline
Зарегистрирован: 09.04.2012

Warning: Unable to open the device in /opt/lampp/htdocs/ard/serial_class.php on line 161

Warning: Device must be opened in /opt/lampp/htdocs/ard/serial_class.php on line 545

Warning: Device must be opened to read it in /opt/lampp/htdocs/ard/serial_class.php on line 478

Скорее всего с доступом беда, врод все настроено...

 

metaforos
Offline
Зарегистрирован: 09.04.2012

vworld пишет:

в классе php_serial.class.php есть функция readPort, но в винде она не работает :(

а так средствами пхп можно fread

хочу вот тоже попробовать реализовать...

пока вот такое работает...

<?php
if ($_POST['read']) {
$fp = fopen ("COM3:", "r+");
if (!$fp) {
    echo 'Не может быть прочитано из порта!';
}
else{
    echo '<br/>Порт открыт для чтения<br/><br/>';
    $buffer = fread($fp, 64 );
    echo $buffer;
    fclose ($fp);
}
echo "<br/><br/>";
echo "Готово!";
}
?> 
<form method="post" action="indexRead2.php">
<input type="submit" value="Считать" name="read">
</form>

 

 

Не работает.... С записью в Ардуину из PHP разобрался - http://www.compcar.ru/forum/showpost.php?p=94283&postcount=9  а вот с чтением - никак... А хочется датчик температуры считывать. :(

fox7812
Offline
Зарегистрирован: 09.04.2012

Тоже не получается. На питоне все работает, может фиг c ним - сделайте на питоне - пусть передает php, если нужно. У меня в итоге не с доступом беда на линуксе:

Warning: Unable to open the device in /opt/lampp/htdocs/ard/serial_class.php on line 161

Warning: Device must be opened in /opt/lampp/htdocs/ard/serial_class.php on line 545

Это выдает php, но плата реагирует перегрузкой. Каждый раз когда обновляю страницу - плата перегружается. Ставил конденсатор между 5v и Reset, чтобы не перегружалось, как советовали по этой проблеме. В итоге тупо мигает TX и все, а php те же ошибки выдает

vworld
vworld аватар
Offline
Зарегистрирован: 26.09.2011

вот работоспособный скрипт на пхп

<?php
if ($_POST['send_n']) {
include "php_serial.class.php";
$serial = new phpSerial;
$serial->deviceSet("COM3"); // предполагаю что это com3
/*$serial->confBaudRate(57600); // скорость должна быть такой как и в скетче
$serial->confBaudRate(1200); // скорость должна быть такой как и в скетче
$serial->confParity("none");
$serial->confCharacterLength(8);
$serial->confStopBits(1);
$serial->confFlowControl("none");*/
$serial->deviceOpen("w+");
$serial->sendMessage("n");
$serial->deviceClose();
echo "Светодиод включен!<br/><br/><br/>";
}

if ($_POST['send_m']) {
{
include "php_serial.class.php";
$serial = new phpSerial;
$serial->deviceSet("COM3"); // предполагаю что это com3
/*$serial->confBaudRate(57600); // скорость должна быть такой как и в скетче
$serial->confBaudRate(1200); // скорость должна быть такой как и в скетче

$serial->confParity("none");
$serial->confCharacterLength(8);
$serial->confStopBits(1);
$serial->confFlowControl("none");*/
$serial->deviceOpen("w+");
$serial->sendMessage("m");
$serial->deviceClose();
echo "Светодиод выключен!<br/><br/><br/>";
}
}

if ($_POST['read']) {
$fp = fopen ("COM3:", "r+");
if (!$fp) {
    echo 'Не может быть прочитано из порта!';
}
else{
    echo '<br/>Порт открыт для чтения<br/>';
	echo '<br/>Значения датчиков - ';
    $buffer = fread($fp, 56 );
    echo $buffer;
    fclose ($fp);
}
echo '<br/><br/>Готово!<br/><br/>';
}
?> 
<form method="post" action="index333.php">
<input type="submit" value="Включить" name="send_n">
</form>
<form method="post" action="index333.php">
<input type="submit" value="Выключить" name="send_m">
</form>
<form method="post" action="index333.php">
<input type="submit" value="Считать" name="read">
</form> 

 

fox7812
Offline
Зарегистрирован: 09.04.2012

Че то не выходит под Windows. Запись нормально работает через serial_class в в вашем примере. А вот чтение никак не хочет работать, сначала страница тупо виснет, а при перезагрузке сразу - не открыть порт.