【2022得捷电子创新设计大赛】ESP32S2 按键控制RGB灯
[复制链接]
esp32-s2-kaluga-1开发板板载了一个音频开发板【ESP-LyraT-8311A v1.3】今天下载了例程,继续学习idf的使用,同时学习一下程序:
1、进入example:C:\Users\Administrator\Documents\GitHub\esp-dev-kits\esp32-s2-kaluga-1\examples\adc_button目录下面:
2、设置开发板idf.py set-target esp32S2【注,如果不设置,会出现编译工程出错提示static const adc_bits_width_t width = ADC_WIDTH_BIT_13;
3、然后idf.py build【注意,如果不设置对esp32S2也如出现下载程序出错】
下载后按相应的按键就RGB灯就会亮不同的颜色。用监视器也会打印出相应的提示:
4、再看一下例程程序,这个例程是基于freertos创建的程序:头文件引入了必须的模块:
#include <stdio.h>
#include <stdint.h>
#include <stddef.h>
#include <string.h>
#include "esp_wifi.h"
#include "esp_system.h"
#include "esp_event.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_heap_caps.h"
#include "esp_log.h"
#include "driver/gpio.h"
#include "driver/adc.h"
#include "driver/rmt.h"
#include "led_strip.h"
2、然后初始化了一些常量与变量的声明:
#define DEFAULT_VREF 1100 /*!< Use adc2_vref_to_gpio() to obtain a better estimate */
#define NO_OF_SAMPLES 64
#define SAMPLE_TIME 200 /*!< Sampling time(ms) */
static const adc_channel_t channel = ADC_CHANNEL_5; /*!< PIO7 if ADC1, GPIO17 if ADC2 */
static const adc_bits_width_t width = ADC_WIDTH_BIT_13;
static const adc_atten_t atten = ADC_ATTEN_DB_11;
static const adc_unit_t unit = ADC_UNIT_1;
static xQueueHandle adc_queue = NULL;
led_strip_t *strip;
#define DEVIATION 0.1
const char *TAG = "main";
3、电压转函数,感觉ADC的是13位ADC,然后电压最大值也是2.6V
double adc_voltage_conversion(uint32_t adc_reading)
{
double voltage = 0;
voltage = (2.60 * adc_reading) / 8191;
return voltage;
}
4、按键检测电路,翻看原理图,是接在一个IO上,然后不同的按键接了不同的电阻,通过电压来检测是哪个按键按下了:
检测任务函数如下,检测到电压后,会把检测值更新到队列里面,以便RGB程序来获取:
void button_task(void *arg)
{
/*!<Continuously sample ADC1*/
while (1) {
uint32_t adc_reading = 0;
double voltage = 0;
/*!< Multisampling */
for (int i = 0; i < NO_OF_SAMPLES; i++) {
if (unit == ADC_UNIT_1) {
adc_reading += adc1_get_raw((adc1_channel_t)channel);
} else {
int raw;
adc2_get_raw((adc2_channel_t)channel, width, &raw);
adc_reading += raw;
}
}
adc_reading /= NO_OF_SAMPLES;
voltage = adc_voltage_conversion(adc_reading);
ESP_LOGD(TAG, "ADC%d CH%d Raw: %d ; Voltage: %0.2lfV", unit, channel, adc_reading, voltage);
xQueueSend(adc_queue, (double *)&voltage, 0);
vTaskDelay(pdMS_TO_TICKS(SAMPLE_TIME));
}
vTaskDelete(NULL);
}
5、RGB亮灯任务函数,主要是检测adc队列里的值,如果有新的值,就做出相应变化:
void led_task(void *arg)
{
double voltage = 0;
while (1) {
xQueueReceive(adc_queue, &voltage, portMAX_DELAY);
if (voltage > 2.6) {
continue;
} else if (voltage > 2.41 - DEVIATION && voltage <= 2.41 + DEVIATION) {
ESP_LOGI(TAG, "rec(K1) -> red");
ESP_ERROR_CHECK(strip->set_pixel(strip, 0, 255, 0, 0));
ESP_ERROR_CHECK(strip->refresh(strip, 0));
} else if (voltage > 1.98 - DEVIATION && voltage <= 1.98 + DEVIATION) {
ESP_LOGI(TAG, "mode(K2) -> green");
ESP_ERROR_CHECK(strip->set_pixel(strip, 0, 0, 255, 0));
ESP_ERROR_CHECK(strip->refresh(strip, 0));
} else if (voltage > 1.65 - DEVIATION && voltage <= 1.65 + DEVIATION) {
ESP_LOGI(TAG, "play(K3) -> blue");
ESP_ERROR_CHECK(strip->set_pixel(strip, 0, 0, 0, 255));
ESP_ERROR_CHECK(strip->refresh(strip, 0));
} else if (voltage > 1.11 - DEVIATION && voltage <= 1.11 + DEVIATION) {
ESP_LOGI(TAG, "set(K4) -> yellow");
ESP_ERROR_CHECK(strip->set_pixel(strip, 0, 255, 255, 0));
ESP_ERROR_CHECK(strip->refresh(strip, 0));
} else if (voltage > 0.82 - DEVIATION && voltage <= 0.82 + DEVIATION) {
ESP_LOGI(TAG, "vol(K5) -> purple");
ESP_ERROR_CHECK(strip->set_pixel(strip, 0, 255, 0, 255));
ESP_ERROR_CHECK(strip->refresh(strip, 0));
} else if (voltage > 0.38 - DEVIATION && voltage <= 0.38 + DEVIATION) {
ESP_LOGI(TAG, "vol+(K6) -> write");
ESP_ERROR_CHECK(strip->set_pixel(strip, 0, 255, 255, 255));
ESP_ERROR_CHECK(strip->refresh(strip, 0));
}
}
vTaskDelete(NULL);
}
6、按键ADC初始化:
void adc_init(void)
{
if (unit == ADC_UNIT_1) {
adc1_config_width(width);
adc1_config_channel_atten(channel, atten);
} else {
adc2_config_channel_atten((adc2_channel_t)channel, atten);
}
}
7、日志打印、RGB初始化:
esp_err_t example_rmt_init(uint8_t gpio_num, int led_number, uint8_t rmt_channel)
{
ESP_LOGI(TAG, "Initializing WS2812");
rmt_config_t config = RMT_DEFAULT_CONFIG_TX(gpio_num, rmt_channel);
/*!< set counter clock to 40MHz */
config.clk_div = 2;
ESP_ERROR_CHECK(rmt_config(&config));
ESP_ERROR_CHECK(rmt_driver_install(config.channel, 0, 0));
led_strip_config_t strip_config = LED_STRIP_DEFAULT_CONFIG(led_number, (led_strip_dev_t)config.channel);
strip = led_strip_new_rmt_ws2812(&strip_config);
if (!strip) {
ESP_LOGE(TAG, "install WS2812 driver failed");
return ESP_FAIL;
}
/*!< Clear LED strip (turn off all LEDs) */
ESP_ERROR_CHECK(strip->clear(strip, 100));
/*!< Show simple rainbow chasing pattern */
return ESP_OK;
}
8、主函数,主要是初始化外设,然后建立两个任务:
void app_main()
{
/*!< WS2812 init*/
ESP_ERROR_CHECK(example_rmt_init(CONFIG_EXAMPLE_RMT_TX_GPIO, CONFIG_EXAMPLE_STRIP_LED_NUMBER, RMT_CHANNEL_0));
adc_queue = xQueueCreate(1, sizeof(double));
adc_init();
xTaskCreatePinnedToCore(&button_task, "button_task", 3 * 1024, NULL, 5, NULL, 0);
xTaskCreatePinnedToCore(&led_task, "led_task", 3 * 1024, NULL, 5, NULL, 0);
}
【总结】以前对FreeRTOS也有过初步的接触,但是看这个主程序,还是花了不少时间,理解还不是很透。感觉用luatOS跟python还是适应些,不过这个效率高。
|