Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
ESP32: ETH + RELAY
#1
Hi, I plugged my board via ethernet to my router, but it has no IP, my net is 192.168.2.*.

Anyway, I would like to flash my own code witn ESP32 python to enable / disable relays via http, how to set up a static ip? and which are the gpio pins to enable / disable relays?

Thank you Smile
Reply
#2
because new board no firmware inside of ESP32, you need download KCS v2 firmware by usb-c cable firstly, here is online guide: https://www.kincony.com/esp32-kcsv2-firmware.html
if you want write your own python code, sure, it's ok.
Reply
#3
(07-03-2025, 07:59 AM)admin Wrote: because new board no firmware inside of ESP32, you need download KCS v2 firmware by usb-c cable firstly, here is online guide: https://www.kincony.com/esp32-kcsv2-firmware.html
if you want write your own python code, sure, it's ok.

thanks for the reply, but I use linux and in the zip there is no "KC868-A64-V1.0.9.bin" file there are:

demo_cn.bin (i suppose that is chinese version)
demo_en.bin (i suppose that is english version)
NOTE_test_board_fw_v.10
Reply
#4
I see the relay 1 is 15 pin and relay 2 pin is 2 here:

https://www.kincony.com/forum/showthread.php?tid=2691

well, I flashed the ESP32 using idd.py and I build this code and works fine, but is using wifi, i need to work with ethernet, if someone can helps me I really appreciated:

PHP Code:
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_wifi.h"
#include "esp_event.h"
#include "esp_log.h"
#include "nvs_flash.h"
#include "esp_netif.h"
#include "esp_http_server.h"
#include "driver/gpio.h"

// Wi-Fi credentials
#define WIFI_SSID "WIFI_NAME"
#define WIFI_PASS "WIFI_PASSWORD"

// GPIOs for relays
#define RELAY1_GPIO GPIO_NUM_15
#define RELAY2_GPIO GPIO_NUM_2

static const char *TAG "relay_server";

// Relay control
static void set_relay(int relay_numbool on) {
    gpio_num_t gpio = (relay_num == 1) ? RELAY1_GPIO RELAY2_GPIO;
    gpio_set_level(gpioon 1);  // Active LOW
}

// HTTP Handlers
esp_err_t relay1_on_handler(httpd_req_t *req) {
    set_relay(1false);
    httpd_resp_send(req"Relay 1 ON"HTTPD_RESP_USE_STRLEN);
    return ESP_OK;
}

esp_err_t relay1_off_handler(httpd_req_t *req) {
    set_relay(1true);
    httpd_resp_send(req"Relay 1 OFF"HTTPD_RESP_USE_STRLEN);
    return ESP_OK;
}

esp_err_t relay2_on_handler(httpd_req_t *req) {
    set_relay(2false);
    httpd_resp_send(req"Relay 2 ON"HTTPD_RESP_USE_STRLEN);
    return ESP_OK;
}

esp_err_t relay2_off_handler(httpd_req_t *req) {
    set_relay(2true);
    httpd_resp_send(req"Relay 2 OFF"HTTPD_RESP_USE_STRLEN);
    return ESP_OK;
}

esp_err_t root_handler(httpd_req_t *req) {
    const charresp_str =
        "ESP32 Relay Control:\n"
        "/relay1/on  or /relay1/off\n"
        "/relay2/on  or /relay2/off\n";
    httpd_resp_send(reqresp_strHTTPD_RESP_USE_STRLEN);
    return ESP_OK;
}

// HTTP Server
httpd_handle_t start_webserver(void) {
    httpd_config_t config HTTPD_DEFAULT_CONFIG();
    httpd_handle_t server NULL;

    if (httpd_start(&server, &config) == ESP_OK) {
        httpd_uri_t root = {
            .uri       "/",
            .method    HTTP_GET,
            .handler   root_handler,
            .user_ctx  NULL
        
};
        httpd_uri_t relay1_on = {
            .uri       "/relay1/on",
            .method    HTTP_GET,
            .handler   relay1_on_handler,
            .user_ctx  NULL
        
};
        httpd_uri_t relay1_off = {
            .uri       "/relay1/off",
            .method    HTTP_GET,
            .handler   relay1_off_handler,
            .user_ctx  NULL
        
};
        httpd_uri_t relay2_on = {
            .uri       "/relay2/on",
            .method    HTTP_GET,
            .handler   relay2_on_handler,
            .user_ctx  NULL
        
};
        httpd_uri_t relay2_off = {
            .uri       "/relay2/off",
            .method    HTTP_GET,
            .handler   relay2_off_handler,
            .user_ctx  NULL
        
};

        httpd_register_uri_handler(server, &root);
        httpd_register_uri_handler(server, &relay1_on);
        httpd_register_uri_handler(server, &relay1_off);
        httpd_register_uri_handler(server, &relay2_on);
        httpd_register_uri_handler(server, &relay2_off);
    }

    return server;
}

