• Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

Нужна помощь Организация обмена данными посредством WebSockets

rkravt

Member
Запросы на сервер каждую секунду - ни есть хорошо. Это первое.
Т.е. esp отпраялет запросы на удаленный сервер раз в 1 sec, и что-то вызывает проблемы при этом....

Как я понимаю, есть путь запустить сервер-сокет на самом есп, но ведь он будет работать в локальной сети и доступ извне к нему не получить.
Абсолютно верно!
WebSocket - это не "сервер", это ... WebSocket — протокол полнодуплексной связи поверх TCP-соединения. Нет соединения... как в том анеке, нет и мультиков ;)
Сетевые соединения лежат на более низком уровне чем сокеты.
 

rkravt

Member
timon1991j, как мне кажется, Вы немного запутались в "теме" ;)
Это нормально! )
Тут все такие ;) Все по граблям ходим ))
Вы как .. бы, более подробней расписали бы кейс, входные-выходные данные, варики воздействия ... поможем советом с реализацией ;)
 

timon1991j

New member
В общем глухота какая-то с этими вебсокетами.. Может кто поможет? Есть arduino и esp8266. Задача простая - мигать диодом при помощи переключателя на удаленном сервере, используя при этом Websocket. Вот рабочий пример, который отправляет запросы каждые 2 секунды и в зависимости от нажатия кнопки на сервере включает/выключает диод:

Код:
#include <SoftwareSerial.h>

SoftwareSerial espSerial(10, 11); // ESP TX - 10 (Arduino SoftwareSerial RX), ESP RX - 11 (Arduino SoftwareSerial TX)
const int COM_BAUD = 9600;

#define SSID "ssid"
#define PASS "password"
#define IP "domain.ru"
String GETREAD = "GET http://domain.ru/script.php";

void setup() {
  espSerial.begin(COM_BAUD);
  Serial.begin(COM_BAUD);
  pinMode(13, OUTPUT);
  Serial.println("Start AT");
  espSerial.println("AT");
  if(espSerial.find("OK")){
    connectWiFi();
    Serial.println("Start update data");
    readValue();
  } else {
    Serial.println("AT error");
  }
}

void readValue(){
  String cmd = "AT+CIPSTART=\"TCP\",\"";
  cmd += IP;
  cmd += "\",80";
  espSerial.println(cmd);
  if(espSerial.find("Error")){
    return;
  }
  cmd = GETREAD;
  cmd += "\r\n";
  cmd += "Host: ";
  cmd += IP;
  cmd += "\r\n";
  espSerial.print("AT+CIPSEND=");
  espSerial.println(cmd.length());
  delay(500);
  if(espSerial.find(">")){
    espSerial.print(cmd);
    if(espSerial.find("On")){
        digitalWrite(13, HIGH);
        Serial.println("On!");
    } else {
        Serial.println("Off!");
        digitalWrite(13, LOW);
    }
  }else{
    espSerial.println("AT+CIPCLOSE");
    Serial.println("Update error");
  }
}

boolean connectWiFi(){
  Serial.println("AT ok, connect to Wi-Fi");
  espSerial.println("AT+CWMODE=1");
  delay(2000);
  String cmd="AT+CWJAP=\"";
  cmd+=SSID;
  cmd+="\",\"";
  cmd+=PASS;
  cmd+="\"";
  espSerial.println(cmd);
  delay(5000);
  if(espSerial.find("OK")){
  Serial.println("Success connect to Wi-Fi");
    return true;
  }else{
  Serial.println("Fail connect to Wi-Fi");
    return false;
  }
}

