main
Tarik Hijstek 3 years ago
parent c8e7e2d3fa
commit 8651369c01

@ -0,0 +1,10 @@
# The following lines of boilerplate have to be in your project's CMakeLists
# in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.16)
# (Not part of the boilerplate)
# This example uses an extra component for common functions such as Wi-Fi and Ethernet connection.
set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/protocol_examples_common)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(simple)

@ -0,0 +1,61 @@
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- |
# Simple HTTPD Server Example
The Example consists of HTTPD server demo with demostration of URI handling :
1. URI \hello for GET command returns "Hello World!" message
2. URI \echo for POST command echoes back the POSTed message
## How to use example
### Hardware Required
* A development board with ESP32/ESP32-S2/ESP32-C3 SoC (e.g., ESP32-DevKitC, ESP-WROVER-KIT, etc.)
* A USB cable for power supply and programming
### Configure the project
```
idf.py menuconfig
```
* Open the project configuration menu (`idf.py menuconfig`) to configure Wi-Fi or Ethernet. See "Establishing Wi-Fi or Ethernet Connection" section in [examples/protocols/README.md](../../README.md) for more details.
### Build and Flash
Build the project and flash it to the board, then run monitor tool to view serial output:
```
idf.py -p PORT flash monitor
```
(Replace PORT with the name of the serial port to use.)
(To exit the serial monitor, type ``Ctrl-]``.)
See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects.
### Test the example :
* run the test script : "python scripts/client.py \<IP\> \<port\> \<MSG\>"
* the provided test script first does a GET \hello and displays the response
* the script does a POST to \echo with the user input \<MSG\> and displays the response
* or use curl (asssuming IP is 192.168.43.130):
1. "curl 192.168.43.130:80/hello" - tests the GET "\hello" handler
2. "curl -X POST --data-binary @anyfile 192.168.43.130:80/echo > tmpfile"
* "anyfile" is the file being sent as request body and "tmpfile" is where the body of the response is saved
* since the server echoes back the request body, the two files should be same, as can be confirmed using : "cmp anyfile tmpfile"
3. "curl -X PUT -d "0" 192.168.43.130:80/ctrl" - disable /hello and /echo handlers
4. "curl -X PUT -d "1" 192.168.43.130:80/ctrl" - enable /hello and /echo handlers
## Example Output
```
I (9580) example_connect: - IPv4 address: 192.168.194.219
I (9580) example_connect: - IPv6 address: fe80:0000:0000:0000:266f:28ff:fe80:2c74, type: ESP_IP6_ADDR_IS_LINK_LOCAL
I (9590) example: Starting server on port: '80'
I (9600) example: Registering URI handlers
I (66450) example: Found header => Host: 192.168.194.219
I (66460) example: Request headers lost
```
## Troubleshooting
* If the server log shows "httpd_parse: parse_block: request URI/header too long", especially when handling POST requests, then you probably need to increase HTTPD_MAX_REQ_HDR_LEN, which you can find in the project configuration menu (`idf.py menuconfig`): Component config -> HTTP Server -> Max HTTP Request Header Length

@ -0,0 +1,2 @@
idf_component_register(SRCS "main.c"
INCLUDE_DIRS ".")

@ -0,0 +1,29 @@
menu "Example Configuration"
config EXAMPLE_BASIC_AUTH
bool "Basic Authentication"
default n
help
Basic Authentication is a method for an HTTP user agent (e.g. a web browser)
to provide a user name and password when making a request. It is the simplest
technique for enforcing access controls to web resources. because it doesn't
require cookies, session identifiers, or login pages; rather, it uses standard
fields in the HTTP header.
Note that, Basic Authentication is not encrypted channel and also easy to retrieve
credentials as they are sent in plain text format.
config EXAMPLE_BASIC_AUTH_USERNAME
string "Basic Authenticate User Name"
depends on EXAMPLE_BASIC_AUTH
default "ESP32"
help
The client's user name which used for basic authenticate.
config EXAMPLE_BASIC_AUTH_PASSWORD
string "Basic Authenticate Password"
depends on EXAMPLE_BASIC_AUTH
default "ESP32Webserver"
help
The client's password which used for basic authenticate.
endmenu

