Skocz do zawartości

Komunikacja ESP - ESP (za pośrednictwem Arduino)


PierwiastekZdwa

Pomocna odpowiedź

Witam, w końcu znalazłem czas oraz chęci i uporałem się z problemami które sprawiały mi te moduły. Przestały się sypać dopiero gdy każdy moduł miał oddzielną płytkę z polutowanym stabilizatorem napięcia oraz filtracją na wejściu i na wyjściu (jak najmniej kabelków). Dla testów podłączyłem do jednego z modułów microswitcha a program zlicza jego naciśnięcia. Chciałbym teraz aby to ESP które liczy wysyłało liczbę naciśnięć na serwer postawiony na drugim ESP oraz aby była możliwość podglądu tej liczby na serial monitorze serwera. Nie bardzo jestem zorientowany w temacie sieci, serwerów itd. dlatego nawet czytając i oglądając różne projekty i poradniki nie potrafię zrozumieć co tak naprawdę muszę zrobić. Będę bardzo wdzięczny za podpowiedzi.

Pozdrawiam

Link do komentarza
Share on other sites

Masz dwie możliwości.

1) UDP. Wysłanie pakietu jest szybkie (praktycznie niezauważalne dla działania programu), niestety - nie masz pewności czy pakiet dotarł do odbiorcy. W rezultacie możesz zgubić jakieś kliknięcie jeśli były jakieś zakłócenia w sieci (to w dużym uproszczeniu, proszę Panów Ekspertów od Administracji Sieciami o przymrużenie oka).

2) TCP. Wysłanie pakietu nie jest już tak szybkie, strona nadająca musi sobie pogadać z odbiornikiem (chociaż dla Ciebie jako programisty jest to niewidoczne). Jeśli odbiorca nie odpowiada, próby są ponawiane, po iluś tam próbach nadawca otrzymuje informację że odbiorca nie chce z nim gadać, i kwestią aplikacji jest co z tą informacją zrobię. W rezultacie możesz zgubić jakieś kliknięcie, jeśli w sieci były jakieś zakłócenia i Ty sobie klikałeś a nadajnik był zajęty czekaniem na odpowiedź odbiornika (również w dużym uproszczeniu).

Którą wersję wybierasz? Od tego zależy dalsza pomoc.

Ja bym proponował UDP, prostszy i łatwiej go zrozumieć, ale to tylko moje zdanie.

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

Dziękuję za tak proste wyjaśnienie 😉 Wydaje mi się, że faktycznie lepsze dla mnie będzie UDP. Do zliczania wykorzystuję ten program:

#define przycisk 12
int wynik=0;
boolean stan=0;

void setup() {
 pinMode(przycisk,INPUT);
 Serial.begin(115200);
}

void loop() {
 if(digitalRead(przycisk)==1 && stan==0){
   wynik++;
   stan=1;
 }

 if(digitalRead(przycisk)==0){
   stan=0;
 }
 Serial.println(wynik);
}

Ogólnie rozumiem, że jeden moduł trzeba będzie skonfigurować jako serwer a ten który liczy jako klient który będzie łączył się z serwerem. O ile to jest raczej oczywiste i widziałem to w różnych przykładach to kompletnie nie rozumiem w jaki sposób ma nastąpić wysyłanie danych.

Link do komentarza
Share on other sites

Przede wszystkim zastanów się, jakie dane chcesz wysyłać.

Załóżmy sytuację jedną z najprostszych: wysyłasz jeden bajt informujący, co serwer ma zrobić. Niech wartość 1 będzie oznaczać "zlicz impuls".

Załóżmy, że połączenie WiFi zostało już skonfigurowane, i wybieramy port PORT do komunikacji.

W obu modułach rozpoczynasz od:

#include <ESP8266WiFi.h>
#include <WiFiUdp.h>

WiFiUDP Udp; // tak na przykład
#define PORT 1234

a w setup()

Udp.begin(PORT);

Po stronie nadającej po stwierdzeniu impulsu wykonujesz coś w stylu:


uint8_t packet;
packet = 1; // czyli polecenie "zlicz"