void loop() {
  readValue();
  delay(1500);
}
Нужно сделать то же самое, только подключив esp к socket.io (использую его на сервере). Сколько библиотек перепробовал, ничего не получается. Комп с компом соединить или с телефоном через socket.io не проблема, а вот как подключить esp не доходит, бьюсь уже который день :(
 

pet

Member
В общем глухота какая-то с этими вебсокетами.. Может кто поможет? Есть arduino и esp8266. Задача простая - мигать диодом при помощи переключателя на удаленном сервере, используя при этом Websocket. Вот рабочий пример, который отправляет запросы каждые 2 секунды и в зависимости от нажатия кнопки на сервере включает/выключает диод:

Код:
#include <SoftwareSerial.h>

SoftwareSerial espSerial(10, 11); // ESP TX - 10 (Arduino SoftwareSerial RX), ESP RX - 11 (Arduino SoftwareSerial TX)
const int COM_BAUD = 9600;

#define SSID "ssid"
#define PASS "password"
#define IP "domain.ru"
String GETREAD = "GET http://domain.ru/script.php";

void setup() {
  espSerial.begin(COM_BAUD);
  Serial.begin(COM_BAUD);
  pinMode(13, OUTPUT);
  Serial.println("Start AT");
  espSerial.println("AT");
  if(espSerial.find("OK")){
    connectWiFi();
    Serial.println("Start update data");
    readValue();
  } else {
    Serial.println("AT error");
  }
}

void readValue(){
  String cmd = "AT+CIPSTART=\"TCP\",\"";
  cmd += IP;
  cmd += "\",80";
  espSerial.println(cmd);
  if(espSerial.find("Error")){
    return;
  }
  cmd = GETREAD;
  cmd += "\r\n";
  cmd += "Host: ";
  cmd += IP;
  cmd += "\r\n";
  espSerial.print("AT+CIPSEND=");
  espSerial.println(cmd.length());
  delay(500);
  if(espSerial.find(">")){
    espSerial.print(cmd);
    if(espSerial.find("On")){
        digitalWrite(13, HIGH);
        Serial.println("On!");
    } else {
        Serial.println("Off!");
        digitalWrite(13, LOW);
    }
  }else{
    espSerial.println("AT+CIPCLOSE");
    Serial.println("Update error");
  }
}

boolean connectWiFi(){
  Serial.println("AT ok, connect to Wi-Fi");
  espSerial.println("AT+CWMODE=1");
  delay(2000);
  String cmd="AT+CWJAP=\"";
  cmd+=SSID;
  cmd+="\",\"";
  cmd+=PASS;
  cmd+="\"";
  espSerial.println(cmd);
  delay(5000);
  if(espSerial.find("OK")){
  Serial.println("Success connect to Wi-Fi");
    return true;
  }else{
  Serial.println("Fail connect to Wi-Fi");
    return false;
  }
}

void loop() {
  readValue();
  delay(1500);
}
Нужно сделать то же самое, только подключив esp к socket.io (использую его на сервере). Сколько библиотек перепробовал, ничего не получается. Комп с компом соединить или с телефоном через socket.io не проблема, а вот как подключить esp не доходит, бьюсь уже который день :(
здесь не смотрели?!Socket.io v1.x Library for W5100 & ENC28J60 + ESP8266
 

timon1991j

New member
Смотрел.. Library will not work when the ESP8266 is being driven by a Uno. У меня как раз uno :( Смотрел и другие библиотеки, но они почти все завязаны на Ethernet шилде, а те что попадаются на esp, те не работают. Вообще даже espwifi библиотека не хочет работать, выдаёт какие-то ошибки при компиляции, поэтому все так напрямую через at команды и писал.
 

sergey-fedor

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

pvvx

Активный участник сообщества
А если 300 и более точек в секунду отправлять из websocket ?
Обычно, ESP8266, в локалке c малым временем пинга, успевает обменяться к 1000 текстовыми запросами через websocket в секунду... (вам уже писал о ограничениях приме-передачи ESP8266 к примерно за 1000 пакетов в секунду)
С некоторыми датчиками приходится вставлять задержку. К примеру с INA219...
Arduino для ESP это не касается - там и так всё в задержках на каждый пакет к 10 ms...
 
Последнее редактирование:

view24

Member
Вы про какую библиотеку 'websocket для esp8266 говорите'? Ссылку дайте.
 

view24

Member
Помогаю про websocket для esp8266. Смотрите сайт www.view24.ru. Через минуту будете мигать диодом. Время реакции не более 1 сек.
 

pvvx

Активный участник сообщества
Вы про какую библиотеку 'websocket для esp8266 говорите'? Ссылку дайте.
Та по всему форуму раскидано :) Разработка ‘библиотеки’ малого webсервера на esp8266.
Замер самого себя (при частой отсылке ток потребления повышается):
Работает без всяких сторонних серверов и ссылок, можно по DynDNS, если IP не фиксед.
 
Последнее редактирование:

zsm812

New member
Всем привет .
Подскажите пожалуйста в каую сторону копать чтобы реализовать подобное?
обязательно ли использование websocket для такой скорости ?


 

DernKov

New member
Добрый день! Разрабатываю приложение для Android для связи с ESP8266, раньше использовал обычные get запросы. Все было нормально. Но сейчас задача в том, чтобы в нужный момент приложение реагировало на какое-то событие на есп. Получается, что надо, например, каждые 10 сек делать запрос, что быстро посадит батарею смартфона. Поэтому решил использовать socket'ы, чтобы есп сама отправляла данные. По совету timon1991j использую библиотеку WebSocket Server, запустил пример WebSocketServer_LEDcontrol, немного изменив его. Через браузер управлять получается, а вот через приложение нет. Причём пробовал подключаться через ftp клиент, но безуспешно. Правда программа пишет, что подключилась, но не принимать, не отправлять сообщения не получается. При подключении в мониторе порта тоже ничего нет. Но при разрыве соединения пишет Disconnected. Может у кого-нибудь будут идеи. Заранее спасибо!

Код:
#include <Arduino.h>

#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>
#include <WebSocketsServer.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>
#include <Hash.h>
int wsClientNumber[5] = { -1, -1, -1, -1, -1};
int lastClientIndex = 0;
const int max_ws_client = 5;

#define LED_RED     15
#define LED_GREEN   12
#define LED_BLUE    13

#define USE_SERIAL Serial

ESP8266WiFiMulti WiFiMulti;

ESP8266WebServer server = ESP8266WebServer(80);
IPAddress apIP(192, 168, 4, 1);
WebSocketsServer webSocket = WebSocketsServer(81);

void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t length) {
    switch(type) {
        case WStype_DISCONNECTED:
            USE_SERIAL.printf("[%u] Disconnected!\n", num);
            break;
           
        case WStype_CONNECTED: {
            webSocket.sendTXT(num, "You are " + (String)num);
            IPAddress ip = webSocket.remoteIP(num);
            USE_SERIAL.printf("[%u] Connected from %d.%d.%d.%d url: %s\n", num, ip[0], ip[1], ip[2], ip[3], payload);
           
            int index = (num % max_ws_client);
            if (index <= 0) index = 0;
              wsClientNumber[index] = num;
            }
            webSocket.sendTXT(num, "Connected");
            break;
           
        case WStype_TEXT:
            USE_SERIAL.printf("[%u] get Text: %s\n", num, payload);

            if(payload[0] == '#') {
                // we get RGB data
                // efcfba - белый
                // decode rgb data
                uint32_t rgb = (uint32_t) strtol((const char *) &payload[1], NULL, 16);

                analogWrite(LED_RED,    ((rgb >> 16) & 0xFF));
                analogWrite(LED_GREEN,  ((rgb >> 8) & 0xFF));
                analogWrite(LED_BLUE,   ((rgb >> 0) & 0xFF));
            }
            break;
    }
}

void setup() {
    USE_SERIAL.begin(115200);

    USE_SERIAL.println();
    USE_SERIAL.println();
    USE_SERIAL.println();

    for(uint8_t t = 4; t > 0; t--) {
        USE_SERIAL.printf("[SETUP] BOOT WAIT %d...\n", t);
        USE_SERIAL.flush();
        delay(1000);
    }

    pinMode(LED_RED, OUTPUT);
    pinMode(LED_GREEN, OUTPUT);
    pinMode(LED_BLUE, OUTPUT);

    digitalWrite(LED_RED, 1);
    digitalWrite(LED_GREEN, 1);
    digitalWrite(LED_BLUE, 1);

    WiFi.disconnect();
    WiFi.mode(WIFI_AP);
    WiFi.softAPConfig(apIP, apIP, IPAddress(255, 255, 255, 0));
    WiFi.softAP("TEST", "12345678");

    // start webSocket server
    webSocket.begin();
    webSocket.onEvent(webSocketEvent);

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

    // handle index
    server.on("/", []() {
        // send index.html
        server.send(200, "text/html", "<html><head><script>var connection = new WebSocket('ws://'+location.hostname+':81/', ['arduino']);connection.onopen = function () {  connection.send('Connect ' + new Date()); }; connection.onerror = function (error) {    console.log('WebSocket Error ', error);};connection.onmessage = function (e) {  console.log('Server: ', e.data);};function sendRGB() {  var r = parseInt(document.getElementById('r').value).toString(16);  var g = parseInt(document.getElementById('g').value).toString(16);  var b = parseInt(document.getElementById('b').value).toString(16);  if(r.length < 2) { r = '0' + r; }   if(g.length < 2) { g = '0' + g; }   if(b.length < 2) { b = '0' + b; }   var rgb = '#'+r+g+b;    console.log('RGB: ' + rgb); connection.send(rgb); }</script></head><body>LED Control:<br/><br/>R: <input id=\"r\" type=\"range\" min=\"0\" max=\"255\" step=\"1\" oninput=\"sendRGB();\" /><br/>G: <input id=\"g\" type=\"range\" min=\"0\" max=\"255\" step=\"1\" oninput=\"sendRGB();\" /><br/>B: <input id=\"b\" type=\"range\" min=\"0\" max=\"255\" step=\"1\" oninput=\"sendRGB();\" /><br/></body></html>");
    });

    server.begin();

    // Add service to MDNS
    MDNS.addService("http", "tcp", 80);
    MDNS.addService("ws", "tcp", 81);

    digitalWrite(LED_RED, 0);
    digitalWrite(LED_GREEN, 0);
    digitalWrite(LED_BLUE, 0);

}

uint32_t prT;

void loop() {
    webSocket.loop();
    server.handleClient();
    if(millis() - prT >= 5000){
      for (int numcl = 0; numcl < max_ws_client; numcl++)
      {
        if (wsClientNumber[numcl] != -1)
          webSocket.sendTXT(wsClientNumber[numcl], "Time from start " + (String)millis());
      }
      prT = millis();
    }
}
 

DernKov

New member
Наверное, нужно попробовать другие библиотеки, например с сайта
Scada View24 Plus OPC server IOT
Описывается полив цветов.
Посмотреть вложение 5122
А WebSocketsServer не рабочая? Мне бы хотелось её использовать, потому что в
Scada View24 Plus OPC server IOT
как-то всё уж сильно заморочено.
 

Ильнар

New member
У меня тоже по железу почти все нормально, а вот с веб мордой проблема, знания html и JavaScript десятилетней давности:) явно не хватает, пришлось штудировать матчасть. Но кое что уже есть, надо только "причесать" код веб-клиента, сырой с мусором выкладывать не хочется, только с толку сбивать коллег. Двусторонняя связь через WebSocket у меня уже работает, от ESPшки идут данные от термодатчиков, обратно есть возможность по кнопкам управлять подключенными к ESPшке 3мя реле. Сейчас пытаюсь реализовать сохранение полученных от ESPшки данных в локальном файле на стороне веб-клиента, пока глухо:(.
День добрый. Пытаюсь такой же проект запустить, но вебсокет не поддается:).Застрял на передаче данных с датчиков...
 

