hehung 发表于 2020-8-16 19:07

【ESP32-S2-Kaluga-1测评】5. 图片显示,按键以及RGB LED操作

<p>这一周弄了弄板载的按键以及RGB LED。</p>

<p>下面说一下具体实现的功能,使用官方提供的例程进行修改,显示了自己的一个logo图片</p>

<p></p>

<p>&nbsp;</p>

<p>接着是操作RGB LED,在官方例程中进行修改,代码如下,</p>

<p>改代码的含义是,红蓝绿交替显示:</p>

<p>&nbsp;</p>

<p>显示效果如下:</p>

<p><iframe allowfullscreen="true" frameborder="0" height="510" src="https://training.eeworld.com.cn/shareOpenCourseAPI?isauto=true&amp;lessonid=27035" style="background:#eee;margin-bottom:10px;" width="750"></iframe><br />
&nbsp;</p>

<p>接下来是按钮的控制,ESP32S2的按键是连接在ADC上面的,所以需要配合ADC读取相应的电压值,不同的按键或者组合按键按下去有不同的电压值,需要ADC进行采集</p>

<p>电路原理图如下:</p>

<p></p>

<p>&nbsp;</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>&nbsp;</p>

<p>我写的程序是RGB LED和按键分别用了两个不同的任务,按下按键K1就暂停RGB LED任务,松开按键K1就继续RGB LED任务。</p>

<p>&nbsp;</p>

<p>效果如下:</p>

<p><iframe allowfullscreen="true" frameborder="0" height="510" src="https://training.eeworld.com.cn/shareOpenCourseAPI?isauto=true&amp;lessonid=27036" style="background:#eee;margin-bottom:10px;" width="750"></iframe><br />
&nbsp;</p>

<div aria-label="代码段 小部件" contenteditable="false" role="region" tabindex="-1">
<pre data-widget="codesnippet">
<code class="hljs">f((1 == key_pressed_status) &amp;&amp; (0 == Last_key_pressed_status)){   // pressed
      vTaskSuspend(RGBLEDTask_Handler);
      ESP_LOGI(TAG, &quot;K1 activated&quot;);
    }else if((0 == key_pressed_status) &amp;&amp; (1 == Last_key_pressed_status)){      // released
      vTaskResume(RGBLEDTask_Handler);
      ESP_LOGI(TAG, &quot;K1 inactivated&quot;);
    }else{

    }</code></pre>
<img src="data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==" /><span style="background: url(&quot;https://bbs.eeworld.com.cn/static/editor/plugins/widget/images/handle.png&quot;) 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>&nbsp;</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 &lt;stdio.h&gt;</span>
<span class="hljs-preprocessor">#include &lt;stdint.h&gt;</span>
<span class="hljs-preprocessor">#include &lt;stddef.h&gt;</span>
<span class="hljs-preprocessor">#include &lt;string.h&gt;</span>

<span class="hljs-preprocessor">#include &quot;esp_wifi.h&quot;</span>
<span class="hljs-preprocessor">#include &quot;esp_system.h&quot;</span>
<span class="hljs-preprocessor">#include &quot;nvs_flash.h&quot;</span>
<span class="hljs-preprocessor">#include &quot;esp_event.h&quot;</span>
<span class="hljs-preprocessor">#include &quot;freertos/FreeRTOS.h&quot;</span>
<span class="hljs-preprocessor">#include &quot;freertos/task.h&quot;</span>
<span class="hljs-preprocessor">#include &quot;esp_heap_caps.h&quot;</span>
<span class="hljs-preprocessor">#include &quot;esp_log.h&quot;</span>
<span class="hljs-preprocessor">#include &quot;esp_spiffs.h&quot;</span>

<span class="hljs-preprocessor">#include &quot;lcd.h&quot;</span>
<span class="hljs-preprocessor">#include &quot;jpeg.h&quot;</span>
<span class="hljs-preprocessor">#include &quot;board.h&quot;</span>
<span class="hljs-preprocessor">#include &quot;sccb.h&quot;</span>
<span class="hljs-preprocessor">#include &quot;cam.h&quot;</span>

<span class="hljs-preprocessor">#include &quot;ov2640.h&quot;</span>
<span class="hljs-preprocessor">#include &quot;ov3660.h&quot;</span>
<span class="hljs-preprocessor">#include &quot;sensor.h&quot;</span>

<span class="hljs-preprocessor">#include &quot;driver/gpio.h&quot;</span>
<span class="hljs-preprocessor">#include &quot;driver/adc.h&quot;</span>
<span class="hljs-preprocessor">#include &quot;driver/rmt.h&quot;</span>
<span class="hljs-preprocessor">#include &quot;led_strip.h&quot;</span>