Udp.beginPacket(adres_ip_serwera, PORT);
Udp.write(&packet, 1); // wysyłamy jeden bajt
Udp.endPacket();

Po stronie serwera w głównej pętli wykonujesz coś w stylu:

uint8_t packet;

if (Udp.parsePacket() != 0) {
   Udp.read(&packet, 1); // czytasz jeden bajt
   if (packet == 1) { // czyli trzeba policzyć impulsy
       dodaj_impuls();
   }
}

Ot - i cała filozofia 🙂

Pamiętaj, że to jedynie jeden z możliwych scenariuszy, można to rozwiązać na różne sposoby, ten jednak mi się wydaje najłatwiejszy do zrozumienia.

Możesz równiesz liczyć impulsy po stronie klienta, a do serwera wysyłać ilość zliczonych impulsów.

Aha, piszę to z pamięci czyli gdzieś mogłem się machnąć.

  • Lubię! 1
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

Znowu miałem trochę czasu i posiedziałem z tymi układami. Coś takiego poskładałem po stronie klienta do którego podpięty jest przycisk:

#include <WiFi.h>
#include <WiFiUdp.h> 

WiFiUDP Udp;
#define PORT 1234 

const char* ssid = "TEST";
const char* password =  "TEST";
IPAddress ip(192, 168, 1, 4);

#define przycisk 12 
int wynik=0; 
boolean stan=0; 

void setup() { 
 pinMode(przycisk,INPUT); 

 Udp.begin(PORT);

 Serial.begin(115200); 

 WiFi.begin(ssid, password);

 while (WiFi.status() != WL_CONNECTED) {
   delay(500);
   Serial.println("Connecting to WiFi..");
 }

 Serial.println("Connected to the WiFi network");
} 

void loop() { 
 if(digitalRead(przycisk)==1 && stan==0){ 
   uint8_t packet; 
 packet = 1; // czyli polecenie "zlicz" 
 Udp.beginPacket(ip, PORT); 
 Udp.write(&packet, 1); // wysyłamy jeden bajt 
 Udp.endPacket(); 
   wynik++; 
   stan=1; 
 } 

 if(digitalRead(przycisk)==0){ 
   stan=0; 
 } 
 Serial.println(wynik); 
}

Wydaje mi się, że działa to tak: łączy się z serwerem, w momencie naciśnięcia przycisku licznik uwzględnia jedno naciśnięcie i wysyła do serwera informację, żeby to zliczył.

Strona serwera:

#include <WiFi.h>
#include <WiFiUdp.h> 

WiFiUDP Udp;
#define PORT 1234 

int wynik=0;

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

void setup() {
 Udp.begin(PORT); 
 Serial.begin(115200);
 WiFi.softAP(ssid, password);

 Serial.println();
 Serial.print("IP address: ");
 Serial.println(WiFi.softAPIP());
 pinMode(34,OUTPUT);

}

void loop() {
 uint8_t packet; 

if (Udp.parsePacket() != 0) { 
   Udp.read(&packet, 1); // czytasz jeden bajt 
   if (packet == 1) { // czyli trzeba policzyć impulsy 
       wynik++;
       digitalWrite(34,HIGH);

   } 
} 
Serial.println(wynik);
}

To natomiast najpierw tworzy sieć a w momencie gdy klient coś wyśle odbiera i zwiększa licznik o jeden oraz zaświeca diodę LED. Czy cokolwiek co napisałem ma jakiś sens? Próby uruchomienia utwierdzają mnie, że raczej nic tutaj nie jest dobrze.

Link do komentarza
Share on other sites

Program klienta przebiega tak jak powinien. Na początku jest "Connecting to WiFi..", następnie "Connected to the WiFi network" i pojawia się stan licznika. Wygląda na to, że serwer nie odbiera tego co wysyła (lub nie) klient.

Link do komentarza
Share on other sites

