Точка доступа ESP8266 + JSON

Mestniy2496

New member
Друзья Есть у кого примеры как можно реализовать подобную систему?
Имеется приложение на андроид:
Fireplace.zip
Мне вот что нужно:
  • Это нужно реализовать в МК.
  • private final String BASE_ADDRESS = "http://127.0.0.1:8080/";
  • private final String VOLUME_INCREASE = "volume_increase";
  • private final String VOLUME_DECREASE = "volume_decrease";
  • private final String DEVICE_ON = "device_on";
  • private final String DEVICE_OFF = "device_off";
  • private final String TIMER_INCREASE = "timer_increase";
  • private final String TIMER_DECREASE = "timer_decrease";
  • private final String GET_STATE = "state";
  • ответ от МК всегда один, в виде Json:
  • final JSONObject jsonObject = new JSONObject(source);
  • final FirePlace firePlace = new FirePlace();
  • firePlace.setVolume(jsonObject.getInt("volume"));
  • firePlace.setOn(jsonObject.getBoolean("on"));
  • firePlace.setTime(jsonObject.getLong("time"));
Интересует именно реализация ESp в качестве точки доступа. Без прохода через роутера. Именно Android и ESP. Заранее Спасибо
 

Mestniy2496

New member
Код:
#include <ESP8266WiFi.h>
void setup()
{
  Serial.begin(115200);
  Serial.println();
  Serial.print("Setting soft-AP ... ");
           //  "Настройка программной точки доступа ... "
  Serial.println(WiFi.softAP("Fireplace", "Fireplace") ? "Ready" : "Failed!");
}
void loop()
{
}
Вот создание точки доступа в arduino IDE. как принять данные по HTTP от устройства, подключенного к этой ТД? И отправлять JSON? Я так понимаю нужна библиотека Arduinojson 6. Кто еще знаете что?
 

enjoynering

Active member
для 2019 года - это типовая задача на ESP (примеров куча)

- Arduinojson
- файловая система spiffs
- и асинхронный webserver - ESPAsyncWebServer (хоть в режиме STA, хоть в AP)

ограничение - 4 клиента.
 

Mestniy2496

New member
для 2019 года - это типовая задача на ESP (примеров куча)

- Arduinojson
- файловая система spiffs
- и асинхронный webserver - ESPAsyncWebServer (хоть в режиме STA, хоть в AP)

ограничение - 4 клиента.
А и еще вопрос возник: При чем тут SPIFFS? Мне нужно принимать пакеты данных HTTP. Обрабатывать их и отправлять ответ по JSON.
 

enjoynering

Active member
Есть ссылки с примерами?
я так понял вы из поклонения родившихся поле 80-х. только они имея под рукой гугл, яндекс и КЛЮЧЕВЫЕ слова для поиска все равно требуют ссылок. и лучше чтоб это был ютубчик, а не текст (читать щас не модно). молодеж. раньше чтобы достать информацию приходилось 2 часа на автобусе трястись до библиотеке, потом в картотеке рыться и ждать час пока книги принесут. а вам лень открыть новую вкладку, набрать ключевые слова и опа первая же ссылка ведет куда надо.

если только принимать пакеты данных HTTP, обрабатывать их и отправлять ответ по JSON, то да SPIFFS не нужен.
 

CodeNameHawk

Moderator
Команда форума
Очень благодарен. Есть ссылки с примерами? Если не трудно...
я так понял вы из поклонения родившихся поле 80-х. только они имея под рукой гугл, яндекс и КЛЮЧЕВЫЕ слова для поиска все равно требуют ссылок. и лучше чтоб это был ютубчик, а не текст (читать щас не модно). молодеж. раньше чтобы достать информацию приходилось 2 часа на автобусе трястись до библиотеке, потом в картотеке рыться и ждать час пока книги принесут. а вам лень открыть новую вкладку, набрать ключевые слова и опа первая же ссылка ведет куда надо.
Так все еще проще, вместе с библиотеками идут примеры.
 

Mestniy2496

New member
Ничего не получается =(((
Не совместимы некотореы строки с ESP8266WebServer.
Код:
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>

const char* ssid = "........";
const char* password = "........";

ESP8266WebServer server(80);
int volume_sound = 0;
bool device;
int volume_timer = 0;
int state = 0;
void handleRoot() {
  server.send(200, "text/plain", "hello from esp8266!");
}

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);

}

void setup(void){

  Serial.begin(115200);
  WiFi.begin(ssid, password);
  Serial.println("");

  // Wait for connection
  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());

  if (MDNS.begin("esp8266")) {
    Serial.println("MDNS responder started");
  }

  server.on("/", handleRoot);

server.on("/inline", HTTP_GET, [](){
  server.send(200, "text/plain", "this works as well");
});

  server.onNotFound(handleNotFound);

  server.begin();
  Serial.println("HTTP server started");
}