vavanvanvanovich

New member
Напишу обязательно! Просто я смотрю никто особо не интересуется, вопросов не задают, может здесь так не принято:). Пока сделано что то типа WiFi-логгера с обратной связью, на стороне ESPшки организован WebSocketServer, он же опрашивает пока два датчика на ds18xxxx, отсылает данные по WiFi клиенту и принимает команды от клиента управляя 3мя реле. Клиент написан на Html и JavaScript, загружается локально с компьютера или с удаленного сервера, изначально клиент должен был грузится со встроенного в ESPшку WebServerа, но из-за глюка IDE Atduino версии 1.65, пока от этого отказался. К сожалению все материалы по проекту у меня на работе, кое что сохранено в облаке, надо поискать. Сейчас времени очень мало, сами понимаете за "каникулы" нужно многое успеть сделать, пока есть возможность, завтра пороюсь в облаке, если что найду выложу.
Привет!!! На даты смотрю, вроде давно писали но может ответите))) я начинающий вроде-программист и пытаюсь к ESP8266 подключить несколько смартфонов, столько всего прочитал что уже ничего не понимаю. на андроиде открыт сокет, по одиночке через WiFi client esp8266 =все лампочки зажигают, а как этот Async WebSocket s androidom сделать не пойму......
 

Ильнар

