ESP32 WROVER E not reaching the TCP host via Ethernet

Vilius
Posts: 26
Joined: Mon Nov 13, 2023 9:22 am

ESP32 WROVER E not reaching the TCP host via Ethernet

Postby Vilius » Mon Nov 27, 2023 11:38 am

Hi,

I am quite new to ESP32 programming. I have a task to establish the TCP communication via ESP and PC (PC wont send anything to the ESP, It will be one way communication from ESP to PC). I am using the ESP Ethernet KIT (ESP32 WROVER E)

I took an existing basic ethernet example form the ESP IDF built in project examples and with a little help of AI and testing came up with this code:

Code: Select all

#include <stdio.h>
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"
#include "esp_netif.h"
#include "esp_eth.h"
#include "esp_event.h"
#include "esp_log.h"
#include "lwip/sockets.h"
#include "lwip/dns.h"
#include "lwip/netdb.h"
#include "ethernet_init.h"
#include "sdkconfig.h"

static const char *TAG = "eth_example";
static const char *PC_IP = "10.10.16.111";
static const int PC_PORT = 5190;

// Static IP configuration
static const char *ESP_IP = "10.10.16.112"; // Change this to your desired static IP
static const char *ESP_NETMASK = "255.255.255.0";
static const char *ESP_GATEWAY = "10.10.16.1";

static EventGroupHandle_t eth_event_group;
static const int ETH_CONNECTED_BIT = BIT0;

static void send_message_to_pc();
static void periodic_task(void *pvParameters);

/** Event handler for Ethernet events */
static void eth_event_handler(void *arg, esp_event_base_t event_base,
                              int32_t event_id, void *event_data)
{
    esp_eth_handle_t eth_handle = *(esp_eth_handle_t *)event_data;

    switch (event_id) {
    case ETHERNET_EVENT_CONNECTED:
        xEventGroupSetBits(eth_event_group, ETH_CONNECTED_BIT);
        ESP_LOGI(TAG, "Ethernet Link Up");
        break;
    case ETHERNET_EVENT_DISCONNECTED:
        xEventGroupClearBits(eth_event_group, ETH_CONNECTED_BIT);
        ESP_LOGI(TAG, "Ethernet Link Down");
        break;
    default:
        break;
    }
}

/** Event handler for IP_EVENT_ETH_GOT_IP */
static void got_ip_event_handler(void *arg, esp_event_base_t event_base,
                                 int32_t event_id, void *event_data)
{
    // Configure static IP settings
    esp_netif_ip_info_t ip_info;
    ip_info.ip.addr = inet_addr(ESP_IP);
    ip_info.netmask.addr = inet_addr(ESP_NETMASK);
    ip_info.gw.addr = inet_addr(ESP_GATEWAY);

    // Apply static IP settings
    esp_netif_set_ip_info(esp_netif_get_handle_from_ifkey("ETH"), &ip_info);

    // Send a message to the PC when IP is obtained
    send_message_to_pc();
}

static void send_message_to_pc() {
    int sockfd;
    struct sockaddr_in server_addr;

    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0) {
        ESP_LOGE(TAG, "Unable to create socket");
        return;
    }

    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(PC_PORT);
    inet_aton(PC_IP, &server_addr.sin_addr);

    if (connect(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
        ESP_LOGE(TAG, "Connection failed: %s", strerror(errno));
        close(sockfd);
        return;
    }

    const char *message = "Hello from ESP32!";
    if (write(sockfd, message, strlen(message)) < 0) {
        ESP_LOGE(TAG, "Error sending message: %s", strerror(errno));
    } else {
        ESP_LOGI(TAG, "Message sent successfully");
    }

    close(sockfd);
}

static void periodic_task(void *pvParameters) {
    while (1) {
        // Wait for the Ethernet to be connected
        xEventGroupWaitBits(eth_event_group, ETH_CONNECTED_BIT, pdTRUE, pdTRUE, portMAX_DELAY);

        // Send a message to the PC periodically
        send_message_to_pc();

        // Adjust the delay based on your requirements
        vTaskDelay(pdMS_TO_TICKS(5000));  // Delay for 5 seconds
    }
}