void loop(void){
  server.handleClient();
// проверяем, подключен ли клиент:
  WiFiClient client = server.available();
  if (!client) {
    return;
  }
 
  // ждем, когда клиент отправит какие-нибудь данные:
  Serial.println("new client");  //  "новый клиент"
  while(!client.available()){
    delay(1);
  }
 
  // считываем первую строчку запроса:
  String request = client.readStringUntil('\r');
  Serial.println(request);
  client.flush();
 
   // обрабатываем запрос:
  if (request.indexOf("/volume_increase") != -1) {
    if (volume_sound < 10)
    {
    volume_sound = volume_sound+1;
    Serial.println("volume_sound"+('0'+volume_sound))
    }
  }
  delay(1);
 
  if (request.indexOf("/volume_decrease") != -1){
    if (volume_sound > 0)
    {
    volume_sound = volume_sound - 1;
    Serial.println('0'+volume_sound)
    }
  }
  delay(1);
 
    if (request.indexOf("/timer_increase") != -1){
    if (volume_sound < 90)
    {
    volume_sound = volume_sound + 10;
    }
  }
  delay(1);
 
    if (request.indexOf("/timer_decrease") != -1){
    if (volume_sound > 0)
    {
    volume_sound = volume_sound - 10;
    }
  }
  delay(1);
 
    if (request.indexOf("/device_on") != -1){
    device = true;
  }
 
  delay(1);
      if (request.indexOf("/device_off") != -1){
    device = false;
  }
  delay(1);
 
}
}
Вот строка ошибки
Код:
WiFiClient client = server.available();
А вот сама ошибка:
Код:
exit status 1
'using ESP8266WebServer = class esp8266webserver::ESP8266WebServerTemplate<WiFiServer>' has no member named 'available'

Этот отчёт будет иметь больше информации с
включенной опцией Файл -> Настройки ->
"Показать подробный вывод во время компиляции"
 

Алексей.

Active member
Вы путаете кислое с зеленым, у сервера ESP8266WebServer вызываете метод, которого там нет. Этот метод есть у другого сервера WiFiServer.
 

Mestniy2496

New member
Я снова пришел насиловать ваши мозги. Не могу я посмотреть на входящие GET с помощью данной библиотеки. Хоть убейте.
 

Mestniy2496

New member
Можете мне обьяснить по строкам - как обработать get запрос и создать для него условие и обозначить IP?
 

Mestniy2496

New member
  • "volume_increase";volume_decrease"; "device_on";"device_off"; "timer_increase";"timer_decrease";"state"; Вот что мне отправляет приложение по IP и порту, который я хотел бы указать в arduino. Оно приходит в ESP, мне нужно перенаправлять эти показатели по serial в ардуино. А в Arduino обрабатывать и отправлять ответ ESP а та в свою очередь отправляла бы JSON ответ подключенному устройству.
 

Алексей.

Active member
Код:
#include <Arduino.h>
#include <ArduinoJson.h>

#ifdef ARDUINO_ARCH_ESP8266
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#define WebServerImpl ESP8266WebServer
#elif ARDUINO_ARCH_ESP32
#include <WiFi.h>
#include <WebServer.h>
#define WebServerImpl WebServer
#else
#error Unsupported architecture, use ARDUINO_ARCH_ESP8266 or ARDUINO_ARCH_ESP32
#endif

// Это ip адрес по которому будет доступен веб-сервер
IPAddress local_ip(192, 168,   4, 22);
// Это ip адрес шлюза, этот шлюз будут использовать wifi клиенты подключившиеся к точке доступа
IPAddress gateway (192, 168,   4,  9);
// Это маска подсети
IPAddress subnet  (255, 255, 255,  0);

// Экземпляр веб-сервера
WebServerImpl server(80);

// Это обработчик для запроса корневого url
void handle_root() {
  // Отвечаем текстом что выполнен запрос корневого url
  server.send(200, "text/plain", "This is response for root url.");
}

