Как вариант, можно вообще всю страничку разместить на внешнем ресурсе, а в ардуинке только значения параметров.
Ага, если бы всё было так просто ;) Вы попробуйте, и расскажите нам о результатах, когда с одного домена, на котором у вас размещена страница, вы будете получать данные, отправляя запрос к другому домену (которым будет выступать дуина). И тогда сразу лихорадочно будем вспоминать про политики ограничения кроссдоменных запросов в браузерах, и как это побороть.
Ага, если бы всё было так просто ;) Вы попробуйте, и расскажите нам о результатах, когда с одного домена, на котором у вас размещена страница, вы будете получать данные, отправляя запрос к другому домену (которым будет выступать дуина). И тогда сразу лихорадочно будем вспоминать про политики ограничения кроссдоменных запросов в браузерах, и как это побороть.
Прошу понять меня правильно и не обижаться. Есть код (выкладывал его ранее), который я подогнал на работу с восемью датчиками и восемью реле (подогнал из первоначального скетча в этой теме). Есть необходимость уйти с ENC28J60 на W5100. На то свои причины, главная из которой - неработоспособность ENC при превышении HTTP_части кода 1279 символов, включая пробелы. Сам я не программист ни разу, о чем тоже сообщал. И теперь, вместо того, что бы написать: "парни, пишите так и вот так", я вижу много слов на тему "код, что привели - в помойку", "есть RFC на тему...." Вопрос чисто риторический: вот какой практический смысл всего этого? Блеснуть познаниями в RFC? Тогда где номер RFC? Просто блеснуть чем-либо? Ну ок, потешил эго, дальше что? Еще раз призываю понять меня правильно и не обижаться.
Переживу. Особенно учитывая, что это не "мой код". я взял код тс. И просто подогнал под большее кол-во датчиков. Для себя я рано или поздно сделаю задуманное. Как и во всех случаях, за исключением одного, без участия этого форума. :)
Зачем вам два домена можете пояснить???? Ардуино справляется с этим прекрасно, будущий клиентом
Речь шла о локальной HTML-странице, с которой идёт запрос к ардуине. В терминах веб, локальная страница - тоже отдельный домен. Дальше объяснять или сами про CORS в вики почитаете?
Ага, если бы всё было так просто ;) Вы попробуйте, и расскажите нам о результатах, когда с одного домена, на котором у вас размещена страница, вы будете получать данные, отправляя запрос к другому домену (которым будет выступать дуина). И тогда сразу лихорадочно будем вспоминать про политики ограничения кроссдоменных запросов в браузерах, и как это побороть.
Начинай лихорадочно вспоминать про кроссдоменные запросы.
Дык то, что вы привели - костыль, который специально используют, чтобы обойти CORS, называется этот костыль - JSONP. Без P - работать не будет. Что такое P после JSON - предлагаю догадаться.
Прошу понять меня правильно и не обижаться. Есть код (выкладывал его ранее), который я подогнал на работу с восемью датчиками и восемью реле (подогнал из первоначального скетча в этой теме). Есть необходимость уйти с ENC28J60 на W5100. На то свои причины, главная из которой - неработоспособность ENC при превышении HTTP_части кода 1279 символов, включая пробелы. Сам я не программист ни разу, о чем тоже сообщал. И теперь, вместо того, что бы написать: "парни, пишите так и вот так", я вижу много слов на тему "код, что привели - в помойку", "есть RFC на тему...." Вопрос чисто риторический: вот какой практический смысл всего этого? Блеснуть познаниями в RFC? Тогда где номер RFC? Просто блеснуть чем-либо? Ну ок, потешил эго, дальше что? Еще раз призываю понять меня правильно и не обижаться.
Да никаких обид. Просто я речь веду о том, что если вы взялись делать что-то подобной сложности - надо для начала почитать хотя бы основы, а не кидаться сразу в бой. Ничем я блеснуть не хочу, мне и без этого работ и забот хватает. Я лишь предупреждаю, что при таком подходе - дальше будет только хуже, и понимания - не придёт ни на грош, будет только тупое и бессмысленное дёрганье кусков кода из чужих скетчей. Хочешь сделать хорошо? Сделай это сам!
У нас вообще классно всё устроено - можно без прав и знания ПДД шмалять по дорогам на убитых машинах - а чо, вон друзья ездят! Вот ваш подход примерно из той же оперы - не зная самых необходимых основ - пытаетесь сразу впихнуть невпихуемое. А чревато это, как и в случае с авто - скорой аварией. Впрочем, зато механикам работа всегда будет.
Короче, я на вас молюсь - не будь вас, не было бы у меня работы :)
Где там речь о локальной странице??? Парень предложил просто саму страницу разместить на "внешнем ресурсе", Не придав смысла. А имел ввиду скорее всего создать страницу, к которой будет обращаться Ардуино, но ни как на оборот.
Если все же, я ошибся, то тогда встречный вопрос , а зачем все так усложнять???
Где там речь о локальной странице??? Парень предложил просто саму страницу разместить на "внешнем ресурсе", Не придав смысла. А имел ввиду скорее всего создать страницу, к которой будет обращаться Ардуино, но ни как на оборот. Если все же, я ошибся, то тогда встречный вопрос , а зачем все так усложнять???
Может и я не так понял - кто к кому будет обращаться, бывает. К вопросу "зачем всё так усложнять" - а зачем вообще знать основы? Ведь можно взять - и наговнякать. Это не к вам лично, это вообще - современный потреблядский подход: сначала сделать, а потом чесать репу - почему не работает. Потом задать кучу ненужных вопросов, которые можно было бы решить, почитав сразу документацию.
Ну ведь основа же - политики безопасности браузеров. И кстати - есть сценарии использования, при которых вы не сможете без плясок с бубном получить данные со страницы в веб, неважно, запросив их с ардуины ли или ещё откуда. Но я об этом тихо промолчу, ок? А то всё равно это никому неинтересно.
Даже очень интересно, Вот сейчас сижу и калдую, динамическую переменную получаю с удаленный вебстр
Я вот колбасу в дальнем магазине тоже покупаю без проблем, и что? Без указания юзкейса ваши слова - ни о чём. Я тоже могу получить чего-нибудь с веб-страницы, но - далеко не с каждой, и далеко не любым способом. Если вам это подвластно - поздравляю, вы волшебник.
Впрочем, разговор ни о чём, поскольку тут никто даже не заморачивается чтением хоть какой-либо документации, как правило.
З.Ы. У вас, кстати, при получении значения переменной анализируется Expires и, хотя бы, 302 Content moved? Я уже не говорю о Last-Modified - а то вы там такого старого говна получите с сервера, что уверенности в достоверности полученных данных не останется ни на грош. Впрочем, это неправильный, профессиональный подход, правильные пацаны таким не заморачиваются.
Вы правы, Мне незачем этим париться))). Я конечно не гуру, но у меня страница получает данные каждую секунду, записывая все в базу. Изменения на странице, Так-же записываются в базу и выводятся в строчку.Ну а дальше генерации графиков и т.п. Смысл создания был, Не привязываться к одному контролеру и максимальную гибкость. На данный момент можно добавлять очень много контроллеров, к примеру esp12 встроенных в выключатели, розетки и т.п. И управлять всем этим с одной страницы. Гибкость, пишу приложение под андроид.
Я к чему, что каждый начинает как может. Только хватит ума и терпения не каждому. Ну а кто пытается хоть как, молодцы, Все лучше чем х**ней страдать
Это называется поумничали и разошлись =), а по делу хоть номер RFC дайте, а еще лучше если уж Вы на нас молитесь и для Вас это просто напишите реализацию этих умных слов: "FORM описать атрибуты TARGET и METHOD, чтобы браузер знал, куда и каким методом засунуть данные, введённые пользователем. Затем - при отправке формы по кнопке <input type="submit"...> на URI, указанный в TARGET, методом, указанном в METHOD, придут данные, закодированные в соответствии с указанием кодировки, это описывается аттрибутом ENCTYPE формы. Принимаете HTTP-запрос для этого URI, разбираете переданные значения, декодируете их, если потребуется"
Переживу. Особенно учитывая, что это не "мой код". я взял код тс. И просто подогнал под большее кол-во датчиков. Для себя я рано или поздно сделаю задуманное. Как и во всех случаях, за исключением одного, без участия этого форума. :)
а может попробуем взять данные не из формы ввода, а из кнопки и например сделаем 2-4 кнопки к которым будет привяза определенная температура, быть может так будет проще?
Это называется поумничали и разошлись =), а по делу хоть номер RFC дайте, а еще лучше если уж Вы на нас молитесь и для Вас это просто напишите реализацию этих умных слов: "FORM описать атрибуты TARGET и METHOD, чтобы браузер знал, куда и каким методом засунуть данные, введённые пользователем. Затем - при отправке формы по кнопке <input type="submit"...> на URI, указанный в TARGET, методом, указанном в METHOD, придут данные, закодированные в соответствии с указанием кодировки, это описывается аттрибутом ENCTYPE формы. Принимаете HTTP-запрос для этого URI, разбираете переданные значения, декодируете их, если потребуется"
ЗЫ. память пока не жмет, ее еще много =)
За вас писать? Зачем? У меня и так работы хватает. Вам нужен RFC по HTTP? В гугле не забанили часом? Так и набираете - HTTP RFC. Заодно можно стандарт HTML почитать, про те же атрибуты тега FORM, чтобы прояснение наступило.
По поводу "поумничали": не далее как пару дней назад ещё раз убедился, что политика безопасности браузеров работает, и, если не знать про CORS - дулю можно получить вместо результата запроса. Суть была проста: есть страничка, которая выдаётся Мегой с SD-карточки в браузер, через вай-фай-вундерфафлю ESP8266. С неё отправляю AJAX-запросы на мегу же, получаю ответ, чего-то там на страничке делаю JavaScript'ом. Ну ведь неудобно же - изменил страницу, для тестирования её надо закачать на карточку, а для этого карточку надо вынуть из меги. Сохранил страницу локально, открываю её, жмакаю кнопку "опросить датчики", а Firefox дулей крутит и говорит: мил человек, не покажу я тебе ответ от меги, т.к. не нашёл я в ответе заголовок один секретный, поэтому - кури в сторонке.
Думаю - а ведь точно, прошляпил по старости лет. Открыл прошивку, дописал выдачу заголовка Access-Control-Allow-Origin: * - и пошёл пить чай, т.к. всё заработало.
Но это реальным пацанам неинтересно - RFC ведь мало того, что читать надо, так они, цуки, ещё и на басурманском! Мы лучше так налабаем, а потом будем кричать - ааа, почему не работает мой кривой скетч?
З.Ы. Полная реализация обработки данных с формы, если делать в соответствии с RFC - вещь далеко не тривиальная и, боюсь, ресурсиков дурины тут не хватит.
З.З.Ы. Вот моё видео, в котором показана работа с браузером. Там и ссылка на проект на гитхабе есть.
ПОдскажите куда копать. собрал схему, когда захожу на веб морду температуру пишет -0.06 и никак не меняеться. куда копать. через монитор порта темперетуру показывают датчики правильбную а через веб никак. куда копнуть кто подскажет.
#include <Wire.h>
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <WiFiUdp.h>
#include <pgmspace.h>
#include <RtcDS3231.h>
#include <OneWire.h>
#include <EEPROM.h>
#include <ESP8266HTTPClient.h>
#include <ESP8266httpUpdate.h>
#include <DallasTemperature.h>
#define countof(a) (sizeof(a) / sizeof(a[0]))
char* const ver = "ESP-HomeMaster-0.60";
unsigned int localPort = 2390;
RtcDS3231<TwoWire> Rtc(Wire);
IPAddress timeServerIP;
const char* ntpServerName = "time.google.com";
//IPAddress timeServer(129, 6, 15, 28);
const int NTP_PACKET_SIZE = 48;
byte packetBuffer[NTP_PACKET_SIZE];
WiFiUDP Udp;
const byte PinTemp = 0; // Датчики Dallas DS18B20 Temperature Sensors
int addr = 8; // i2c arduino
OneWire ds(PinTemp);
DallasTemperature DS18B20(&ds);
int numberOfDevices; // Number of temperature devices found
DeviceAddress tempDeviceAddress;
float temp1;
float temp2;
float temp3;
float temp4;
byte CRC;
char chartemp1[10];
char chartemp2[10];
char chartemp3[10];
char chartemp4[10];
byte TargetTemp1;
byte TargetTemp2;
byte TargetTemp3;
byte TargetTemp4;
byte hs, ms, he, me;
byte hour, minute;
byte SSR1on = 0; // 0 is Off, 1 is On
byte SSR2on = 0; // 0 is Off, 1 is On
byte SSR3on = 0; // 0 is Off, 1 is On
byte SSR4on = 0; // 0 is Off, 1 is On
byte sensor1[8];
byte sensor2[8];
byte sensor3[8];
byte sensor4[8];
char datestring[20];
const char* ssid = "-------------";
const char* password = "-------------";
unsigned long previousMillis = 0;
unsigned long UpdateMillis = 0;
ESP8266WebServer server ( 80 );
void checkupd() {
unsigned long currentMillis = millis();
if ((unsigned long)(currentMillis - UpdateMillis) >= 60000) {
UpdateMillis = currentMillis;
t_httpUpdate_return ret = ESPhttpUpdate.update("http://------------/esp/update.php", ver);
switch (ret) {
case HTTP_UPDATE_FAILED:
break;
case HTTP_UPDATE_NO_UPDATES:
break;
case HTTP_UPDATE_OK:
break;
}
}
}
float tempread(byte sensoraddr[])
// error codes:
// -1 no sensors found
// -2 invalid CRC
// -3 not a DS1820
{
byte i;
byte present = 0;
byte data[12];
byte addr[8];
for ( i = 0; i < 8; i++) {
addr[i] = sensoraddr[i];
}
ds.reset(); // pulse the pins and wait for a response to reset the DS1820
ds.select(addr); // 0x55 (MATCH_ROM) followed by the address of the 1820 to talk to.
ds.write(0x44, 0); //PARASITE POWER OFF
present = ds.reset();
ds.select(addr);
ds.write(0xBE); // Read Scratchpad
for ( i = 0; i < 9; i++) { // we need 9 bytes
data[i] = ds.read();
}
int16_t raw = (data[1] << 8) | data[0];
if (raw == -1 or raw == 0) {
if (CRC < 250) CRC++;
raw = 4000;
}
else
{
CRC = 0;
}
float temp = (float)raw / 16.0;
return temp;
}
void tim(const RtcDateTime& dt)
{
hour = dt.Hour();
minute = dt.Minute();
}
void relays() {
RtcDateTime now = Rtc.GetDateTime();
tim(now);
if (temp1 < TargetTemp1 - 1 and SSR1on == 0 and (CRC > 10 or CRC == 0)) {
byte senderArray[] = {4, 1, 0};
int addr = 8;
Wire.beginTransmission(addr); // transmit to device #8
Wire.write(senderArray, 3); // sends
Wire.endTransmission();
SSR1on = 1;
}
else if (temp1 > TargetTemp1 + 1 and SSR1on == 1 and (CRC > 10 or CRC == 0)) {
byte senderArray[] = {4, 1, 200};
int addr = 8;
Wire.beginTransmission(addr); // transmit to device #8
Wire.write(senderArray, 3); // sends
Wire.endTransmission();
SSR1on = 0;
}
if (temp2 < TargetTemp2 - 1 and SSR2on == 0 and (CRC > 10 or CRC == 0)) {
byte senderArray[] = {5, 1, 0};
int addr = 8;
Wire.beginTransmission(addr); // transmit to device #8
Wire.write(senderArray, 3); // sends
Wire.endTransmission();
SSR2on = 1;
}
else if (temp2 > TargetTemp2 + 1 and SSR2on == 1 and (CRC > 10 or CRC == 0)) {
byte senderArray[] = {5, 1, 200};
int addr = 8;
Wire.beginTransmission(addr); // transmit to device #8
Wire.write(senderArray, 3); // sends
Wire.endTransmission();
SSR2on = 0;
}
if (temp3 < TargetTemp3 - 1 and SSR3on == 0 and (CRC > 10 or CRC == 0)) {
byte senderArray[] = {2, 1, 0};
int addr = 8;
Wire.beginTransmission(addr); // transmit to device #8
Wire.write(senderArray, 3); // sends
Wire.endTransmission();
SSR3on = 1;
}
else if (temp3 > TargetTemp3 + 1 and SSR3on == 1 and (CRC > 10 or CRC == 0)) {
byte senderArray[] = {2, 1, 200};
int addr = 8;
Wire.beginTransmission(addr); // transmit to device #8
Wire.write(senderArray, 3); // sends
Wire.endTransmission();
SSR3on = 0;
}
if (temp4 < TargetTemp4 - 1 and SSR4on == 0 and (CRC > 10 or CRC == 0)) {
byte senderArray[] = {3, 1, 200};
int addr = 8;
Wire.beginTransmission(addr); // transmit to device #8
Wire.write(senderArray, 3); // sends
Wire.endTransmission();
SSR4on = 1;
}
else if (temp4 > TargetTemp4 + 1 and SSR4on == 1 and (CRC > 10 or CRC == 0)) {
byte senderArray[] = {3, 1, 0};
int addr = 8;
Wire.beginTransmission(addr); // transmit to device #8
Wire.write(senderArray, 3); // sends
Wire.endTransmission();
SSR4on = 0;
}
}
void Pdt(const RtcDateTime& dt)
{
snprintf(datestring,
20,
"%02d.%02d.%04d %02d:%02d:%02d",
dt.Day(),
dt.Month(),
dt.Year(),
dt.Hour(),
dt.Minute(),
dt.Second() );
}
void tempupd() {
temp1 = tempread(sensor1);
dtostrf(temp1, 4, 2, chartemp1);
temp2 = tempread(sensor2);
dtostrf(temp2, 4, 2, chartemp2);
temp3 = tempread(sensor3);
dtostrf(temp3, 4, 2, chartemp3);
temp4 = tempread(sensor4);
dtostrf(temp4, 4, 2, chartemp4);
}
void ds18b20() {
if (server.hasArg("ttemp1")) {
int SensorId = server.arg("ttemp1").toInt();
DS18B20.getAddress(tempDeviceAddress, SensorId);
for (uint8_t k = 0; k < 8; k++)
{
int p = k + 10;
EEPROM.write(p, tempDeviceAddress[k]);
sensor1[k] = tempDeviceAddress[k];
}
EEPROM.commit();
}
if (server.hasArg("ttemp2")) {
int SensorId = server.arg("ttemp2").toInt();
DS18B20.getAddress(tempDeviceAddress, SensorId);
for (uint8_t k = 0; k < 8; k++)
{
int p = k + 20;
EEPROM.write(p, tempDeviceAddress[k]);
sensor2[k] = tempDeviceAddress[k];
}
EEPROM.commit();
}
if (server.hasArg("ttemp3")) {
int SensorId = server.arg("ttemp3").toInt();
DS18B20.getAddress(tempDeviceAddress, SensorId);
for (uint8_t k = 0; k < 8; k++)
{
int p = k + 30;
EEPROM.write(p, tempDeviceAddress[k]);
sensor3[k] = tempDeviceAddress[k];
}
EEPROM.commit();
}
if (server.hasArg("ttemp4")) {
int SensorId = server.arg("ttemp4").toInt();
DS18B20.getAddress(tempDeviceAddress, SensorId);
for (uint8_t k = 0; k < 8; k++)
{
int p = k + 40;
EEPROM.write(p, tempDeviceAddress[k]);
sensor4[k] = tempDeviceAddress[k];
}
EEPROM.commit();
}
DS18B20.begin();
numberOfDevices = DS18B20.getDeviceCount();
DS18B20.requestTemperatures();
String output = "<!DOCTYPE html> <html>\
<meta http-equiv='Content-Type' content='text/html; charset=utf-8'>\
<title>Умный дом - настройка датчиков</title>";
output += "Devices: ";
output += numberOfDevices;
output += "<br>";
for (int i = 0; i < numberOfDevices; i++)
{
if (DS18B20.getAddress(tempDeviceAddress, i))
{
output += "ID " + String(i) + " - ";
for (uint8_t k = 0; k < 8; k++)
{
output += "0x";
// zero pad the address if necessary
if (tempDeviceAddress[k] < 16) output += "0";
output += String(tempDeviceAddress[k], HEX);
output += " ";
}
output += ": ";
output += DS18B20.getTempCByIndex(i);
//printAddress(tempDeviceAddress);
output += "°C<br>";
}
}
output += "<br>Прихожая <form method=POST><input type=text name=ttemp1 size=1> <input type=submit value=ОК> </form><br>\
Ванна <form method=POST><input type=text name=ttemp2 size=1> <input type=submit value=ОК> </form><br>\
Кухня <form method=POST><input type=text name=ttemp3 size=1> <input type=submit value=ОК> </form><br>\
Зал <form method=POST><input type=text name=ttemp4 size=1> <input type=submit value=ОК> </form><br>";
server.send ( 200, "text/html", output );
}
void root() {
if (server.hasArg("ttemp1")) {
TargetTemp1 = server.arg("ttemp1").toInt();
EEPROM.write(1, TargetTemp1);
EEPROM.commit();
}
if (server.hasArg("ttemp2")) {
TargetTemp2 = server.arg("ttemp2").toInt();
EEPROM.write(2, TargetTemp2);
EEPROM.commit();
}
if (server.hasArg("ttemp3")) {
TargetTemp3 = server.arg("ttemp3").toInt();
EEPROM.write(3, TargetTemp3);
EEPROM.commit();
}
if (server.hasArg("ttemp4")) {
TargetTemp4 = server.arg("ttemp4").toInt();
EEPROM.write(4, TargetTemp4);
EEPROM.commit();
}
relays();
char* ssr1;
char* ssr2;
char* ssr3;
char* ssr4;
int temp1i, temp1i2, temp2i, temp2i2, temp3i, temp3i2, temp4i, temp4i2;
temp1i = temp1;
temp2i = temp2;
temp3i = temp3;
temp4i = temp4;
temp1i2 = trunc((temp1 - temp1i) * 100);
temp2i2 = trunc((temp2 - temp2i) * 100);
temp3i2 = trunc((temp3 - temp3i) * 100);
temp4i2 = trunc((temp4 - temp4i) * 100);
int sec = millis() / 1000;
int min = sec / 60;
int hr = min / 60;
int days = hr / 24;
if (SSR1on == 0) ssr1 = "<font color=red><b>ВЫКЛ</b>";
else ssr1 = "<font color=green><b>ВКЛ</b>";
if (SSR2on == 0) ssr2 = "<font color=red><b>ВЫКЛ</b>";
else ssr2 = "<font color=green><b>ВКЛ</b>";
if (SSR3on == 0) ssr3 = "<font color=red><b>ВЫКЛ</b>";
else ssr3 = "<font color=green><b>ВКЛ</b>";
if (SSR4on == 0) ssr4 = "<font color=red><b>ВЫКЛ</b>";
else ssr4 = "<font color=green><b>ВКЛ</b>";
RtcDateTime now = Rtc.GetDateTime();
Pdt(now);
char temp[2000];
snprintf_P ( temp, 2000, "<!DOCTYPE html><html><head>\
<meta http-equiv='refresh' content='120'/>\
<meta http-equiv='Content-Type' content='text/html; charset=utf-8'>\
<title>Умный дом</title>\
<link rel='stylesheet' type='text/css' href='/main.css' media='all'>\
</head><body>\
<div class='main'>\
<center>\
<table border='0' class='catalogue' >\
<tr><td colspan=5 align=center><h3>Управление обогревом</h3></td></tr>\
<tr style='background-color: silver'>\
<td>Помещение:</td><td>Прихожая</td><td>Ванна</td><td>Кухня</td><td>Зал</td></tr>\
<tr><td>Температура:</td><td>%s °C</td><td>%s °C</td><td>%s °C</td><td>%s °C</td></tr>\
<tr><td>Обогрев:</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td></tr>\
<tr><td>Цель:</td><td>%d °C</td><td>%d °C</td><td>%d °C</td><td>%d °C</td></tr>\
<tr><td>Установить:</td>\
<td><form method=POST><input type=text name=ttemp1 size=1> <input type=submit value=ОК> </form></td>\
<td><form method=POST><input type=text name=ttemp2 size=1> <input type=submit value=ОК> </form></td>\
<td><form method=POST><input type=text name=ttemp3 size=1> <input type=submit value=ОК> </form></td>\
<td><form method=POST><input type=text name=ttemp4 size=1> <input type=submit value=ОК> </form></td>\
</tr></table><br>\
<table class='catalogue'>\
<tr><td colspan=2 align=center><h3>Часы</h3></td></tr>\
<tr style='background-color: silver'>\
<td>Аптайм</td><td>Время</td></tr>\
<tr><td>%dдн. %02d:%02d:%02d</td>\
<td>%s</td>\
</tr>\
</table>\
</center></div></body></html>", chartemp1, chartemp2, chartemp3, chartemp4, ssr1, ssr2, ssr3, ssr4, TargetTemp1, TargetTemp2, TargetTemp3, TargetTemp4, days, hr % 24, min % 60, sec % 60, datestring);
server.send ( 200, "text/html", temp );
}
void css () {
server.send ( 200, "text/css", "body { background:#990000;font-family:'Lucida Grande', Tahoma, Arial, Verdana, sans-serif;font-size:medium;margin:8px 0 16px;text-align:center; }\
.main { background:#fff;margin:0 auto;text-align:left;width:640px;box-shadow: 13px 6px 16px rgba(22,22,22,0.5);border-radius:6px;padding: 3px 4px 3px 4px; }\
TABLE.catalogue {BACKGROUND: #FEFEFE; margin: 2px 2px 2px 5px; BORDER: #999999 1px solid; WIDTH: 99%; BORDER-COLLAPSE: collapse; }\
TABLE.catalogue td {FONT-SIZE: 14px; text-align: center; padding:2px 2px 2px 2px; BORDER: #BBBBBB 1px solid; }\
input { text-align: center; FONT-SIZE: 14px; }\
h3 {padding:0;margin:0;}");
}
void handleNotFound() {
String message = "File Not Found\n\n";
message += "URI: ";
message += server.uri();
message += "\nMethod: ";
message += ( server.method() == HTTP_GET ) ? "GET" : "POST";
message += "\nArguments: ";
message += server.args();
message += "\n";
for ( uint8_t i = 0; i < server.args(); i++ ) {
message += " " + server.argName ( i ) + ": " + server.arg ( i ) + "\n";
}
server.send ( 404, "text/plain", message );
}
unsigned long sendNTPpacket(IPAddress& address) {
memset(packetBuffer, 0, NTP_PACKET_SIZE);
packetBuffer[0] = 0b11100011; // LI, Version, Mode
packetBuffer[1] = 0; // Stratum, or type of clock
packetBuffer[2] = 6; // Polling Interval
packetBuffer[3] = 0xEC; // Peer Clock Precision
packetBuffer[12] = 49;
packetBuffer[13] = 0x4E;
packetBuffer[14] = 49;
packetBuffer[15] = 52;
Udp.beginPacket(address, 123); //NTP requests are to port 123
Udp.write(packetBuffer, NTP_PACKET_SIZE);
Udp.endPacket();
}
void timeupd () {
unsigned long currentMillis = millis();
if ((unsigned long)(currentMillis - previousMillis) >= 36000000) {
previousMillis = currentMillis;
Serial.println("TimeUpdate!");
WiFi.hostByName(ntpServerName, timeServerIP);
sendNTPpacket(timeServerIP);
delay(1000);
int cb = Udp.parsePacket();
if (cb) {
Udp.read(packetBuffer, NTP_PACKET_SIZE); // read the packet into the buffer
unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);
unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]);
unsigned long secsSince1900 = highWord << 16 | lowWord;
Serial.print("Seconds since Jan 1 1900 = " );
Serial.println(secsSince1900);
Serial.print("From 2000 time = ");
const unsigned long seventyYears = 3155662800UL;
unsigned long epoch = secsSince1900 - seventyYears;
Serial.println(epoch);
Serial.print("The UTC time is "); // UTC is the time at Greenwich Meridian (GMT)
Serial.print((epoch % 86400L) / 3600); // print the hour (86400 equals secs per day)
Serial.print(':');
if ( ((epoch % 3600) / 60) < 10 ) {
Serial.print('0');
}
Serial.print((epoch % 3600) / 60); // print the minute (3600 equals secs per minute)
Serial.print(':');
if ( (epoch % 60) < 10 ) {
Serial.print('0');
}
Serial.println(epoch % 60); // print the second
RtcDateTime compiled = RtcDateTime(epoch);
if (!Rtc.IsDateTimeValid())
{
Rtc.SetDateTime(compiled);
}
if (!Rtc.GetIsRunning())
{
Rtc.SetIsRunning(true);
}
RtcDateTime now = Rtc.GetDateTime();
Rtc.SetDateTime(compiled);
}
}
}
void setup() {
EEPROM.begin(50);
pinMode(PinTemp, INPUT);
Udp.begin(localPort);
TargetTemp1 = EEPROM.read(1);
TargetTemp2 = EEPROM.read(2);
TargetTemp3 = EEPROM.read(3);
TargetTemp4 = EEPROM.read(4);
for (int i = 0; i < 8; i++) {
int k = i + 10;
sensor1[i] = EEPROM.read(k);
k = k + 10;
sensor2[i] = EEPROM.read(k);
k = k + 10;
sensor3[i] = EEPROM.read(k);
k = k + 10;
sensor4[i] = EEPROM.read(k);
}
WiFi.mode(WIFI_STA);
Serial.begin(115200);
WiFi.begin ( ssid, password );
Serial.println ( "" );
while ( WiFi.status() != WL_CONNECTED ) {
delay ( 500 );
Serial.print ( "." );
}
Serial.println ( "" );
Serial.print ( "Connected to " );
Serial.println ( ssid );
Serial.print ( "IP address: " );
Serial.println ( WiFi.localIP() );
server.on ( "/", root );
server.on ( "/ds18b20", ds18b20 );
server.on ( "/main.css", css );
server.onNotFound ( handleNotFound );
server.begin();
Wire.begin(); // join i2c bus (address optional for master)
Wire.pins(4, 5);
int addr = 8;
byte senderArray2[] = {2, 1, 200};
Wire.beginTransmission(addr); // transmit to device #8
Wire.write(senderArray2, 3); // sends
Wire.endTransmission();
byte senderArray3[] = {3, 1, 0};
Wire.beginTransmission(addr); // transmit to device #8
Wire.write(senderArray3, 3); // sends
Wire.endTransmission();
byte senderArray4[] = {4, 1, 200};
Wire.beginTransmission(addr); // transmit to device #8
Wire.write(senderArray4, 3); // sends
Wire.endTransmission();
byte senderArray5[] = {5, 1, 200};
Wire.beginTransmission(addr); // transmit to device #8
Wire.write(senderArray5, 3); // sends
Wire.endTransmission();
Serial.print("compiled: ");
Serial.print(__DATE__);
Serial.print(" ");
Serial.println(__TIME__);
Rtc.Begin();
RtcDateTime compiled = RtcDateTime(__DATE__, __TIME__);
Pdt(compiled);
Serial.println();
if (!Rtc.IsDateTimeValid())
{
Serial.println("RTC lost confidence in the DateTime!");
Rtc.SetDateTime(compiled);
}
if (!Rtc.GetIsRunning())
{
Serial.println("RTC was not actively running, starting now");
Rtc.SetIsRunning(true);
}
RtcDateTime now = Rtc.GetDateTime();
if (now < compiled)
{
Serial.println("RTC is older than compile time! (Updating DateTime)");
Rtc.SetDateTime(compiled);
}
else if (now > compiled)
{
Serial.println("RTC is newer than compile time. (this is expected)");
}
else if (now == compiled)
{
Serial.println("RTC is the same as compile time! (not expected but all is fine)");
}
// never assume the Rtc was last configured by you, so
// just clear them to your needed state
Rtc.Enable32kHzPin(false);
Rtc.SetSquareWavePin(DS3231SquareWavePin_ModeNone);
timeupd ();
}
void loop() {
server.handleClient();
timeupd();
relays();
tempupd();
checkupd();
}
Небольшие пояснения по коду:
1) Это ESP8266.
2) Этот модуль работает на 3.3в, а модули реле у меня требуют 5в, поэтому пришлось использовать Arduino как прокладку =) ESP с Ардуино общается по Wire
3) Еще есть RTC модуль для хранения времени, тоже подключен по Wire.
4) Добавилась страница /ds18b20 где выводится список всех датчиков, которые можно сохранить в EEPROM встроенный в ESP, чтоб не прописывать в коде руками.
Как вариант, можно вообще всю страничку разместить на внешнем ресурсе, а в ардуинке только значения параметров.
Ага, если бы всё было так просто ;) Вы попробуйте, и расскажите нам о результатах, когда с одного домена, на котором у вас размещена страница, вы будете получать данные, отправляя запрос к другому домену (которым будет выступать дуина). И тогда сразу лихорадочно будем вспоминать про политики ограничения кроссдоменных запросов в браузерах, и как это побороть.
Зачем вам два домена можете пояснить????
Ардуино справляется с этим прекрасно, будущий клиентом
Рассказываю.
Данные передаем через iframe.src=http://ТвойДомен/arduina.html?param=value
Получаем через:
<script type="text/javascript" src="http://ТвойДомен/script.js"></script>
путем обновления страницы.
Начинай лихорадочно вспоминать про кроссдоменные запросы.
DIYMan
Прошу понять меня правильно и не обижаться. Есть код (выкладывал его ранее), который я подогнал на работу с восемью датчиками и восемью реле (подогнал из первоначального скетча в этой теме). Есть необходимость уйти с ENC28J60 на W5100. На то свои причины, главная из которой - неработоспособность ENC при превышении HTTP_части кода 1279 символов, включая пробелы. Сам я не программист ни разу, о чем тоже сообщал. И теперь, вместо того, что бы написать: "парни, пишите так и вот так", я вижу много слов на тему "код, что привели - в помойку", "есть RFC на тему...." Вопрос чисто риторический: вот какой практический смысл всего этого? Блеснуть познаниями в RFC? Тогда где номер RFC? Просто блеснуть чем-либо? Ну ок, потешил эго, дальше что? Еще раз призываю понять меня правильно и не обижаться.
Deuce, в твоем коде никто не захочет ковыряться.
Вот здесь реализовано на W5100: http://arduino.ru/forum/programmirovanie/webserver-na-arduino-2560-i-eth...
Deuce, в твоем коде никто не захочет ковыряться.
Переживу. Особенно учитывая, что это не "мой код". я взял код тс. И просто подогнал под большее кол-во датчиков. Для себя я рано или поздно сделаю задуманное. Как и во всех случаях, за исключением одного, без участия этого форума. :)
Речь шла о локальной HTML-странице, с которой идёт запрос к ардуине. В терминах веб, локальная страница - тоже отдельный домен. Дальше объяснять или сами про CORS в вики почитаете?
Рассказываю.
Данные передаем через iframe.src=http://ТвойДомен/arduina.html?param=value
Получаем через:
<script type="text/javascript" src="http://ТвойДомен/script.js"></script>
путем обновления страницы.
Начинай лихорадочно вспоминать про кроссдоменные запросы.
Дык то, что вы привели - костыль, который специально используют, чтобы обойти CORS, называется этот костыль - JSONP. Без P - работать не будет. Что такое P после JSON - предлагаю догадаться.
DIYMan
Прошу понять меня правильно и не обижаться. Есть код (выкладывал его ранее), который я подогнал на работу с восемью датчиками и восемью реле (подогнал из первоначального скетча в этой теме). Есть необходимость уйти с ENC28J60 на W5100. На то свои причины, главная из которой - неработоспособность ENC при превышении HTTP_части кода 1279 символов, включая пробелы. Сам я не программист ни разу, о чем тоже сообщал. И теперь, вместо того, что бы написать: "парни, пишите так и вот так", я вижу много слов на тему "код, что привели - в помойку", "есть RFC на тему...." Вопрос чисто риторический: вот какой практический смысл всего этого? Блеснуть познаниями в RFC? Тогда где номер RFC? Просто блеснуть чем-либо? Ну ок, потешил эго, дальше что? Еще раз призываю понять меня правильно и не обижаться.
Да никаких обид. Просто я речь веду о том, что если вы взялись делать что-то подобной сложности - надо для начала почитать хотя бы основы, а не кидаться сразу в бой. Ничем я блеснуть не хочу, мне и без этого работ и забот хватает. Я лишь предупреждаю, что при таком подходе - дальше будет только хуже, и понимания - не придёт ни на грош, будет только тупое и бессмысленное дёрганье кусков кода из чужих скетчей. Хочешь сделать хорошо? Сделай это сам!
У нас вообще классно всё устроено - можно без прав и знания ПДД шмалять по дорогам на убитых машинах - а чо, вон друзья ездят! Вот ваш подход примерно из той же оперы - не зная самых необходимых основ - пытаетесь сразу впихнуть невпихуемое. А чревато это, как и в случае с авто - скорой аварией. Впрочем, зато механикам работа всегда будет.
Короче, я на вас молюсь - не будь вас, не было бы у меня работы :)
Где там речь о локальной странице??? Парень предложил просто саму страницу разместить на "внешнем ресурсе", Не придав смысла. А имел ввиду скорее всего создать страницу, к которой будет обращаться Ардуино, но ни как на оборот.
Если все же, я ошибся, то тогда встречный вопрос , а зачем все так усложнять???
Конечно лет 10 назад, я бы еще понял, экономия трафика, но сейчас...
Может и я не так понял - кто к кому будет обращаться, бывает. К вопросу "зачем всё так усложнять" - а зачем вообще знать основы? Ведь можно взять - и наговнякать. Это не к вам лично, это вообще - современный потреблядский подход: сначала сделать, а потом чесать репу - почему не работает. Потом задать кучу ненужных вопросов, которые можно было бы решить, почитав сразу документацию.
Ну ведь основа же - политики безопасности браузеров. И кстати - есть сценарии использования, при которых вы не сможете без плясок с бубном получить данные со страницы в веб, неважно, запросив их с ардуины ли или ещё откуда. Но я об этом тихо промолчу, ок? А то всё равно это никому неинтересно.
Даже очень интересно, Вот сейчас сижу и калдую, динамическую переменную получаю с удаленный вебстр
Я вот колбасу в дальнем магазине тоже покупаю без проблем, и что? Без указания юзкейса ваши слова - ни о чём. Я тоже могу получить чего-нибудь с веб-страницы, но - далеко не с каждой, и далеко не любым способом. Если вам это подвластно - поздравляю, вы волшебник.
Впрочем, разговор ни о чём, поскольку тут никто даже не заморачивается чтением хоть какой-либо документации, как правило.
З.Ы. У вас, кстати, при получении значения переменной анализируется Expires и, хотя бы, 302 Content moved? Я уже не говорю о Last-Modified - а то вы там такого старого говна получите с сервера, что уверенности в достоверности полученных данных не останется ни на грош. Впрочем, это неправильный, профессиональный подход, правильные пацаны таким не заморачиваются.
Вы, наверное, тоже не паритесь? ;)
Вы правы, Мне незачем этим париться))). Я конечно не гуру, но у меня страница получает данные каждую секунду, записывая все в базу. Изменения на странице, Так-же записываются в базу и выводятся в строчку.Ну а дальше генерации графиков и т.п. Смысл создания был, Не привязываться к одному контролеру и максимальную гибкость. На данный момент можно добавлять очень много контроллеров, к примеру esp12 встроенных в выключатели, розетки и т.п. И управлять всем этим с одной страницы. Гибкость, пишу приложение под андроид.
Я к чему, что каждый начинает как может. Только хватит ума и терпения не каждому. Ну а кто пытается хоть как, молодцы, Все лучше чем х**ней страдать
Это называется поумничали и разошлись =), а по делу хоть номер RFC дайте, а еще лучше если уж Вы на нас молитесь и для Вас это просто напишите реализацию этих умных слов: "FORM описать атрибуты TARGET и METHOD, чтобы браузер знал, куда и каким методом засунуть данные, введённые пользователем. Затем - при отправке формы по кнопке <input type="submit"...> на URI, указанный в TARGET, методом, указанном в METHOD, придут данные, закодированные в соответствии с указанием кодировки, это описывается аттрибутом ENCTYPE формы. Принимаете HTTP-запрос для этого URI, разбираете переданные значения, декодируете их, если потребуется"
ЗЫ. память пока не жмет, ее еще много =)
Deuce, в твоем коде никто не захочет ковыряться.
Переживу. Особенно учитывая, что это не "мой код". я взял код тс. И просто подогнал под большее кол-во датчиков. Для себя я рано или поздно сделаю задуманное. Как и во всех случаях, за исключением одного, без участия этого форума. :)
а может попробуем взять данные не из формы ввода, а из кнопки и например сделаем 2-4 кнопки к которым будет привяза определенная температура, быть может так будет проще?
Это называется поумничали и разошлись =), а по делу хоть номер RFC дайте, а еще лучше если уж Вы на нас молитесь и для Вас это просто напишите реализацию этих умных слов: "FORM описать атрибуты TARGET и METHOD, чтобы браузер знал, куда и каким методом засунуть данные, введённые пользователем. Затем - при отправке формы по кнопке <input type="submit"...> на URI, указанный в TARGET, методом, указанном в METHOD, придут данные, закодированные в соответствии с указанием кодировки, это описывается аттрибутом ENCTYPE формы. Принимаете HTTP-запрос для этого URI, разбираете переданные значения, декодируете их, если потребуется"
ЗЫ. память пока не жмет, ее еще много =)
За вас писать? Зачем? У меня и так работы хватает. Вам нужен RFC по HTTP? В гугле не забанили часом? Так и набираете - HTTP RFC. Заодно можно стандарт HTML почитать, про те же атрибуты тега FORM, чтобы прояснение наступило.
По поводу "поумничали": не далее как пару дней назад ещё раз убедился, что политика безопасности браузеров работает, и, если не знать про CORS - дулю можно получить вместо результата запроса. Суть была проста: есть страничка, которая выдаётся Мегой с SD-карточки в браузер, через вай-фай-вундерфафлю ESP8266. С неё отправляю AJAX-запросы на мегу же, получаю ответ, чего-то там на страничке делаю JavaScript'ом. Ну ведь неудобно же - изменил страницу, для тестирования её надо закачать на карточку, а для этого карточку надо вынуть из меги. Сохранил страницу локально, открываю её, жмакаю кнопку "опросить датчики", а Firefox дулей крутит и говорит: мил человек, не покажу я тебе ответ от меги, т.к. не нашёл я в ответе заголовок один секретный, поэтому - кури в сторонке.
Думаю - а ведь точно, прошляпил по старости лет. Открыл прошивку, дописал выдачу заголовка Access-Control-Allow-Origin: * - и пошёл пить чай, т.к. всё заработало.
Но это реальным пацанам неинтересно - RFC ведь мало того, что читать надо, так они, цуки, ещё и на басурманском! Мы лучше так налабаем, а потом будем кричать - ааа, почему не работает мой кривой скетч?
З.Ы. Полная реализация обработки данных с формы, если делать в соответствии с RFC - вещь далеко не тривиальная и, боюсь, ресурсиков дурины тут не хватит.
З.З.Ы. Вот моё видео, в котором показана работа с браузером. Там и ссылка на проект на гитхабе есть.
http://www.youtube.com/watch?v=L8ox4UzQNxs
вот то что получилось у меня, создал новую тему потому что пришедший сюда новичек вроде меня, не найдет http://arduino.ru/forum/proekty/web-server-dlya-mega5100dhtds18b20
ПОдскажите куда копать. собрал схему, когда захожу на веб морду температуру пишет -0.06 и никак не меняеться. куда копать. через монитор порта темперетуру показывают датчики правильбную а через веб никак. куда копнуть кто подскажет.
Рад что кому-то пригодились мои труды =)
Скоро выложу обновленный код на ESP
Небольшие пояснения по коду:
1) Это ESP8266.
2) Этот модуль работает на 3.3в, а модули реле у меня требуют 5в, поэтому пришлось использовать Arduino как прокладку =) ESP с Ардуино общается по Wire
3) Еще есть RTC модуль для хранения времени, тоже подключен по Wire.
4) Добавилась страница /ds18b20 где выводится список всех датчиков, которые можно сохранить в EEPROM встроенный в ESP, чтоб не прописывать в коде руками.
5) Есть OTA обновления по воздуху.