【ESP32-S2-Kaluga-1测评】5. 图片显示,按键以及RGB LED操作
<p>这一周弄了弄板载的按键以及RGB LED。</p><p>下面说一下具体实现的功能,使用官方提供的例程进行修改,显示了自己的一个logo图片</p>
<p></p>
<p> </p>
<p>接着是操作RGB LED,在官方例程中进行修改,代码如下,</p>
<p>改代码的含义是,红蓝绿交替显示:</p>
<p> </p>
<p>显示效果如下:</p>
<p><iframe allowfullscreen="true" frameborder="0" height="510" src="https://training.eeworld.com.cn/shareOpenCourseAPI?isauto=true&lessonid=27035" style="background:#eee;margin-bottom:10px;" width="750"></iframe><br />
</p>
<p>接下来是按钮的控制,ESP32S2的按键是连接在ADC上面的,所以需要配合ADC读取相应的电压值,不同的按键或者组合按键按下去有不同的电压值,需要ADC进行采集</p>
<p>电路原理图如下:</p>
<p></p>
<p> </p>
<p><span style="color:#e74c3c;"><strong>注意,这个原理图上对按钮1的电压值标注不对,我最开始的时候使用按钮K1,用2.41V怎么都不对,检测不出来,其他按键都是可以的,然后我用串口debug了一下,K1采集出来是2.3V</strong></span></p>
<p>如下图:</p>
<p></p>
<p>然后使用2.3V可以正常识别。</p>
<p> </p>
<p>我写的程序是RGB LED和按键分别用了两个不同的任务,按下按键K1就暂停RGB LED任务,松开按键K1就继续RGB LED任务。</p>
<p> </p>
<p>效果如下:</p>
<p><iframe allowfullscreen="true" frameborder="0" height="510" src="https://training.eeworld.com.cn/shareOpenCourseAPI?isauto=true&lessonid=27036" style="background:#eee;margin-bottom:10px;" width="750"></iframe><br />
</p>
<div aria-label="代码段 小部件" contenteditable="false" role="region" tabindex="-1">
<pre data-widget="codesnippet">
<code class="hljs">f((1 == key_pressed_status) && (0 == Last_key_pressed_status)){ // pressed
vTaskSuspend(RGBLEDTask_Handler);
ESP_LOGI(TAG, "K1 activated");
}else if((0 == key_pressed_status) && (1 == Last_key_pressed_status)){ // released
vTaskResume(RGBLEDTask_Handler);
ESP_LOGI(TAG, "K1 inactivated");
}else{
}</code></pre>
<img src="data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==" /><span style="background: url("https://bbs.eeworld.com.cn/static/editor/plugins/widget/images/handle.png") rgba(220, 220, 220, 0.5); top: -15px; left: 0px; display: block;"><img height="15" role="presentation" src="data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==" title="点击并拖拽以移动" width="15" /></span></div>
<p> </p>
<p>下面我贴上源代码。</p>
<p>但是需要注意的是,除了修改main.c中的代码之外,还需要修改<span style="color:#e74c3c;"><strong>Kconfig.probuild以及CMakeLists.txt</strong></span>文件</p>
<p></p>
<p>源代码(main.c):</p>
<div aria-label="代码段 小部件" contenteditable="false" role="region" tabindex="-1">
<pre data-widget="codesnippet">
<code class="hljs language-cpp"><span class="hljs-comment">/*
Autor: hehung
*/</span>
<span class="hljs-preprocessor">#include <stdio.h></span>
<span class="hljs-preprocessor">#include <stdint.h></span>
<span class="hljs-preprocessor">#include <stddef.h></span>
<span class="hljs-preprocessor">#include <string.h></span>
<span class="hljs-preprocessor">#include "esp_wifi.h"</span>
<span class="hljs-preprocessor">#include "esp_system.h"</span>
<span class="hljs-preprocessor">#include "nvs_flash.h"</span>
<span class="hljs-preprocessor">#include "esp_event.h"</span>
<span class="hljs-preprocessor">#include "freertos/FreeRTOS.h"</span>
<span class="hljs-preprocessor">#include "freertos/task.h"</span>
<span class="hljs-preprocessor">#include "esp_heap_caps.h"</span>
<span class="hljs-preprocessor">#include "esp_log.h"</span>
<span class="hljs-preprocessor">#include "esp_spiffs.h"</span>
<span class="hljs-preprocessor">#include "lcd.h"</span>
<span class="hljs-preprocessor">#include "jpeg.h"</span>
<span class="hljs-preprocessor">#include "board.h"</span>
<span class="hljs-preprocessor">#include "sccb.h"</span>
<span class="hljs-preprocessor">#include "cam.h"</span>
<span class="hljs-preprocessor">#include "ov2640.h"</span>
<span class="hljs-preprocessor">#include "ov3660.h"</span>
<span class="hljs-preprocessor">#include "sensor.h"</span>
<span class="hljs-preprocessor">#include "driver/gpio.h"</span>
<span class="hljs-preprocessor">#include "driver/adc.h"</span>
<span class="hljs-preprocessor">#include "driver/rmt.h"</span>
<span class="hljs-preprocessor">#include "led_strip.h"</span>
<span class="hljs-keyword">static</span> <span class="hljs-keyword">const</span> <span class="hljs-keyword">char</span> *TAG = <span class="hljs-string">"main"</span>;
<span class="hljs-comment">/******** Start Macro Definition ********/</span>
<span class="hljs-comment">/* Picture - Start up picture */</span>
<span class="hljs-comment">/* LCD */</span>
<span class="hljs-preprocessor">#define IMAGE_MAX_SIZE (100 * 1024)/**< The maximum size of a single picture in the boot animation */</span>
<span class="hljs-preprocessor">#define IMAGE_WIDTH (320) /*!< width of jpeg file */</span>
<span class="hljs-preprocessor">#define IMAGE_HIGHT (240) /*!< height of jpeg file */</span>
<span class="hljs-comment">/* Camera */</span>
<span class="hljs-preprocessor">#define CAM_WIDTH (320) /* camera width */</span>
<span class="hljs-preprocessor">#define CAM_HIGH (240) /* camera height */</span>
<span class="hljs-comment">/* ADC Button */</span>
<span class="hljs-preprocessor">#define DEFAULT_VREF 1100 /*!< Use adc2_vref_to_gpio() to obtain a better estimate */</span>
<span class="hljs-preprocessor">#define NO_OF_SAMPLES 64</span>
<span class="hljs-preprocessor">#define SAMPLE_TIME 200 /*!< Sampling time(ms) */</span>
<span class="hljs-preprocessor">#define DEVIATION 0.1</span>
<span class="hljs-comment">/******** End Macro Definition ********/</span>
<span class="hljs-comment">/******** Start Variables Declaration********/</span>
<span class="hljs-comment">/* LED */</span>
<span class="hljs-keyword">static</span> led_strip_t *strip;
<span class="hljs-comment">/* ADC Button */</span>
<span class="hljs-keyword">static</span> <span class="hljs-keyword">const</span> adc_channel_t channel = ADC_CHANNEL_5; <span class="hljs-comment">/*!< PIO7 if ADC1, GPIO17 if ADC2 */</span>
<span class="hljs-keyword">static</span> <span class="hljs-keyword">const</span> adc_bits_width_t width = ADC_WIDTH_BIT_13;
<span class="hljs-keyword">static</span> <span class="hljs-keyword">const</span> adc_atten_t atten = ADC_ATTEN_DB_11;
<span class="hljs-keyword">static</span> <span class="hljs-keyword">const</span> adc_unit_t unit = ADC_UNIT_1;
<span class="hljs-keyword">static</span> xQueueHandle adc_queue = NULL;
<span class="hljs-comment">/* freertos tasks handler */</span>
TaskHandle_t RGBLEDTask_Handler; <span class="hljs-comment">//RGB LED任务句柄</span>
TaskHandle_t ButtonTask_Handler; <span class="hljs-comment">//RGB LED任务句柄</span>
TaskHandle_t CameraTask_Handler; <span class="hljs-comment">//RGB LED任务句柄</span>
<span class="hljs-comment">/******** End Variables Declaration********/</span>
<span class="hljs-comment">/******** Start Function Declaration********/</span>
<span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> start_display(<span class="hljs-keyword">void</span>);
<span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> cam_task(<span class="hljs-keyword">void</span> *arg);
<span class="hljs-keyword">void</span> button_task(<span class="hljs-keyword">void</span> *arg);
<span class="hljs-keyword">void</span> led_task(<span class="hljs-keyword">void</span> *arg);
esp_err_t Rmt_init(uint8_t gpio_num, <span class="hljs-keyword">int</span> led_number, uint8_t rmt_channel);
<span class="hljs-keyword">void</span> adc_init(<span class="hljs-keyword">void</span>);
<span class="hljs-keyword">void</span> button_task(<span class="hljs-keyword">void</span> *arg);
<span class="hljs-keyword">double</span> adc_voltage_conversion(uint32_t adc_reading);
<span class="hljs-keyword">void</span> Button_Selection(<span class="hljs-keyword">double</span> voltage);
<span class="hljs-comment">/******** End Function Declaration********/</span>
<span class="hljs-comment">/******** Start Function Definition********/</span>
<span class="hljs-comment">/* main */</span>
<span class="hljs-keyword">void</span> app_main()
{
<span class="hljs-comment">/* Show a picture */</span>
start_display();
adc_queue = xQueueCreate(<span class="hljs-number">1</span>, <span class="hljs-keyword">sizeof</span>(<span class="hljs-keyword">double</span>));
adc_init();
<span class="hljs-comment">/* Show the Camera */</span>
<span class="hljs-comment">// xTaskCreate(cam_task, "cam_task", 2048, NULL, 3, &CameraTask_Handler);</span>
<span class="hljs-comment">/**/</span>
xTaskCreate(&button_task, <span class="hljs-string">"button_task"</span>, <span class="hljs-number">3</span>*<span class="hljs-number">1024</span>, NULL, <span class="hljs-number">4</span>, &ButtonTask_Handler);
xTaskCreate(&led_task, <span class="hljs-string">"led_task"</span>, <span class="hljs-number">3</span>*<span class="hljs-number">1024</span>, NULL, <span class="hljs-number">5</span>, &RGBLEDTask_Handler);
<span class="hljs-comment">// vTaskStartScheduler(); //this is write in cpu_start.c</span>
}
<span class="hljs-comment">/*initialization the ADC */</span>
<span class="hljs-keyword">void</span> adc_init(<span class="hljs-keyword">void</span>)
{
<span class="hljs-keyword">if</span> (unit == ADC_UNIT_1) {
adc1_config_width(width);
adc1_config_channel_atten(channel, atten);
} <span class="hljs-keyword">else</span> {
adc2_config_channel_atten((adc2_channel_t)channel, atten);
}
}
<span class="hljs-comment">/* ADC conversion */</span>
<span class="hljs-keyword">double</span> adc_voltage_conversion(uint32_t adc_reading)
{
<span class="hljs-keyword">double</span> voltage = <span class="hljs-number">0</span>;
voltage = (<span class="hljs-number">2.60</span> * adc_reading) / <span class="hljs-number">8191</span>;
<span class="hljs-keyword">return</span> voltage;
}
<span class="hljs-comment">/* button task */</span>
<span class="hljs-keyword">void</span> button_task(<span class="hljs-keyword">void</span> *arg)
{
<span class="hljs-comment">/*!<Continuously sample ADC1*/</span>
<span class="hljs-keyword">while</span> (<span class="hljs-number">1</span>) {
uint32_t adc_reading = <span class="hljs-number">0</span>;
<span class="hljs-keyword">double</span> voltage = <span class="hljs-number">0</span>;
<span class="hljs-comment">/*!< Multisampling */</span>
<span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> i = <span class="hljs-number">0</span>; i < NO_OF_SAMPLES; i++) {
<span class="hljs-keyword">if</span> (unit == ADC_UNIT_1) {
adc_reading += adc1_get_raw((adc1_channel_t)channel);
} <span class="hljs-keyword">else</span> {
<span class="hljs-keyword">int</span> 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, <span class="hljs-string">"ADC%d CH%d Raw: %d ; Voltage: %0.2lfV"</span>, unit, channel, adc_reading, voltage);
ESP_LOGI(TAG, <span class="hljs-string">"Voltage: %0.2lfV"</span>, voltage);
xQueueSend(adc_queue, (<span class="hljs-keyword">double</span> *)&voltage, <span class="hljs-number">0</span>);
<span class="hljs-comment">// xQueueReceive(adc_queue, &voltage, portMAX_DELAY);</span>
Button_Selection(voltage);
vTaskDelay(pdMS_TO_TICKS(SAMPLE_TIME));
}
vTaskDelete(NULL);
}
<span class="hljs-comment">/* Button Selection */</span>
<span class="hljs-keyword">void</span> Button_Selection(<span class="hljs-keyword">double</span> voltage)
{
<span class="hljs-comment">// double voltage = 0;</span>
<span class="hljs-comment">// xQueueReceive(adc_queue, &voltage, portMAX_DELAY);</span>
<span class="hljs-keyword">static</span> <span class="hljs-keyword">bool</span> key_pressed_status[<span class="hljs-number">6</span>] = {<span class="hljs-number">0</span>};
<span class="hljs-keyword">static</span> <span class="hljs-keyword">bool</span> Last_key_pressed_status[<span class="hljs-number">6</span>] = {<span class="hljs-number">0</span>};
<span class="hljs-keyword">if</span> (voltage > <span class="hljs-number">2.30</span> - DEVIATION&& voltage <= <span class="hljs-number">2.30</span> + DEVIATION) {
key_pressed_status[<span class="hljs-number">0</span>] = <span class="hljs-number">1</span>;
ESP_LOGI(TAG, <span class="hljs-string">"K1 Pressed"</span>);
} <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (voltage > <span class="hljs-number">1.98</span> - DEVIATION && voltage <= <span class="hljs-number">1.98</span> + DEVIATION) {
key_pressed_status[<span class="hljs-number">1</span>] = <span class="hljs-number">1</span>;
ESP_LOGI(TAG, <span class="hljs-string">"K2 Pressed"</span>);
} <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (voltage > <span class="hljs-number">1.65</span> - DEVIATION && voltage <= <span class="hljs-number">1.65</span> + DEVIATION) {
key_pressed_status[<span class="hljs-number">2</span>] = <span class="hljs-number">1</span>;
ESP_LOGI(TAG, <span class="hljs-string">"K3 Pressed"</span>);
} <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (voltage > <span class="hljs-number">1.11</span> - DEVIATION && voltage <= <span class="hljs-number">1.11</span> + DEVIATION) {
key_pressed_status[<span class="hljs-number">3</span>] = <span class="hljs-number">1</span>;
ESP_LOGI(TAG, <span class="hljs-string">"K4 Pressed"</span>);
} <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (voltage > <span class="hljs-number">0.82</span> - DEVIATION && voltage <= <span class="hljs-number">0.82</span> + DEVIATION) {
key_pressed_status[<span class="hljs-number">4</span>] = <span class="hljs-number">1</span>;
ESP_LOGI(TAG, <span class="hljs-string">"K5 Pressed"</span>);
} <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (voltage > <span class="hljs-number">0.38</span> - DEVIATION && voltage <= <span class="hljs-number">0.38</span> + DEVIATION) {
key_pressed_status[<span class="hljs-number">5</span>] = <span class="hljs-number">1</span>;
ESP_LOGI(TAG, <span class="hljs-string">"K6 Pressed"</span>);
}<span class="hljs-keyword">else</span>{
key_pressed_status[<span class="hljs-number">0</span>] = <span class="hljs-number">0</span>;
key_pressed_status[<span class="hljs-number">1</span>] = <span class="hljs-number">0</span>;
key_pressed_status[<span class="hljs-number">2</span>] = <span class="hljs-number">0</span>;
key_pressed_status[<span class="hljs-number">3</span>] = <span class="hljs-number">0</span>;
key_pressed_status[<span class="hljs-number">4</span>] = <span class="hljs-number">0</span>;
key_pressed_status[<span class="hljs-number">5</span>] = <span class="hljs-number">0</span>;
}
<span class="hljs-keyword">if</span>((<span class="hljs-number">1</span> == key_pressed_status[<span class="hljs-number">0</span>]) && (<span class="hljs-number">0</span> == Last_key_pressed_status[<span class="hljs-number">0</span>])){ <span class="hljs-comment">// pressed</span>
vTaskSuspend(RGBLEDTask_Handler);
ESP_LOGI(TAG, <span class="hljs-string">"K1 activated"</span>);
}<span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span>((<span class="hljs-number">0</span> == key_pressed_status[<span class="hljs-number">0</span>]) && (<span class="hljs-number">1</span> == Last_key_pressed_status[<span class="hljs-number">0</span>])){ <span class="hljs-comment">// released</span>
vTaskResume(RGBLEDTask_Handler);
ESP_LOGI(TAG, <span class="hljs-string">"K1 inactivated"</span>);
}<span class="hljs-keyword">else</span>{
}
Last_key_pressed_status[<span class="hljs-number">0</span>] = key_pressed_status[<span class="hljs-number">0</span>];
Last_key_pressed_status[<span class="hljs-number">1</span>] = key_pressed_status[<span class="hljs-number">1</span>];
Last_key_pressed_status[<span class="hljs-number">2</span>] = key_pressed_status[<span class="hljs-number">2</span>];
Last_key_pressed_status[<span class="hljs-number">3</span>] = key_pressed_status[<span class="hljs-number">3</span>];
Last_key_pressed_status[<span class="hljs-number">4</span>] = key_pressed_status[<span class="hljs-number">4</span>];
Last_key_pressed_status[<span class="hljs-number">5</span>] = key_pressed_status[<span class="hljs-number">5</span>];
}
<span class="hljs-comment">/* RGB LED Initialization */</span>
esp_err_t Rmt_init(uint8_t gpio_num, <span class="hljs-keyword">int</span> led_number, uint8_t rmt_channel)
{
ESP_LOGI(TAG, <span class="hljs-string">"Initializing WS2812"</span>);
rmt_config_t config = RMT_DEFAULT_CONFIG_TX(gpio_num, rmt_channel);
<span class="hljs-comment">/*!< set counter clock to 40MHz */</span>
config.clk_div = <span class="hljs-number">2</span>;
ESP_ERROR_CHECK(rmt_config(&config));
ESP_ERROR_CHECK(rmt_driver_install(config.channel, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>));
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);
<span class="hljs-keyword">if</span> (!strip) {
ESP_LOGE(TAG, <span class="hljs-string">"install WS2812 driver failed"</span>);
<span class="hljs-keyword">return</span> ESP_FAIL;
}
<span class="hljs-comment">/*!< Clear LED strip (turn off all LEDs) */</span>
ESP_ERROR_CHECK(strip->clear(strip, <span class="hljs-number">100</span>));
<span class="hljs-comment">/*!< Show simple rainbow chasing pattern */</span>
<span class="hljs-keyword">return</span> ESP_OK;
}
<span class="hljs-comment">/* led task */</span>
<span class="hljs-keyword">void</span> led_task(<span class="hljs-keyword">void</span> *arg)
{
<span class="hljs-keyword">static</span> <span class="hljs-keyword">unsigned</span> <span class="hljs-keyword">char</span> LED_change_count1 = <span class="hljs-number">0u</span>;
<span class="hljs-keyword">static</span> <span class="hljs-keyword">unsigned</span> <span class="hljs-keyword">char</span> LED_change_count2 = <span class="hljs-number">0u</span>;
<span class="hljs-keyword">static</span> <span class="hljs-keyword">unsigned</span> <span class="hljs-keyword">char</span> LED_change_count3 = <span class="hljs-number">0u</span>;
<span class="hljs-comment">/*!< WS2812 init*/</span>
ESP_ERROR_CHECK(Rmt_init(<span class="hljs-number">45</span>, <span class="hljs-number">4</span>, RMT_CHANNEL_0));
ESP_ERROR_CHECK(strip->set_pixel(strip, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>));
<span class="hljs-keyword">while</span> (<span class="hljs-number">1</span>) {
<span class="hljs-keyword">if</span>((LED_change_count1 != <span class="hljs-number">255</span>)
&& (LED_change_count2 == <span class="hljs-number">0</span>)
&& (LED_change_count3 == <span class="hljs-number">0</span>))
{
LED_change_count1 ++;
}<span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span>((LED_change_count1 == <span class="hljs-number">255</span>)
&& (LED_change_count2 != <span class="hljs-number">255</span>)
&& (LED_change_count3 == <span class="hljs-number">0</span>))
{
LED_change_count2 ++;
}<span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span>((LED_change_count1 == <span class="hljs-number">255</span>)
&& (LED_change_count2 == <span class="hljs-number">255</span>)
&& (LED_change_count3 != <span class="hljs-number">255</span>))
{
LED_change_count3 ++;
}<span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span>((LED_change_count1 != <span class="hljs-number">0</span>)
&& (LED_change_count2 == <span class="hljs-number">255</span>)
&& (LED_change_count3 == <span class="hljs-number">255</span>))
{
LED_change_count1 --;
}<span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span>((LED_change_count1 == <span class="hljs-number">0</span>)
&& (LED_change_count2 != <span class="hljs-number">0</span>)
&& (LED_change_count3 == <span class="hljs-number">255</span>))
{
LED_change_count2 --;
}<span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span>((LED_change_count1 == <span class="hljs-number">0</span>)
&& (LED_change_count2 == <span class="hljs-number">0</span>)
&& (LED_change_count3 != <span class="hljs-number">0</span>))
{
LED_change_count3 --;
}<span class="hljs-keyword">else</span>
{
}
ESP_LOGI(TAG, <span class="hljs-string">"R-%d,G-%d,B-%d"</span>, LED_change_count1, LED_change_count2, LED_change_count3);
ESP_ERROR_CHECK(strip->set_pixel(strip, <span class="hljs-number">0</span>, LED_change_count1, LED_change_count2, LED_change_count3));
ESP_ERROR_CHECK(strip->refresh(strip, <span class="hljs-number">0</span>));
vTaskDelay(pdMS_TO_TICKS(<span class="hljs-number">10</span>));
}
vTaskDelete(NULL);
}
<span class="hljs-comment">/* Cmera task */</span>
<span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> cam_task(<span class="hljs-keyword">void</span> *arg)
{
cam_config_t cam_config = {
.bit_width = <span class="hljs-number">8</span>,
<span class="hljs-preprocessor">#ifdef CONFIG_CAMERA_JPEG_MODE</span>
.mode.jpeg = <span class="hljs-number">1</span>,
<span class="hljs-preprocessor">#else</span>
.mode.jpeg = <span class="hljs-number">0</span>,
<span class="hljs-preprocessor">#endif</span>
.xclk_fre = <span class="hljs-number">16</span> * <span class="hljs-number">1000</span> * <span class="hljs-number">1000</span>,
.pin= {
.xclk = CAM_XCLK,
.pclk = CAM_PCLK,
.vsync = CAM_VSYNC,
.hsync = CAM_HSYNC,
},
.pin_data = {CAM_D0, CAM_D1, CAM_D2, CAM_D3, CAM_D4, CAM_D5, CAM_D6, CAM_D7},
.vsync_invert = <span class="hljs-keyword">true</span>,
.hsync_invert = <span class="hljs-keyword">false</span>,
.size = {
.width = CAM_WIDTH,
.high = CAM_HIGH,
},
.max_buffer_size = <span class="hljs-number">8</span> * <span class="hljs-number">1024</span>,
.task_stack = <span class="hljs-number">1024</span>,
.task_pri = configMAX_PRIORITIES
};
<span class="hljs-comment">/*!< With PingPang buffers, the frame rate is higher, or you can use a separate buffer to save memory */</span>
cam_config.frame1_buffer = (uint8_t *)heap_caps_malloc(CAM_WIDTH * CAM_HIGH * <span class="hljs-number">2</span> * <span class="hljs-keyword">sizeof</span>(uint8_t), MALLOC_CAP_SPIRAM);
cam_config.frame2_buffer = (uint8_t *)heap_caps_malloc(CAM_WIDTH * CAM_HIGH * <span class="hljs-number">2</span> * <span class="hljs-keyword">sizeof</span>(uint8_t), MALLOC_CAP_SPIRAM);
cam_init(&cam_config);
sensor_t sensor;
<span class="hljs-keyword">int</span> camera_version = <span class="hljs-number">0</span>; <span class="hljs-comment">/*!<If the camera version is determined, it can be set to manual mode */</span>
SCCB_Init(CAM_SDA, CAM_SCL);
sensor.slv_addr = SCCB_Probe();
ESP_LOGI(TAG, <span class="hljs-string">"sensor_id: 0x%x\n"</span>, sensor.slv_addr);
<span class="hljs-preprocessor">#ifdef CONFIG_CAMERA_OV2640</span>
camera_version = <span class="hljs-number">2640</span>;
<span class="hljs-preprocessor">#endif</span>
<span class="hljs-preprocessor">#ifdef CONFIG_CAMERA_OV3660</span>
camera_version = <span class="hljs-number">3660</span>;
<span class="hljs-preprocessor">#endif</span>
<span class="hljs-preprocessor">#ifdef CONFIG_CAMERA_AUTO</span>
<span class="hljs-comment">/*!< If you choose this mode, Dont insert the Audio board, audio will affect the camera register read. */</span>
<span class="hljs-preprocessor">#endif</span>
<span class="hljs-keyword">if</span> (sensor.slv_addr == <span class="hljs-number">0x30</span> || camera_version == <span class="hljs-number">2640</span>) { <span class="hljs-comment">/*!< Camera: OV2640 */</span>
ESP_LOGI(TAG, <span class="hljs-string">"OV2640 init start..."</span>);
<span class="hljs-keyword">if</span> (OV2640_Init(<span class="hljs-number">0</span>, <span class="hljs-number">1</span>) != <span class="hljs-number">0</span>) {
<span class="hljs-keyword">goto</span> fail;
}
<span class="hljs-keyword">if</span> (cam_config.mode.jpeg) {
OV2640_JPEG_Mode();
} <span class="hljs-keyword">else</span> {
OV2640_RGB565_Mode(<span class="hljs-keyword">false</span>); <span class="hljs-comment">/*!< RGB565 mode */</span>
}
OV2640_ImageSize_Set(<span class="hljs-number">800</span>, <span class="hljs-number">600</span>);
OV2640_ImageWin_Set(<span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">800</span>, <span class="hljs-number">600</span>);
OV2640_OutSize_Set(CAM_WIDTH, CAM_HIGH);
} <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (sensor.slv_addr == <span class="hljs-number">0x3C</span> || camera_version == <span class="hljs-number">3660</span>) { <span class="hljs-comment">/*!< Camera: OV3660 */</span>
sensor.slv_addr = <span class="hljs-number">0x3C</span>; <span class="hljs-comment">/*!< In special cases, slv_addr may change */</span>
ESP_LOGI(TAG, <span class="hljs-string">"OV3660 init start..."</span>);
ov3660_init(&sensor);
sensor.init_status(&sensor);
<span class="hljs-keyword">if</span> (sensor.reset(&sensor) != <span class="hljs-number">0</span>) {
<span class="hljs-keyword">goto</span> fail;
}
<span class="hljs-keyword">if</span> (cam_config.mode.jpeg) {
sensor.set_pixformat(&sensor, PIXFORMAT_JPEG);
} <span class="hljs-keyword">else</span> {
sensor.set_pixformat(&sensor, PIXFORMAT_RGB565);
}
<span class="hljs-comment">/*!< TotalX gets smaller, frame rate goes up */</span>
<span class="hljs-comment">/*!< TotalY gets smaller, frame rate goes up, vsync gets shorter */</span>
sensor.set_res_raw(&sensor, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">2079</span>, <span class="hljs-number">1547</span>, <span class="hljs-number">8</span>, <span class="hljs-number">2</span>, <span class="hljs-number">1920</span>, <span class="hljs-number">800</span>, CAM_WIDTH, CAM_HIGH, <span class="hljs-keyword">true</span>, <span class="hljs-keyword">true</span>);
sensor.set_vflip(&sensor, <span class="hljs-number">1</span>);
sensor.set_hmirror(&sensor, <span class="hljs-number">1</span>);
sensor.set_pll(&sensor, <span class="hljs-keyword">false</span>, <span class="hljs-number">15</span>, <span class="hljs-number">1</span>, <span class="hljs-number">0</span>, <span class="hljs-keyword">false</span>, <span class="hljs-number">0</span>, <span class="hljs-keyword">true</span>, <span class="hljs-number">5</span>); <span class="hljs-comment">/*!< ov3660: 39 fps */</span>
} <span class="hljs-keyword">else</span> {
ESP_LOGE(TAG, <span class="hljs-string">"sensor is temporarily not supported\n"</span>);
<span class="hljs-keyword">goto</span> fail;
}
ESP_LOGI(TAG, <span class="hljs-string">"camera init done\n"</span>);
cam_start();
<span class="hljs-keyword">while</span> (<span class="hljs-number">1</span>) {
uint8_t *cam_buf = NULL;
cam_take(&cam_buf);
<span class="hljs-preprocessor">#ifdef CONFIG_CAMERA_JPEG_MODE</span>
<span class="hljs-keyword">int</span> w, h;
uint8_t *img = jpeg_decode(cam_buf, &w, &h);
<span class="hljs-keyword">if</span> (img) {
ESP_LOGI(TAG, <span class="hljs-string">"jpeg: w: %d, h: %d\n"</span>, w, h);
lcd_set_index(<span class="hljs-number">0</span>, <span class="hljs-number">0</span>, w - <span class="hljs-number">1</span>, h - <span class="hljs-number">1</span>);
lcd_write_data(img, w * h * <span class="hljs-keyword">sizeof</span>(uint16_t));
<span class="hljs-built_in">free</span>(img);
}
<span class="hljs-preprocessor">#else</span>
lcd_set_index(<span class="hljs-number">0</span>, <span class="hljs-number">0</span>, CAM_WIDTH - <span class="hljs-number">1</span>, CAM_HIGH - <span class="hljs-number">1</span>);
lcd_write_data(cam_buf, CAM_WIDTH * CAM_HIGH * <span class="hljs-number">2</span>);
<span class="hljs-preprocessor">#endif</span>
cam_give(cam_buf);
<span class="hljs-comment">/*!< Use a logic analyzer to observe the frame rate */</span>
gpio_set_level(LCD_BK, <span class="hljs-number">1</span>);
gpio_set_level(LCD_BK, <span class="hljs-number">0</span>);
}
fail:
<span class="hljs-built_in">free</span>(cam_config.frame1_buffer);
<span class="hljs-built_in">free</span>(cam_config.frame2_buffer);
cam_deinit();
vTaskDelete(NULL);
}
<span class="hljs-comment">/*start display show*/</span>
<span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> start_display(<span class="hljs-keyword">void</span>)
{
lcd_config_t lcd_config = {
<span class="hljs-preprocessor">#ifdef CONFIG_LCD_ST7789</span>
.clk_fre = <span class="hljs-number">80</span> * <span class="hljs-number">1000</span> * <span class="hljs-number">1000</span>, <span class="hljs-comment">/*!< ILI9341 Stable frequency configuration */</span>
<span class="hljs-preprocessor">#endif</span>
<span class="hljs-preprocessor">#ifdef CONFIG_LCD_ILI9341</span>
.clk_fre = <span class="hljs-number">40</span> * <span class="hljs-number">1000</span> * <span class="hljs-number">1000</span>, <span class="hljs-comment">/*!< ILI9341 Stable frequency configuration */</span>
<span class="hljs-preprocessor">#endif</span>
.pin_clk = LCD_CLK,
.pin_mosi = LCD_MOSI,
.pin_dc = LCD_DC,
.pin_cs = LCD_CS,
.pin_rst = LCD_RST,
.pin_bk = LCD_BK,
.max_buffer_size = <span class="hljs-number">2</span> * <span class="hljs-number">1024</span>,
.horizontal = <span class="hljs-number">2</span> <span class="hljs-comment">/*!< 2: UP, 3: DOWN */</span>
};
lcd_init(&lcd_config);
ESP_LOGI(TAG, <span class="hljs-string">"My Project Start ...."</span>);
esp_vfs_spiffs_conf_t conf = {
.base_path = <span class="hljs-string">"/spiffs"</span>,
.partition_label = NULL,
.max_files = <span class="hljs-number">5</span>,
.format_if_mount_failed = <span class="hljs-keyword">false</span>
};
<span class="hljs-comment">/*!< Use settings defined above to initialize and mount SPIFFS filesystem. */</span>
<span class="hljs-comment">/*!< Note: esp_vfs_spiffs_register is an all-in-one convenience function. */</span>
ESP_ERROR_CHECK(esp_vfs_spiffs_register(&conf));
size_t total = <span class="hljs-number">0</span>, used = <span class="hljs-number">0</span>;
ESP_ERROR_CHECK(esp_spiffs_info(NULL, &total, &used));
uint8_t *img = NULL;
uint8_t *buf = <span class="hljs-built_in">malloc</span>(IMAGE_MAX_SIZE);
<span class="hljs-keyword">int</span> read_bytes = <span class="hljs-number">0</span>;
<span class="hljs-keyword">int</span> width = <span class="hljs-number">0</span>, height = <span class="hljs-number">0</span>;
FILE *fd = fopen(<span class="hljs-string">"/spiffs/1.jpg"</span>, <span class="hljs-string">"r"</span>);
read_bytes = fread(buf, <span class="hljs-number">1</span>, IMAGE_MAX_SIZE, fd);
ESP_LOGI(TAG, <span class="hljs-string">"spiffs:read_bytes:%dfd: %p"</span>, read_bytes, fd);
fclose(fd);
img = jpeg_decode(buf, &width, &height);
lcd_set_index(<span class="hljs-number">0</span>, <span class="hljs-number">0</span>, IMAGE_WIDTH - <span class="hljs-number">1</span>, IMAGE_HIGHT - <span class="hljs-number">1</span>);
lcd_write_data(img, IMAGE_WIDTH * IMAGE_HIGHT * <span class="hljs-keyword">sizeof</span>(uint16_t));
<span class="hljs-built_in">free</span>(buf);
vTaskDelay(<span class="hljs-number">2000</span> / portTICK_RATE_MS);
}
<span class="hljs-comment">/******** End Function Definition********/</span></code></pre>
<img src="data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==" /><span style="background: url("https://bbs.eeworld.com.cn/static/editor/plugins/widget/images/handle.png") rgba(220, 220, 220, 0.5); top: -15px; left: 0px; display: block;"><img height="15" role="presentation" src="data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==" title="点击并拖拽以移动" width="15" /></span></div>
<p> </p>
<p>Kconfig.probuild文件,这个文件是mebuconfig的例程配置文件:</p>
<pre>
<code>menu "Example Configuration"
choice CAMERA_PAD_TYPE
prompt "camera pad type"
default CAMERA_PAD_ESP32_S2_KALUGA_V1_3
config CAMERA_PAD_ESP32_S2_KALUGA_V1_3
bool "ESP32-S2-KALUGA_V1.3"
config CAMERA_PAD_ESP32_S2_KALUGA_V1_2
bool "ESP32-S2-KALUGA_V1.2"
config CAMERA_PAD_ESP32_S2_KALUGA_V1_1
bool "ESP32-S2-KALUGA_V1.1"
endchoice
choice LCD_PAD_TYPE
prompt "LCD pad type"
default LCD_PAD_ESP32_S2_KALUGA_V1_3
config LCD_PAD_ESP32_S2_KALUGA_V1_3
bool "ESP32-S2-KALUGA_V1.3"
config LCD_PAD_ESP32_S2_KALUGA_V1_2
bool "ESP32-S2-KALUGA_V1.2"
config LCD_PAD_ESP32_S2_KALUGA_V1_1
bool "ESP32-S2-KALUGA_V1.1"
endchoice
choice CAMERA_VERSION
prompt "Camera version"
default CAMERA_OV2640
config CAMERA_OV2640
bool "OV2640"
config CAMERA_OV3660
bool "OV3660"
config CAMERA_AUTO
bool "Auto (If you choose this mode, Dont insert the Audio board!)"
help
Set camera version
endchoice
choice LCD_VERSION
prompt "LCD version"
default ILI9341
config LCD_ST7789
bool "ST7789"
config LCD_ILI9341
bool "ILI9341"
help
Set LCD version
endchoice
configCAMERA_JPEG_MODE
bool "jpeg mode"
endmenu
</code></pre>
<p> </p>
<p>CmakeLists.txt文件:</p>
<pre>
<code># 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.5)
set(EXTRA_COMPONENT_DIRS "../../components/board"
"../../components/lcd"
"../../components/jpeg"
"../../components/cam"
"../../components/sensors"
"../../components/led_strip"
)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
add_compile_options (-fdiagnostics-color=always)
project(esp32-s2-hmi)
</code></pre>
<p> </p>
<p>然后使用终端进入工程文件夹,设置环境变量:. $HOME/esp/esp-idf/export.sh</p>
<p>设置编译类型以及进入menuconfig进行配置:idf.py set-target esp32s2 menuconfig</p>
<p>设置如下:</p>
<p></p>
<p> </p>
<p>编译:idf.py build</p>
<p>下载:idf.py -p /dev/ttyUSB1 flash</p>
<p>监控:idf.py -p /dev/ttyUSB1 monitor</p>
<p>收工</p>
<p> </p>
<p> </p>
<p> </p>
页:
[1]