ESP32 IoT project web interface

yukselzngn
Posts: 1
Joined: Tue Oct 03, 2023 6:56 pm

ESP32 IoT project web interface

Postby yukselzngn » Tue Oct 03, 2023 7:20 pm

Hello everyone,

I am using ESP32 as a WebSocket server in my project. I would like to add a user interface similar to a web page. However, I'm stuck on how to do it. It will be a system similar to a web interface where when I enter the IP of the ESP32, a login page will appear, and after logging in, I will reach the main page.

I created a simple example:
My main.c file:


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "esp_spi_flash.h"
#include <esp_http_server.h>
#include "nvs_flash.h"
#include "esp_spiffs.h"

#include "connect_wifi.h"

httpd_handle_t server = NULL;
struct async_resp_arg {
httpd_handle_t hd;
int fd;
};

static const char *TAG = "WebSocket Server";
int led_state = 0;

#define INDEX_HTML_PATH "/spiffs/index.html"
char index_html[4096];
char response_data[4096];

static void initi_web_page_buffer(void)
{
esp_vfs_spiffs_conf_t conf = {
.base_path = "/spiffs",
.partition_label = NULL,
.max_files = 5,
.format_if_mount_failed = true};

ESP_ERROR_CHECK(esp_vfs_spiffs_register(&conf));

memset((void *)index_html, 0, sizeof(index_html));

struct stat st;

stat(INDEX_HTML_PATH, &st);

FILE *fp = fopen(INDEX_HTML_PATH, "r");

fread(index_html, st.st_size, 1, fp);

fclose(fp);
}

esp_err_t get_req_handler(httpd_req_t *req)
{
int response = httpd_resp_send(req, index_html, HTTPD_RESP_USE_STRLEN);
return response;
}


static void ws_async_send(void *arg)
{
httpd_ws_frame_t ws_pkt;
struct async_resp_arg *resp_arg = arg;
httpd_handle_t hd = resp_arg->hd;
int fd = resp_arg->fd;

char buff[4];
memset(buff, 0, sizeof(buff));
memset(&ws_pkt, 0, sizeof(httpd_ws_frame_t));
ws_pkt.payload = (uint8_t *)buff;
ws_pkt.len = strlen(buff);
ws_pkt.type = HTTPD_WS_TYPE_TEXT;

static size_t max_clients = CONFIG_LWIP_MAX_LISTENING_TCP;
size_t fds = max_clients;
int client_fds[max_clients];

esp_err_t ret = httpd_get_client_list(server, &fds, client_fds);

if (ret != ESP_OK) {
return;
}

for (int i = 0; i < fds; i++) {
int client_info = httpd_ws_get_fd_info(server, client_fds);
if (client_info == HTTPD_WS_CLIENT_WEBSOCKET) {
httpd_ws_send_frame_async(hd, client_fds, &ws_pkt);
}
}
free(resp_arg);
}

static esp_err_t trigger_async_send(httpd_handle_t handle, httpd_req_t *req)
{
struct async_resp_arg *resp_arg = malloc(sizeof(struct async_resp_arg));
resp_arg->hd = req->handle;
resp_arg->fd = httpd_req_to_sockfd(req);
return httpd_queue_work(handle, ws_async_send, resp_arg);
}

static esp_err_t handle_ws_req(httpd_req_t *req)
{
if (req->method == HTTP_GET)
{
ESP_LOGI(TAG, "Handshake done, the new connection was opened");
return ESP_OK;
}

httpd_ws_frame_t ws_pkt;
uint8_t *buf = NULL;
memset(&ws_pkt, 0, sizeof(httpd_ws_frame_t));
ws_pkt.type = HTTPD_WS_TYPE_TEXT;
esp_err_t ret = httpd_ws_recv_frame(req, &ws_pkt, 0);
if (ret != ESP_OK)
{
ESP_LOGE(TAG, "httpd_ws_recv_frame failed to get frame len with %d", ret);
return ret;
}

if (ws_pkt.len)
{
buf = calloc(1, ws_pkt.len + 1);
if (buf == NULL)
{
ESP_LOGE(TAG, "Failed to calloc memory for buf");
return ESP_ERR_NO_MEM;
}
ws_pkt.payload = buf;
ret = httpd_ws_recv_frame(req, &ws_pkt, ws_pkt.len);
if (ret != ESP_OK)
{
ESP_LOGE(TAG, "httpd_ws_recv_frame failed with %d", ret);
free(buf);
return ret;
}
ESP_LOGI(TAG, "Got packet with message: %s", ws_pkt.payload);
}

ESP_LOGI(TAG, "frame len is %d", ws_pkt.len);

return ESP_OK;
}

