WiFi CONNECTION : ESP32 to LAPTOP : It just won't work

RogerInHawaii
Posts: 21
Joined: Mon Sep 14, 2020 1:21 am

WiFi CONNECTION : ESP32 to LAPTOP : It just won't work

Postby RogerInHawaii » Sat Oct 24, 2020 9:50 pm

I WILL BE SOOO GRATEFUL IF SOMEONE CAN TELL ME WHAT I'M DOING WRONG ! :D

I want to send data, via WiFi, from my ESP32 to my laptop, but am not having success in doing so. It just always fails to connect, the failure code coming back to my ESP32 sketch. The C# program running on the laptop, waiting for a connection request, runs merrily along and never thinks any request is coming in.

I have internet cable which is connected to a router. The router is connected to a WiFi station. My laptop has its internet access via WiFi connection with that WiFi station.

I've written a C# Windows Form application that sets itself up to listen for a connection request. That application seems to be working properly, in that it keeps checking for whether or not a connection request has been made and, if it has, it will respond by making the connection and then accepting any data coming in across that connection.

I've also written a sketch for the ESP32 that makes a connection with the WiFi station and then attempts to establish a connection through to my laptop. It does indeed succeed in establishing the connection with the WiFi station, but it always fails to connect through to the laptop. The C# program running on the laptop never gets an indication that anything is attempting to connect to it.

Most of the code that I'm using, both for the C# program and the ESP32 sketch comes from examples and sources I've come across on the Internet, most significantly from a YouTube video:

https://www.youtube.com/watch?v=c9M8QWsYGRM

But it's not working. I'm hoping someone might be able to figure out what I'm doing wrong.


In my ESP32 sketch I call a function I call WiFinit, as follows:

Code: Select all

bool WifiInit()
{
  WiFi.mode(WIFI_STA);
  WiFi.disconnect();
  if (esp_now_init() == ESP_OK) 
  {
    return true;
  }
  else 
  {
    ESP.restart();
  } 
  return false;
}
and that returns true, so it looks like that much works just fine.

I then call a function, ConnectToWiFiServerStation(), which attempts to find the desired WiFi Station (by name and password) and to connect to it...

Code: Select all

esp_now_peer_info_t TheWiFiServerStation;

bool ConnectToWiFiServerStation(String DesiredWiFiServerStationName)
{
  #define CHANNEL 3
  int8_t scanResults = WiFi.scanNetworks();
  bool TheWiFiServerStationFound = false;
  memset(&TheWiFiServerStation, 0, sizeof(TheWiFiServerStation));

  if (scanResults == 0) 
  {
    Serial.println("In ConnectToWiFiServerStation: No WiFi devices in AP Mode found");
  } 
  else 
  {
    for (int i = 0; i < scanResults; ++i) 
    {
      String SSID = WiFi.SSID(i);
      int32_t RSSI = WiFi.RSSI(i);
      String BSSIDstr = WiFi.BSSIDstr(i);

      delay(10); 
      // Check if the current device is DesiredWiFiServerStationName
      if (SSID.indexOf(DesiredWiFiServerStationName) == 0)
      {
        // It's the one we're looking for.
        // Get BSSID => Mac Address of the TheWiFiServerStation
        int mac[6];
        if ( 6 == sscanf(BSSIDstr.c_str(), "%x:%x:%x:%x:%x:%x",  &mac[0], &mac[1], &mac[2], &mac[3], &mac[4], &mac[5] ) ) 
        {
          for (int ii = 0; ii < 6; ++ii ) 
          {
            TheWiFiServerStation.peer_addr[ii] = (uint8_t) mac[ii];
          }
        }

        TheWiFiServerStation.channel = CHANNEL; // This is 3. That number was specified
					// in the example code I located
					// but I have no clue what that means or
					// or if there is significance to that number.
        TheWiFiServerStation.encrypt = 0; // No encryption

        TheWiFiServerStationFound = true;
        break;
      }
    }
  }

  if (TheWiFiServerStationFound) 
  {
    // Add TheWiFiServerStation as peer if it has not been added already.
    bool isPaired = PairWithWiFiStation();
    if (isPaired) 
    {
      // pair success or already paired.
      Serial.println("In ConnectToWiFiServerStation: SUCCESSFULLY PAIRED with TheWiFiServerStation");
    } 
    else 
    {
      // Failed to pair this machine with target
      Serial.println("In ConnectToWiFiServerStation: FAILED TO PAIR with TheWiFiServerStation");
    }
  } 
  else 
  {
    Serial.println("TheWiFiServerStation Not Found, trying again.");
  }

  // clean up ram
  WiFi.scanDelete();

  esp_now_register_send_cb(OnDataSent);

  return TheWiFiServerStationFound;
}
That ConnectToWiFiServerStation() function call returns true, indicating that it did indeed successfully connect to the WiFi Station.

A couple of notes about it, though:

A CHANNEL number is specified, in:

Code: Select all