// Wi-Fi event handler
static void wifi_event_handler(voidargesp_event_base_t event_base,
                               int32_t event_idvoidevent_data) {
    if (event_id == WIFI_EVENT_STA_START) {
        esp_wifi_connect();
    } else if (event_id == WIFI_EVENT_STA_DISCONNECTED) {
        esp_wifi_connect();
    } else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) {
        ESP_LOGI(TAG"Connected with IP");
        start_webserver();
    }
}

// Initialize Wi-Fi
void wifi_init(void) {
    esp_netif_init();
    esp_event_loop_create_default();
    esp_netif_create_default_wifi_sta();

    wifi_init_config_t cfg WIFI_INIT_CONFIG_DEFAULT();
    esp_wifi_init(&cfg);

    esp_event_handler_register(WIFI_EVENTESP_EVENT_ANY_ID, &wifi_event_handlerNULL);
    esp_event_handler_register(IP_EVENTIP_EVENT_STA_GOT_IP, &wifi_event_handlerNULL);

    wifi_config_t wifi_config = {
        .sta = {
            .ssid WIFI_SSID,
            .password WIFI_PASS,
        },
    };
    esp_wifi_set_mode(WIFI_MODE_STA);
    esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config);
    esp_wifi_start();
}

// GPIO setup
void relay_gpio_init() {
    gpio_config_t io_conf = {
        .pin_bit_mask = (1ULL << RELAY1_GPIO) | (1ULL << RELAY2_GPIO),
        .mode GPIO_MODE_OUTPUT,
        .pull_up_en 0,
        .pull_down_en 0,
        .intr_type GPIO_INTR_DISABLE,
    };
    gpio_config(&io_conf);

    // Default state: OFF
    gpio_set_level(RELAY1_GPIO0);
    gpio_set_level(RELAY2_GPIO0);
}