<span class="hljs-keyword">static</span> <span class="hljs-keyword">const</span> <span class="hljs-keyword">char</span> *TAG = <span class="hljs-string">&quot;main&quot;</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)/**&lt; The maximum size of a single picture in the boot animation */</span>
<span class="hljs-preprocessor">#define IMAGE_WIDTH    (320) /*!&lt; width of jpeg file */</span>
<span class="hljs-preprocessor">#define IMAGE_HIGHT    (240) /*!&lt; 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                            /*!&lt; 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                           /*!&lt; 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">/*!&lt; 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, &quot;cam_task&quot;, 2048, NULL, 3, &amp;CameraTask_Handler);</span>
    <span class="hljs-comment">/**/</span>
    xTaskCreate(&amp;button_task, <span class="hljs-string">&quot;button_task&quot;</span>, <span class="hljs-number">3</span>*<span class="hljs-number">1024</span>, NULL, <span class="hljs-number">4</span>, &amp;ButtonTask_Handler);
    xTaskCreate(&amp;led_task, <span class="hljs-string">&quot;led_task&quot;</span>, <span class="hljs-number">3</span>*<span class="hljs-number">1024</span>, NULL, <span class="hljs-number">5</span>, &amp;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">/*!&lt;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">/*!&lt; Multisampling */</span>
      <span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> i = <span class="hljs-number">0</span>; i &lt; 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, &amp;raw);
                adc_reading += raw;
            }
      }

      adc_reading /= NO_OF_SAMPLES;

      voltage = adc_voltage_conversion(adc_reading);
      ESP_LOGD(TAG, <span class="hljs-string">&quot;ADC%d CH%d Raw: %d   ; Voltage: %0.2lfV&quot;</span>, unit, channel, adc_reading, voltage);
      ESP_LOGI(TAG, <span class="hljs-string">&quot;Voltage: %0.2lfV&quot;</span>, voltage);
      xQueueSend(adc_queue, (<span class="hljs-keyword">double</span> *)&amp;voltage, <span class="hljs-number">0</span>);
    <span class="hljs-comment">//    xQueueReceive(adc_queue, &amp;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, &amp;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 &gt; <span class="hljs-number">2.30</span> - DEVIATION&amp;&amp; voltage &lt;= <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">&quot;K1 Pressed&quot;</span>);
    } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (voltage &gt; <span class="hljs-number">1.98</span> - DEVIATION &amp;&amp; voltage &lt;= <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">&quot;K2 Pressed&quot;</span>);
    } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (voltage &gt; <span class="hljs-number">1.65</span> - DEVIATION &amp;&amp; voltage &lt;= <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">&quot;K3 Pressed&quot;</span>);
    } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (voltage &gt; <span class="hljs-number">1.11</span> - DEVIATION &amp;&amp; voltage &lt;= <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">&quot;K4 Pressed&quot;</span>);
    } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (voltage &gt; <span class="hljs-number">0.82</span> - DEVIATION &amp;&amp; voltage &lt;= <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">&quot;K5 Pressed&quot;</span>);
    } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (voltage &gt; <span class="hljs-number">0.38</span> - DEVIATION &amp;&amp; voltage &lt;= <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">&quot;K6 Pressed&quot;</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>]) &amp;&amp; (<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">&quot;K1 activated&quot;</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>]) &amp;&amp; (<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">&quot;K1 inactivated&quot;</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">&quot;Initializing WS2812&quot;</span>);
    rmt_config_t config = RMT_DEFAULT_CONFIG_TX(gpio_num, rmt_channel);

    <span class="hljs-comment">/*!&lt; set counter clock to 40MHz */</span>
    config.clk_div = <span class="hljs-number">2</span>;

    ESP_ERROR_CHECK(rmt_config(&amp;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(&amp;strip_config);

    <span class="hljs-keyword">if</span> (!strip) {
      ESP_LOGE(TAG, <span class="hljs-string">&quot;install WS2812 driver failed&quot;</span>);
      <span class="hljs-keyword">return</span> ESP_FAIL;
    }

    <span class="hljs-comment">/*!&lt; Clear LED strip (turn off all LEDs) */</span>
    ESP_ERROR_CHECK(strip-&gt;clear(strip, <span class="hljs-number">100</span>));
    <span class="hljs-comment">/*!&lt; 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">/*!&lt; 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-&gt;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>)
            &amp;&amp; (LED_change_count2 == <span class="hljs-number">0</span>)
            &amp;&amp; (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>)
            &amp;&amp; (LED_change_count2 != <span class="hljs-number">255</span>)
            &amp;&amp; (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>)
            &amp;&amp; (LED_change_count2 == <span class="hljs-number">255</span>)
            &amp;&amp; (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>)
            &amp;&amp; (LED_change_count2 == <span class="hljs-number">255</span>)
            &amp;&amp; (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>)
            &amp;&amp; (LED_change_count2 != <span class="hljs-number">0</span>)
            &amp;&amp; (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>)
            &amp;&amp; (LED_change_count2 == <span class="hljs-number">0</span>)
            &amp;&amp; (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">&quot;R-%d,G-%d,B-%d&quot;</span>, LED_change_count1, LED_change_count2, LED_change_count3);
      ESP_ERROR_CHECK(strip-&gt;set_pixel(strip, <span class="hljs-number">0</span>, LED_change_count1, LED_change_count2, LED_change_count3));
      ESP_ERROR_CHECK(strip-&gt;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">/*!&lt; 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(&amp;cam_config);

    sensor_t sensor;
    <span class="hljs-keyword">int</span> camera_version = <span class="hljs-number">0</span>;      <span class="hljs-comment">/*!&lt;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">&quot;sensor_id: 0x%x\n&quot;</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">/*!&lt; 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">/*!&lt; Camera: OV2640 */</span>
      ESP_LOGI(TAG, <span class="hljs-string">&quot;OV2640 init start...&quot;</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">/*!&lt; 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">/*!&lt; Camera: OV3660 */</span>

      sensor.slv_addr = <span class="hljs-number">0x3C</span>; <span class="hljs-comment">/*!&lt; In special cases, slv_addr may change */</span>
      ESP_LOGI(TAG, <span class="hljs-string">&quot;OV3660 init start...&quot;</span>);
      ov3660_init(&amp;sensor);
      sensor.init_status(&amp;sensor);

      <span class="hljs-keyword">if</span> (sensor.reset(&amp;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(&amp;sensor, PIXFORMAT_JPEG);
      } <span class="hljs-keyword">else</span> {
            sensor.set_pixformat(&amp;sensor, PIXFORMAT_RGB565);
      }

      <span class="hljs-comment">/*!&lt; TotalX gets smaller, frame rate goes up */</span>
      <span class="hljs-comment">/*!&lt; TotalY gets smaller, frame rate goes up, vsync gets shorter */</span>
      sensor.set_res_raw(&amp;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(&amp;sensor, <span class="hljs-number">1</span>);
      sensor.set_hmirror(&amp;sensor, <span class="hljs-number">1</span>);
      sensor.set_pll(&amp;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">/*!&lt; ov3660: 39 fps */</span>
    } <span class="hljs-keyword">else</span> {
      ESP_LOGE(TAG, <span class="hljs-string">&quot;sensor is temporarily not supported\n&quot;</span>);
      <span class="hljs-keyword">goto</span> fail;
    }

    ESP_LOGI(TAG, <span class="hljs-string">&quot;camera init done\n&quot;</span>);
    cam_start();

    <span class="hljs-keyword">while</span> (<span class="hljs-number">1</span>) {
      uint8_t *cam_buf = NULL;
      cam_take(&amp;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, &amp;w, &amp;h);

      <span class="hljs-keyword">if</span> (img) {
            ESP_LOGI(TAG, <span class="hljs-string">&quot;jpeg: w: %d, h: %d\n&quot;</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">/*!&lt; 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">/*!&lt; 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">/*!&lt; 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">/*!&lt; 2: UP, 3: DOWN */</span>
    };

    lcd_init(&amp;lcd_config);

    ESP_LOGI(TAG, <span class="hljs-string">&quot;My Project Start ....&quot;</span>);
    esp_vfs_spiffs_conf_t conf = {
      .base_path = <span class="hljs-string">&quot;/spiffs&quot;</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">/*!&lt; Use settings defined above to initialize and mount SPIFFS filesystem. */</span>
    <span class="hljs-comment">/*!&lt; Note: esp_vfs_spiffs_register is an all-in-one convenience function. */</span>
    ESP_ERROR_CHECK(esp_vfs_spiffs_register(&amp;conf));
    size_t total = <span class="hljs-number">0</span>, used = <span class="hljs-number">0</span>;
    ESP_ERROR_CHECK(esp_spiffs_info(NULL, &amp;total, &amp;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">&quot;/spiffs/1.jpg&quot;</span>, <span class="hljs-string">&quot;r&quot;</span>);

    read_bytes = fread(buf, <span class="hljs-number">1</span>, IMAGE_MAX_SIZE, fd);
    ESP_LOGI(TAG, <span class="hljs-string">&quot;spiffs:read_bytes:%dfd: %p&quot;</span>, read_bytes, fd);
    fclose(fd);

    img = jpeg_decode(buf, &amp;width, &amp;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(&quot;https://bbs.eeworld.com.cn/static/editor/plugins/widget/images/handle.png&quot;) 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>&nbsp;</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>&nbsp;</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>&nbsp;</p>

<p>然后使用终端进入工程文件夹,设置环境变量:. $HOME/esp/esp-idf/export.sh</p>

<p>设置编译类型以及进入menuconfig进行配置:idf.py set-target esp32s2 menuconfig</p>

<p>设置如下:</p>

<p></p>

<p>&nbsp;</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>&nbsp;</p>

<p>&nbsp;</p>

<p>&nbsp;</p>
页: [1]
查看完整版本: 【ESP32-S2-Kaluga-1测评】5. 图片显示,按键以及RGB LED操作