TheWiFiServerStation.channel = CHANNEL;
and the channel number is given as 3. That number came from the example code I was referencing as a basis for my sketch. Is that OK? Should it be some other number? Am I correct in assuming that a given ESP32 can validly have more than one WiFi connection, each to a separate Wifi Station, and it's the channel member of TheWiFiServerStation that distinguishes among them?

That ConnectToWiFiServerStation() function also calls another function, PairWithWiFiStation(), as follows:

Code: Select all

bool PairWithWiFiStation()
 {
  if (TheWiFiServerStation.channel == CHANNEL)
  {
    // check if the peer exists
    bool exists = esp_now_is_peer_exist(TheWiFiServerStation.peer_addr);
    if ( exists) 
    {
      // TheWiFiServerStation already paired.
      Serial.println("Already Paired");
      return true;
    } 
    else 
    {
      // TheWiFiServerStation not paired, attempt pair
      esp_err_t addStatus = esp_now_add_peer(&TheWiFiServerStation);
      if (addStatus == ESP_OK) 
      {
        // Pair success
        Serial.println("Pair success");
        return true;
      } 
      else if (addStatus == ESP_ERR_ESPNOW_NOT_INIT) 
      {
        // How did we get so far!!
        Serial.println("ESPNOW Not Init");
        return false;
      } 
      else if (addStatus == ESP_ERR_ESPNOW_ARG) 
      {
        Serial.println("Invalid Argument");
        return false;
      } 
      else if (addStatus == ESP_ERR_ESPNOW_FULL) 
      {
        Serial.println("Peer list full");
        return false;
      } 
      else if (addStatus == ESP_ERR_ESPNOW_NO_MEM) 
      {
        Serial.println("Out of memory");
        return false;
      } 
      else if (addStatus == ESP_ERR_ESPNOW_EXIST) 
      {
        Serial.println("Peer Exists");
        return true;
      } else 
      {
        Serial.println("Not sure what happened");
        return false;
      }
    }
  } 
  else 
  {
    // No TheWiFiServerStation found to process
    Serial.println("IN PairWithWiFiStation() : No TheWiFiServerStation found to pair\n");
    return false;
  }
}
That call to PairWithWiFiStation() also returns true, so it appears that it has successfully paired with the WiFi Station.

So far, so good.

After the successful call to ConnectToWiFiServerStation() I then try to connect THROUGH that WiFi connection to get to my laptop. I've determined that the IP of my laptop is 192.168.0.106, and I've set up the C# program running on my laptop to be accessing port 1000,i.e. checking that port for incoming connection requests. That number, 1000, for the port, again comes from the sample code I've been basing my programs in.

Is 1000 a valid port number? Should I be using something different? I tried 80, having recalled that number from some code I wrote years ago, but that also didn't work.

Anyway, my current code uses 1000 as the port, both in the ESP32 sketch and the C# program.

Here's what I'm doing in my ESP32 sketch AFTER the ConnectToWiFiServerStation() succeeds:

Code: Select all

    const uint16_t port = 1000;
    const char * host = "192.168.0.106";// MY COMPUTER !!!

    WiFiClient ThisESP32_Wifi_Client;
    if (ThisESP32_Wifi_Client.connect(host, port) == 0)
    {
      Serial.print("Connection failed\n");
    }
    else
    {
      Serial.print("Connection SUCCESS!\n");
    }
And it ALWAYS FAILS!

I should note that when I run this sketch on my ESP32 I have previously started up the Windows App that's running there waiting for connection requests, so I think it SHOULD succeed in connecting. But it never does.

One thought that comes to mind is this: The successful connection that's established with the WiFi station is done using:

Code: Select all

esp_now_peer_info_t TheWiFiServerStation;
i.e. an object named TheWiFiServerStation of type esp_now_peer_info_t.

So that TheWiFiServerStation is what knows about the WiFi server. But when I attempt to connect to the laptop via:

Code: Select all

    WiFiClient ThisESP32_CAM_Wifi_Client;
    if (ThisESP32_CAM_Wifi_Client.connect(host, port) == 0)
it only references the WiFiCLient object, named ThisESP32_Wifi_Client.

BIG QUESTION

How does the WiFiClient object know to use the connection that's been set up and is connected to the WiFi Station?

I don't see anything in the WiFiClient.h file, like an init() method, that would tell it about the WiFiServerStation, or even maybe speficy what "channel" it should use.

SOMETHING WRONG WITH MY SKETCH?

Does it look like there's something wrong with my ESP32 sketch? Am I connecting incorrectly to the WiFi station? Conecting incorrectly to the laptop? Using an ivalid channel number?

IF EVERYTHING'S OK WITH THE SKETCH

Let's take a look at my C# code, the imprortant part of which is in ClassWiFiServer:

Code: Select all

    class ClassWiFiServer
    {
        static string ThisComputerIPAddress = "192.168.0.106";
        public event MessageEventHandler Message;
        public delegate void MessageEventHandler(ClassWiFiServer sender, string Data);

        // Server Control
        public IPAddress ServerIP = IPAddress.Parse(ThisComputerIPAddress);
        static public int ServerPort = 1000; // NO idea why this number is used.
        public TcpListener myserver;

        public Thread Comthread;
        public bool IsListening = true;

        // Clients
        private TcpClient client = null;
        private StreamReader clientdata = null;

        public ClassWiFiServer() // CONSTRUCTOR
        {
            myserver = new TcpListener(ServerIP, ServerPort);
            myserver.Start();
            Comthread = new Thread(new ThreadStart(Hearing));
            Comthread.Start();
        }

        private void Hearing() // Listening for incoming connection requests
        {
            while (!IsListening == false)
            {
                if (myserver.Pending() == true) // Pending means that a connection request is pending
                {
                     // It NEVER GETS HERE, never recognizes that my ESP32 sketch is trying to connect with this computer
                    client = myserver.AcceptTcpClient();
                    clientdata = new StreamReader(client.GetStream());
                }

                if (clientdata != null)
                {
                    try
                    {
                        Message?.Invoke(this, clientdata.ReadLine());
                    }
                    catch (Exception ex)
                    {
                    }
                }
                Thread.Sleep(10);
            }
        }
    }
Again, note that this code comes from example code I had come across on the Internet.
It sets up the Hearing() function (I would have called it "Listening" :) which waits for myserver.Pending() to be true, which appears to mean that someone is trying to connect into it.

But Pending() always remains false, even though my ESP32 sketch is running and has connected to the WiFi station and is attempting to connect through to the computer, using the correct ISP and port number.

By running this C# program in debug mode I can see that it does repeatedly get to the

Code: Select all

                if (myserver.Pending() == true)
line, but myserver.Pending() is always false. It never recognizes that the ESP32 sketch is trying to connect with it.

So what am I doing wrong? Is there something that I'm misunderstanding, something that I set up incorrectly?

boarchuz
Posts: 315
Joined: Tue Aug 21, 2018 5:28 am

Re: WiFi CONNECTION : ESP32 to LAPTOP : It just won't work

Postby boarchuz » Sun Oct 25, 2020 2:49 am

You've got a bizarre hodgepodge of ESP NOW and WiFi. ESP NOW and WiFi are different protocols, different components, different things.

Adding an ESP NOW peer has absolutely no association with connection to a WiFi access point.

I'd suggest looking at a standard simple Arduino WiFi sketch and using that as a base for a rewrite.

RogerInHawaii
Posts: 21
Joined: Mon Sep 14, 2020 1:21 am

Re: WiFi CONNECTION : ESP32 to LAPTOP : It just won't work

Postby RogerInHawaii » Mon Oct 26, 2020 1:08 am

Well, I've searched all around and what I showed in my post is the best I could come up with from what I was able to locate.

The C# server comes directly from the YouTube video that I referenced. As far as I can tell it's set up as a TCP server.

You suggest that I find some simple, standard Arduino sketch and start with that. But the only thing I can find is one that is an AsyncUDPClient sketch. I tried using that, even though it's a UDP client not a TCP client. But the very odd thing with that is that it indicates success in connecting even when I specify a totally random IP address. udp.connect(IPAddress(0, 0, 0, 0), 1000) works just as well (returns a true value) as udp.connect(IPAddress(192, 168, 0, 106), 1000), the IP and port of my local computer.

I have my C# program running on my computer waiting for a connection request (or maybe it's just waiting for data to come in, it's not actually clear from the code provided by that YouTube video what it's waiting for). But either way, the C# code never detects anything that's pending.

Code: Select all

myserver = new TcpListener(ServerIP, ServerPort);
myserver.Start();
Comthread = new Thread(new ThreadStart(Hearing));
Comthread.Start();
...

private void Hearing() // Listening for info to come back.
{
  while (!IsListening == false)
   {
      if (myserver.Pending() == true)
      {
        client = myserver.AcceptTcpClient(); // It NEVER GETS HERE

Can you point me to any example code, at least for the ESP32, that works properly and works with TCP, not UDP, that actually connects through to the program running on a local computer, accessible via WiFi?

davidzuhn
Posts: 3
Joined: Fri Sep 20, 2019 1:50 am

Re: WiFi CONNECTION : ESP32 to LAPTOP : It just won't work

Postby davidzuhn » Mon Oct 26, 2020 1:57 am

examples/protocols/sockets/tcp_client in esp-idf v4.1 contains basic socket example code, using IDF only (not the Arduino wrappers).

The sockets interface for TCP code works pretty much just like the sockets interface anywhere else, so books or websites that cover Unix network programming will be spot on for the same functionality under ESP-IDF.

WiFive
Posts: 2985
Joined: Tue Dec 01, 2015 7:35 am

Re: WiFi CONNECTION : ESP32 to LAPTOP : It just won't work

Postby WiFive » Mon Oct 26, 2020 2:30 am

you may want to consider working with a micropython or espruino or moddable or lua precompiled firmware environment

Who is online

Users browsing this forum: Baidu [Spider] and 33 guests