@ -0,0 +1,504 @@
/* Simple HTTP Server Example
This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
#include <esp_wifi.h>
#include <esp_event.h>
#include <esp_log.h>
#include <esp_system.h>
#include <nvs_flash.h>
#include <sys/param.h>
#include "nvs_flash.h"
#include "esp_netif.h"
#include "esp_eth.h"
#include "protocol_examples_common.h"
#include "protocol_examples_utils.h"
#include "esp_tls_crypto.h"
#include <esp_http_server.h>
#include "driver/ledc.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
//LED defines.
#define LEDC_TIMER LEDC_TIMER_0
#define LEDC_MODE LEDC_LOW_SPEED_MODE
#define LEDC_OUTPUT_IO (38 ) // Define the output GPIO. 38 in the onboard LED.
#define LEDC_CHANNEL LEDC_CHANNEL_0
#define LEDC_DUTY_RES LEDC_TIMER_13_BIT // Set duty resolution to 13 bits
#define LEDC_DUTY (4095) // Set duty to 50%. ((2 ** 13) - 1) * 50% = 4095
#define LEDC_FREQUENCY (5000) // Frequency in Hertz. Set frequency at 5 kHz
#define EXAMPLE_HTTP_QUERY_KEY_MAX_LEN (64)
/* A simple example that demonstrates how to create GET and POST
* handlers for the web server.
*/
static const char *TAG = "example";
#if CONFIG_EXAMPLE_BASIC_AUTH
typedef struct {
char *username;
char *password;
} basic_auth_info_t;
#define HTTPD_401 "401 UNAUTHORIZED" /*!< HTTP Response 401 */
static char *http_auth_basic(const char *username, const char *password)
{
int out;
char *user_info = NULL;
char *digest = NULL;
size_t n = 0;
asprintf(&user_info, "%s:%s", username, password);
if (!user_info) {
ESP_LOGE(TAG, "No enough memory for user information");
return NULL;
}
esp_crypto_base64_encode(NULL, 0, &n, (const unsigned char *)user_info, strlen(user_info));
/* 6: The length of the "Basic " string
* n: Number of bytes for a base64 encode format
* 1: Number of bytes for a reserved which be used to fill zero
*/
digest = calloc(1, 6 + n + 1);
if (digest) {
strcpy(digest, "Basic ");
esp_crypto_base64_encode((unsigned char *)digest + 6, n, (size_t *)&out, (const unsigned char *)user_info, strlen(user_info));
}
free(user_info);
return digest;
}
/* An HTTP GET handler */
static esp_err_t basic_auth_get_handler(httpd_req_t *req)
{
char *buf = NULL;
size_t buf_len = 0;
basic_auth_info_t *basic_auth_info = req->user_ctx;
buf_len = httpd_req_get_hdr_value_len(req, "Authorization") + 1;
if (buf_len > 1) {
buf = calloc(1, buf_len);
if (!buf) {
ESP_LOGE(TAG, "No enough memory for basic authorization");
return ESP_ERR_NO_MEM;
}
if (httpd_req_get_hdr_value_str(req, "Authorization", buf, buf_len) == ESP_OK) {
ESP_LOGI(TAG, "Found header => Authorization: %s", buf);
} else {
ESP_LOGE(TAG, "No auth value received");
}
char *auth_credentials = http_auth_basic(basic_auth_info->username, basic_auth_info->password);
if (!auth_credentials) {
ESP_LOGE(TAG, "No enough memory for basic authorization credentials");
free(buf);
return ESP_ERR_NO_MEM;
}
if (strncmp(auth_credentials, buf, buf_len)) {
ESP_LOGE(TAG, "Not authenticated");
httpd_resp_set_status(req, HTTPD_401);
httpd_resp_set_type(req, "application/json");
httpd_resp_set_hdr(req, "Connection", "keep-alive");
httpd_resp_set_hdr(req, "WWW-Authenticate", "Basic realm=\"Hello\"");
httpd_resp_send(req, NULL, 0);
} else {
ESP_LOGI(TAG, "Authenticated!");
char *basic_auth_resp = NULL;
httpd_resp_set_status(req, HTTPD_200);
httpd_resp_set_type(req, "application/json");
httpd_resp_set_hdr(req, "Connection", "keep-alive");
asprintf(&basic_auth_resp, "{\"authenticated\": true,\"user\": \"%s\"}", basic_auth_info->username);
if (!basic_auth_resp) {
ESP_LOGE(TAG, "No enough memory for basic authorization response");
free(auth_credentials);
free(buf);
return ESP_ERR_NO_MEM;
}
httpd_resp_send(req, basic_auth_resp, strlen(basic_auth_resp));
free(basic_auth_resp);
}
free(auth_credentials);
free(buf);
} else {
ESP_LOGE(TAG, "No auth header received");
httpd_resp_set_status(req, HTTPD_401);
httpd_resp_set_type(req, "application/json");
httpd_resp_set_hdr(req, "Connection", "keep-alive");
httpd_resp_set_hdr(req, "WWW-Authenticate", "Basic realm=\"Hello\"");
httpd_resp_send(req, NULL, 0);
}
return ESP_OK;
}
static httpd_uri_t basic_auth = {
.uri = "/basic_auth",
.method = HTTP_GET,
.handler = basic_auth_get_handler,
};
static void httpd_register_basic_auth(httpd_handle_t server)
{
basic_auth_info_t *basic_auth_info = calloc(1, sizeof(basic_auth_info_t));
if (basic_auth_info) {
basic_auth_info->username = CONFIG_EXAMPLE_BASIC_AUTH_USERNAME;
basic_auth_info->password = CONFIG_EXAMPLE_BASIC_AUTH_PASSWORD;
basic_auth.user_ctx = basic_auth_info;
httpd_register_uri_handler(server, &basic_auth);
}
}
#endif
/* An HTTP GET handler */
static esp_err_t hello_get_handler(httpd_req_t *req)
{
char* buf;
size_t buf_len;
/* Get header value string length and allocate memory for length + 1,
* extra byte for null termination */
buf_len = httpd_req_get_hdr_value_len(req, "Host") + 1;
if (buf_len > 1) {
buf = malloc(buf_len);
/* Copy null terminated value string into buffer */
if (httpd_req_get_hdr_value_str(req, "Host", buf, buf_len) == ESP_OK) {
ESP_LOGI(TAG, "Found header => Host: %s", buf);
}
free(buf);
}
buf_len = httpd_req_get_hdr_value_len(req, "Test-Header-2") + 1;
if (buf_len > 1) {
buf = malloc(buf_len);
if (httpd_req_get_hdr_value_str(req, "Test-Header-2", buf, buf_len) == ESP_OK) {
ESP_LOGI(TAG, "Found header => Test-Header-2: %s", buf);
}
free(buf);
}
buf_len = httpd_req_get_hdr_value_len(req, "Test-Header-1") + 1;
if (buf_len > 1) {
buf = malloc(buf_len);
if (httpd_req_get_hdr_value_str(req, "Test-Header-1", buf, buf_len) == ESP_OK) {
ESP_LOGI(TAG, "Found header => Test-Header-1: %s", buf);
}
free(buf);
}
/* Read URL query string length and allocate memory for length + 1,
* extra byte for null termination */
buf_len = httpd_req_get_url_query_len(req) + 1;
if (buf_len > 1) {
buf = malloc(buf_len);
if (httpd_req_get_url_query_str(req, buf, buf_len) == ESP_OK) {
ESP_LOGI(TAG, "Found URL query => %s", buf);
char param[EXAMPLE_HTTP_QUERY_KEY_MAX_LEN], dec_param[EXAMPLE_HTTP_QUERY_KEY_MAX_LEN] = {0};
/* Get value of expected key from query string */
if (httpd_query_key_value(buf, "query1", param, sizeof(param)) == ESP_OK) {
ESP_LOGI(TAG, "Found URL query parameter => query1=%s", param);
example_uri_decode(dec_param, param, strnlen(param, EXAMPLE_HTTP_QUERY_KEY_MAX_LEN));
ESP_LOGI(TAG, "Decoded query parameter => %s", dec_param);
}
if (httpd_query_key_value(buf, "query3", param, sizeof(param)) == ESP_OK) {
ESP_LOGI(TAG, "Found URL query parameter => query3=%s", param);
example_uri_decode(dec_param, param, strnlen(param, EXAMPLE_HTTP_QUERY_KEY_MAX_LEN));
ESP_LOGI(TAG, "Decoded query parameter => %s", dec_param);
}
if (httpd_query_key_value(buf, "query2", param, sizeof(param)) == ESP_OK) {
ESP_LOGI(TAG, "Found URL query parameter => query2=%s", param);
example_uri_decode(dec_param, param, strnlen(param, EXAMPLE_HTTP_QUERY_KEY_MAX_LEN));
ESP_LOGI(TAG, "Decoded query parameter => %s", dec_param);
}
}
free(buf);
}
/* Set some custom headers */
httpd_resp_set_hdr(req, "Custom-Header-1", "Custom-Value-1");
httpd_resp_set_hdr(req, "Custom-Header-2", "Custom-Value-2");
/* Send response with custom headers and body set as the
* string passed in user context*/
const char* resp_str = (const char*) req->user_ctx;
httpd_resp_send(req, resp_str, HTTPD_RESP_USE_STRLEN);
/* After sending the HTTP response the old HTTP request
* headers are lost. Check if HTTP request headers can be read now. */
if (httpd_req_get_hdr_value_len(req, "Host") == 0) {
ESP_LOGI(TAG, "Request headers lost");
}
return ESP_OK;
}
static const httpd_uri_t hello = {
.uri = "/hello",
.method = HTTP_GET,
.handler = hello_get_handler,
/* Let's pass response string in user
* context to demonstrate it's usage */
.user_ctx = "Hello World!"
};
/* An HTTP POST handler */
static esp_err_t echo_post_handler(httpd_req_t *req)
{
char buf[100];
int ret, remaining = req->content_len;
while (remaining > 0) {
/* Read the data for the request */
if ((ret = httpd_req_recv(req, buf,
MIN(remaining, sizeof(buf)))) <= 0) {
if (ret == HTTPD_SOCK_ERR_TIMEOUT) {
/* Retry receiving if timeout occurred */
continue;
}
return ESP_FAIL;
}
/* Send back the same data */
httpd_resp_send_chunk(req, buf, ret);
remaining -= ret;
/* Log data received */
ESP_LOGI(TAG, "=========== RECEIVED DATA ==========");
ESP_LOGI(TAG, "%.*s", ret, buf);
ESP_LOGI(TAG, "====================================");
}
// End response
httpd_resp_send_chunk(req, NULL, 0);
return ESP_OK;
}
static const httpd_uri_t echo = {
.uri = "/echo",
.method = HTTP_POST,
.handler = echo_post_handler,
.user_ctx = NULL
};
/* This handler allows the custom error handling functionality to be
* tested from client side. For that, when a PUT request 0 is sent to
* URI /ctrl, the /hello and /echo URIs are unregistered and following
* custom error handler http_404_error_handler() is registered.
* Afterwards, when /hello or /echo is requested, this custom error
* handler is invoked which, after sending an error message to client,
* either closes the underlying socket (when requested URI is /echo)
* or keeps it open (when requested URI is /hello). This allows the
* client to infer if the custom error handler is functioning as expected
* by observing the socket state.
*/
esp_err_t http_404_error_handler(httpd_req_t *req, httpd_err_code_t err)
{
if (strcmp("/hello", req->uri) == 0) {
httpd_resp_send_err(req, HTTPD_404_NOT_FOUND, "/hello URI is not available");
/* Return ESP_OK to keep underlying socket open */
return ESP_OK;
} else if (strcmp("/echo", req->uri) == 0) {
httpd_resp_send_err(req, HTTPD_404_NOT_FOUND, "/echo URI is not available");
/* Return ESP_FAIL to close underlying socket */
return ESP_FAIL;
}
/* For any other URI send 404 and close socket */
httpd_resp_send_err(req, HTTPD_404_NOT_FOUND, "Some 404 error message");
return ESP_FAIL;
}
/* An HTTP PUT handler. This demonstrates realtime
* registration and deregistration of URI handlers
*/
static esp_err_t ctrl_put_handler(httpd_req_t *req)
{
char buf;
int ret;
if ((ret = httpd_req_recv(req, &buf, 1)) <= 0) {
if (ret == HTTPD_SOCK_ERR_TIMEOUT) {
httpd_resp_send_408(req);
}
return ESP_FAIL;
}
if (buf == '0') {
/* URI handlers can be unregistered using the uri string */
ESP_LOGI(TAG, "Unregistering /hello and /echo URIs");
httpd_unregister_uri(req->handle, "/hello");
httpd_unregister_uri(req->handle, "/echo");
/* Register the custom error handler */
httpd_register_err_handler(req->handle, HTTPD_404_NOT_FOUND, http_404_error_handler);
}
else {
ESP_LOGI(TAG, "Registering /hello and /echo URIs");
httpd_register_uri_handler(req->handle, &hello);
httpd_register_uri_handler(req->handle, &echo);
/* Unregister custom error handler */
httpd_register_err_handler(req->handle, HTTPD_404_NOT_FOUND, NULL);
}
/* Respond with empty body */
httpd_resp_send(req, NULL, 0);
return ESP_OK;
}
static const httpd_uri_t ctrl = {
.uri = "/ctrl",
.method = HTTP_PUT,
.handler = ctrl_put_handler,
.user_ctx = NULL
};
static esp_err_t led1_handler(httpd_req_t *req){
//Op request de Duty cycle veranderen.
// Ben geen fan van het hard crashen als het aanpassen van de LED niet goed gaat, maar voor nu houd ik het er in.
// Kan goede logging bevatten.
ESP_ERROR_CHECK(ledc_set_duty(LEDC_MODE, LEDC_CHANNEL, LEDC_DUTY));
ESP_ERROR_CHECK(ledc_update_duty(LEDC_MODE, LEDC_CHANNEL));
//TODO: cycle colour between calls
// Do this via a const addition.
ESP_LOGI(TAG, "LED mode set!");
//send empty body back
httpd_resp_sendstr(req, "LED Mode set!");
return ESP_OK;
}
static const httpd_uri_t led1 = {
.uri = "/led",
.method = HTTP_GET,
.handler = led1_handler,
.user_ctx = NULL
};
static httpd_handle_t start_webserver(void)
{
httpd_handle_t server = NULL;
httpd_config_t config = HTTPD_DEFAULT_CONFIG();
config.lru_purge_enable = true;
// Start the httpd server
ESP_LOGI(TAG, "Starting server on port: '%d'", config.server_port);
if (httpd_start(&server, &config) == ESP_OK) {
// Set URI handlers
ESP_LOGI(TAG, "Registering URI handlers");
httpd_register_uri_handler(server, &hello);
httpd_register_uri_handler(server, &echo);
httpd_register_uri_handler(server, &ctrl);
httpd_register_uri_handler(server, &led1);
#if CONFIG_EXAMPLE_BASIC_AUTH
httpd_register_basic_auth(server);
#endif
return server;
}
ESP_LOGI(TAG, "Error starting server!");
return NULL;
}
static esp_err_t stop_webserver(httpd_handle_t server)
{
// Stop the httpd server
return httpd_stop(server);
}
static void disconnect_handler(void* arg, esp_event_base_t event_base,
int32_t event_id, void* event_data)
{
httpd_handle_t* server = (httpd_handle_t*) arg;
if (*server) {
ESP_LOGI(TAG, "Stopping webserver");
if (stop_webserver(*server) == ESP_OK) {
*server = NULL;
} else {
ESP_LOGE(TAG, "Failed to stop http server");
}
}
}
static void connect_handler(void* arg, esp_event_base_t event_base,
int32_t event_id, void* event_data)
{
httpd_handle_t* server = (httpd_handle_t*) arg;
if (*server == NULL) {
ESP_LOGI(TAG, "Starting webserver");
*server = start_webserver();
}
}
static void example_ledc_init(void)
{
// Prepare and then apply the LEDC PWM timer configuration
ledc_timer_config_t ledc_timer = {
.speed_mode = LEDC_MODE,
.timer_num = LEDC_TIMER,
.duty_resolution = LEDC_DUTY_RES,
.freq_hz = LEDC_FREQUENCY, // Set output frequency at 5 kHz
.clk_cfg = LEDC_AUTO_CLK
};
ESP_ERROR_CHECK(ledc_timer_config(&ledc_timer));
// Prepare and then apply the LEDC PWM channel configuration
ledc_channel_config_t ledc_channel = {
.speed_mode = LEDC_MODE,
.channel = LEDC_CHANNEL,
.timer_sel = LEDC_TIMER,
.intr_type = LEDC_INTR_DISABLE,
.gpio_num = LEDC_OUTPUT_IO,
.duty = LEDC_DUTY, // Set duty to 0%
.hpoint = 0
};
ESP_ERROR_CHECK(ledc_channel_config(&ledc_channel));
ESP_LOGI(TAG, "LEDC init done");
}
void app_main(void)
{
static httpd_handle_t server = NULL;
ESP_ERROR_CHECK(nvs_flash_init());
ESP_ERROR_CHECK(esp_netif_init());
ESP_ERROR_CHECK(esp_event_loop_create_default());
/* This helper function configures Wi-Fi or Ethernet, as selected in menuconfig.
* Read "Establishing Wi-Fi or Ethernet Connection" section in
* examples/protocols/README.md for more information about this function.
*/
ESP_ERROR_CHECK(example_connect());
//Initialise LED.
example_ledc_init();
/* Register event handlers to stop the server when Wi-Fi or Ethernet is disconnected,
* and re-start it upon connection.
*/
#ifdef CONFIG_EXAMPLE_CONNECT_WIFI
ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &connect_handler, &server));
ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_DISCONNECTED, &disconnect_handler, &server));
#endif // CONFIG_EXAMPLE_CONNECT_WIFI
#ifdef CONFIG_EXAMPLE_CONNECT_ETHERNET
ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_ETH_GOT_IP, &connect_handler, &server));
ESP_ERROR_CHECK(esp_event_handler_register(ETH_EVENT, ETHERNET_EVENT_DISCONNECTED, &disconnect_handler, &server));
#endif // CONFIG_EXAMPLE_CONNECT_ETHERNET
/* Start the server for the first time */
server = start_webserver();
}

