Здравствуйте. Подскажите, как отправить данные с веб-сервера ардуино? Ардуино подключен к интернету с помощью ENC28J60 В библиотеке EtherCard за это отвечает tcpReply(), скетч выглядит так: Код (C++): session = ether.tcpSend(); const char* reply = ether.tcpReply(session); if (reply != 0) { //res = 0; String data(reply); Serial.println(F(" >>>REPLY recieved....")); Serial.println(reply); } php-код, обрабатывающий нажатие кнопки: PHP: include('../connect.php'); $query = 'SELECT * FROM `data` where `id`=3 ORDER by time DESC'; // берем текущее состояние кнопки $result = mysqli_query($link, $query); $row = mysqli_fetch_array($result); $S2=!$row['data']; // меняем на противоположное $query = 'INSERT INTO `data` (`id`, `data`, `time`, `prim`) VALUES ("3", "'.$S2.'", "'.date('Y-m-d H:i:s').'", "")'; $result = mysqli_query($link, $query); echo "v1=".$S2; // выводим значение кнопки для ардуино после нажатия кнопки, ардуино видит ответ сервера, в мониторе пишется >>>REPLY recieved...., но сам reply пустой Подскажите, что не так делаю, может не так запрос с сервера отправляю, или reply надо как-то по-другому обрабатывать?
зачем вы превращаете reply в строку data. если потом ею не пользуетесь? Попробуйте выводить на печать data. может и получится. если нет - сначала проверьте. посылает ли сервер ответ. Тот PHP код. который вы цитируете - абсолютно не имеет отношения к ответу сервера.
я пробовал и Serial.println(reply); и Serial.println(data); все равно пустой результат я и чувствую...а как отправить ответ сервера ардуино? и непонятно почему тогда срабатывает reply!=0?
Не выглядит он так. Это кусок. Давайте весь. В каком месте там обработка кнопки? Я вижу только запросы к БД.
весь скетч: Код (C++): #include <EtherCard.h> // Подключаем библиотеку для взаимодействия ENC28J60 #include <OneWire.h> // Подключаем библиотеку для взаимодействия с устройствами, работающими на шине и по протоколу 1-Wire #include <DallasTemperature.h> // Подключаем библиотеку с функциями для работы с DS18B20 (запросы, считывание и преобразование возвращаемых данных) #define ONE_WIRE_BUS 2 // Указываем пин подключения data-вывода датчика температуры #define term_power 4 // Указываем пин подключения питания датчика температуры OneWire oneWire(ONE_WIRE_BUS); // Сообщаем библиотеке об устройстве, работающем по протоколу 1-Wire DallasTemperature sensors(&oneWire); // Связываем функции библиотеки DallasTemperature с нашим 1-Wire устройством (DS18B20) #define HTTP_HEADER_OFFSET 0 static byte mymac[] = { 0x74,0x69,0x69,0x2D,0x30,0x31 }; const char website[] PROGMEM = "www.moysite"; const char* reply; byte Ethernet::buffer[700]; static uint32_t timer = 0; static byte session; Stash stash; float t[2], tmp[]={77.1, 77,11}; char param[20]; /* static void response_callback (byte status, word off, word len) { Serial.print((const char*) Ethernet::buffer + off + HTTP_HEADER_OFFSET); } */ void setup () { Serial.begin(57600); sensors.begin(); // Запускаем библиотеку измерения температуры pinMode(term_power, OUTPUT); // Определяем пин подключения питания датчика температуры if (ether.begin(sizeof Ethernet::buffer, mymac, SS) == 0) // проверка ENC28J60 модуля и соединения Serial.println(F("Failed to access Ethernet controller")); if (!ether.dhcpSetup()) Serial.println(F("DHCP failed")); if (!ether.dhcpSetup()) { Serial.println("Failed to get configuration from DHCP"); while(1); } else Serial.println("DHCP configuration done"); if (!ether.dnsLookup(website)) { Serial.println("DNS failed"); while(1); } else Serial.println("DNS resolution done"); ether.printIp("SRV IP:\t", ether.hisip); // конец проверки ENC28J60 модуля и соединения } void temperature() // Измеряем температуру { digitalWrite(term_power, HIGH); // Включаем питание датчика температуры delay(100); // Задержка перед первым измерением sensors.requestTemperatures(); // Запрос на измерение температуры (1-й ошибочный) delay(500); // Задержка перед повторным измерением sensors.requestTemperatures(); // Запрос на измерение температуры (повторный) t[0] = float(sensors.getTempCByIndex(0)); // Получаем значение температуры t[1] = float(sensors.getTempCByIndex(1)); digitalWrite(term_power, LOW); // Отключаем питание датчика температуры // delay(4400); // Задержка, чтобы датчик не нагревался от частых измерений // return(); // Возвращаем значение температуры в место вызова функции } void loop() { ether.packetLoop(ether.packetReceive()); if (millis() > timer) { timer = millis() + 5000; // проверка таймера 1 раз в 5 секунд byte sd = stash.create(); if(tmp[0]!=77.11) { tmp[0]=t[0]; tmp[1]=t[1]; }; temperature(); //param=""; if(t[0]!=tmp[0]) // Записываем значение датчика 1, если оно изменилось { stash.print("t1="); stash.print(t[0],1); // Выводим текущее значение температуры датчика, округленное до десятых Serial.println(t[0],1); }; if(t[1]!=tmp[1]) // Записываем значение датчика 2, если оно изменилось { if(t[0]!=tmp[0]) stash.print("&"); stash.print("t2="); stash.print(t[1],1); // Выводим текущее значение температуры датчика, округленное до десятых Serial.println(t[1],1); }; if((t[0]!=tmp[0])||(t[1]!=tmp[1])) // Отправляем данные на сервер, если значение датчиков 1 или 2 изменилось { stash.save(); Stash::prepare(PSTR("POST http://sbm78.cf/add_data.php HTTP/1.0" "\r\n" // отправка запроса на сервер "Host: www.sbm78.cf \r\n" "Content-Length: $D" "\r\n" "Content-Type: application/x-www-form-urlencoded \r\n" "\r\n" "$H"), stash.size(), sd); session = ether.tcpSend(); }; const char* reply = ether.tcpReply(session); if (reply != 0) { //res = 0; String data(reply); Serial.println(F(" >>>REPLY recieved....")); Serial.println(reply); Serial.println(data); Serial.println(data.length()); } } } сам приведенный файл led.php является обработчиком кнопки из index.php HTML: <form id="led" action="" method="post" > <div class="r3" id="content-3" onclick="AjaxFormRequest('messegeResult', 'led', 'transfer/led.php')" ></div> </form> при нажатии на кнопку вызывается led.php, там идет проверка состояния кнопки, меняется на противоположное, записывается обратно в базу и должно в конце послать запрос ардуино echo"v1=".$S2; но видать это неверно
echo"v1=".$S2; - это не запрос, это всего лишь печать строчки типа "v1=ON" Самого запроса, так же как управления кнопкой - в этом коде нет
файл index.php: PHP: <html> <head> <title>HOME</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <script src="//code.jquery.com/jquery-1.11.0.min.js"></script> <link rel="stylesheet" type="text/css" href="style.css"> <script> function show() { $.ajax({ url: "transfer/ledstate.php", cache: false, success: function(html){ $("#content-3").html(html); } }); } $(document).ready(function(){ show(); setInterval('show()',5000); }); function AjaxFormRequest(result_id,led,url) { jQuery.ajax({ url: url, type: "GET", dataType: "html", data: jQuery("#"+led).serialize(), }); show(); } </script> </head> <body> <div class="rr"> <p class="r1">Состояние <a href="transfer/graf.php?id=3"><img src="../images/graf.png" style="vertical-align: middle" alt="Смотреть график"></a></p> <div class="r2"style="font-size:35px" > <form id="led" action="" method="post" > <div class="r3" id="content-3" onclick="AjaxFormRequest('messegeResult', 'led', 'transfer/led.php')" ></div> </form> </div> </div> </body> </html> при нажатии на кнопку вызывается и отрабатывается изменение состоянии кнопки в файле led.php led.php: PHP: <?php include('../connect.php'); $query = 'SELECT * FROM `data` where `id`=3 ORDER by time DESC'; //echo $query.'<br>'; $result = mysqli_query($link, $query); $row = mysqli_fetch_array($result); $S2=!$row['data']; $query = 'INSERT INTO `data` (`id`, `data`, `time`, `prim`) VALUES ("3", "'.$S2.'", "'.date('Y-m-d H:i:s').'", "")'; //echo $query.'<br>'; $result = mysqli_query($link, $query); echo "v1=".$S2; ?> как тогда отправить запрос ардуино?
чем дальше, тем меньше понимаю. Кнопку-то вы где нажимаете? На ардуино? Поправка. кнопку нашел. Но понятнее не стало.
нет, на сервере (на сайте) - файл index.php и при нажатии кнопки на сервере, ардуино должно что-то включить, получив запрос с сервера т.е. отправить данные на сервер (сайт) у меня получается, а обратно с сайта в ардиуно ответ получить нет
сорри, дальше вряд ли помогу. Могу только повторить совет подключится к серверу обычным браузером и убедится. что он хоть что-то возвращает
Ну подскажите, пожалуйста, а принимаю я ответ сервера правильно? Код (C++): const char* reply = ether.tcpReply(session); if (reply != 0) { Serial.println(F(" >>>REPLY recieved....")); Serial.println(reply); } при том, что сервер возвращает данные, указанный код должен их выводить в сериал порт?
вам на ардуино.ру правильный вопрос задали. Вы из ардуины посылаете запрос совсем к другому файлу - не к index.php и не к led.php. а какому-то add_data.php. . Вот именно этот файл и надо изуячать в первую очередь
да, я там объяснил, что add_data.php принимает данные с датчиков, это у меня хорошо получается, по этому вопросов нет. но когда я на сайте нажимаю кнопку, которая обрабатывается led.php, на сайте состояние кнопки меняется, но как послать ответ ардуино и как его принять, я не знаю и прошу в этом помощи
никак Ардуине нельзя послать никаких данных, для этого сервером должна быть ардуина, а не ПК. Единственный вариант - это хранить состояние кнопки на сервере в виде какой-то строчки и периодически запрашивать его с ардуино. Для этого нужно написать отдельный скрипт на сервере. который отдавал бы состояние кнопки. а в коде на ардуино сформировать к этому скрипту полноценный запрос по типу того. что у вас обращается к add_data.php - и вот от этого-то нового запроса и получать ответ. а сейчас вы в коде делаете ерунду - посылаете запрос к одному скрипту, а ждете ответ совсем от другого, так не заработает
я исправил скетч, теперь и датчики и кнопку обрабатывает один файл add_data.php скетч: Код (C++): #include <EtherCard.h> // Подключаем библиотеку для взаимодействия ENC28J60 #include <OneWire.h> // Подключаем библиотеку для взаимодействия с устройствами, работающими на шине и по протоколу 1-Wire #include <DallasTemperature.h> // Подключаем библиотеку с функциями для работы с DS18B20 (запросы, считывание и преобразование возвращаемых данных) #define ONE_WIRE_BUS 2 // Указываем пин подключения data-вывода датчика температуры #define term_power 4 // Указываем пин подключения питания датчика температуры OneWire oneWire(ONE_WIRE_BUS); // Сообщаем библиотеке об устройстве, работающем по протоколу 1-Wire DallasTemperature sensors(&oneWire); // Связываем функции библиотеки DallasTemperature с нашим 1-Wire устройством (DS18B20) #define HTTP_HEADER_OFFSET 0 static byte mymac[] = { 0x74,0x69,0x69,0x2D,0x30,0x31 }; const char website[] PROGMEM = "www.my.site"; const char* reply; byte Ethernet::buffer[900]; static uint32_t timer = 0; static byte session; Stash stash; float t[2], tmp[]={77.1, 77,11}; char param[20]; /* static void response_callback (byte status, word off, word len) { Serial.print((const char*) Ethernet::buffer + off + HTTP_HEADER_OFFSET); } */ void setup () { Serial.begin(57600); sensors.begin(); // Запускаем библиотеку измерения температуры pinMode(term_power, OUTPUT); // Определяем пин подключения питания датчика температуры if (ether.begin(sizeof Ethernet::buffer, mymac, SS) == 0) // проверка ENC28J60 модуля и соединения Serial.println(F("Failed to access Ethernet controller")); if (!ether.dhcpSetup()) Serial.println(F("DHCP failed")); if (!ether.dhcpSetup()) { Serial.println("Failed to get configuration from DHCP"); while(1); } else Serial.println("DHCP configuration done"); if (!ether.dnsLookup(website)) { Serial.println("DNS failed"); while(1); } else Serial.println("DNS resolution done"); ether.printIp("SRV IP:\t", ether.hisip); // конец проверки ENC28J60 модуля и соединения } void temperature() // Измеряем температуру { digitalWrite(term_power, HIGH); // Включаем питание датчика температуры delay(100); // Задержка перед первым измерением sensors.requestTemperatures(); // Запрос на измерение температуры (1-й ошибочный) delay(500); // Задержка перед повторным измерением sensors.requestTemperatures(); // Запрос на измерение температуры (повторный) t[0] = float(sensors.getTempCByIndex(0)); // Получаем значение температуры t[1] = float(sensors.getTempCByIndex(1)); digitalWrite(term_power, LOW); // Отключаем питание датчика температуры } void loop() { ether.packetLoop(ether.packetReceive()); if (millis() > timer) { timer = millis() + 5000; // проверка таймера 1 раз в 5 секунд byte sd = stash.create(); temperature(); stash.print("t1="); stash.print(t[0],1); // Выводим текущее значение температуры датчика, округленное до десятых Serial.println(t[0],1); stash.print("&t2="); stash.print(t[1],1); // Выводим текущее значение температуры датчика, округленное до десятых Serial.println(t[1],1); stash.save(); Stash::prepare(PSTR("POST <a href="http://my.site/add_data.php" title="http://my.site/add_data.php" rel="nofollow">http://my.site/add_data.php</a> HTTP/1.0" "\r\n" // отправка запроса на сервер "Host: <a href="http://www.my.site" title="www.my.site" rel="nofollow">www.my.site</a> \r\n" "Content-Length: $D" "\r\n" "Content-Type: application/x-www-form-urlencoded \r\n" "\r\n" "$H"), stash.size(), sd); session = ether.tcpSend(); const char* reply = ether.tcpReply(session); if (reply != 0) { Serial.println(F(" >>>REPLY recieved....")); Serial.println(reply); } } } add_data.php: PHP: <?php include('connect.php'); $query = 'INSERT INTO `data` (`id`, `data`, `time`, `prim`) VALUES (1, '.$_POST['t1'].', "'.date("Y-m-d H-i-s").'", ""), (2, '.$_POST['t2'].', "'.date("Y-m-d H-i-s").'", "")'; $result = mysqli_query($link, $query); // записали данные по температуре if(@$_POST['led']==11) // проверка, что есть запрос на изменение состояния кнопки с сайта { $query = 'SELECT * FROM `data` where `id`=3 ORDER by time DESC'; $result = mysqli_query($link, $query); $row = mysqli_fetch_array($result); $S2=!$row['data']; $query = 'INSERT INTO `data` (`id`, `data`, `time`, `prim`) VALUES ("3", "'.$S2.'", "'.date('Y-m-d H:i:s').'", "")'; $result = mysqli_query($link, $query); echo "v1=".$S2; } ?> на стороне сайта, работает хорошо: температура выводится и кнопка переключается, но в ардуино данные все равно не возвращаются( reply в 95 строке всегда почему-то 0