Skocz do zawartości

Komunikacja między ESP8266 - Arduino IDE


ptakpl

Pomocna odpowiedź

Cześć,

czy ktoś mógłby mi podpowiedzieć, jakiej komendy użyć, aby wysyłać polecenia z jednego ESP na drugie? Mam zaprogramowane ESP8266 przez adruino za pomocą Konwerter USB - UART ESP01, w kodzie stały adres IP, żeby identyfikować zaprogramowane ESP bez problemu. Do każdego z nich wchodzę wpisując adres IP przeglądarce i odpowiednio dodając za adresem /RELAYON lub RELAYOFF załączam lub wyłączam przekaźnik.

Kolejnym krokiem chciałbym, aby było sprawdzanie stanów na jednym ESP (wysoki,niski) i wysyłanie reakcji na inne ESP wykorzystując IP np. z ESP o adresie 192.168.1.123, który czyta stany i czeka na stan wysoki wysłać komendę na 192.168.1.200/RELAYON.

Czy ktoś mógłby mi podpowiedzieć co nieco?

Cały kod:

#include <ESP8266WiFi.h>

const char* ssid = "SSID";//type your ssid
const char* password = "PASSWORD";//type your password

int relayPin = 2; // GPIO2 of ESP8266
WiFiServer ESPserver(80);//Service Port

void setup()
{
Serial.begin(115200);
pinMode(relayPin, OUTPUT);
digitalWrite(relayPin, HIGH);

Serial.println();
Serial.println();
Serial.print("Connecting to: ");
Serial.println(ssid);

WiFi.begin(ssid, password);
delay(5000);

/*
 The following four line of the
 code will assign a Static IP Address to
 the ESP Module. If you do not want this,
 comment out the following four lines. 
 */

IPAddress ip(192,168,1,254);   
IPAddress gateway(192,168,1,1);   
IPAddress subnet(255,255,255,0);   
WiFi.config(ip, gateway, subnet);
delay(5000);

while (WiFi.status() != WL_CONNECTED)
{
delay(100);
Serial.print("*");
}
Serial.println("");
Serial.println("WiFi connected");

// Start the server
ESPserver.begin();
Serial.println("Server started");

// Print the IP address
Serial.print("The URL to control ESP8266: ");
Serial.print("http://");
Serial.print(WiFi.localIP());
}

void loop()
{
// Check if a client has connected
WiFiClient client = ESPserver.available();
if (!client)
{
return;
}

// Wait until the client sends some data
Serial.println("New Client");
while(!client.available())
{
delay(1);
}

// Read the first line of the request
String request = client.readStringUntil('\r');
Serial.println(request);
client.flush();

// Match the request

int value = LOW;
if (request.indexOf("/RELAYON") != -1)
{
Serial.println("LAMP is ON");
digitalWrite(relayPin, LOW);
value = LOW;
}
if (request.indexOf("/RELAYOFF") != -1)
{
Serial.println("LAMP is OFF");
digitalWrite(relayPin, HIGH);
value = HIGH;
}

// Return the response
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println(""); //  IMPORTANT
client.println("<!DOCTYPE HTML>");
client.println("<html>");

client.print("Status of the Lamp: ");

if(value == LOW)
{
client.print("ON"); 
}
else
{
client.print("OFF");
}

delay(1);
//client.stop();
Serial.println("Client disconnected");
Serial.println("");
}

 

 

Link do komentarza
Share on other sites

9 godzin temu, ptakpl napisał:

czy ktoś mógłby mi podpowiedzieć, jakiej komendy użyć, aby wysyłać polecenia z jednego ESP na drugie?

Nie ma komendy jak w UART wyślij / odbierz. Zacząłbym od tego, że niepotrzebnie używasz TCP. Przez to musisz postawić serwer, na drugim ESP clienta. Wiesz, ze jak client się nie połączy to ESP "zawiśnie" na 5 sekund? Użyj UDP. Jak koniecznie chcesz sterować przekaźnikami przez URL to ok, postaw serwer ale do komunikacji pomiędzy modułami użyj UDP.

Wiesz czym się różni TCP od UDP?

 

PS. Widzę, że tak jak typ zmiennoprzecinkowy jest nadużywany przez Arduino, int zamiast unit8_t, tak w ESP nadużywane jest połączenie TCP. Robiłem porównania czasu wykonani funkcji wysyłania tych samych danych przez TCP i UDP. TCP to 100..200ms (o ile wszystko jest ok, bo jak źle to 5000ms), UDP 700..800us! Widać różnicę?

Link do komentarza
Share on other sites

4 godziny temu, RFM napisał:

Wiesz czym się różni TCP od UDP?

Podpowiem: tym, że w przypadku UDP jeśli wysyłasz coś do drugiej maszyny to nie wiesz czy doszło 😉

Ale zgodzę się, dość szybko nie wiesz.

Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

Dziękuję za wypowiedzi, pytanie, czy do opisanej przez Was metody w dalszym ciągu mogę użyć arduino? Jeśli tak, to z której biblioteki skorzystać? Nie upieram się też, żeby to robić po sieci, ale mam kilka wemosów, esp, więc szkoda by było niewykorzystać wemosa i  wejść cyfrowych w połączeniu z centralą alarmową satel. Podpowiecie jeszcze coś? 🙂

Link do komentarza
Share on other sites

1 godzinę temu, ptakpl napisał:

Podpowiecie jeszcze coś?

W przykładach do biblioteki dla ESP masz zarówno serwer jak i klienta tak TCP jak i UDP. Przykłady działają poprawnie. Pobaw się nimi, pomierz czasy, gdy serwer jest w sieci i gdy go nie ma. Przeczytaj o różnicach w TCP i UDP. Jak potrzebujesz potwierdzeń a zależy na szybkości działania pętli głównej to użyj UDP i potwierdzaj ramki przez ICMP albo UDP. Jak petla główna moze "wisieć" 5 sekund użyj TCP.

