This commit is contained in:
2023-01-11 00:39:00 +01:00
commit 73633af366
41 changed files with 5143 additions and 0 deletions
+6
View File
@@ -0,0 +1,6 @@
set(COMPONENT_SRCS "cmd_wifi.c"
"meteo_task.c"
"meteo_main.c")
set(COMPONENT_ADD_INCLUDEDIRS ".")
register_component()
+11
View File
@@ -0,0 +1,11 @@
menu "App Configuration"
config STORE_HISTORY
bool "Store command history in flash"
default y
help
Linenoise line editing library provides functions to save and load
command history. If this option is enabled, initalizes a FAT filesystem
and uses it to store command history.
endmenu
+20
View File
@@ -0,0 +1,20 @@
/* Console example — declarations of command registration functions.
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.
*/
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
#include "cmd_system.h"
#include "cmd_wifi.h"
#ifdef __cplusplus
}
#endif
+285
View File
@@ -0,0 +1,285 @@
/* Console example — WiFi commands
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 <stdio.h>
#include <string.h>
#include "esp_log.h"
#include "esp_console.h"
#include "argtable3/argtable3.h"
#include "freertos/FreeRTOS.h"
#include "freertos/event_groups.h"
#include "esp_wifi.h"
#include "tcpip_adapter.h"
#include "esp_event_loop.h"
#include "cmd_wifi.h"
#include "nvs.h"
static EventGroupHandle_t wifi_event_group;
const int CONNECTED_BIT = BIT0;
static esp_err_t event_handler(void *ctx, system_event_t *event)
{
/* For accessing reason codes in case of disconnection */
system_event_info_t *info = &event->event_info;
switch(event->event_id) {
case SYSTEM_EVENT_STA_GOT_IP:
xEventGroupSetBits(wifi_event_group, CONNECTED_BIT);
break;
case SYSTEM_EVENT_STA_DISCONNECTED:
ESP_LOGI(__func__, "Disconnect reason : %d", info->disconnected.reason);
if (info->disconnected.reason == WIFI_REASON_BASIC_RATE_NOT_SUPPORT) {
/*Switch to 802.11 bgn mode */
esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCOL_11B | WIFI_PROTOCOL_11G | WIFI_PROTOCOL_11N);
}
esp_wifi_connect();
xEventGroupClearBits(wifi_event_group, CONNECTED_BIT);
break;
default:
break;
}
return ESP_OK;
}
void initialise_wifi(void)
{
esp_err_t rv;
esp_log_level_set("wifi", ESP_LOG_WARN);
static bool initialized = false;
if (initialized) {
return;
}
tcpip_adapter_init();
wifi_event_group = xEventGroupCreate();
ESP_ERROR_CHECK( esp_event_loop_init(event_handler, NULL) );
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK( esp_wifi_init(&cfg) );
ESP_ERROR_CHECK( esp_wifi_set_storage(WIFI_STORAGE_FLASH) );
ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_STA) );
ESP_ERROR_CHECK( esp_wifi_start() );
nvs_handle_t hnvs;
ESP_ERROR_CHECK( nvs_open("wifi", NVS_READONLY, &hnvs) );
uint8_t use_dhcpc;
rv = nvs_get_u8(hnvs, "use_dhcpc", &use_dhcpc);
if (rv != ESP_OK) {
use_dhcpc = 1;
ESP_LOGW(__func__, "Fail to read 'use_dhcpc'");
}
if (!use_dhcpc) {
char ip[16], gw[16], mask[16];
size_t iplen = 16;
size_t gwlen = 16;
size_t masklen = 16;
rv = nvs_get_str(hnvs, "static_ip", ip, &iplen);
if (rv != ESP_OK) {
use_dhcpc = 1;
ESP_LOGW(__func__, "Fail to load 'static_ip'");
}
rv = nvs_get_str(hnvs, "static_gw", gw, &gwlen);
if (rv != ESP_OK) {
use_dhcpc = 1;
ESP_LOGW(__func__, "Fail to load 'static_gw'");
}
rv = nvs_get_str(hnvs, "static_mask", mask, &masklen);
if (rv != ESP_OK) {
use_dhcpc = 1;
ESP_LOGW(__func__, "Fail to load 'static_mask'");
}
printf("Static IP config: IP: %s, GW: %s, Mask: %s\n", ip, gw, mask);
tcpip_adapter_ip_info_t ip_info;
if (!use_dhcpc) {
ip_info.ip.addr = ipaddr_addr(ip);
ip_info.gw.addr = ipaddr_addr(gw);
ip_info.netmask.addr = ipaddr_addr(mask);
if (ip_info.ip.addr == IPADDR_NONE || ip_info.gw.addr == IPADDR_NONE || ip_info.netmask.addr == IPADDR_NONE) {
use_dhcpc = 1;
ESP_LOGW(__func__, "Fail to parse static IP config");
}
}
if (!use_dhcpc) {
tcpip_adapter_dhcpc_stop(TCPIP_ADAPTER_IF_STA);
tcpip_adapter_set_ip_info(TCPIP_ADAPTER_IF_STA, &ip_info);
}
}
nvs_commit(hnvs);
nvs_close(hnvs);
ESP_ERROR_CHECK( esp_wifi_connect() );
initialized = true;
}
static bool wifi_join(const char* ssid, const char* pass, int timeout_ms)
{
initialise_wifi();
wifi_config_t wifi_config = { 0 };
strncpy((char*) wifi_config.sta.ssid, ssid, sizeof(wifi_config.sta.ssid));
if (pass) {
strncpy((char*) wifi_config.sta.password, pass, sizeof(wifi_config.sta.password));
}
ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_STA) );
ESP_ERROR_CHECK( esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config) );
ESP_ERROR_CHECK( esp_wifi_connect() );
int bits = xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT,
1, 1, timeout_ms / portTICK_PERIOD_MS);
return (bits & CONNECTED_BIT) != 0;
}
/** Arguments used by 'join' function */
static struct {
struct arg_int *timeout;
struct arg_str *ssid;
struct arg_str *password;
struct arg_end *end;
} join_args;
static int connect(int argc, char** argv)
{
int nerrors = arg_parse(argc, argv, (void**) &join_args);
if (nerrors != 0) {
arg_print_errors(stderr, join_args.end, argv[0]);
return 1;
}
ESP_LOGI(__func__, "Connecting to '%s'",
join_args.ssid->sval[0]);
bool connected = wifi_join(join_args.ssid->sval[0],
join_args.password->sval[0],
join_args.timeout->ival[0]);
if (!connected) {
ESP_LOGW(__func__, "Connection timed out");
return 1;
}
ESP_LOGI(__func__, "Connected");
return 0;
}
void console_register_wifi()
{
join_args.timeout = arg_int0(NULL, "timeout", "<t>", "Connection timeout, ms");
join_args.timeout->ival[0] = 5000; // set default value
join_args.ssid = arg_str1(NULL, NULL, "<ssid>", "SSID of AP");
join_args.password = arg_str0(NULL, NULL, "<pass>", "PSK of AP");
join_args.end = arg_end(2);
const esp_console_cmd_t join_cmd = {
.command = "join",
.help = "Join WiFi AP as a station",
.hint = NULL,
.func = &connect,
.argtable = &join_args
};
ESP_ERROR_CHECK( esp_console_cmd_register(&join_cmd) );
}
/** Arguments used by 'join' function */
static struct {
struct arg_lit *dhcp_on;
struct arg_lit *dhcp_off;
struct arg_str *static_ip;
struct arg_str *static_gw;
struct arg_str *static_mask;
struct arg_end *end;
} ip_args;
static int ipcmd(int argc, char** argv)
{
esp_err_t rv;
int nerrors = arg_parse(argc, argv, (void**) &ip_args);
if (nerrors != 0) {
arg_print_errors(stderr, ip_args.end, argv[0]);
return 1;
}
nvs_handle_t hnvs;
ESP_ERROR_CHECK( nvs_open("wifi", NVS_READWRITE, &hnvs) );
if (ip_args.dhcp_on->count) {
nvs_set_u8(hnvs, "use_dhcpc", 1);
} else if (ip_args.dhcp_off->count) {
nvs_set_u8(hnvs, "use_dhcpc", 0);
}
if (ip_args.static_ip->count) {
nvs_set_str(hnvs, "static_ip", ip_args.static_ip->sval[0]);
}
if (ip_args.static_gw->count) {
nvs_set_str(hnvs, "static_gw", ip_args.static_gw->sval[0]);
}
if (ip_args.static_mask->count) {
nvs_set_str(hnvs, "static_mask", ip_args.static_mask->sval[0]);
}
// read current config
uint8_t use_dhcpc;
rv = nvs_get_u8(hnvs, "use_dhcpc", &use_dhcpc);
if (rv != ESP_OK) {
use_dhcpc = 1;
}
char ip[16], gw[16], mask[16];
size_t iplen = 16;
size_t gwlen = 16;
size_t masklen = 16;
ip[0] = gw[0] = mask[0] = 0;
nvs_get_str(hnvs, "static_ip", ip, &iplen);
nvs_get_str(hnvs, "static_gw", gw, &gwlen);
nvs_get_str(hnvs, "static_mask", mask, &masklen);
printf("DHCP = %s\n", use_dhcpc ? "Yes (dynamic IP)" : "No (static IP)");
printf("Saved static IP = %s\n", ip);
printf("Saved static GW = %s\n", gw);
printf("Saved static MASK = %s\n", mask);
nvs_close(hnvs);
printf("Any changes are applied after restart.\n");
return 0;
}
void console_register_ip()
{
ip_args.dhcp_on = arg_lit0("d", "dhcp", "Enable DHCP");
ip_args.dhcp_off = arg_lit0("s", "no-dhcp", "Disable DHCP (use static)");
ip_args.static_ip = arg_str0("a", NULL, "<IP>", "Set static IP");
ip_args.static_gw = arg_str0("g", NULL, "<IP>", "Set static GW");
ip_args.static_mask = arg_str0("m", NULL, "<IP>", "Set static MASK (e.g. 255.255.255.0)");
ip_args.end = arg_end(5);
const esp_console_cmd_t ip_cmd = {
.command = "ip",
.help = "Configure TCP/IP",
.hint = NULL,
.func = &ipcmd,
.argtable = &ip_args
};
ESP_ERROR_CHECK( esp_console_cmd_register(&ip_cmd) );
}
+25
View File
@@ -0,0 +1,25 @@
/* Console example — declarations of command registration functions.
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.
*/
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
// Register WiFi functions
void console_register_wifi();
void initialise_wifi(void);
void console_register_ip();
#ifdef __cplusplus
}
#endif
+5
View File
@@ -0,0 +1,5 @@
#
# "main" pseudo-component makefile.
#
# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.)
+168
View File
@@ -0,0 +1,168 @@
#include <stdio.h>
#include <string.h>
#include "esp_system.h"
#include "esp_log.h"
#include "esp_console.h"
#include "esp_vfs_dev.h"
#include "FreeRTOS.h"
#include "task.h"
#include "driver/uart.h"
#include "linenoise/linenoise.h"
#include "argtable3/argtable3.h"
#include "cmd_decl.h"
#include "nvs.h"
#include "nvs_flash.h"
#include "meteo_task.h"
#define TAG "example"
static void initialize_nvs()
{
esp_err_t err = nvs_flash_init();
if (err == ESP_ERR_NVS_NO_FREE_PAGES) {
ESP_ERROR_CHECK( nvs_flash_erase() );
err = nvs_flash_init();
}
ESP_ERROR_CHECK(err);
// ensure the namespaces we need exist
nvs_handle_t hnvs;
ESP_ERROR_CHECK( nvs_open("wifi", NVS_READWRITE, &hnvs) );
nvs_close(hnvs);
}
static void initialize_console()
{
/* Disable buffering on stdin */
setvbuf(stdin, NULL, _IONBF, 0);
/* Minicom, screen, idf_monitor send CR when ENTER key is pressed */
esp_vfs_dev_uart_set_rx_line_endings(ESP_LINE_ENDINGS_CR);
/* Move the caret to the beginning of the next line on '\n' */
esp_vfs_dev_uart_set_tx_line_endings(ESP_LINE_ENDINGS_CRLF);
/* Configure UART. Note that REF_TICK is used so that the baud rate remains
* correct while APB frequency is changing in light sleep mode.
*/
uart_config_t uart_config = {
.baud_rate = CONFIG_ESP_CONSOLE_UART_BAUDRATE,
.data_bits = UART_DATA_8_BITS,
.parity = UART_PARITY_DISABLE,
.stop_bits = UART_STOP_BITS_1,
};
ESP_ERROR_CHECK( uart_param_config(CONFIG_ESP_CONSOLE_UART_NUM, &uart_config) );
/* Install UART driver for interrupt-driven reads and writes */
ESP_ERROR_CHECK( uart_driver_install(CONFIG_ESP_CONSOLE_UART_NUM,
256, 0, 0, NULL, 0) );
/* Tell VFS to use UART driver */
esp_vfs_dev_uart_use_driver(CONFIG_ESP_CONSOLE_UART_NUM);
/* Initialize the console */
esp_console_config_t console_config = {
.max_cmdline_args = 8,
.max_cmdline_length = 256,
#if CONFIG_LOG_COLORS
.hint_color = atoi(LOG_COLOR_CYAN)
#endif
};
ESP_ERROR_CHECK( esp_console_init(&console_config) );
/* Configure linenoise line completion library */
/* Enable multiline editing. If not set, long commands will scroll within
* single line.
*/
linenoiseSetMultiLine(1);
/* Tell linenoise where to get command completions and hints */
linenoiseSetCompletionCallback(&esp_console_get_completion);
linenoiseSetHintsCallback((linenoiseHintsCallback*) &esp_console_get_hint);
/* Set command history size */
linenoiseHistorySetMaxLen(100);
}
void app_main()
{
initialize_nvs();
initialize_console();
initialise_wifi();
console_register_ip();
xTaskCreate(meteo_task, "meteo_task", 2048, NULL, 10, NULL);
/* Print chip information */
esp_chip_info_t chip_info;
esp_chip_info(&chip_info);
printf("This is ESP8266 chip with %d CPU cores, WiFi, ",
chip_info.cores);
printf("silicon revision %d, ", chip_info.revision);
printf("%dMB %s flash\n", spi_flash_get_chip_size() / (1024 * 1024),
(chip_info.features & CHIP_FEATURE_EMB_FLASH) ? "embedded" : "external");
/* Register commands */
esp_console_register_help_command();
console_register_system();
console_register_wifi();
/* Prompt to be printed before each line.
* This can be customized, made dynamic, etc.
*/
const char* prompt = LOG_COLOR_I "esp8266> " LOG_RESET_COLOR;
printf("\n"
"Welcome to ESP-IDF console.\n"
"Type 'help' to get the list of commands.\n"
"Use UP/DOWN arrows to navigate through command history.\n"
"Press TAB when typing command name to auto-complete.\n");
/* Figure out if the terminal supports escape sequences */
int probe_status = linenoiseProbe();
if (probe_status) { /* zero indicates success */
printf("\n"
"Your terminal application does not support escape sequences.\n"
"Line editing and history features are disabled.\n"
"On Windows, try using Putty instead.\n");
linenoiseSetDumbMode(1);
#if CONFIG_LOG_COLORS
/* Since the terminal doesn't support escape sequences,
* don't use color codes in the prompt.
*/
prompt = "esp8266> ";
#endif //CONFIG_LOG_COLORS
}
/* Main loop */
while(true) {
/* Get a line using linenoise.
* The line is returned when ENTER is pressed.
*/
char* line = linenoise(prompt);
if (line == NULL) { /* Ignore empty lines */
continue;
}
/* Add the command to the history */
linenoiseHistoryAdd(line);
/* Try to run the command */
int ret;
esp_err_t err = esp_console_run(line, &ret);
if (err == ESP_ERR_NOT_FOUND) {
printf("Unrecognized command\n");
} else if (err == ESP_ERR_INVALID_ARG) {
// command was empty
} else if (err == ESP_OK && ret != ESP_OK) {
printf("Command returned non-zero error code: 0x%x (%s)\n", ret, esp_err_to_name(err));
} else if (err != ESP_OK) {
printf("Internal error: %s\n", esp_err_to_name(err));
}
/* linenoise allocates line buffer on the heap, so need to free it */
linenoiseFree(line);
}
}
+39
View File
@@ -0,0 +1,39 @@
/**
* TODO file description
*/
#include <stdio.h>
#include <FreeRTOS.h>
#include <task.h>
#include "meteo_task.h"
#include "ds18b20.h"
#include "dht.h"
#include "driver/gpio.h"
void meteo_task(void* pvParameters)
{
// Try to unfuck GPIOs
PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDI_U, FUNC_GPIO12);
PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTCK_U, FUNC_GPIO13);
PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTMS_U, FUNC_GPIO14);
PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDO_U, FUNC_GPIO15);
float dht_hum, dht_temp, ds_temp;
while (1) {
// this works ...
ds_temp = ds18b20_measure_and_read(0, DS18B20_ANY);
if (ds_temp != ds_temp) { // NAN
printf("Fail to read temp\n");
} else {
printf("Dallas: %f °C\n", ds_temp);
}
if (dht_read_float_data(DHT_TYPE_DHT11, 12, &dht_hum, &dht_temp)) {
printf("DHT: %f °C, %f %%r.H\n", dht_temp, dht_hum);
}
vTaskDelay(pdMS_TO_TICKS(1000));
}
vTaskDelete(NULL);
}
+10
View File
@@ -0,0 +1,10 @@
/**
* TODO file description
*/
#ifndef METEO_TASK_H
#define METEO_TASK_H
void meteo_task(void* pvParameters);
#endif //METEO_TASK_H