httpd_handle_t setup_websocket_server(void)
{
httpd_config_t config = HTTPD_DEFAULT_CONFIG();

httpd_uri_t uri_get = {
.uri = "/",
.method = HTTP_GET,
.handler = get_req_handler,
.user_ctx = NULL
};


httpd_uri_t ws = {
.uri = "/ws",
.method = HTTP_GET,
.handler = handle_ws_req,
.user_ctx = NULL,
.is_websocket = true};


if (httpd_start(&server, &config) == ESP_OK)
{
httpd_register_uri_handler(server, &uri_get);
httpd_register_uri_handler(server, &ws);
}

return server;
}

void app_main()
{
// Initialize NVS
esp_err_t ret = nvs_flash_init();
if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND)
{
ESP_ERROR_CHECK(nvs_flash_erase());
ret = nvs_flash_init();
}
ESP_ERROR_CHECK(ret);

connect_wifi();

if (wifi_connect_status)
{

led_state = 0;
ESP_LOGI(TAG, "ESP32 ESP-IDF WebSocket Web Server is running ... ...\n");
initi_web_page_buffer();
setup_websocket_server();
}
}

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

my html file:

<!DOCTYPE html>
<html lang="tr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>login</title>
<style>
body {
font-family: Arial, sans-serif;
background-color: #f4f4f4;
margin: 0;
padding: 0;
display: flex
justify-content: center;
align-items: center;A
height: 100vh;
}

.container {
background-color: #ffffff;
border-radius: 5px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
padding: 20px;
width: 300px;
}

.container h2 {
text-align: center;
}

.form-group {
margin-bottom: 20px;
}

.form-group label {
display: block;
font-weight: bold;
}

.form-group input {
width: 100%;
padding: 10px;
border: 1px solid #ccc;
border-radius: 5px;
}

.btn {
background-color: #007BFF;
color: #ffffff;
border: none;
padding: 10px 20px;
border-radius: 5px;
cursor: pointer;
width: 100%;
}

.btn:hover {
background-color: #0056b3;
}
</style>
</head>

<body>
<div class="container">
<h2>Giriş Yap</h2>
<form id="loginForm">
<div class="form-group">
<label for="username">username:</label>
<input type="text" id="username" name="username" required>
</div>
<div class="form-group">
<label for="password">password:</label>
<input type="password" id="password" name="password" required>
</div>
<button type="submit" id="button" class="button">Giriş Yap</button>
</form>
</div>
<script>
var username;
var password;



var gateway = `ws://${window.location.hostname}/ws`;
var websocket;
window.addEventListener('load', onLoad);
function initWebSocket() {
console.log('Trying to open a WebSocket connection...');
websocket = new WebSocket(gateway);
websocket.onopen = onOpen;
websocket.onclose = onClose;
websocket.onmessage = onMessage; // <-- add this line
}
function onOpen(event) {
console.log('Connection opened');
}
function onClose(event) {
console.log('Connection closed');
setTimeout(initWebSocket, 2000);
}
function onMessage(event) {
console.log(event.data);
}
function onLoad(event) {
initWebSocket();
initButton();
}
function initButton() {
document.getElementById('button').addEventListener('click', toggle);
}
function toggle() {
websocket.send('toggle');

document.getElementById("loginForm").addEventListener("submit", function (event) {
event.preventDefault();

username = document.getElementById("username").value;
password = document.getElementById("password").value;


websocket.send("username : " + username);
websocket.send("password: " + password);
websocket.

});




}
</script>
</body>

</html>

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


When I do it this way, the login page appears, and when I press login, the information is sent to the ESP32. However, I'm not sure how to proceed after pressing login; I can't figure out how to transition to the interface. I would greatly appreciate it if you could help me with this.

bidrohini
Posts: 202
Joined: Thu Oct 27, 2022 12:55 pm

Re: ESP32 IoT project web interface

Postby bidrohini » Wed Oct 04, 2023 9:39 am

You may want to try Thinkspeak. Here is a tutorial that may help you.
https://www.theengineeringprojects.com/ ... esp32.html
Here is a discussion on a Web-Server Based Weather Monitoring System Using ESP32. It shows how to upload Sensor data online.

MicroController
Posts: 1707
Joined: Mon Oct 17, 2022 7:38 pm
Location: Europe, Germany

Re: ESP32 IoT project web interface

Postby MicroController » Wed Oct 04, 2023 12:43 pm


Who is online

Users browsing this forum: Bing [Bot] and 119 guests