Udało się skomunikować! Dziękuję bardzo! Problemem była najprawdopodobniej zbyt krótka nazwa sieci, ponieważ rozgłaszane ssid serwera było inne niż to napisane w programie. Nie rozumiem tylko czemu klient mimo wszystko z czymś się łączył... Ale skoro działa to już nieważne 😃 Próbowałem się troszkę bawić z tym kodem i dodałem drugi przycisk, który powoduje odejmowanie i co 5 sekund wysyłany jest pakiet będący wynikiem a następnie licznik jest zerowany. Serwer otrzymuje wynik i dodaje go do swojego licznika. Wszystko działa dopóki wynik nie jest ujemny. Ponieważ liczba wysyłana w pakiecie musi być uint8_t to właśnie nie potrafię poradzić sobie z poprawnym działaniem w przypadku liczb ujemnych. Mógłbym prosić o podpowiedź co w takim przypadku mogę zrobić?

Pozdrawiam

Link do komentarza
Share on other sites

Działa! ethanak, bardzo dziękuję za zainteresowanie tematem, pisanie wszystkiego w przyjazny sposób i za bardzo szybkie odpowiedzi 😉

Pozdrawiam

[ Dodano: 21-05-2018, 22:52 ]

Wszystko było dobrze dopóki nie zachciało mi się wdrażać w życie kolejnego etapu mojego pomysłu... 😃 Teraz chciałbym spróbować wysłać coś w sieć. W tym celu setup ustawiam tak:

void setup() {
 Serial.begin(115200);
 WiFi.mode(WIFI_AP_STA);
 WiFi.softAP(ssid, password);
 Serial.println();
 Serial.print("IP address: ");
 Serial.println(WiFi.softAPIP());
 Udp.begin(PORT);

 Serial.print("connecting to");
 Serial.println(SSID);
 WiFi.begin(SSID,PASS);
 while(WiFi.status() != WL_CONNECTED){
   delay(500);
   Serial.println(".");
 }
 Serial.println("WiFi connected");
 Serial.println("IP adress:");
 Serial.println(WiFi.localIP());
 }

I problem jest w tym, że moja sieć powstaje, moduł łączy się z WiFi (co prawda trwa to bardzo długo ale finalnie się łączy) i... na tym koniec. W ogóle nie wykonuje się to co jest w loopie. Nie rozumiem czym to jest spowodowane.

Link do komentarza
Share on other sites

Łączenie do sieci trwa baaardzo długo, czasami trzeba kilka resetów żeby w końcu się udało. Po połączeniu dostaję IP i na tym kończy się program.

#include <WiFi.h>
#include <WiFiUdp.h>

WiFiUDP Udp;

#define PORT 1234
int licznik = 0;


const char *ssid = "test";
const char *password = "12345678";

const char *cSSID = "abc";
const char *cPASS = "12345678";

unsigned long aktualnyCzas = 0;
unsigned long zapamietanyCzas = 0;

void setup() {
 Serial.begin(115200);
 WiFi.mode(WIFI_AP_STA);
 WiFi.softAP(ssid, password);
 Serial.println();
 Serial.print("IP address: ");
 Serial.println(WiFi.softAPIP());
 Udp.begin(PORT);

 Serial.print("connecting to ");
 Serial.println(cSSID);
 WiFi.begin(cSSID,cPASS);
 while(WiFi.status() != WL_CONNECTED){
   delay(500);
   Serial.println(".");
 }
 Serial.println("WiFi connected");
 Serial.println("IP adress:");
 Serial.println(WiFi.localIP());
 }


void loop() {
 aktualnyCzas = millis();

 int packet;

 if (Udp.parsePacket() != 0) {
   Udp.read((uint8_t*)&packet, sizeof packet);
   licznik+=packet;

 if(aktualnyCzas-zapamietanyCzas >=1000){  
   zapamietanyCzas = aktualnyCzas;
   Serial.println(licznik);
 }

}

}

Link do komentarza
Share on other sites

Jaka to płytka w ogóle?

U mnie na ESP-12E po zmianie

#include <WiFi.h>

na

#include <ESP8266WiFi.h>

i dopisaniu na samym początku setup:

WiFi.disconnect(); //tak na wszelki wypadek

ten kod działa od strzału, łączy się w ciągu 2-3 sekund i reaguje na pakiety wysłane z obu sieci (własnej i domowej)...

Link do komentarza
Share on other sites

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Anonim
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.

×
×
  • 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.