Skocz do zawartości

Przesylanie danych typu INT/FLOAT przez UDP na ESP-ESP


Miksior

Pomocna odpowiedź

Witam serdecznie

wczoraj pol dnia glowilem sie nad pewnym tematem i nic nie wymyslilem, robie zdalny system pomiarowy w ktorym kilka modulów WiFi (jeden glowny ESP32 jest serverem, pozostale 8266 to klienci) beda zbierac dane z czujnikow, wysylac po UDP (moze w przyszlosci TCP) do serwera a stamtad powedruja na jakas strone/apke.

Mam zrobiona na esp komunikacje UDP zarowno po stronie accespointa jak i klienta, natomiast przesylana ramka danych jest w formacie ASCII, problem (moze trywialny) to wyslanie i odebranie danych w formacie int/float (bo tego typu dane beda pochodzily z czujnikow). Probowalem roznych funkcji jak i sposobow rzutowania, zawsze arduino ide (bo w tym programuje ESP) zwraca mi bledy o niedozwolonej konwersji itp... 
Wrzuce kod na ktorym poprawnie sa wysylane dane jednak tak jak pisalem jako tekst w ASCII:
Strona klienta:
 

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

WiFiUDP Udp;
unsigned int localUdpPort = 4210;  // local port to listen on
IPAddress ip(192, 168, 4, 1);

void setup()
{
  Serial.begin(115200);
  Serial.println();

  WiFi.begin("ESP32", "123456789");

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

  Serial.print("Connected, IP address: ");
  Serial.println(WiFi.localIP());
}

void loop() {

while (WiFi.status() != WL_CONNECTED)
{
  WiFi.reconnect();
  delay(10000);
  Serial.print(".Reconnected");
  Serial.println(WiFi.localIP());
}
Udp.beginPacket(ip, localUdpPort);
Udp.write("45"); // wysyłamy jeden bajt
Udp.endPacket();
Serial.print("Wyslalem cos\n");
delay(5000);
}


Jak widac wyslanie tekstu nie jest problemem ale nie umiem wyslac danych np z typu int, gdyz wysyla sie calkmien zmieniona wartosc Na stronie serwera wyglada to tak: 

#include <WiFi.h>
#include <WiFiClient.h>
#include <WiFiAP.h>
#include <WiFiUdp.h>
#include <stdlib.h>

WiFiUDP Udp;
unsigned int localUdpPort = 4210;  // local port to listen on
char incomingPacket[255];  // buffer for incoming packets


void setup()
{
  Serial.begin(115200);
  Serial.println();

  Serial.print("Setting soft-AP ... ");
  Serial.println(WiFi.softAP("ESP32", "123456789") ? "Ready" : "Failed!");
  IPAddress myIP = WiFi.softAPIP();
  Serial.print("AP IP address: ");
  Serial.println(myIP);

  
  Udp.begin(localUdpPort);
  Serial.printf("Now listening at IP %s, UDP port %d\n", WiFi.localIP().toString().c_str(), localUdpPort);
}

void loop()
{
  int packetSize = Udp.parsePacket();
  if (packetSize)
  {
    // receive incoming UDP packets
    Serial.printf("Received %d bytes from %s, port %d\n", packetSize, Udp.remoteIP().toString().c_str(), Udp.remotePort());
    int len = Udp.read(incomingPacket, 255);
    if (len > 0)
    {
      incomingPacket[len] = 0;
    }
    Serial.printf("UDP packet contents: %s\n", incomingPacket);
  }
}

 

Czy ktos moglby powiedziec albo moze wskazac przyklad jak poprzez UDP przeslac np float? 
Bede wdzieczny za rady

Edytowano przez Miksior
Link do komentarza
Share on other sites

Niestety nie podrzucę gotowca ale może jakoś Cię nakieruję na rozwiązanie. Otóż dane różnych typów po "drugiej stronie" drutu interpretowane są na podstawie kontekstu a nie samych danych jako takich bo bez różnicy na to jak są one formatowane przez arduino/esp to na końcu drutu to i tak tylko 0 i 1. Wiedząc o tym należy tak sterować kontekstem przesyłanych danych aby nie było nieporozumień i po to właśnie wymyślono tyle protokołów i trybów (binarny/tekstowy/mieszany/customowy itd itp udp) transmisji danych aby każdy wtajemniczony w magię drutu i eteru mógł sobie wybrać ten najbardziej odpowiedni dla swoich potrzeb ;)

Przyjrzyj się formatowaniu funkcji printf, mówi Ci to coś?

Link do komentarza
Share on other sites

Dobrym zwyczajem jest opublikowanie rozwiązania problemu z którym się zmagałeś, być może komuś oszczędzisz kilku godzin życia na szukanie rozwiązań gdy będzie się zmagał z podobnym problemem. "Człowieku, nie bondź takim egoistom" ;)

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

oczywiscie 🙂

w przypadku konwersji przychodzacej wiadomosci:

String msg = String(incomingPacket);
int jakaśliczba = msg.toInt();

w przypadku proby wyslania jakiejs liczby typu int:

char buffer[16]; //16 bitow
sprintf(buffer, "%d", jakaśliczba); 
Udp.write(buffer, sizeof(char) * 16)

 

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

(edytowany)

Zgadza sie,  ogarnalem tez komunikacje poprzez TCP i dziala dopoki nie chcialem polaczyc 3 moduly, jeden glowny ktory jest AP i czyta dane, jeden wysyla dane po UDP a drugi po TCP,

Wklejam kod:

Moze ktos jest w stanie powiedziec mi co tutaj blokuje komunikacje z wykorzystaniem obu protokolow na raz? jak to rozdzielic?

#include <WiFi.h>
#include <WiFiClient.h>
#include <WiFiAP.h>
#include <WiFiUdp.h>
#include <stdlib.h>

WiFiServer server(80);                // Set a object server as a WiFiServer class
IPAddress IP(192,168,4,1);           // Select ip and mask
IPAddress mask = (255, 255, 255, 0);
WiFiUDP Udp;
unsigned int localUdpPort = 4210;  // local port to listen on
char incomingPacket[255]; // buffer for incoming packets
char incomingPacket1[255];// wyciecie litery z ramki UDP aby przekonwertowac String na float
float temp;
float hum;

// The devices that want to connect to our Access Point will need to use the next credentials.
char ssid[] = "ESP32";           // SSID for the Access Point 
char pass[] = "123456789";         // password for the Access Point

void setup() {
  
  Serial.begin(115200);
  
  Serial.print("Setting soft-AP ... ");
  Serial.println(WiFi.softAP("ESP32", "123456789") ? "Ready" : "Failed!");
  IPAddress myIP = WiFi.softAPIP();
  Serial.print("AP IP address: ");
  Serial.println(myIP);
  server.begin();     // Begin the server
  Udp.begin(localUdpPort);
  //Serial.printf("Now listening at IP %d, UDP port %d\n", WiFi.softAPIP(), localUdpPort);
  Serial.print("Now listening at IP: ");
  Serial.print(WiFi.softAPIP());
  Serial.print(" UDP PORT: ");
  Serial.print(localUdpPort);
  Serial.println(" TCP PORT: 80 ");
}

void loop() {
WiFiUDP Udp;
  //UDP:
  int packetSize = Udp.parsePacket();
  if (packetSize)
  {
    // receive incoming UDP packets
    Serial.printf("Dostalem po UDP: Received %d bytes from %s, port %d\n", packetSize, Udp.remoteIP().toString().c_str(), Udp.remotePort());
    int len = Udp.read(incomingPacket, 255);
    Serial.printf("UDP packet contents: %s\n", incomingPacket);
    
    if (incomingPacket[0]=='t'){ //sprawdzanie jaka wartosc przyszla (temp czy humidity czy inna)
    for (int i=1; i<7; i++){      // wyciecie litery z ramki UDP aby przekonwertowac String na float
      incomingPacket1[i-1]=incomingPacket[i];
    }
    String msg = String(incomingPacket1);   //konwersja string na float
    float jakasliczba = msg.toFloat();      //konwersja string na float
    Serial.print("Temperatura wynosi :");   
    Serial.println(jakasliczba);
    temp=jakasliczba;
    }
    
    if (incomingPacket[0]=='h'){
    for (int i=1; i<7; i++){
      incomingPacket1[i-1]=incomingPacket[i];
    }
    String msg = String(incomingPacket1);
    float jakasliczba = msg.toFloat();
    Serial.print("Humidity wynosi :");
    Serial.println(jakasliczba);
    hum=jakasliczba;
    }
    if (len > 0)
    {
      incomingPacket[len] = 0;
    } 
    //TCP: 
  WiFiClient client = server.available(); // Return a client object to the class if there is a client available
  if (!client) {return;}                  // Return cuts the function (loop) if client class is not connected  
  String request = client.readStringUntil('\r');    // Reads string received until \r and saves as string 
  Serial.println(" Dostalem po TCP: " + request);  
  //client.flush();                                 
  client.println(" Dostalem po TCP: " + request + "\r");   // Send the data with the \r so the client knows when to stop
  //Serial.println(request  + "Aknowledge");     
}
 WiFiClient client = server.available(); // Return a client object to the class if there is a client available
  if (!client) {return;}                  // Return cuts the function (loop) if client class is not connected  
  String request = client.readStringUntil('\r');    // Reads string received until \r and saves as string 
  Serial.println(" Dostalem po TCP: " + request);  
  //client.flush();                                 
  client.println(" Dostalem po TCP: " + request + "\r");   // Send the data with the \r so the client knows when to stop
  //Serial.println(request  + "Aknowledge");     
}

EDIT: rozwiazalem, trzeba bylo wstawic linijke: client.stop(); 

Edytowano przez Miksior
  • Lubię! 1
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.