@ -0,0 +1,173 @@
#!/usr/bin/env python
#
# SPDX-FileCopyrightText: 2018-2022 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: Apache-2.0
import logging
import os
import random
import socket
import string
import sys
import threading
import time
import pytest
try:
from idf_http_server_test import client
except ModuleNotFoundError:
sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', '..', '..', 'tools', 'ci', 'python_packages'))
from idf_http_server_test import client
from common_test_methods import get_env_config_variable
from pytest_embedded import Dut
class http_client_thread(threading.Thread):
def __init__(self, ip: str, port: int, delay: int) -> None:
threading.Thread.__init__(self)
self.ip = ip
self.port = port
self.delay = delay
self.exc = 0
# Thread function used to open a socket and wait for specific amount of time before returning
def open_connection(self, ip: str, port: int, delay: int) -> None:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.settimeout(delay)
s.connect((ip, port))
time.sleep(delay)
def run(self) -> None:
try:
self.open_connection(self.ip, self.port, self.delay)
except socket.timeout:
self.exc = 1
def join(self, timeout=None): # type: ignore
threading.Thread.join(self)
if self.exc:
raise socket.timeout
# When running on local machine execute the following before running this script
# > make app bootloader
# > make print_flash_cmd | tail -n 1 > build/download.config
@pytest.mark.esp32
@pytest.mark.esp32c3
@pytest.mark.esp32s3
@pytest.mark.wifi_router
def test_examples_protocol_http_server_simple(dut: Dut) -> None:
# Get binary file
binary_file = os.path.join(dut.app.binary_path, 'simple.bin')
bin_size = os.path.getsize(binary_file)
logging.info('http_server_bin_size : {}KB'.format(bin_size // 1024))
# Upload binary and start testing
logging.info('Starting http_server simple test app')
# Parse IP address of STA
logging.info('Waiting to connect with AP')
if dut.app.sdkconfig.get('EXAMPLE_WIFI_SSID_PWD_FROM_STDIN') is True:
dut.expect('Please input ssid password:')
env_name = 'wifi_router'
ap_ssid = get_env_config_variable(env_name, 'ap_ssid')
ap_password = get_env_config_variable(env_name, 'ap_password')
dut.write(' '.join([ap_ssid, ap_password]))
got_ip = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)[^\d]', timeout=30)[1].decode()
got_port = dut.expect(r"(?:[\s\S]*)Starting server on port: '(\d+)'", timeout=30)[1].decode()
logging.info('Got IP : {}'.format(got_ip))
logging.info('Got Port : {}'.format(got_port))
# Expected Logs
dut.expect('Registering URI handlers', timeout=30)
# Run test script
# If failed raise appropriate exception
logging.info('Test /hello GET handler')
if not client.test_get_handler(got_ip, str(got_port)):
raise RuntimeError
# Acquire host IP. Need a way to check it
dut.expect(r'(?:[\s\S]*)Found header => Host: (\d+.\d+.\d+.\d+)', timeout=30)
# Match additional headers sent in the request
dut.expect('Found header => Test-Header-2: Test-Value-2', timeout=30)
dut.expect('Found header => Test-Header-1: Test-Value-1', timeout=30)
dut.expect('Found URL query parameter => query1=value1', timeout=30)
dut.expect('Found URL query parameter => query3=value3', timeout=30)
dut.expect('Found URL query parameter => query2=value2', timeout=30)
dut.expect('Request headers lost', timeout=30)
logging.info('Test /ctrl PUT handler and realtime handler de/registration')
if not client.test_put_handler(got_ip, got_port):
raise RuntimeError
dut.expect('Unregistering /hello and /echo URIs', timeout=30)
dut.expect('Registering /hello and /echo URIs', timeout=30)
# Generate random data of 10KB
random_data = ''.join(string.printable[random.randint(0,len(string.printable)) - 1] for _ in range(10 * 1024))
logging.info('Test /echo POST handler with random data')
if not client.test_post_handler(got_ip, got_port, random_data):
raise RuntimeError
queries = 'query1=http%3A%2F%2Ffoobar&query3=abcd%2B1234%20xyz&query2=Esp%21%40%20%23%2471'
logging.info('Test /hello with custom query')
if not client.test_custom_uri_query(got_ip, got_port, queries):
raise RuntimeError
dut.expect_exact('Found URL query => query1=http%3A%2F%2Ffoobar&query3=abcd%2B1234%20xyz&query2=Esp%21%40%20%23%2471', timeout=30)
dut.expect_exact('Found URL query parameter => query1=http%3A%2F%2Ffoobar', timeout=30)
dut.expect_exact('Decoded query parameter => http://foobar', timeout=30)
dut.expect_exact('Found URL query parameter => query3=abcd%2B1234%20xyz', timeout=30)
dut.expect_exact('Decoded query parameter => abcd+1234 xyz', timeout=30)
dut.expect_exact('Found URL query parameter => query2=Esp%21%40%20%23%2471', timeout=30)
dut.expect_exact('Decoded query parameter => Esp!@ #$71', timeout=30)
@pytest.mark.esp32
@pytest.mark.esp32c3
@pytest.mark.esp32s3
@pytest.mark.wifi_router
def test_examples_protocol_http_server_lru_purge_enable(dut: Dut) -> None:
# Get binary file
binary_file = os.path.join(dut.app.binary_path, 'simple.bin')
bin_size = os.path.getsize(binary_file)
logging.info('http_server_bin_size : {}KB'.format(bin_size // 1024))
# Upload binary and start testing
logging.info('Starting http_server simple test app')
# Parse IP address of STA
logging.info('Waiting to connect with AP')
if dut.app.sdkconfig.get('EXAMPLE_WIFI_SSID_PWD_FROM_STDIN') is True:
dut.expect('Please input ssid password:')
env_name = 'wifi_router'
ap_ssid = get_env_config_variable(env_name, 'ap_ssid')
ap_password = get_env_config_variable(env_name, 'ap_password')
dut.write(f'{ap_ssid} {ap_password}')
got_ip = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)[^\d]', timeout=30)[1].decode()
got_port = dut.expect(r"(?:[\s\S]*)Starting server on port: '(\d+)'", timeout=30)[1].decode()
logging.info('Got IP : {}'.format(got_ip))
logging.info('Got Port : {}'.format(got_port))
# Expected Logs
dut.expect('Registering URI handlers', timeout=30)
threads = []
# Open 20 sockets, one from each thread
for _ in range(20):
try:
thread = http_client_thread(got_ip, (int(got_port)), 20)
thread.start()
threads.append(thread)
except OSError as err:
logging.info('Error: unable to start thread, {}'.format(err))
for t in threads:
t.join()

@ -0,0 +1,2 @@
CONFIG_EXAMPLE_BASIC_AUTH=y
CONFIG_EXAMPLE_WIFI_SSID_PWD_FROM_STDIN=y

@ -20,4 +20,23 @@ Dit bouwt op mijn kennis van het web, en geeft mij een aantal protocollen om te
Helloworld applicatie kunne flashen op ESP! En een heel kleine aanpassing kunnen maken aan de snelheid van de helloworld main loop :)
Woensdag 22/02/2023
Donderdag 22/02/2023
Wifi voorbeeld aan de praat gekregen. Rest van de tijd besteed aan het snappen van de code.
Moet wennen aan hoevaak de ESP_ERROR_CHECK wordt aangeroepen.
Woensdag 01/03/2023
Blijkt dat er al een HTTP server voorbeeld is. Mijn nieuwe plan moet dus weer wat aangepast worden zodat ik wel echt iets kan showen. Espressif heeft wel veel voorbeelden, en het is goed om deze te weten te vinden.
Plan voor nu is de server werkend te krijgen, en dan via een HTTP command een ledje aansturen. Er zit er slechts 1 ingebakken op het bord zelf, Dus ik zal wss van kantoor een aantal andere moeten lenen.
Zaterdag 04/03/2023
HTTP voorbeeld server werkt! Via menuconfig het wifi wachtwoord ingegeven, en de basis /hello en /echo werken! Ze hebben zelfs extra aandacht gegeven om 404's en 405's te ondersteunen.
Het LED voorbeeld lijkt alleen niet te werken. Moet uitzoeken wat er precies mis is. De main LED is op IO38. Maar alleen de pin aanpassen in het voorbeeld is niet genoeg.
Om te valideren dat ik wel werkende code heb, wil ik de ESPOTEK labrador gebruiken. Dit is een mini oscilloscoop, signal generater en logic analyser in 1 dev bord. Deze kreeg ik helaas niet aan de praat op mijn pc, en heb een support request uitgestuurt voor hulp.
Maandag 06/03/2023
ESPOTEK Labrador aan de praat gekregen! Moest via een andere computer eerst een firmware opnieuw flashen, daarna werkte het.
Dinsdag 07/03/2023
Code aangepast zodat deze op pin5 een led zou moeten aansturen. Dit met de scope geprobeert te zien of de PWM signalen wel gegenereerd worden, maar die kon ik niet uitlezen.
Weet niet wat het probleem is. Ook met het LEDC voorbeeld niet kunnen zien dat er iets gebeurt.

@ -9,6 +9,11 @@ void app_main(void)
while (1) {
printf("[%d] Hello world!\n", i);
i++;
vTaskDelay(5000 / portTICK_PERIOD_MS);
//vTaskDelay(5000 / portTICK_PERIOD_MS); // print helloworld every 5 seconds.
if((i % 10) == 0){
//TODO: blink led.
}
vTaskDelay(portTICK_PERIOD_MS); // print helloworld as fast as possible.
}
}