New member
Я тоже долго возился с этим но в итоге перешел на MQTT, и никаких проблем. ТЗ какое если не секрет?
 

vavanvanvanovich

New member
Вижу здесь давно писали, но может кто отзовется. Подключил я ВебСокет и вроде всё работает, но одна проблема, соединение перегружается и данные пропадают, я пока просто с яркостью Леда пытыюсь научиться. пока сокет подключен, все работает, но как перезагрузка- лед гаснет и надо все сначала его включать. вот код если кто поможет

void sliderWebSocket( char* data, AsyncWebSocketClient *client) {
val = atoi(data);
val = map(val, MIN, MAX, 0, 255);
Serial.println(val);
 

Atom

Member
Запросы на сервер каждую секунду - ни есть хорошо. Это первое. Второе - задержка при управлении, от 1 секунды до 4х, отчего так пока точно не понятно, при том что интервал стоит в 1 секунду, может сам esp не успевает получать ответ, что вполне реально.
Все зависит от задачи, размера и формата пересылаемых данных.

Можно сделать из него клиента для подключения к внешнему серверу, это уже вроде подходит.
судя по тому как он организовывает, то это идет через js и вероятно всего браузер. Локально, точно, будет работать. Но вот обращение к внешнему серверу браузер может не допустить. Точнее даже не браузер, а сторонний сервер, к которому ведется запрос. На них тоже устанавливаются правила, от всяческих любителей взлома.

Вообще такой обмен обычно организуют для задач типа "показывать реальные данные из com-порта в терминальном окне". Не более того.

У меня есть серверная часть, грубо говоря все пишется в файл настроек, в котором хранятся данные о включении/выключении пинов на Ардуине, вот его постоянно мониторить нужно на предмет изменений, вот думаю, как это подогнать.
Есть еще и другая технология: называется AJAX. В JS пишется скрипт, по опросу тайтера отправляющий запрос на сервер. Сервером выступает esp. Определенная страница должна выдавать в данных определенного формата: текстовые, XML или JSON (называю то, с чем имел дело, но может быть куча других форматов). Там же в скрипте все эти данные парсятся и на лету изменяют значения на странице.
Итого: esp занимается только обработкой web-запросов, все остальные красивости исполняются у клиентов, в браузере и не особо утруждают бедный чип.
 
Сверху Снизу