void app_main(void) {
    ESP_ERROR_CHECK(nvs_flash_init());
    relay_gpio_init();
    wifi_init();



To enable disable relays (you can see the IP in the logs):

http://IP/relay1/on
http://IP/relay1/off
http://IP/relay2/on
http://IP/relay2/off
Reply
#5
maybe you can use for test:
Code:
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_event.h"
#include "esp_log.h"
#include "nvs_flash.h"
#include "esp_netif.h"
#include "esp_eth.h"
#include "driver/gpio.h"
#include "esp_http_server.h"
#include "esp_mac.h"
#include "esp_eth_phy.h"
#include "esp_eth_phy_lan8720.h"
#include "esp_eth_driver.h"

// Relay GPIOs
#define RELAY1_GPIO GPIO_NUM_15
#define RELAY2_GPIO GPIO_NUM_2

// Ethernet config
#define ETH_ADDR        0
#define ETH_POWER_PIN  -1
#define ETH_MDC_PIN    23
#define ETH_MDIO_PIN   18
#define ETH_TYPE       ETH_PHY_LAN8720
#define ETH_CLK_MODE   ETH_CLOCK_GPIO17_OUT

static const char *TAG = "ethernet_relay";

// ==========================
// Relay Control
// ==========================
static void set_relay(int relay_num, bool on) {
    gpio_num_t gpio = (relay_num == 1) ? RELAY1_GPIO : RELAY2_GPIO;
    gpio_set_level(gpio, on ? 0 : 1);  // Active LOW
}

// ==========================
// HTTP Handlers
// ==========================
esp_err_t relay1_on_handler(httpd_req_t *req) {
    set_relay(1, false);
    httpd_resp_send(req, "Relay 1 ON", HTTPD_RESP_USE_STRLEN);
    return ESP_OK;
}

esp_err_t relay1_off_handler(httpd_req_t *req) {
    set_relay(1, true);
    httpd_resp_send(req, "Relay 1 OFF", HTTPD_RESP_USE_STRLEN);
    return ESP_OK;
}

esp_err_t relay2_on_handler(httpd_req_t *req) {
    set_relay(2, false);
    httpd_resp_send(req, "Relay 2 ON", HTTPD_RESP_USE_STRLEN);
    return ESP_OK;
}

esp_err_t relay2_off_handler(httpd_req_t *req) {
    set_relay(2, true);
    httpd_resp_send(req, "Relay 2 OFF", HTTPD_RESP_USE_STRLEN);
    return ESP_OK;
}

esp_err_t root_handler(httpd_req_t *req) {
    const char* resp_str =
        "ESP32 Relay Control (Ethernet):\n"
        "/relay1/on  or /relay1/off\n"
        "/relay2/on  or /relay2/off\n";
    httpd_resp_send(req, resp_str, HTTPD_RESP_USE_STRLEN);
    return ESP_OK;
}

// ==========================
// HTTP Server
// ==========================
httpd_handle_t start_webserver(void) {
    httpd_config_t config = HTTPD_DEFAULT_CONFIG();
    httpd_handle_t server = NULL;

    if (httpd_start(&server, &config) == ESP_OK) {
        httpd_register_uri_handler(server, &(httpd_uri_t){.uri="/", .method=HTTP_GET, .handler=root_handler});
        httpd_register_uri_handler(server, &(httpd_uri_t){.uri="/relay1/on", .method=HTTP_GET, .handler=relay1_on_handler});
        httpd_register_uri_handler(server, &(httpd_uri_t){.uri="/relay1/off", .method=HTTP_GET, .handler=relay1_off_handler});
        httpd_register_uri_handler(server, &(httpd_uri_t){.uri="/relay2/on", .method=HTTP_GET, .handler=relay2_on_handler});
        httpd_register_uri_handler(server, &(httpd_uri_t){.uri="/relay2/off", .method=HTTP_GET, .handler=relay2_off_handler});
    }

    return server;
}

// ==========================
// Ethernet Event Handler
// ==========================
static void eth_event_handler(void *arg, esp_event_base_t event_base,
                              int32_t event_id, void *event_data) {
    switch (event_id) {
        case ETHERNET_EVENT_CONNECTED:
            ESP_LOGI(TAG, "Ethernet Connected");
            break;
        case ETHERNET_EVENT_DISCONNECTED:
            ESP_LOGI(TAG, "Ethernet Disconnected");
            break;
        case ETHERNET_EVENT_START:
            ESP_LOGI(TAG, "Ethernet Started");
            break;
        case ETHERNET_EVENT_STOP:
            ESP_LOGI(TAG, "Ethernet Stopped");
            break;
        default:
            break;
    }
}

static void got_ip_event_handler(void *arg, esp_event_base_t event_base,
                                 int32_t event_id, void *event_data) {
    ip_event_got_ip_t *event = (ip_event_got_ip_t *) event_data;
    ESP_LOGI(TAG, "Got IP Address: " IPSTR, IP2STR(&event->ip_info.ip));
    start_webserver();
}

// ==========================
// Ethernet Initialization
// ==========================
void eth_init(void) {
    ESP_ERROR_CHECK(esp_netif_init());
    ESP_ERROR_CHECK(esp_event_loop_create_default());
    esp_netif_config_t cfg = ESP_NETIF_DEFAULT_ETH();
    esp_netif_t *eth_netif = esp_netif_new(&cfg);

    esp_eth_mac_t *mac = esp_eth_mac_new_esp32();
    eth_phy_config_t phy_config = ETH_PHY_DEFAULT_CONFIG();
    phy_config.phy_addr = ETH_ADDR;
    phy_config.reset_gpio_num = ETH_POWER_PIN;
    esp_eth_phy_t *phy = esp_eth_phy_new_lan8720(&phy_config);

    esp_eth_handle_t eth_handle = NULL;
    esp_eth_config_t eth_config = ETH_DEFAULT_CONFIG(mac, phy);
    ESP_ERROR_CHECK(esp_eth_driver_install(&eth_config, &eth_handle));
    ESP_ERROR_CHECK(esp_netif_attach(eth_netif, esp_eth_new_netif_glue(eth_handle)));

    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));

    ESP_ERROR_CHECK(esp_eth_start(eth_handle));
}