@ -19,3 +19,4 @@ wat betekend tm060sdhe1 op het scherm?
> alternatieve naam voor display.
Wat is minimaal nodig om een build te doen?
> idf tooling. Staat in de getting started voor de esp32s3.

@ -0,0 +1,6 @@
# The following five lines of boilerplate have to be in your project's
# CMakeLists in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.16)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(wifi_station)

@ -0,0 +1,121 @@
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- |
# Wi-Fi Station Example
(See the README.md file in the upper level 'examples' directory for more information about examples.)
This example shows how to use the Wi-Fi Station functionality of the Wi-Fi driver of ESP for connecting to an Access Point.
## How to use example
### Configure the project
Open the project configuration menu (`idf.py menuconfig`).
In the `Example Configuration` menu:
* Set the Wi-Fi configuration.
* Set `WiFi SSID`.
* Set `WiFi Password`.
Optional: If you need, change the other options according to your requirements.
### Build and Flash
Build the project and flash it to the board, then run the monitor tool to view the serial output:
Run `idf.py -p PORT flash monitor` to build, flash and monitor the project.
(To exit the serial monitor, type ``Ctrl-]``.)
See the Getting Started Guide for all the steps to configure and use the ESP-IDF to build projects.
* [ESP-IDF Getting Started Guide on ESP32](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/get-started/index.html)
* [ESP-IDF Getting Started Guide on ESP32-S2](https://docs.espressif.com/projects/esp-idf/en/latest/esp32s2/get-started/index.html)
* [ESP-IDF Getting Started Guide on ESP32-C3](https://docs.espressif.com/projects/esp-idf/en/latest/esp32c3/get-started/index.html)
## Example Output
Note that the output, in particular the order of the output, may vary depending on the environment.
Console output if station connects to AP successfully:
```
I (589) wifi station: ESP_WIFI_MODE_STA
I (599) wifi: wifi driver task: 3ffc08b4, prio:23, stack:3584, core=0
I (599) system_api: Base MAC address is not set, read default base MAC address from BLK0 of EFUSE
I (599) system_api: Base MAC address is not set, read default base MAC address from BLK0 of EFUSE
I (629) wifi: wifi firmware version: 2d94f02
I (629) wifi: config NVS flash: enabled
I (629) wifi: config nano formating: disabled
I (629) wifi: Init dynamic tx buffer num: 32
I (629) wifi: Init data frame dynamic rx buffer num: 32
I (639) wifi: Init management frame dynamic rx buffer num: 32
I (639) wifi: Init management short buffer num: 32
I (649) wifi: Init static rx buffer size: 1600
I (649) wifi: Init static rx buffer num: 10
I (659) wifi: Init dynamic rx buffer num: 32
I (759) phy: phy_version: 4180, cb3948e, Sep 12 2019, 16:39:13, 0, 0
I (769) wifi: mode : sta (30:ae:a4:d9:bc:c4)
I (769) wifi station: wifi_init_sta finished.
I (889) wifi: new:<6,0>, old:<1,0>, ap:<255,255>, sta:<6,0>, prof:1
I (889) wifi: state: init -> auth (b0)
I (899) wifi: state: auth -> assoc (0)
I (909) wifi: state: assoc -> run (10)
I (939) wifi: connected with #!/bin/test, aid = 1, channel 6, BW20, bssid = ac:9e:17:7e:31:40
I (939) wifi: security type: 3, phy: bgn, rssi: -68
I (949) wifi: pm start, type: 1
I (1029) wifi: AP's beacon interval = 102400 us, DTIM period = 3
I (2089) esp_netif_handlers: sta ip: 192.168.77.89, mask: 255.255.255.0, gw: 192.168.77.1
I (2089) wifi station: got ip:192.168.77.89
I (2089) wifi station: connected to ap SSID:myssid password:mypassword
```
Console output if the station failed to connect to AP:
```
I (589) wifi station: ESP_WIFI_MODE_STA
I (599) wifi: wifi driver task: 3ffc08b4, prio:23, stack:3584, core=0
I (599) system_api: Base MAC address is not set, read default base MAC address from BLK0 of EFUSE
I (599) system_api: Base MAC address is not set, read default base MAC address from BLK0 of EFUSE
I (629) wifi: wifi firmware version: 2d94f02
I (629) wifi: config NVS flash: enabled
I (629) wifi: config nano formating: disabled
I (629) wifi: Init dynamic tx buffer num: 32
I (629) wifi: Init data frame dynamic rx buffer num: 32
I (639) wifi: Init management frame dynamic rx buffer num: 32
I (639) wifi: Init management short buffer num: 32
I (649) wifi: Init static rx buffer size: 1600
I (649) wifi: Init static rx buffer num: 10
I (659) wifi: Init dynamic rx buffer num: 32
I (759) phy: phy_version: 4180, cb3948e, Sep 12 2019, 16:39:13, 0, 0
I (759) wifi: mode : sta (30:ae:a4:d9:bc:c4)
I (769) wifi station: wifi_init_sta finished.
I (889) wifi: new:<6,0>, old:<1,0>, ap:<255,255>, sta:<6,0>, prof:1
I (889) wifi: state: init -> auth (b0)
I (1889) wifi: state: auth -> init (200)
I (1889) wifi: new:<6,0>, old:<6,0>, ap:<255,255>, sta:<6,0>, prof:1
I (1889) wifi station: retry to connect to the AP
I (1899) wifi station: connect to the AP fail
I (3949) wifi station: retry to connect to the AP
I (3949) wifi station: connect to the AP fail
I (4069) wifi: new:<6,0>, old:<6,0>, ap:<255,255>, sta:<6,0>, prof:1
I (4069) wifi: state: init -> auth (b0)
I (5069) wifi: state: auth -> init (200)
I (5069) wifi: new:<6,0>, old:<6,0>, ap:<255,255>, sta:<6,0>, prof:1
I (5069) wifi station: retry to connect to the AP
I (5069) wifi station: connect to the AP fail
I (7129) wifi station: retry to connect to the AP
I (7129) wifi station: connect to the AP fail
I (7249) wifi: new:<6,0>, old:<6,0>, ap:<255,255>, sta:<6,0>, prof:1
I (7249) wifi: state: init -> auth (b0)
I (8249) wifi: state: auth -> init (200)
I (8249) wifi: new:<6,0>, old:<6,0>, ap:<255,255>, sta:<6,0>, prof:1
I (8249) wifi station: retry to connect to the AP
I (8249) wifi station: connect to the AP fail
I (10299) wifi station: connect to the AP fail
I (10299) wifi station: Failed to connect to SSID:myssid, password:mypassword
```
## Troubleshooting
For any technical queries, please open an [issue](https://github.com/espressif/esp-idf/issues) on GitHub. We will get back to you soon.

@ -0,0 +1,2 @@
idf_component_register(SRCS "station_example_main.c"
INCLUDE_DIRS ".")

@ -0,0 +1,47 @@
menu "Example Configuration"
config ESP_WIFI_SSID
string "WiFi SSID"
default "myssid"
help
SSID (network name) for the example to connect to.
config ESP_WIFI_PASSWORD
string "WiFi Password"
default "mypassword"
help
WiFi password (WPA or WPA2) for the example to use.
config ESP_MAXIMUM_RETRY
int "Maximum retry"
default 5
help
Set the Maximum retry to avoid station reconnecting to the AP unlimited when the AP is really inexistent.
choice ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD
prompt "WiFi Scan auth mode threshold"
default ESP_WIFI_AUTH_WPA2_PSK
help
The weakest authmode to accept in the scan mode.
This value defaults to ESP_WIFI_AUTH_WPA2_PSK incase password is present and ESP_WIFI_AUTH_OPEN is used.
Please select ESP_WIFI_AUTH_WEP/ESP_WIFI_AUTH_WPA_PSK incase AP is operating in WEP/WPA mode.
config ESP_WIFI_AUTH_OPEN
bool "OPEN"
config ESP_WIFI_AUTH_WEP
bool "WEP"
config ESP_WIFI_AUTH_WPA_PSK
bool "WPA PSK"
config ESP_WIFI_AUTH_WPA2_PSK
bool "WPA2 PSK"
config ESP_WIFI_AUTH_WPA_WPA2_PSK
bool "WPA/WPA2 PSK"
config ESP_WIFI_AUTH_WPA3_PSK
bool "WPA3 PSK"
config ESP_WIFI_AUTH_WPA2_WPA3_PSK
bool "WPA2/WPA3 PSK"
config ESP_WIFI_AUTH_WAPI_PSK
bool "WAPI PSK"
endchoice
endmenu

@ -0,0 +1,162 @@
/* WiFi station Example
This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"
#include "esp_system.h"
#include "esp_wifi.h"
#include "esp_event.h"
#include "esp_log.h"
#include "nvs_flash.h"
#include "lwip/err.h"
#include "lwip/sys.h"
/* The examples use WiFi configuration that you can set via project configuration menu
If you'd rather not, just change the below entries to strings with
the config you want - ie #define EXAMPLE_WIFI_SSID "mywifissid"
*/
#define EXAMPLE_ESP_WIFI_SSID CONFIG_ESP_WIFI_SSID
#define EXAMPLE_ESP_WIFI_PASS CONFIG_ESP_WIFI_PASSWORD
#define EXAMPLE_ESP_MAXIMUM_RETRY CONFIG_ESP_MAXIMUM_RETRY
#if CONFIG_ESP_WIFI_AUTH_OPEN
#define ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_OPEN
#elif CONFIG_ESP_WIFI_AUTH_WEP
#define ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WEP
#elif CONFIG_ESP_WIFI_AUTH_WPA_PSK
#define ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA_PSK
#elif CONFIG_ESP_WIFI_AUTH_WPA2_PSK
#define ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA2_PSK
#elif CONFIG_ESP_WIFI_AUTH_WPA_WPA2_PSK
#define ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA_WPA2_PSK
#elif CONFIG_ESP_WIFI_AUTH_WPA3_PSK
#define ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA3_PSK
#elif CONFIG_ESP_WIFI_AUTH_WPA2_WPA3_PSK
#define ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA2_WPA3_PSK
#elif CONFIG_ESP_WIFI_AUTH_WAPI_PSK
#define ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WAPI_PSK
#endif
/* FreeRTOS event group to signal when we are connected*/
static EventGroupHandle_t s_wifi_event_group;
/* The event group allows multiple bits for each event, but we only care about two events:
* - we are connected to the AP with an IP
* - we failed to connect after the maximum amount of retries */
#define WIFI_CONNECTED_BIT BIT0
#define WIFI_FAIL_BIT BIT1
static const char *TAG = "wifi station";
static int s_retry_num = 0;
static void event_handler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data){
if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) {
esp_wifi_connect();
} else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) {
if (s_retry_num < EXAMPLE_ESP_MAXIMUM_RETRY) {
esp_wifi_connect();
s_retry_num++;
ESP_LOGI(TAG, "retry to connect to the AP");
} else {
xEventGroupSetBits(s_wifi_event_group, WIFI_FAIL_BIT);
}
ESP_LOGI(TAG,"connect to the AP fail");
} else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) {
ip_event_got_ip_t* event = (ip_event_got_ip_t*) event_data;
ESP_LOGI(TAG, "got ip:" IPSTR, IP2STR(&event->ip_info.ip));
s_retry_num = 0;
xEventGroupSetBits(s_wifi_event_group, WIFI_CONNECTED_BIT);
}
}
void wifi_init_sta(void){
s_wifi_event_group = xEventGroupCreate();
ESP_ERROR_CHECK(esp_netif_init());
ESP_ERROR_CHECK(esp_event_loop_create_default());
esp_netif_create_default_wifi_sta();
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
esp_event_handler_instance_t instance_any_id;
esp_event_handler_instance_t instance_got_ip;
ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT,
ESP_EVENT_ANY_ID,
&event_handler,
NULL,
&instance_any_id));
ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT,
IP_EVENT_STA_GOT_IP,
&event_handler,
NULL,
&instance_got_ip));
wifi_config_t wifi_config = {
.sta = {
.ssid = EXAMPLE_ESP_WIFI_SSID,
.password = EXAMPLE_ESP_WIFI_PASS,
/* Authmode threshold resets to WPA2 as default if password matches WPA2 standards (pasword len => 8).
* If you want to connect the device to deprecated WEP/WPA networks, Please set the threshold value
* to WIFI_AUTH_WEP/WIFI_AUTH_WPA_PSK and set the password with length and format matching to
* WIFI_AUTH_WEP/WIFI_AUTH_WPA_PSK standards.
*/
.threshold.authmode = ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD,
.sae_pwe_h2e = WPA3_SAE_PWE_BOTH,
},
};
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA) );
ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config) );
ESP_ERROR_CHECK(esp_wifi_start() );
ESP_LOGI(TAG, "wifi_init_sta finished.");
/* Waiting until either the connection is established (WIFI_CONNECTED_BIT) or connection failed for the maximum
* number of re-tries (WIFI_FAIL_BIT). The bits are set by event_handler() (see above) */
EventBits_t bits = xEventGroupWaitBits(s_wifi_event_group,
WIFI_CONNECTED_BIT | WIFI_FAIL_BIT,
pdFALSE,
pdFALSE,
portMAX_DELAY);
/* xEventGroupWaitBits() returns the bits before the call returned, hence we can test which event actually
* happened. */
if (bits & WIFI_CONNECTED_BIT) {
ESP_LOGI(TAG, "connected to ap SSID:%s password:%s",
EXAMPLE_ESP_WIFI_SSID, EXAMPLE_ESP_WIFI_PASS);
} else if (bits & WIFI_FAIL_BIT) {
ESP_LOGI(TAG, "Failed to connect to SSID:%s, password:%s",
EXAMPLE_ESP_WIFI_SSID, EXAMPLE_ESP_WIFI_PASS);
} else {
ESP_LOGE(TAG, "UNEXPECTED EVENT");
}
}
void app_main(void){
//Initialize NVS (Non Volitile Storage)
// https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/storage/nvs_flash.html
esp_err_t ret = nvs_flash_init();
// Some errors we can solve by erasing and re-initing.
if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
ESP_ERROR_CHECK(nvs_flash_erase()); // Abort if erase throws an error
ret = nvs_flash_init();
}
ESP_ERROR_CHECK(ret);
ESP_LOGI(TAG, "ESP_WIFI_MODE_STA");
wifi_init_sta();
}

@ -0,0 +1,2 @@
CONFIG_ESP_WIFI_SSID="ssid_${IDF_TARGET}_${CI_PIPELINE_ID}"
CONFIG_ESP_WIFI_PASSWORD="password_${IDF_TARGET}_${CI_PIPELINE_ID}"

@ -0,0 +1,2 @@
CONFIG_IDF_TARGET="esp32c2"
CONFIG_XTAL_FREQ_26=y
Loading…
Cancel
Save