как создать примеры в среде ESPRESSIF себе = заготовки
Цель: Получить элементарную систему дискретного управления. В каких целях она будет использоваться и чем управлять - это другая история. Пусть это будет тележка или пневматика или гидравлика. Алгоритм управление естественно можно потом поменять по вашему усмотрению.
За основу берем , что указано в заголовке. схема предоставлена ниже.
Среда разработки Espressif и как ей пользоваться и интернет завались. Можете набрать Бесполезны ли потуги творчества в поисковике и там пошаговые темы и рассмотрение примеров и ссылки на материалы. как раз проблемы с в версиями были, Ну суть там несколько и повторяется и потому как бы не влом , то вникнуть можно.
плата esp32 s3 не из дешёвых.
В общем схема подключения кнопок хороша простотой.
в программе надо указать
pio_reset_pin( НОМЕР НОЖКИ); //сброс настроек
gpio_set_direction( НОМЕР НОЖКИ, GPIO_MODE_INPUT);// на вход
gpio_set_pull_mode( НОМЕР НОЖКИ, GPIO_PULLUP_ONLY);//подтяг
Недостаток в том , что использует подтягивающий РЕЗИСТОР внутри МК и потому МК больше потребляет и как бы греется. Он является источником тепла , а не внешний элемент типа резистора и стабилизатора, оптрона, что не оч и хорошо, но и не плохо . по причине , что в современных МК есть термометры и термостаты, которые выключают функционирования логики с целью предотвращения нестабильных срабатываний. Все 9 кнопок заведены по такому принципу и потому в настройках одинаковы
ниже заголовок с перечнем библиотек и обозначением переменных , которые состыкуют аппаратно входы и выходы с алгоритмами программы в main.c
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#include <unistd.h>
#include <driver/gpio.h>
#include "hal/gpio_types.h"
#include "freertos/FreeRTOS.h"
#include "freertos/queue.h"
#include "freertos/task.h"
#include "esp_chip_info.h"
#include "esp_system.h"
#include "soc/gpio_num.h"
//#include "esp_flash.h"
//#include <inttypes.h>
//#include "sdkconfig.h"
////////////список под WEB ////////////////
#include <stdlib.h>
#include "esp_system.h"
#include "esp_spi_flash.h"
#include <esp_http_server.h>
#include "esp_wifi.h"
#include "esp_event.h"
#include "freertos/event_groups.h"
#include "esp_log.h"
#include "nvs_flash.h"
#include "esp_netif.h"
#include <lwip/sockets.h>
#include <lwip/sys.h>
#include <lwip/api.h>
#include <lwip/netdb.h>
//////////////конец список библиотек
#define key_1 GPIO_NUM_12
#define key_2 GPIO_NUM_13
#define key_3 GPIO_NUM_14
#define key_4 GPIO_NUM_11
#define key_5 GPIO_NUM_10
#define key_6 GPIO_NUM_21
#define key_7 GPIO_NUM_4
#define key_8 GPIO_NUM_5
#define key_9 GPIO_NUM_6
//////////////////
#define led_1 GPIO_NUM_38
#define led_2 GPIO_NUM_48
#define led_3 GPIO_NUM_35
#define led_4 GPIO_NUM_36
#define led_5 GPIO_NUM_37
#define led_6 GPIO_NUM_39
#define led_7 GPIO_NUM_40
#define led_8 GPIO_NUM_41
#define led_9 GPIO_NUM_47
//////////// переменные глобальные
описали выше библиотеки для использования и аппаратные переменные.🚩
ниже функция cfg_inp стартовой настройки обработки сигналов по входу. В поисковике достаточно набрать gpio_reset_pin или gpio_set_pull_mode , или gpio_set_direction и информации будет предостаточно вам для понимания.
void cfg_inp(void)///////////////////////////////////////////
{ gpio_reset_pin( key_1); gpio_set_direction( key_1, GPIO_MODE_INPUT);
gpio_set_pull_mode( key_1, GPIO_PULLUP_ONLY);
gpio_reset_pin(key_2); gpio_set_direction( key_2, GPIO_MODE_INPUT );
gpio_set_pull_mode( key_2, GPIO_PULLUP_ONLY);
gpio_reset_pin(key_3); gpio_set_direction( key_3, GPIO_MODE_INPUT );
gpio_set_pull_mode( key_3, GPIO_PULLUP_ONLY);
gpio_reset_pin(key_4); gpio_set_direction( key_4, GPIO_MODE_INPUT );
gpio_set_pull_mode( key_4, GPIO_PULLUP_ONLY);
gpio_reset_pin(key_5); gpio_set_direction( key_5, GPIO_MODE_INPUT );
gpio_set_pull_mode( key_5, GPIO_PULLUP_ONLY);
gpio_reset_pin(key_6); gpio_set_direction( key_6, GPIO_MODE_INPUT );
gpio_set_pull_mode( key_6, GPIO_PULLUP_ONLY);
gpio_reset_pin(key_7); gpio_set_direction( key_7, GPIO_MODE_INPUT );
gpio_set_pull_mode( key_7, GPIO_PULLUP_ONLY);
gpio_reset_pin(key_8); gpio_set_direction( key_8, GPIO_MODE_INPUT );
gpio_set_pull_mode( key_8, GPIO_PULLUP_ONLY);
gpio_reset_pin(key_9); gpio_set_direction( key_9, GPIO_MODE_INPUT );
gpio_set_pull_mode( key_9, GPIO_PULLUP_ONLY);
}///////////////////////////////
ниже функция cfg_out стартовой настройки обработки сигналов по выходу. В поисковике достаточно набрать gpio_reset_pin или gpio_set_pull_mode , или gpio_set_direction и информации будет предостаточно вам для понимания.
void cfg_out(void)
{ gpio_reset_pin(led_1); gpio_set_direction( led_1, GPIO_MODE_OUTPUT );
gpio_set_pull_mode( led_1, GPIO_FLOATING);
gpio_reset_pin(led_2); gpio_set_direction( led_2, GPIO_MODE_OUTPUT );
gpio_set_pull_mode( led_2, GPIO_FLOATING);
gpio_reset_pin(led_3); gpio_set_direction( led_3, GPIO_MODE_OUTPUT );
gpio_set_pull_mode( led_3, GPIO_FLOATING);
gpio_reset_pin(led_4); gpio_set_direction( led_4, GPIO_MODE_OUTPUT );
gpio_set_pull_mode( led_4, GPIO_FLOATING);
gpio_reset_pin(led_5); gpio_set_direction( led_5, GPIO_MODE_OUTPUT );
gpio_set_pull_mode( led_5, GPIO_FLOATING);
gpio_reset_pin(led_6); gpio_set_direction( led_6, GPIO_MODE_OUTPUT );
gpio_set_pull_mode( led_6, GPIO_FLOATING);
gpio_reset_pin(led_7); gpio_set_direction( led_7, GPIO_MODE_OUTPUT );
gpio_set_pull_mode( led_7, GPIO_FLOATING);
gpio_reset_pin(led_8); gpio_set_direction( led_8, GPIO_MODE_OUTPUT );
gpio_set_pull_mode( led_8, GPIO_FLOATING);
gpio_reset_pin(led_9); gpio_set_direction( led_9, GPIO_MODE_OUTPUT );
gpio_set_pull_mode( led_9, GPIO_FLOATING);
}/////////////////////////////////------------------------------------------------
вставим строки ниже ////// переменные глобальные(смотрите выше код)
static const char *TAG = "espressif"; int led_state = 0; int len_on = 0; int state = 0;
static int k1_on_off=0, k2_on_off=0, k_on_off=0, k6_on_off=0, k8_on_off=0;
static int k3_on_off=0, k4_on_off=0, k5_on_off=0, k7_on_off=0, k9_on_off=0;
static EventGroupHandle_t s_wifi_event_group;
также ниже вставите функции , которые будут выполнятся при нажатии кнопок - так называемые программы прерываний реагирующие на аппаратные прерывания gpio_intr_disable - это понятно для чего же? в общем оклеить кнопку , чтобы не было срабатываний лишний = дребезга
////////////////////////////////////////
static void IRAM_ATTR int_key_1(void* arg)
{ gpio_intr_disable(key_1); k_on_off=1; k1_on_off=1; }//////// ////////// /////////
static void IRAM_ATTR int_key_2(void* arg)
{gpio_intr_disable(key_2); k_on_off=2; k2_on_off=2; }//////// ////////// /////////
static void IRAM_ATTR int_key_3(void* arg)
{ gpio_intr_disable(key_3); k_on_off=3; k3_on_off=3; }//////// ////////// /////////
static void IRAM_ATTR int_key_4(void* arg)
{ gpio_intr_disable(key_4); k_on_off=4; k4_on_off=4; }//////// ////////// /////////
static void IRAM_ATTR int_key_5(void* arg)
{ gpio_intr_disable(key_5); k_on_off=5; k5_on_off=5;}//////// ////////// /////////
static void IRAM_ATTR int_key_6(void* arg)
{ gpio_intr_disable(key_6); k_on_off=6; k6_on_off=6; }//////// ////////// /////////
static void IRAM_ATTR int_key_7(void* arg)
{ gpio_intr_disable(key_7); k_on_off=7; k7_on_off=7;}//////// ////////// /////////
static void IRAM_ATTR int_key_8(void* arg)
{ gpio_intr_disable(key_8); k_on_off=8; k8_on_off=8; }//////// ////////// /////////
static void IRAM_ATTR int_key_9(void* arg)
{ gpio_intr_disable(key_9); k_on_off=9; k9_on_off=9; }//////// ////////// /////////
ниже функция настройки характера реакции события на кнопки в поисковике поинтересуйтесь gpio_set_intr_type и gpio_isr_handler_add
void cfg_int_inp(void)
{ gpio_set_intr_type(key_1, GPIO_INTR_ANYEDGE );
gpio_set_intr_type(key_2, GPIO_INTR_ANYEDGE );
gpio_set_intr_type(key_3, GPIO_INTR_ANYEDGE );
gpio_set_intr_type(key_4, GPIO_INTR_ANYEDGE );
gpio_set_intr_type(key_5, GPIO_INTR_ANYEDGE );
gpio_set_intr_type(key_6, GPIO_INTR_ANYEDGE );
gpio_set_intr_type(key_7, GPIO_INTR_ANYEDGE );
gpio_set_intr_type(key_8, GPIO_INTR_ANYEDGE );
gpio_set_intr_type(key_9, GPIO_INTR_ANYEDGE );
// gpio_set_intr_type(key_2, GPIO_INTR_LOW_LEVEL );
// gpio_set_intr_type(key_3, GPIO_INTR_LOW_LEVEL );
// gpio_set_intr_type(key_4, GPIO_INTR_LOW_LEVEL );
// gpio_set_intr_type(key_5, GPIO_INTR_LOW_LEVEL );
esp_err_t err = gpio_install_isr_service(0);
if (err == ESP_ERR_INVALID_STATE) { printf( "GPIO isr service already installed"); };
gpio_isr_handler_add(key_1, int_key_1, (void *)key_1);
gpio_isr_handler_add(key_2, int_key_2, (void *)key_2);
gpio_isr_handler_add(key_3, int_key_3, (void *)key_3);
gpio_isr_handler_add(key_4, int_key_4, (void *)key_4);
gpio_isr_handler_add(key_5, int_key_5, (void *)key_5);
gpio_isr_handler_add(key_6, int_key_6, (void *)key_6);
gpio_isr_handler_add(key_7, int_key_7, (void *)key_7);
gpio_isr_handler_add(key_8, int_key_8, (void *)key_8);
gpio_isr_handler_add(key_9, int_key_9, (void *)key_9);
gpio_intr_enable(key_1); gpio_intr_enable(key_2); gpio_intr_enable(key_3); gpio_intr_enable(key_4);gpio_intr_enable(key_5); gpio_intr_enable(key_6); gpio_intr_enable(key_7);gpio_intr_enable(key_8); gpio_intr_enable(key_9);
}///////////////////////////////////////
с настройками входов и выходов окончено.😁
ниже функция next_board контроля реакции на кнопку вперёд next_old это предыдущее состояние движение вперед. gpio_set_level - почитайте в документации . gpio_intr_enable включают аппаратные прерывания после выполнения функции. next_ove - состояние которое должно быть. k5_on_off - переменная указывающая, что была реакция на клавишу вперед = Флаг . k_on_off - переменная указывающая, что была реакция на кнопки.
uint8_t next_board( uint8_t next_old , uint8_t next_ove)
{if (next_old==next_ove){ } else {gpio_set_level(led_6, 0);
gpio_set_level(led_7, 0); gpio_set_level(led_8, 0); gpio_set_level(led_9, 0);
return next_ove;}
if ( k2_on_off==2) gpio_intr_enable(key_2);
if ( k5_on_off==5) gpio_intr_enable(key_5);
if ( k2_on_off==2) k2_on_off=0; if ( k5_on_off==5) k5_on_off=0;
// k1_on_off=0; K6_on_off=0; k3_on_off=0; k4_on_off=0; k7_on_off=0;
if (next_ove==2 )
{gpio_set_level(led_6, 1);gpio_set_level(led_7, 0); gpio_set_level(led_8, 1);
gpio_set_level(led_9, 0); k_on_off=0; return next_ove; }
if (next_ove==1 )
{gpio_set_level(led_6, 0);gpio_set_level(led_7, 1);
gpio_set_level(led_8, 0); gpio_set_level(led_9, 1); k_on_off=0;
return next_ove;} return next_old;
}////////////////////////////////////////////////////////////////
ниже функция left_board контроля реакции на кнопку влево next_old это предыдущее состояние движение вперед. gpio_set_level - почитайте в документации . gpio_intr_enable включают аппаратные прерывания после выполнения функции. next_ove - состояние которое должно быть. k3_on_off - переменная указывающая, что была реакция на клавишу вперед. k_on_off - переменная указывающая, что была реакция на кнопки.
uint8_t left_righ( uint8_t right_left, uint8_t next_ove )
{ if (next_ove==1){ next_ove=0;
gpio_set_level(led_6, 0);gpio_set_level(led_7, 0);
gpio_set_level(led_8, 0);gpio_set_level(led_9, 0);
return 0;}
if ( k3_on_off==3) gpio_intr_enable(key_3);
if ( k4_on_off==4) gpio_intr_enable(key_4);
if ( k3_on_off==3) k3_on_off=0;
if ( k4_on_off==4) k4_on_off=0;
// k1_on_off=0; k2_on_off=0; k7_on_off=0; K6_on_off=0; k5_on_off=0;
if (right_left==2 )
{gpio_set_level(led_6, 1);gpio_set_level(led_7, 0);
gpio_set_level(led_8, 0);gpio_set_level(led_9, 0); k_on_off=0;
return 0;}
if (right_left==1 )
{gpio_set_level(led_6, 0);gpio_set_level(led_7, 0);
gpio_set_level(led_8, 1);gpio_set_level(led_9, 0); k_on_off=0;
return 0; }
return next_ove;
}//////////////////////////////////////
ниже функция invert_left_board контроля реакции на кнопку с влево назад next_old это предыдущее состояние движение вперед. gpio_set_level - почитайте в документации . gpio_intr_enable включают аппаратные прерывания после выполнения функции. next_ove - состояние которое должно быть. k6_on_off - переменная указывающая, что была реакция на клавишу вперед. k_on_off - переменная указывающая, что была реакция на кнопки.
uint8_t invert_left_righ( uint8_t invert_right_left, uint8_t next_ove )
{ if (next_ove==2){ next_ove=0;
gpio_set_level(led_6, 0);gpio_set_level(led_7, 0);
gpio_set_level(led_8, 0);gpio_set_level(led_9, 0);return 0; }
if ( k6_on_off==6) gpio_intr_enable(key_6);
if ( k7_on_off==7) gpio_intr_enable(key_7);
if ( k6_on_off==6) k6_on_off=0; if ( k7_on_off==7) k7_on_off=0;
// k1_on_off=0; k2_on_off=0; k3_on_off=0; k4_on_off=0; k5_on_off=0;
if (invert_right_left==2 )
{gpio_set_level(led_6, 0); gpio_set_level(led_7, 1);
gpio_set_level(led_8, 0); gpio_set_level(led_9, 0); k_on_off=0;
return 0; }
if (invert_right_left==1 )
{gpio_set_level(led_6, 0);gpio_set_level(led_7, 0);
gpio_set_level(led_8, 0); gpio_set_level(led_9, 1); k_on_off=0;
return 0; } return next_ove;
}//////////////////////////////////////
ниже функция circle_left_righ контроля реакции на кнопку с право влево крутиться next_old это предыдущее состояние движение вперед. gpio_set_level - почитайте в документации . gpio_intr_enable включают аппаратные прерывания после выполнения функции. next_ove - состояние которое должно быть. k8_on_off - переменная указывающая, что была реакция на клавишу вперед. k_on_off - переменная указывающая, что была реакция на кнопки.
uint8_t circle_left_righ( uint8_t circle_right_left, uint8_t next_ove )
{ if (next_ove==2){ next_ove=0;
gpio_set_level(led_6, 0); gpio_set_level(led_7, 0);
gpio_set_level(led_8, 0); gpio_set_level(led_9, 0); return 0; }
if ( k8_on_off==8) gpio_intr_enable(key_8);
if ( k9_on_off==9) gpio_intr_enable(key_9);
if ( k8_on_off==8) k8_on_off=0; if ( k9_on_off==9) k9_on_off=0;
// k1_on_off=0; k2_on_off=0; k3_on_off=0; k4_on_off=0; k5_on_off=0;
if (circle_right_left==2 )
{gpio_set_level(led_6, 1); gpio_set_level(led_7, 1);
gpio_set_level(led_8, 0); gpio_set_level(led_9, 0); k_on_off=0;
return 0; }
if (circle_right_left==1 )
{gpio_set_level(led_6, 0); gpio_set_level(led_7, 0);
gpio_set_level(led_8, 1); gpio_set_level(led_9, 1); k_on_off=0;
return 0; }
return next_ove;
}//////////////////////////////////////
функция обеспечения отслеживания состояния флагов и отображения , а также передачу управления на драйвер двигателя.
void task1(void *params)
{ uint8_t right_left=0,t=0, next_ove=0; uint8_t clk=0, next_old=0, K2=0, K3=0,K1=0,K4=0, K5=0, K6=0, K7=0;
uint8_t invert_right_left=0, circle_right_left=0;
while (1) { K1= gpio_get_level(key_1);
K2= gpio_get_level(key_2); K3= gpio_get_level(key_3);
K4= gpio_get_level(key_4); K5= gpio_get_level(key_5);
K6= gpio_get_level(key_6); K7= gpio_get_level(key_7);
printf("Hello from app_main! 0 %d L R %d \n %d , clk = %d k1= %d k2=%d k3=%d k6=%d k7=%d int=%d \n", t, right_left, next_ove, clk,
K1, K2, K3, K6, K7, k_on_off );
clk++; if (clk>10) clk=0; //--задаёт условие мигания двух светодиодов--
sleep(1); //задержка
//if (k_on_off==0) { //если была нажата кнопа
// continue;}
if (k1_on_off==1)
{if (t==0 ) {t=1; } else {t=0;} //старт _ стоп
if (t==0) {gpio_set_level(led_6, 0);
gpio_set_level(led_7, 0); gpio_set_level(led_8, 0);
gpio_set_level(led_9, 0); next_old=next_ove;} k1_on_off=0; k_on_off=0;
gpio_set_level(led_1,!t); right_left=0;
gpio_set_level(led_2,t); invert_right_left=0;
gpio_intr_enable(key_1); next_ove=0; next_old=0;
circle_right_left=0; continue;
} else
if (k2_on_off==2)
{ next_ove=1; if (right_left>0) next_old=2; right_left=0;
if (invert_right_left>0) {next_old=1;} invert_right_left=0;
next_old=next_board( next_old, next_ove);
gpio_set_level(led_3, 1); circle_right_left=0; continue;
} else
if (k3_on_off==3)
{ right_left=1;
if (invert_right_left>0) {next_ove=1;} //+
if (circle_right_left==1) {next_ove=2;} if (circle_right_left==2) {next_ove=1;}
next_old=left_righ( right_left,next_ove ); invert_right_left=0;
gpio_set_level(led_4, 1); next_ove=0; next_old=0;
circle_right_left=0; continue;
} else
if (k4_on_off==4)
{ right_left=2; if (invert_right_left>0) {next_ove=1;} //+
if (circle_right_left==1) {next_ove=1;}
if (circle_right_left==2) {next_ove=2;}
next_old=left_righ( right_left,next_ove ); invert_right_left=0;
gpio_set_level(led_4, 0); next_ove=0; next_old=0;
circle_right_left=0; continue;
} else
if (k5_on_off==5)
{ next_ove=2; if (right_left>0) next_old=2;
if (invert_right_left>0){next_old=1; }
next_old=next_board( next_old, next_ove);
gpio_set_level(led_3, 0);
right_left=0; invert_right_left=0; circle_right_left=0; continue;
} else
if (k6_on_off==6)
{ invert_right_left=1; if (right_left>0) next_ove=2;
if (circle_right_left==1) {next_ove=1;} //+
if (circle_right_left==2) {next_ove=2;} //+
next_old=invert_left_righ( invert_right_left,next_ove );
gpio_set_level(led_5, 1); next_ove=0; next_old=0;
right_left=0; circle_right_left=0; continue;
} else
if (k7_on_off==7)
{ invert_right_left=2; if (right_left>0) next_ove=2;
if (circle_right_left==1) {next_ove=2;} //+
if (circle_right_left==2) {next_ove=1;} //+
next_old=invert_left_righ( invert_right_left,next_ove ); right_left=0;
gpio_set_level(led_5, 0); next_ove=0; next_old=0;
circle_right_left=0; continue;
} else
if (k8_on_off==8)
{ if (circle_right_left==2) next_ove=2; circle_right_left=1;
if (right_left==2) next_ove=2; //+
if (next_ove>0) next_ove=2; //+
if (invert_right_left==2){next_ove=2; }
if (invert_right_left==1){next_ove=1; }
next_old=circle_left_righ( circle_right_left,next_ove ); right_left=0;
gpio_set_level(led_5, 1); invert_right_left=0;
gpio_set_level(led_1, 1); next_ove=0; next_old=0; continue;
} else
if (k9_on_off==9)
{ if (circle_right_left==1) next_ove=2; circle_right_left=2;
if (right_left==1) next_ove=2;
if (next_ove>0 ) next_ove=2;
if (invert_right_left==2){next_ove=1; }
if (invert_right_left==1){next_ove=2; }
next_old=circle_left_righ( circle_right_left,next_ove ); right_left=0;
gpio_set_level(led_4, 1); invert_right_left=0;
gpio_set_level(led_2, 1); next_ove=0; next_old=0; continue;
}
}
}/////////////////////////--------------
ниже функция , которая вызывает все функции
//------------------------------------------------
void app_main(void) /////////////////////////
cfg_inp(); cfg_out();
cfg_int_inp(); k1_on_off=1; led_state = 0;
xTaskCreate(task1, "task1", 2048, NULL, 10, NULL);
}
в общем весь. код и ничего сложного. Лучше взять готовый пример по ссылке
ссылки на код тут
как организовывать пример тут