Отправка запроса от веб-сервера ардуино
- Войдите на сайт для отправки комментариев
Ср, 06/05/2020 - 15:52
Здравствуйте.
Подскажите, как отправить данные с веб-сервера ардуино?
Ардуино подключен к интернету с помощью ENC28J60
В библиотеке EtherCard за это отвечает tcpReply(), скетч выглядит так:
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-код, обрабатывающий нажатие кнопки:
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 надо как-то по-другому обрабатывать?
зачем нужна 6 строчка? память некуда девать?
я пробовал и Serial.println(reply); и Serial.println(data); все равно пустой результат, просто забыл удалить из этого текста
проверьте. что отвечает сервер. может там ответ пустой. Подключитесь к серверу не через ардуино, а с компа
я могу зайти на сервер с компа, но как увидеть, что он отвечает?
как увидеть, что он отвечает?
в браузере
в браузере я вижу только головной файл сайта index.php из него вызывается файл led.php обработчик кнопки и он должен послать запрос ардуино:
index.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:
<?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; ?>последняя строка предполагается отправляет значение v1=1 или 0, но похоже это не так)
arduino к какому файлу обращается?
arduino к какому файлу обращается?
хороший вопрос :) к какому-то add_data.php
вот скетч автора. выложенный на Амперке
#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()); } } }sbm - выложите еще код файла add_data.php
Вот весь скетч:
#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); // Отключаем питание датчика температуры // delay(4400); // Задержка, чтобы датчик не нагревался от частых измерений // return(); // Возвращаем значение температуры в место вызова функции } // called when the client request is complete static void my_callback (byte status, word off, word len) { Serial.println(">>>"); Ethernet::buffer[off+500] = 0; Serial.print((const char*) Ethernet::buffer + off); Serial.println("..."); } 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://my.site/add_data.php HTTP/1.0" "\r\n" // отправка запроса на сервер "Host: www.my.site \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()); } } }ардуино передает данные в файл add_date.php - это у меня отлично получается.
Не получается при нажатии кнопки на сервере (на сайте), передать значение в ардуино
обрабатывает нажатие кнопки led.php и он должен возвращать значение 1 или 0
<?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; ?>в скетче я пытаюсь это сделать в строчках с 119 по 128
в скетче я пытаюсь это сделать в строчках с 119 по 128
ЛОЛ :)
В строчках с 119 по 128 - это ответ на запрос к add_data.php
С нажатием кнопки на сервере это НЕ СВЯЗАНО НИКАК.
И не получится. Вы, похоже, кардинально не понимаете как это все работает. При нажатии кнопки в форме на сайте на ардуину НИЧЕГО НЕ ПЕРЕДАЕТСЯ. Ардуина может что-то получить только в том случае. если сама послала запрос. И посылать этот запрос нужно именно тому скрипту на сервере, который вам вернет состояние кнопки.
sbm, чтоб данные ушли в arduino, вам сначала при нажатии кнопки необходимо исправить данные в бд, т е поставить какой то флаг, а при запросе get с МК смотреть на этот флаг и в зависимости от него слать данные.
отлично, уже немного понял свою ошибку, я действительно плохо понимаю этот процесс
у меня передача данных датчиков и нажатие кнопки - разные процессы, хотя получается их можно объединить в один.
в моем случае, надо послать запрос в led.php и получить от него ответ
в моем случае, надо послать запрос в led.php и получить от него ответ
да, как-то так
Ему нужно просо создать этот файл add data и в нем отдавать значение кнопки из базы в дуню. Если я верно понял вопрос. Причём просто текстом, по виду
в исходной версии сайта данные температуры и состояние кнопки обрабатывались разными скриптами соответственно в файлах add_data.php, который по запросу ардуино добавляет данные в базу, и led.php, который вызывается только сайтом.
Теперь я понял, что нужно переделать в скетче и сайте, будем пробовать, спасибо
я исправил скетч, теперь и датчики и кнопку обрабатывает один файл add_data.php
скетч:
#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 http://my.site/add_data.php HTTP/1.0" "\r\n" // отправка запроса на сервер "Host: www.my.site \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 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
Зачем начинаете незнакомое дело с монстрячих конструкций? Сделайте простой php, который получает число, умножает на два и возвращает результат. Когда это заработает - будете уже свои SQL-и накручивать.
резонно, add_date.php:
<?php if(@$_POST['t1']) $t1=$_POST['t1']+10; if(@$_POST['t2']) $t2=$_POST['t2']+20; echo "?t1=".$_POST['t1']."&t2=".$_POST['t2'] ?>проще некуда, передаю t1=10, t2=15,
должен получить "?t1=20&t2=35", но почему-то возвращает в ардуино пустую строку
Думаю ваш post запрос некорректно на сервер доходит, посмотрите в логах Web сервера ошибки. Я обычно начинал с get запросов, их полностью заставлял корректно работать, причём сначала с браузера, потом уже на post переходил.
Мне тоже кажется, что echo "t1=20" это не POST запрос, а просто вывод на экран t1=20, но тогда можете привести пример как нужно делать get или пост запросы.
Теорию я знаю, get запрос - это index.php?t1=10&t2=15, post запрос, через форму
Но как мне тут написать add_data.php, как Вы говорили умножение на 2 и вернуть это значение?
Начало понятно:
а как вернуть эти значения get запросом?
Так выше же все написано. Или я не понял задачу.
1. Нажимаете кнопку и значение в бд меняется и устанавливается флаг что необходимо отправить данные в ардуино
2. При любом get / post запросе смотрим в бд флаг, если он есть - возвращаем echo то что нам необходимо и сбрасываем флаг.
Вы в логах проверили - запрос доходит корректно?
Пример есть, если найду ближе к обеду скину
Я больше скажу - возьмите оригинальную UIPEthernet - там в экзамплах, вроде как идёт, Webclient. Оно точно работает. На нем и прогоните свой простой алгоритм. EtherCard - своеобразная библиотека, редко тут всплывает.
вот пример PHP откопал, если в параметре GET запроса пришло on то в обратку шлет текст " SetRelayOFF ~", скетч находит эту строку в ответной HTML страничке и выключает реле, ну и наоборот сотвественно.
<?php include_once $_SERVER['DOCUMENT_ROOT'] . '/includes/helpers.inc.php'; ?> <!DOCTYPE html> <html> <?php function tempToFloat($arg) { if ($arg >= 2000) { $res = ($arg-2000); $res = ($res / 10); $res = (0-$res); } else { $res = ($arg / 10); } return $res; } if ((isset($_GET['id'])) and (isset($_GET['rs'])) and (isset($_GET['t0']))) { try { if (isset($_GET['t2'])) { $sql = 'INSERT INTO `thermometers` (`i_id`, `c_strelay`, `f_t1`, `f_t2`, `f_t3`) VALUES (:p1, :p2, :p3, :p4, :p5)'; } else if (isset($_GET['t1'])) { $sql = 'INSERT INTO `thermometers` (`i_id`, `c_strelay`, `f_t1`, `f_t2`) VALUES (:p1, :p2, :p3, :p4)'; } else { $sql = 'INSERT INTO `thermometers` (`i_id`, `c_strelay`, `f_t1`) VALUES (:p1, :p2, :p3)'; } $s = $pdo->prepare($sql); $s->bindValue(':p1', $_GET['id']); $s->bindValue(':p2', $_GET['rs']); $s->bindValue(':p3', tempToFloat($_GET['t0'])); if (isset($_GET['t1'])) { $s->bindValue(':p4', tempToFloat($_GET['t1'])); } if (isset($_GET['t2'])) { $s->bindValue(':p5', tempToFloat($_GET['t2'])); } $s->execute(); } catch (PDOException $e) { $error = 'Error ' . $e->getMessage(); include $_SERVER['DOCUMENT_ROOT'] . '/includes/error.html.php'; exit(); } //echo " Save OK ~"; if ($_GET['rs']=='on') { echo " SetRelayOFF ~"; } else { echo " SetRelayON ~"; } } ?> <p></p> </html>POST и GET запросы адресованы серверу и обрабатываются им (сервером). Он приняв эти запросы "раскладывает их по глобальным переменным" (к примеру, POST: https://www.php.net/manual/ru/reserved.variables.post.php )
Дуня в этой связке предстает КЛИЕНТОМ, а клиент может получать только "ВЫВОД" (обычно в html или чистый текст).
Если дуня будет слать GET запрос (POST используется для большого объема данных), к примеру такого вида:
То получающий на сервере скрипт (add_data.php) должен его обработать и выдать ответ:
<?php include('connect.php'); if ($_GET['mode'] && trim($_GET['mode']) == "dunya") { // Если данные пришли с дуни, то заносим их и возвращаем ОК $query = 'INSERT INTO `data` (`id`, `data`, `time`, `prim`) VALUES (1, '.$_GET['data'].', "'.date("Y-m-d H-i-s").'", ""); $result = mysqli_query($link, $query); // записали данные по температуре if ($result) { echo "OK"; // если все занесли } else { echo "ERROR"; // если внести данные не получилось } } else { // иначе делаете что там Вам нужно по кнопке с сайта или как там у Вас? // пусть останется Ваш текст (не вдавался в подробности о чем он: $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; } ?>Дуня получит ответ или "ОК" или "ERROR" и вы увидите его в выводе. То же самое и для получения данных из БД по GET (POST) запросу.
Что-то усложнили банальную задачу...
ЗЫ: Писал все быстро, могут быть и ошибки в коде.
Спасибо, то что Вы написали с 1 по 12 строку у меня получается.
Задача передать данные с сайта ардуине, если на сайте нажали кнопку. Я может не сказал отдельно, весь сайт находится на удаленном хостинге, не в ардуине.
Еще раз: ардиуно собирает данные с датчиков и выключателей и передает их в бд сайта на хостинге. Там они отображаются и если на сайте происходит нажатие кнопки, то это нужно как-то передать обратно ардуине, чтобы оно включило выключатель.
Размещать весь сайт в ардуине не хочу по некоторым соображениям и т.к. не хватит памяти.
Это надо коннект постоянный с хостингом держать. Что-то тут было такое про вебсокеты Или через MQTT заворачивать.
а есть пример скетча, который ловит этот ответ, было бы здорово
то, что я хочу сделать было реализовано на шилде w5100 без MQTT в этой статье, моя задача сделать тоже самое, только на ENC68J60
И что там написано в статье?
Во второй раз советую - возьмите UIPEthernet. У нее синтаксис такой же, как у визнетовской библиотеки
sbm, вы читали то что выше написано? Поняли? Мне кажется нет :(
Sadman41 прав, если нужна мгновенная реакция, то http не ваш вариант.
Если секунда, две задержки допустимо то берете алгоритм выше.
Нажимая на кнопку - записываете флаг в бд и в ответе php (пример выше) читаете значение из бд и выдаёте в МК.
а есть пример скетча, который ловит этот ответ, было бы здорово
Почитайте в конце концов html ответ в Википедии, тупо поиск подстроки.
там данные датчиков отправляют отдельно и скрипт на php add_data их обрабатывает, а проверка нажатие кнопки отдельно в файле led.php:
if (client.connect(server, 80)) { client.print( "GET /add_data.php?"); client.print("temperature="); client.print( sensors.getTempCByIndex(0) ); client.println( " HTTP/1.1"); client.print( "Host: " ); client.println(server); client.println( "Connection: close" ); client.println(); client.println(); delay(200); while (client.available()) { char c = client.read(); if ( c=='1') buff=1; if ( c=='0') buff=0; } client.stop(); client.flush(); delay(100); } else { client.stop(); delay(1000); client.connect(server, 80); } if ( buff==1) digitalWrite (led1, HIGH); else digitalWrite(led1, LOW);led.php:
<?php $S2 = $_POST['status']; $myFile2 = "../txt/out-1.txt"; $fh2 = fopen($myFile2, 'w') or die("can't open file"); fwrite($fh2, $S2); fclose($fh2); echo $S2; ?>Спасибо, я изучаю примеры, которые Вы рекомендовали, чувствую будут вопросы)
пару секунд задержки совсем не критично
тогда получается, что если при нажатии кнопки на сайте вызывается по post-запросу следующий скрипт
<?php if(@$_POST['t1']) $t1=$_POST['t1']+10; if(@$_POST['t2']) $t2=$_POST['t2']+20; echo "?t1=".$_POST['t1']."&t2=".$_POST['t2'] ?>ардуино следующим скетчем должно увидеть в ответ в reply "?t1=20&t2=35", так?
stash.print("t1=10&t2=15"); stash.save(); Stash::prepare(PSTR("POST http://my.site/add_data.php HTTP/1.0" "\r\n" // отправка запроса на сервер "Host: www.my.site.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) { Serial.println("Got a response!"); Serial.println(reply); }Ну нет :(
По нажатию кнопки записывается флаг в бд.
А МК ардуино каждую например секунду шлет get или post запрос, в ответ на который php шлёт в обратку МК нужные данные с зависимости от данных в бд.
Совершенно верно!
Добавьте в бд отдельную таблицу (если с файлами морочиться не хотите) и проверяйте статус.
Это даже в одной файле скрипта можно реализовать, если так сильно это хочется:
<?php include('connect.php'); if ($_GET['mode'] && trim($_GET['mode']) == "putdunya") { // Если данные пришли с дуни и режим "занести в базу", то заносим их и возвращаем ОК или ERROR если ошибка $query = 'INSERT INTO `data` (`id`, `data`, `time`, `prim`) VALUES (1, '.$_GET['data'].', "'.date("Y-m-d H-i-s").'", ""); $result = mysqli_query($link, $query); // записали данные по температуре if ($result) { echo "OK"; // если все занесли } else { echo "ERROR"; // если внести данные не получилось } } if ($_GET['mode'] && trim($_GET['mode']) == "getdunya") { // Если данные пришли с дуни и режим "получить данные в дуню", то проверяем были ли изменены данных с сайта // и если были, то отправляем их дуне в виде строки: echo $reply; // если изменений небыло, то шлем флаг "ничегонеделать" echo "nojob"; // этот флаг в дуне является маркером ничего не делать // и ОБЯЗАТЕЛЬНО сбрасываем флаг } if ($_GET['mode'] && trim($_GET['mode']) == "putsite") { // если работаем с сайтом напрямую, то делаете что там Вам нужно по кнопке с сайта или как там у Вас? // пусть останется Ваш текст (не вдавался в подробности о чем он: // ============== > }?>Соответственно сами GET-запросы поправить не забудьте. И слать такие запросы на удаленный web-хостинг чаще 1 раз в 10 секунд я бы не стал - сказываются задержки сети и задержки обработки самим web-хостингом.
<?php $query = 'INSERT INTO `data` (`id`, `data`, `time`, `prim`) VALUES (1, '.$_GET['data'].', "'.date("Y-m-d H-i-s").'", "");У вас дыра в запросе, подверженная SQL injection. Данные, полученные с небезопасной стороны, надо хотя бы обернуть в mysql_escape_string ;)
Это не у меня, как Вы выразились, "дыра", а у ТС, я использовал его кусок кода для "наглядности".
Я бы все сделал через API.
ТС, не пугайся уязвимостей, всегда можно VPN-построить и только по VPN данные отдавать, тогда и авторизации не нужно будет использовать (правда не на всех shared, но сейчас VPS не дороже стоит под такие задачи). Чего у тебя там получается то?