// ==========================
// GPIO Initialization
// ==========================
void relay_gpio_init() {
    gpio_config_t io_conf = {
        .pin_bit_mask = (1ULL << RELAY1_GPIO) | (1ULL << RELAY2_GPIO),
        .mode = GPIO_MODE_OUTPUT,
        .pull_up_en = 0,
        .pull_down_en = 0,
        .intr_type = GPIO_INTR_DISABLE,
    };
    gpio_config(&io_conf);

    gpio_set_level(RELAY1_GPIO, 0);
    gpio_set_level(RELAY2_GPIO, 0);
}

// ==========================
// Main
// ==========================
void app_main(void) {
    ESP_ERROR_CHECK(nvs_flash_init());
    relay_gpio_init();
    eth_init();
}
Reply
#6
(07-04-2025, 01:03 AM)admin Wrote: maybe you can use for test:


I have a compilation error:

Code:
[zital@s-400 zitalki-esp32]$ idf.py build
/home/projects/zitalki-esp32/main/main.c:13:10: fatal error: esp_eth_phy_lan8720.h: No such file or directory
   13 | #include "esp_eth_phy_lan8720.h"
      |          ^~~~~~~~~~~~~~~~~~~~~~~
compilation terminated.
[4/9] Completed 'bootloader'
ninja: build stopped: subcommand failed.
ninja failed with exit code 1, output of the command is in the /home/projects/zitalki-esp32/build/log/idf_py_stderr_output_35496 and /home/projects/zitalki-esp32/build/log/idf_py_stdout_output_35496
Reply
#7
sorry, about python code, you need check by yourself.
Reply
#8
this code of python in esp32 works:

Code:
import network
import socket
from machine import Pin
import time

# Wi-Fi credentials
WIFI_SSID = "WIFI_NAME"
WIFI_PASS = "WIFI_PASSWORD"

# GPIO pins for relays (active LOW)
RELAY1_GPIO = 15
RELAY2_GPIO = 2

# Setup GPIOs
relay1 = Pin(RELAY1_GPIO, Pin.OUT, value=1)
relay2 = Pin(RELAY2_GPIO, Pin.OUT, value=1)

def set_relay(relay_num, on):
    gpio = relay1 if relay_num == 1 else relay2
    gpio.value(0 if on else 1)

# Connect to Wi-Fi
def wifi_connect():
    wlan = network.WLAN(network.STA_IF)
    wlan.active(True)
    if not wlan.isconnected():
        print(f"Connecting to {WIFI_SSID} ...")
        wlan.connect(WIFI_SSID, WIFI_PASS)
        while not wlan.isconnected():
            time.sleep(0.5)
            print(".", end="")
    print("\nConnected, IP:", wlan.ifconfig()[0])

# HTTP response helpers
def http_response(conn, body):
    conn.send(b"HTTP/1.1 200 OK\r\n")
    conn.send(b"Content-Type: text/plain\r\n")
    conn.send(b"Content-Length: %d\r\n" % len(body))
    conn.send(b"\r\n")
    conn.send(body)

# HTTP server
def start_server():
    addr = socket.getaddrinfo('0.0.0.0', 80)[0][-1]
    s = socket.socket()
    s.bind(addr)
    s.listen(1)
    print("HTTP server listening on port 80")
    while True:
        try:
            conn, addr = s.accept()
            print("Client connected from", addr)
            request = conn.recv(1024).decode()
            print("Request:", request)
            path = ""
            try:
                path = request.split(" ")[1]
            except:
                pass

            if path == "/":
                body = (
                    "ESP32 Relay Control:\n"
                    "/relay1/on  or /relay1/off\n"
                    "/relay2/on  or /relay2/off\n"
                )
            elif path == "/relay1/on":
                set_relay(1, True)
                body = "Relay 1 ON"
            elif path == "/relay1/off":
                set_relay(1, False)
                body = "Relay 1 OFF"
            elif path == "/relay2/on":
                set_relay(2, True)
                body = "Relay 2 ON"
            elif path == "/relay2/off":
                set_relay(2, False)
                body = "Relay 2 OFF"
            else:
                body = "Invalid path"

            http_response(conn, body.encode())
            conn.close()
        except Exception as e:
            print("Error handling connection:", e)

# Main app
wifi_connect()
start_server()

Now, I'm going to try to do it with Ethernet
Reply


Forum Jump:


Users browsing this thread:
1 Guest(s)