void app_main(void)
{
    eth_event_group = xEventGroupCreate();

    uint8_t eth_port_cnt = 0;
    esp_eth_handle_t *eth_handles;
    ESP_ERROR_CHECK(example_eth_init(&eth_handles, &eth_port_cnt));

    ESP_ERROR_CHECK(esp_netif_init());
    ESP_ERROR_CHECK(esp_event_loop_create_default());

    if (eth_port_cnt == 1) {
        esp_netif_config_t cfg = ESP_NETIF_DEFAULT_ETH();
        esp_netif_t *eth_netif = esp_netif_new(&cfg);
        ESP_ERROR_CHECK(esp_netif_attach(eth_netif, esp_eth_new_netif_glue(eth_handles[0])));
    } else {
        esp_netif_inherent_config_t esp_netif_config = ESP_NETIF_INHERENT_DEFAULT_ETH();
        esp_netif_config_t cfg_spi = {
            .base = &esp_netif_config,
            .stack = ESP_NETIF_NETSTACK_DEFAULT_ETH
        };
        char if_key_str[10];
        char if_desc_str[10];
        char num_str[3];
        for (int i = 0; i < eth_port_cnt; i++) {
            itoa(i, num_str, 10);
            strcat(strcpy(if_key_str, "ETH_"), num_str);
            strcat(strcpy(if_desc_str, "eth"), num_str);
            esp_netif_config.if_key = if_key_str;
            esp_netif_config.if_desc = if_desc_str;
            esp_netif_config.route_prio -= i * 5;
            esp_netif_t *eth_netif = esp_netif_new(&cfg_spi);
            ESP_ERROR_CHECK(esp_netif_attach(eth_netif, esp_eth_new_netif_glue(eth_handles[i])));
        }
    }

    ESP_ERROR_CHECK(esp_event_handler_register(ETH_EVENT, ESP_EVENT_ANY_ID, &eth_event_handler, NULL));
    ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_ETH_GOT_IP, &got_ip_event_handler, NULL));

    // Create a periodic task to send messages to the PC
    xTaskCreate(&periodic_task, "periodic_task", 4096, NULL, 5, NULL);

    for (int i = 0; i < eth_port_cnt; i++) {
        ESP_ERROR_CHECK(esp_eth_start(eth_handles[i]));
    }
}
This should send message to the PC every 5 seconds (for now I am in testing phase). However, when I flash this code to the ESP, eventually I get these logs:

I (376) app_start: Starting scheduler on CPU0
I (380) app_start: Starting scheduler on CPU1
I (380) main_task: Started on CPU0
I (390) main_task: Calling app_main()
I (430) esp_eth.netif.netif_glue: 08:3a:8d:13:5a:73
I (430) esp_eth.netif.netif_glue: ethernet attached to netif
I (2030) main_task: Returned from app_main()
I (2030) eth_example: Ethernet Link Up
E (2030) eth_example: Connection failed: Host is unreachable

On the PC side, I also run a very simple python TCP listening script just to acknowledge the TCp packets:

Code: Select all

import socket

PC_IP = "10.10.16.111"
PC_PORT = 5190

def start_server():
    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server_socket.bind((PC_IP, PC_PORT))
    server_socket.listen(1)

    print(f"Listening for connections on {PC_IP}:{PC_PORT}")

    while True:
        client_socket, client_address = server_socket.accept()
        print(f"Connection established from {client_address}")

        message = client_socket.recv(1024).decode("utf-8")
        print(f"Received message: {message}")

        client_socket.close()

if __name__ == "__main__":
    start_server()
I have created dedicated network adapter on the PC and disabled the DHCP for sure. I assigned the static IP, Subnet and Gateway for both PC and ESP. Picture of my ipconfig is in the attachments, although I am pretty confident I understand the network settings well enough and set everything up the right way...

I have also disabled both windows defender and firewall (once this caused enormous problems for me, but this time all of the protection is off.)

I also ran wireshark to check whats going on, but as expected, I did not see a single packet with the source of 10.10.16.112 (ESP IP).

These are all the tricks I did on my own, but it seems it is not enough for ESP... Any ideas how to establish the TCP commuication by reaching the host? (according to the error logs.) Thank you in advance.
Attachments
1.png
1.png (17.33 KiB) Viewed 2543 times

Who is online

Users browsing this forum: No registered users and 112 guests