вывод информации на веб страницу+ get запрос на сервер
- Войдите на сайт для отправки комментариев
Пт, 19/04/2019 - 20:03
Добрый день,есть проект - глубиномер, вычисляет клубину погружения исходя из разницы давления на поверхности и под водой на двух китайских модулях BMP-280
задача вывести его показания на веб страницу решены в принципе, хотелось бы, чтоб он эти параметры (глубина, температура) отправлял на веб сервер который принимает запросы формата
http://open-monitoring.online/get?cid=НОМЕРУЧЕТКИ&key=ЛИЧНЫЙКЛЮЧ=ЗНАЧ1&p2=ЗНАЧ2&p3=ЗНАЧ3&p4=ЗНАЧ4&p5=ЗНАЧ5&p6=ЗНАЧ6
голову ломаю не получается совместить...
исх код чисто вывод в веб (слепил из пары других) так что сильно не пинайте
//#include <DHT.h>
#include <Wire.h>
#include <EtherCard.h>
#include <Adafruit_BMP280.h>
#include <LiquidCrystal_I2C.h>
// Используемые пины
Adafruit_BMP280 bmp1;
Adafruit_BMP280 bmp2; // I2C
//#define SDA A4
//#define SCL A5
LiquidCrystal_I2C lcd(0x27, 16, 2);
//Настройки сети
byte Ethernet::buffer[700]; //Буфер для приема и передачи по сети
static byte mac[] = {0x74,0x69,0x69,0x2D,0x30,0x31}; // mac-адрес
#define interval_get_data
#define DEBUG 0 // 1 - Отладка по COM-порту
// 0 - без отладки
#define XML 0 // 1 - Вывод данных в формате XML через веб
// 0 - Вывод в HTML
#define STATIC 1 // 0 - использовать DHCP
// 1 - статическая адресация, использовать данные, указаные ниже
#if STATIC
static byte ip[] = { 192,168,1,75 };
static byte gw[] = { 192,168,1,1 };
static byte dns[] = { 192,168,1,254 };
static byte mask[] = { 255,255,255,0 };
#endif
/////////////////////////////////////
// Установки
void setup()
{
Serial.begin(9600);
Serial.println(F("BMP280 test"));
//Инициализируем барометр
//bmp.begin();
bool status;
status = bmp1.begin(0x77);
status = bmp2.begin(0x76);
lcd.init();
lcd.backlight();
//Инициализируем сеть
// Запускаем сеть и указываем куда подключен CS-пин
ether.begin(sizeof Ethernet::buffer, mac, 10);
#if STATIC
ether.staticSetup(ip, gw, dns, mask);
#else
ether.dhcpSetup();
#endif
#if DEBUG
Serial.begin(9600);
#endif
}
/////////////////////////////////////
// Конструкторы объектов
// Adafruit_BME280 bme1; //Барометр
BufferFiller bfill; //Буфер для формирования xml-файла
unsigned long millis_int1=0; //Для задержек на экране
static float correct = 1.55; //Коррекционная переменная
// Опрашиваем датчики и формируем XML
static word sensorsToXml()
{
char tempBmp[6], Glub[7], RaznPres[10], presBmp[7], altBmp[7]; //Барометр
static char cor[15]; //Переменные
// Опрос датчиков и перевод значений в строки
//dtostrf( float d, int w, int r, char* str) - перевод из числа в сторку
// float d - число, которое переводим в строку
// int w - минимальный размер получаемой строки
// int r - количестов знаков после запятой
// char* str- стока, в которую записывается полученое значение
//bmp.readAltitude = (((bmp.readPressure()/9777.2)*1000)-10297);
dtostrf(bmp1.readTemperature() , 4, 2, tempBmp );
dtostrf(((bmp2.readPressure()- (bmp1.readPressure()- 264))/9777.18*1000)*correct , 6, 2, Glub );
dtostrf((bmp2.readPressure()- (bmp1.readPressure()- 264)),6,2, RaznPres);
dtostrf(bmp1.readPressure()*0.007501 , 6, 2, presBmp );
dtostrf(bmp1.readAltitude() , 5, 2, altBmp );
dtostrf(correct , 5, 2, cor );
// Формируем страничку
bfill = ether.tcpOffset();
#if XML // Если надо выдавать в XML
bfill.emit_p(PSTR
(
"<?xml version=\"1.0\"?>\n"
"<сенсоры>\n"
"<ТемператураВоздуха>$S*C</ТемператураВоздуха>\n"
"<Глубина>$Sмм</Глубина>\n"
"<РазницаДавления>$S</РазницаДавления>\n"
"<Давление>$S</Давление>\n"
"<Высота>$Sм</Высота>\n"
"<Корекция>$S</Коррекция>\n"
"</сенсоры>"
),tempBmp, Glub, RaznPres, presBmp, altBmp,corr);
#else // Вывод в HTML
bfill.emit_p(PSTR(
"HTTP/1.0 200 OK\r\n"
"Content-Type: text/html\r\n"
"Pragma: no-cache\r\n"
"\r\n"
"<meta http-equiv='refresh' content='120' charset='utf-8'/>"
"<title>Глубиномер</title>"
"<h1>Температура воздуха $S°C </br></h1>"
"<h1>Глубина $S mm </br></h1>"
"<h1>Разница Давления $S Pa</br></h1>"
"<h1>Давление $S Pa </br></h1>"
"<h1> Высота $S m</h1>"
"<h1> Коррекция $S</h1>"
"Current Temperature Setpoint: <b><font size=""4""> </font></b>"
"<form><input type=text name=daytemp size=4> <input type=submit value=Ok> </form>"
),tempBmp, Glub, RaznPres, presBmp, altBmp, cor);
#endif
#if DEBUG
// Serial.print("BMP280. T: "); пока отключен, так как постоянно в порт шлет отчеты
// Serial.print(tempBmp);
// Serial.print(" P: ");
// Serial.print(presBmp);
// Serial.print(" A:");
// Serial.println(altBmp);
#endif
return bfill.position();
}
// Выполнение
void loop()
{
// Получаем данные из буфера
word pos = ether.packetLoop(ether.packetReceive());
if (pos) // Если данные получены правильно
ether.httpServerReply(sensorsToXml()); // тогда отправляем их на выдачу
// через веб-сервер
delay (1);
if (millis() - millis_int1 > 2000) // Вместо 10000 подставьте нужное вам значение паузы
{
millis_int1 = millis();
Serial.print("Temperature = ");
Serial.print(bmp2.readTemperature());
Serial.println(" *C");
Serial.print("Temperature = ");
Serial.print(bmp1.readTemperature());
Serial.println(" *C");
Serial.print("Pressure = ");
Serial.print(bmp2.readPressure());
Serial.println(" Pa");
Serial.print("Pressure = ");
Serial.print(bmp1.readPressure());
Serial.println(" Pa");
int Glub = ((bmp2.readPressure()- (bmp1.readPressure()- 417))/9777.18*1000); //* correct;
Serial.print("Approx altitude = ");
Serial.print(bmp2.readAltitude(1013.25)); // this should be adjusted to your local forcase
Serial.println(" m");
Serial.print("Glubina = ");
Serial.print(Glub);
Serial.println(" mm");
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("H=");
lcd.print(Glub);
lcd.print("mm ");
lcd.print("t=");
lcd.print(bmp1.readTemperature());
lcd.print("C");
lcd.setCursor(0, 1);
lcd.print("P=");
lcd.print(bmp1.readPressure());
lcd.print("Pa ");
}
#if DEBUG
delay(2000);
#endif
}
Так, не понял, нужна помощь или нужно "не пинать"? Одно с другим несовместимо.
Заметил я вот что: модно стало в последнее время лепить. Петухов из навоза, код... А ведь раньше его писали.
нужна помощь, как к этому прикрутить Get запрос?
простите пожалуйста, я с ардуино познакомился 2 мес назад, потому пока чужие коды использую
нужна помощь, как к этому прикрутить Get запрос?
Ну, не знаю.
Конкретных вопросов, как я понимаю у Вас нет? Вам просто надо, чтобы кто-то за Вас его "прикрутил"?
Или что Вам конкретно нужно?
Заметил я вот что: модно стало в последнее время лепить. Петухов из навоза, код... А ведь раньше его писали.
Так и сейчас пишут. Те, кто умеют. А остальным что делать? Вот они, бедняги, и лепят, набрасывают, кодят, прогают.
да конкретные вопросы есть... 1 - возможно ли прикрутить к данному коду get запрос раз в минуту на определенный адресс, часть из которого состоит из переменных
2 - толкнуть хотя бы к приблизительной реализации того, что я хочу, а то сегодня уже пытался скрестить ужа с ежом, но не получилось, вроде скомпилилось, но не работает( точнее работает как и прежде, но никаких попыток постучатся в куда то в интернер роутер от него не обнаружил
З.Ы.
Пытался скрестить с этим
#include <EtherCard.h> // ethernet interface mac address, must be unique on the LAN 07static byte mymac[] = { 0x74,0x69,0x69,0x2D,0x30,0x31 }; byte Ethernet::buffer[700]; static uint32_t timer; const char website[] PROGMEM = "www.google.com"; // called when the client request is complete static void my_callback (byte status, word off, word len) { Serial.println(">>>"); Ethernet::buffer[off+300] = 0; Serial.print((const char*) Ethernet::buffer + off); Serial.println("..."); } void setup () { Serial.begin(57600); Serial.println(F("\n[webClient]")); if (ether.begin(sizeof Ethernet::buffer, mymac) == 0) Serial.println(F("Failed to access Ethernet controller")); if (!ether.dhcpSetup()) Serial.println(F("DHCP failed")); ether.printIp("IP: ", ether.myip); ether.printIp("GW: ", ether.gwip); ether.printIp("DNS: ", ether.dnsip); if (!ether.dnsLookup(website)) Serial.println("DNS failed"); ether.printIp("SRV: ", ether.hisip); } void loop () { ether.packetLoop(ether.packetReceive()); if (millis() > timer) { timer = millis() + 5000; Serial.println(); Serial.print("<<< REQ "); ether.browseUrl(PSTR("/foo/"), "bar", website, my_callback); } }...продемонстрируйте ужа с ежом.
увы не могу, флешку на работе забыл
предоставил ежа и ужа)
У Вас же ENC28J60?
Я бы для начала посоветовал взять UIPEthernet. Там есть пример WebClient... Вот вместо URL подсовываете свою длинную строку...
да, ENC28J60... пока, заказал ,W5500, попробую еще с ней,а тех ужах/ежах то, что хочу не построить?
Построить. Но я вам советую как проще это сделать.
я просто по отзывам слышал, что наиболее стабильная библиотека ethercard, потому с нее и начал, вот и прошу подсказать куда бы по посмотреть?
вот и прошу подсказать куда бы по посмотреть?
блин, а в примеры к библиотеке не пришло в голову заглянуть? там есть веб-клиент, а в нем get-запрос
выше уже писал, что пытался прикрутить пример с библиотеки, но он не заработал, все компилируется без ошибок, но в статистике роутера нет от клиента никаких попыток никуда постучатся
выше уже писал, что пытался прикрутить пример с библиотеки, но он не заработал, все компилируется без ошибок, но в статистике роутера нет от клиента никаких попыток никуда постучатся
выше вам уже сказали - показывайте, как пытались скрутить два кода. Без этого никакого обсуждения не будет.
На данный момент понял одну ошибку - не правильно формирую адрес сайта
http://open-monitoring.online/get?cid=НОМЕРУЧЕТКИ&key=ЛИЧНЫЙКЛЮЧp1=ЗНАЧ1&p2=ЗНАЧ2
пробовал как в ветке (http://arduino.ru/forum/programmirovanie/pomogite-razobratsya-5) советовал ЕвгенийП
но проблема в том, что в моем адрессе много знаков = и соответственно не получается создать правильно адрес подскажите, как еще можно сформировать этот запрос?
Сделать короткую ссылку и писать мало знаков.
дело в том, что сервер не мой, это как народный мониторинг - они пишут какой должен быть формат ссылки, я его изменить не могу
Я возможно не прав, но буквально сегодня на esp32 рисовал get запрос - можно запихнуть что угодно, т е в чем проблема вписать в запрос любые знаки не понял...
И да, как выше сказали - чем короче ссылка, тем надёжнее работать будет устройство и вообще весь проект.
char buffer[255]; uint32_t token; uint8_t param1; ... token=2312300; param1=123; ... snprintf_P(buffer, sizeof(buffer), PSTR("хттп://site/getdata.php?token=%lu&p1=%u"), token, param1); Serial.println(buffer); ...дело в том, что сервер не мой, это как народный мониторинг - они пишут какой должен быть формат ссылки, я его изменить не могу
А короткая ссылка чем виновата? Сервер её и не увидит. Он увидит свою длинную. Вы знаете сервисы коротких ссылок?
А короткая ссылка чем виновата? Сервер её и не увидит. Он увидит свою длинную. Вы знаете сервисы коротких ссылок?
Попробовал я сервис коротких ссылок, с добавлением параметра, но по типу https://is.gd/2OaJ4v=1200 - но до сервера не доходит параметр
Жаль. Мож другой сервис поискать? У меня с каким-то доходило
По мне так проблема абсолютно надуманная. В 700-байтовый буфер для EtherCard url вполне влезет как с оригинальным url, так и с shortened. А для UIPEthernet вообще можно делать print()/write() пока не надоест.
Да проблема не в том, влезет или нет, проблема в том, что в оригинальном URL присутствуют много знаков '=' и мне после 2х последних = надо вставить данные типа int и float
Не вижу никакой проблемы и в этом. Я понимаю, что ЕвгенийП авторитетней, но в жизни задачи не решаются исключительно одним единственным способом.
Да проблема не в том, влезет или нет, проблема в том, что в оригинальном URL присутствуют много знаков '=' и мне после 2х последних = надо вставить данные типа int и float
Вставляете, что мешает?
Жаль. Мож другой сервис поискать? У меня с каким-то доходило
продолжаю ковырять сервисы, может и найду, но даже это не решит вопроса с 2 мя параметрами
продолжаю ковырять сервисы, может и найду, но даже это не решит вопроса с 2 мя параметрами
может вы все-таки сформулируете точнее - в чем проблема вставить в URL знаки "=" и параметры? Может вы просто не умеете?
может вы все-таки сформулируете точнее - в чем проблема вставить в URL знаки "=" и параметры? Может вы просто не умеете?
Да, что то не получается никак(
еще раз весь код выкладывайте, и указать что конкретно не получается, переводите числовые данные в текст и они очень просто прицепляются к строке запроса
Только свой, самописный, код выкладывайте. Примеров из библиотек каждый из нас насмотрелся уже.
да я сейчас пока создал новый скетч, пытаюсь хотя бы в серийник заставить выводится правильный адрес
попробовал вот так осуществить, но ардуинка никаких телодвижений не делает
#include <Wire.h> #include <EtherCard.h> #include <Adafruit_BME280.h> #include <LiquidCrystal_I2C.h> // Используемые пины Adafruit_BME280 bme1; Adafruit_BME280 bme2; // I2C //#define SDA A4 //#define SCL A5 LiquidCrystal_I2C lcd(0x27, 16, 2); //Настройки сети byte Ethernet::buffer[700]; //Буфер для приема и передачи по сети static byte mac[] = {0x74,0x69,0x69,0x2D,0x30,0x31}; // mac-адрес const char website[] PROGMEM = "http://open-monitoring.online"; const char id[] PROGMEM = "479"; const char key[] PROGMEM = "DXfg2I&p1"; #define interval_get_data #define DEBUG 0 // 1 - Отладка по COM-порту // 0 - без отладки #define XML 0 // 1 - Вывод данных в формате XML через веб // 0 - Вывод в HTML #define STATIC 1 // 0 - использовать DHCP // 1 - статическая адресация, использовать данные, указаные ниже #if STATIC static byte ip[] = { 192,168,1,75 }; static byte gw[] = { 192,168,1,248 }; static byte dns[] = { 192,168,1,248 }; static byte mask[] = { 255,255,255,0 }; #endif ///////////////////////////////////// // Установки void setup() { Serial.begin(9600); Serial.println(F("BMP280 test")); //Инициализируем барометр //bmp.begin(); bool status; status = bme1.begin(0x77); status = bme2.begin(0x76); lcd.init(); lcd.backlight(); //Инициализируем сеть // Запускаем сеть и указываем куда подключен CS-пин ether.begin(sizeof Ethernet::buffer, mac, 10); #if STATIC ether.staticSetup(ip, gw, dns, mask); #else ether.dhcpSetup(); #endif #if DEBUG Serial.begin(9600); #endif } ///////////////////////////////////// // Конструкторы объектов // Adafruit_BME280 bme1; //Барометр BufferFiller bfill; //Буфер для формирования xml-файла unsigned long millis_int1=0; //Для задержек на экране static float correct = 1.05; //Коррекционная переменная int Glub = ((bme2.readPressure()- (bme1.readPressure()- 745))/9777.18*1000)* correct; // Функция отправки данных на сервер void send_package(){ ether.packetLoop(ether.packetReceive()); if (millis() - millis_int1 > 60000){ // Задержка передачи данных, Вместо 60000 подставьте нужное вам значение паузы char string_temp[7]; dtostrf(bme1.readTemperature(), 4, 2, string_temp); char string_glub[10]; int Glub = ((bme2.readPressure()- (bme1.readPressure()- 745))/9777.18*1000)* correct; itoa(Glub, string_glub , 10); Stash stash; byte sd = stash.create(); stash.print("cid="); stash.print(id); stash.print("&key="); stash.print(key); stash.print("p1="); stash.print(string_glub); stash.print("&p2="); stash.print(string_temp); stash.save(); Stash::prepare(PSTR("GET http://open-monitoring.online/get?$H HTTP/1.0" "\r\n" "Host: $F" "\r\n" "\r\n"), sd, website); ether.tcpSend(); Serial.print("Temperature "); Serial.print(string_temp); Serial.print(" sent to website... "); } } // Опрашиваем датчики и формируем XML static word sensorsToXml() { char tempBmp[6], Glub[7], RaznPres[10], presBmp[7], altBmp[7]; //Барометр static char cor[15]; //Переменные // Опрос датчиков и перевод значений в строки //dtostrf( float d, int w, int r, char* str) - перевод из числа в сторку // float d - число, которое переводим в строку // int w - минимальный размер получаемой строки // int r - количестов знаков после запятой // char* str- стока, в которую записывается полученое значение //bmp.readAltitude = (((bmp.readPressure()/9777.2)*1000)-10297); dtostrf(bme1.readTemperature() , 4, 2, tempBmp ); dtostrf(((bme2.readPressure()- (bme1.readPressure()- 745))/9777.18*1000)*correct , 6, 2, Glub ); dtostrf((bme2.readPressure()- (bme1.readPressure()- 745)),6,2, RaznPres); dtostrf(bme1.readPressure()*0.007501 , 6, 2, presBmp ); dtostrf(bme1.readAltitude(1013.25) , 5, 2, altBmp ); dtostrf(correct , 5, 2, cor ); // Формируем страничку bfill = ether.tcpOffset(); #if XML // Если надо выдавать в XML bfill.emit_p(PSTR ( "<?xml version=\"1.0\"?>\n" "<сенсоры>\n" "<ТемператураВоздуха>$S*C</ТемператураВоздуха>\n" "<Глубина>$Sмм</Глубина>\n" "<РазницаДавления>$S</РазницаДавления>\n" "<Давление>$S</Давление>\n" "<Высота>$Sм</Высота>\n" "<Корекция>$S</Коррекция>\n" "</сенсоры>" ),tempBmp, Glub, RaznPres, presBmp, altBmp, corr); #else // Вывод в HTML bfill.emit_p(PSTR( "HTTP/1.0 200 OK\r\n" "Content-Type: text/html\r\n" "Pragma: no-cache\r\n" "\r\n" "<meta http-equiv='refresh' content='120' charset='utf-8'/>" "<title>Глубиномер</title>" "<h1>Температура воздуха $S°C </br></h1>" "<h1>Глубина $S mm </br></h1>" "<h1>Разница Давления $S Pa</br></h1>" "<h1>Давление $S Pa </br></h1>" "<h1> Высота $S m</h1>" "<h1> Коррекция $S</h1>" ),tempBmp, Glub, RaznPres, presBmp, altBmp, cor); #endif #if DEBUG Serial.print("BMP280. T: "); Serial.print(tempBmp); Serial.print(" P: "); Serial.print(presBmp); Serial.print(" A:"); Serial.println(altBmp); #endif return bfill.position(); } // Выполнение void loop() { // Получаем данные из буфера word pos = ether.packetLoop(ether.packetReceive()); if (pos) // Если данные получены правильно ether.httpServerReply(sensorsToXml()); // тогда отправляем их на выдачу // через веб-сервер delay(1); send_package(); if (millis() - millis_int1 > 2000) // Задержка экрана, Вместо 10000 подставьте нужное вам значение паузы { millis_int1 = millis(); Serial.print("Temperature = "); Serial.print(bme2.readTemperature()); Serial.println(" *C"); Serial.print("Temperature = "); Serial.print(bme1.readTemperature()); Serial.println(" *C"); Serial.print("Pressure = "); Serial.print(bme2.readPressure()); Serial.println(" Pa"); Serial.print("Pressure = "); Serial.print(bme1.readPressure()); Serial.println(" Pa"); // int Glub = ((bme2.readPressure()- (bme1.readPressure()- 745))/9777.18*1000)* correct; Serial.print("Approx altitude = "); Serial.print(bme2.readAltitude(1013.25)); // this should be adjusted to your local forcase Serial.println(" m"); Serial.print("Glubina = "); Serial.print(Glub); Serial.println(" mm"); lcd.clear(); lcd.setCursor(0, 0); lcd.print("H="); lcd.print(Glub); lcd.print("mm "); lcd.print("t="); lcd.print(bme1.readTemperature()); lcd.print("C"); lcd.setCursor(0, 1); lcd.print("P="); lcd.print(bme1.readPressure()); lcd.print("Pa "); } #if DEBUG delay(2000); #endif }1) Что такое Stash?;
2) Пытались ли Вы URL через emit_p() сформировать?
как вы думаете, такая строчка допустима? Она хотя бы компилируется?
Почитайте что-нибудь о экранировании спецсимволов в строке - таких как кавычкек, слешей и тд
b707, тут нет его вины - движок форума url корячит, если http находит:
как вы думаете, такая строчка допустима? Она хотя бы компилируется?
Почитайте что-нибудь о экранировании спецсимволов в строке - таких как кавычкек, слешей и тд
так в сайт вставилось он посчитал, что это ссылка, а исправить не дает сейчас
1) Что такое Stash?;
2) Пытались ли Вы URL через emit_p() сформировать?
1 - вычитал что в библиотеке ethercard такая команда есть (буфер)
2 - пытался, но пока что то не получилось, пока гуглил - надрел вот на stash
b707, тут нет его вины - движок форума url корячит, если http находит:
я понимаю, что движок еще дополнительно строку корячит... но тем не менее, в начальной его строчке как минимум внутри строки есть кавычки
const char website[] PROGMEM = "h ttp: //open-monitoring .online";
так она выглядит
Вобщем, тут дело такое... С Ethernet тут мало кто занимается, с ENC28J60 ещё меньше, а по EtherCard тут специалистов почти не встречал. Поэтому придётся или библиотеку сменить или самому крепко вникать. Если, конечно, не найдётся кто-то очень увлечённый и не решит прямо вот ради Вас освоить её.
мне все же кажется, что я что то упустил и возможно самое примитивное
я так думаю вам стоит выкинусть с 96 по 111 строку, самостоятельно сформировать строку запроса, а потом ее вместо 112 строки уже отправить, но да, как выше сказали, надо разбираться с библиотекой, а строка формируется элементарно, типа так например:
String url = "/espimpt/p/"; url += "?rs="; url += countImpuls; url += "&id="; url += deviceid; for (byte i = 0; i < dsCount; ++i) { url += "&t"; url += i; url += "="; url += massTemper[i]; } url = "GET " + url + " HTTP/1.1\r\n" + "Host: " + srvhost + "\r\n" + "User-Agent: Mozilla/5.0 (X11; U; Linux i686; ru; rv:1.9b5) Gecko/2008050509 Firefox/3.0b5\r\n" + "Accept: text/html\r\n" + "Connection: Keep-Close\r\n\r\n"; Serial.println(url); client.println(url);"Keep-Close" - это чего за бульдорог? ;)
"Keep-Close" - это чего за бульдорог? ;)
это мой косяк :) старый код....
конечно же Close должно быть
client.println(url);
насколько я понимаю у ethercard такая команда не прокатит... все сложнее(
Никто не виноват в том, что Вы пытаетесь сделать посложнее, чем умеете.
client.println(url);
насколько я понимаю у ethercard такая команда не прокатит... все сложнее(
Да, все не просто, читаем литературу и документацию....