Link do komentarza
Share on other sites

1 godzinę temu, RFM napisał:

potwierdzaj ramki przez ICMP

Jak się ktoś nie zna na protokołach sieciowych to może nie powinien dawać "dobrych" rad. ICMP nie służy do potwierdzania odebrania danych UDP. To że da się go tak używać jeszcze o niczym nie świadczy. Proponuję starać się dawać dobre rady, a nie złe - szczególnie początkującym użytkownikom. Ewentualnie zamilknąć i wrócić do nadrabiania braków w edukacji.

Edit: żeby nie było, to co napisałem to nie złośliwość, ani zachowanie sprzeczne z PPF - to po prostu stwierdzenie faktu. ICMP należy do zupełnie innej warstwy (do doczytania) niż UDP, ma określone zastosowania (do doczytania). Tworzenie bezawaryjnego łącza z użyciem UDP jest możliwe, ale na ogół bezsensowne, bo duplikuje działanie TCP. A to że ktoś nie potrafi TCP używać to już zupełnie inny temat - i nie powód żeby wszystkim odradzać korzystania z tego protokołu (jak na ironię pisząc post używając przeglądarki oraz TCP...).

  • Lubię! 1
Link do komentarza
Share on other sites

Ja się nie znam wcale więc pytam. Z bibliotek, które przeglądałem nie mogę znaleźć po prostu funkcji get... a jak użyję client.begin to tylko realizuje to i nic więcej. Rozumiem, że na necie lata sporo wersji, ale pytanie, czy ktoś może mi podrzucić bibliotekę, która jest sprawdzona i ktoś realizował tym podobne funkcje? Byłbym wdzięczny. Nie potrzebuję tego robić bez zwłoki po UDP, więc przyjmijmy, że będzie po TCP - tylko jak...

Link do komentarza
Share on other sites

Jeśli chcesz się łączyć po HTTP bez zrozumienia, na czym protokół polega to też polegniesz. Na razie masz kod prostego serwera, a gdzie klient który się łączy? Co to, forum dla wróżek czy stragan ze szklanymi kulami?

Link do komentarza
Share on other sites

(edytowany)

nie mam problemu z połączeniem się z routerem, tą część mam opanowaną. Nie mam problemu z wejściem na adres ESP i wywołaniem komend http://adresIP/ledOn i http://adresIP/ledOff. Nie wiem tylko jak z jednego ESP wywołać reakcję na drugim bez wchodzenia w przeglądarkę, tylko wykorzystując get. 

Edytowano przez ptakpl
Link do komentarza
Share on other sites

1 godzinę temu, ethanak napisał:

Zaczniesz Ty wreszcie na własny dysk zaglądać?

Biblioteka ESP8266HTTPClient, przykład o nazwie BasicHttpClient.

 

 

/**
   BasicHTTPClient.ino

    Created on: 24.05.2015

*/

#include <Arduino.h>

#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>

#include <ESP8266HTTPClient.h>

#include <WiFiClient.h>

ESP8266WiFiMulti WiFiMulti;

void setup() {

  Serial.begin(115200);
  // Serial.setDebugOutput(true);

  Serial.println();
  Serial.println();
  Serial.println();

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

  WiFi.mode(WIFI_STA);
  WiFiMulti.addAP("SSID", "PASSWORD");

}

void loop() {
  // wait for WiFi connection
  if ((WiFiMulti.run() == WL_CONNECTED)) {

    WiFiClient client;

    HTTPClient http;

    Serial.print("[HTTP] begin...\n");
    if (http.begin(client, "http://jigsaw.w3.org/HTTP/connection.html")) {  // HTTP


      Serial.print("[HTTP] GET...\n");
      // start connection and send HTTP header
      int httpCode = http.GET();

      // httpCode will be negative on error
      if (httpCode > 0) {
        // HTTP header has been send and Server response header has been handled
        Serial.printf("[HTTP] GET... code: %d\n", httpCode);

        // file found at server
        if (httpCode == HTTP_CODE_OK || httpCode == HTTP_CODE_MOVED_PERMANENTLY) {
          String payload = http.getString();
          Serial.println(payload);
        }
      } else {
        Serial.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str());
      }

      http.end();
    } else {
      Serial.printf("[HTTP} Unable to connect\n");
    }
  }

  delay(10000);
}

Żeby nie było niejasności, mówimy o tym kodzie?

I która komenda wywoła mi konkretny adres IP? Mam nadzieję, że nie begin? Chyba, że w begin ustawie konkretny adres ip 192.168.1.188, a gdzieś niżej w get dodam /ledOn i /ledOff?

Link do komentarza
Share on other sites

Wybacz, ale jeśli nie znacz podstaw programowania (np. składania stringów) to nie zaczynaj od pytań "jakiej biblioteki mam użyć" tylko zajrzyj do kursu arduino czy podstaw języka. Co z tego, że już się dowiedziałeś jaka to biblioteka jak teraz nie wiesz co się z nią robi?

W http.begin() podajesz URL. W http.GET() wywołujesz tego swojego geta którego nie mogłeś znaleźć. Wiesz co to URL? Jeśli tak, to co powinieneś zrobić żeby zapalić/zgasić ledę? Dlaczego uważasz, że jeżeli begin() przyjmuje URL to możesz tam podać IP a potem coś dodawać?

A jeśli nie wiesz co to URL: to takie coś co się wpisuje do takiego okienka w przeglądarce.

 

Link do komentarza
Share on other sites

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.