// Это обработчик для url /my-status
void handle_my_status() {
  // Строим документ
  StaticJsonDocument<256> doc;
  // Добавляем строковый элемент с именем "some_text" и значением "bla-bla"
  doc["some_text"] = "bla-bla";
  // Добавляем числовой элемент с именем "my_millis" и значением полученных millis
  doc["my_millis"] = millis();
  String output;
  // Серилизуем в строку
  serializeJson(doc, output);
  // Отправляем ответ клиенту
  server.send(200, "application/json", output);
}

// Это обработчик для всех остальных запросов
void handle_not_found() {
  // Отвечаем запросившему всё что мы о нем думаем
  // и отправляем обратно то, что он прислал в запросе.
  String message = "File Not Found\n\n";
  // Добавляем uri
  message += "URI: ";
  message += server.uri();
  // Добавляем запрошенный метод
  message += "\nMethod: ";
  message += server.method() == HTTP_GET ? "GET" : "POST";
  // Если в строке запроса есть ещё аргументы, добавим их в сообщение
  if (server.args() > 0) {
    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);
}

void setup() {
  // Инициализируем wifi
  // Отключаем сохранение параметров во флеш
  WiFi.persistent(false);
  // Выключаем wifi совсем
  WiFi.mode(WIFI_OFF);
  // Зачем-то спим немножко
  delay(100);
  // Устанавливаем параметры ip для интерфейса AP
  WiFi.softAPConfig(local_ip, gateway, subnet);
  // Выбираем режим работы wifi
  WiFi.mode(WIFI_AP);
  // Задаем идентификатор SSID
  WiFi.softAP("MY-ESP");
 
  // Настраиваем веб-сервер
  // Устанавливаем обработчик корневого url
  server.on("/", HTTP_GET, handle_root);
  // Устанавливаем обработчик для url /my-status
  server.on("/my-status", HTTP_GET, handle_my_status);
  // Устанавливаем обработчик для всего остального не обработанного
  server.onNotFound(handle_not_found);
  // Запускаем сервер
  server.begin();
}

void loop() {
  // Даем серверу обрабатывать запросы
  server.handleClient();
}
Опыты проводил на:
Arduino 1.8.9
arduino-esp32 1.0.4
ArduinoJson v6.13.0
 

Mestniy2496

New member
Да этот пример я видел... Я не вижу где здесь обрабатывается get запрос? И как этот запрос отправить в Serial=(((((((
 

Алексей.

Active member
Я не вижу где здесь обрабатывается get запрос? И как этот запрос отправить в Serial=(((((((
Если выполняется код в handle_root handle_my_status и handle_not_found - это как раз и есть то самое место где обрабатывается запрос.
Основное назначение обработки запроса это выполнить какие-то действия и дать клиенту, отравившему его, адекватный ответ.
Обработчики запроса для этого и предназначены. Выполните запрос и получите ответ.
Как вы думаете, если запрос отправлять в сериал, то как из сериала получить ответ на запрос и передать его клиенту?
 

Mestniy2496

New member
Но ведь код загружается в есп? А на арде висят релюшки и т.д.. Дело в том что мне нужно что то отправлять в саму арудино, чтобы управлять компонентами. Я про это и говорил.
 

Алексей.

Active member
Вы спрашивали как настроить esp в режиме точки доступа и как задать её ip адрес, я это показал.
Вы спрашивали как обрабатывать get запросы на веб-сервере, я показал как задать обработчики для конкретных методов и заданных url (в вашем случае должны быть /volume_increase /volume_decrease и т.д) .
Более того, показал в обработчике handle_not_found как узнать какой метод и url был запрошен и какие аргументы были в строке запроса (если они были). Можете не задавать отдельно обработчики по url-ам и всё обрабатывать в handle_not_found, вылавливать ваши url в строке получаемой из server.uri()
Про реле пожалуйста дайте ссылку на пост, я пока не нашел её.
Если речь идет о get запросах (не post а именно get) и get используется для управления реле, то логика переворачивается с ног на голову однако. get-ом мы уже не спрашиваем про что-то, а выполняя get говорим включи/выключи реле.
пичалька...
 

Mestniy2496

New member
Спасибо вам за все это. Я не говрю что нужно get управлять реле - я хочу просто при получении допустим:
"/ON" = отправлять в сериал к арде "ON". Обработку сериала я найду.
 

Алексей.

Active member
Так чтож вам мешает в обработчике not found вылавливать нужные url-ы отправлять в сериал что требуется, а клиенту отвечать двухсотым кодом, а если урло незнакомое отвечать 404-м.
 
Сверху Снизу