alanlan86 发表于 2024-10-30 09:30

2024DigiKey创意大赛】【自行车智能灯】汇总提交

本帖最后由 alanlan86 于 2024-10-30 10:00 编辑

<p align="center"><b>作品名称</b></p>

<p align="center"><b>自行车智能灯</b></p>

<p><b>一、作品简介</b></p>

<ul>
        <li><b>(1)作品照片</b></li>
        <li>&nbsp;</li>
        <li>
        <div style="text-align: center;"></div>
        </li>
</ul>

<p>&nbsp;</p>

<p><b>(2)简介</b></p>

<p>自行车智能车灯安装在自行车把手位置,能够根据光传感器自动点亮LED灯,用于做车头照明;能够根据IMU监测车把的左转右转动作,实现方向闪灯提醒;能够根据毫米波雷达探测前方是否有障碍物,发出警告提醒。</p>

<p>ESP32-S3-LCD-EV-Board做为主控板,外接光敏电阻传感器,通过ADC采集光的强度。通过I2C采集ICM-20948的姿态数据,进行车把方向监测。通过读取毫米波传感器的终端输出,监测前方是否有障碍物。</p>

<p><b>(3)物料清单</b></p>

<table style="border-collapse:collapse; border:none;Times New Roman&quot;">
        <tbody>
                <tr>
                        <td style="border-bottom:1px solid black; border-top:1px solid black; border-right:1px solid black; border-left:1px solid black" valign="top">
                        <p>物料</p>
                        </td>
                        <td style="border-bottom:1px solid black; border-top:1px solid black; border-right:1px solid black; border-left:1px solid black" valign="top">
                        <p>型号</p>
                        </td>
                        <td style="border-bottom:1px solid black; border-top:1px solid black; border-right:1px solid black; border-left:1px solid black" valign="top">
                        <p>功能</p>
                        </td>
                </tr>
                <tr>
                        <td style="border-bottom:1px solid black; border-top:none; border-right:1px solid black; border-left:1px solid black" valign="top">
                        <p>1</p>
                        </td>
                        <td style="border-bottom:1px solid black; border-top:none; border-right:1px solid black; border-left:1px solid black" valign="top">
                        <p>ESP32-S3-LCD-EV-Board</p>
                        </td>
                        <td style="border-bottom:1px solid black; border-top:none; border-right:1px solid black; border-left:1px solid black" valign="top">
                        <p>主控、LCD显示交互、LED三色灯</p>
                        </td>
                </tr>
                <tr>
                        <td style="border-bottom:1px solid black; border-top:none; border-right:1px solid black; border-left:1px solid black" valign="top">
                        <p>2</p>
                        </td>
                        <td style="border-bottom:1px solid black; border-top:none; border-right:1px solid black; border-left:1px solid black" valign="top">
                        <p>ADAFRUIT TDK INVENSENSE ICM-20948</p>
                        </td>
                        <td style="border-bottom:1px solid black; border-top:none; border-right:1px solid black; border-left:1px solid black" valign="top">
                        <p>9轴传感器</p>
                        </td>
                </tr>
                <tr>
                        <td style="border-bottom:1px solid black; border-top:none; border-right:1px solid black; border-left:1px solid black" valign="top">
                        <p>3</p>
                        </td>
                        <td style="border-bottom:1px solid black; border-top:none; border-right:1px solid black; border-left:1px solid black" valign="top">
                        <p>MerryTek MC01-5G</p>
                        </td>
                        <td style="border-bottom:1px solid black; border-top:none; border-right:1px solid black; border-left:1px solid black" valign="top">
                        <p>毫米波传感器(集成光敏电阻)</p>
                        </td>
                </tr>
        </tbody>
</table>

<p>&nbsp;&nbsp; &nbsp; &nbsp;&nbsp; &nbsp;</p>

<p>&nbsp;</p>

<p><b>A、ESP32-S3-LCD-EV-Board</b></p>

<p>ESP32-S3-LCD-EV-Board 是一款基于 ESP32-S3 芯片的屏幕交互开发板,通过搭配不同类型的 LCD 子板,可以驱动 IIC、SPI、8080 以及 RGB 接口的 LCD 显示屏。同时它还搭载双麦克风阵列,支持语音识别和近/远场语音唤醒,具有触摸屏交互和语音交互功能,满足用户对多种不同分辨率以及接口的触摸屏应用产品的开发需求。</p>

<p>目前从Digikey上采购到的开发板:搭配 480x480 LCD 的 ESP32-S3-LCD-EV-Board,有丰富的外设和强大的显示能力。</p>

<p>该款开发板核心模组型号ESP32-S3-WROOM-1-N16R16V, 该模组是一款通用型 Wi-Fi + 低功耗蓝牙 MCU 模组,搭载 ESP32-S3 系列芯片,内置 16 MB flash 以及 16 MB PSRAM。除具有丰富的外设接口外,模组还拥有强大的神经网络运算能力和信号处理能力,适用于 AIoT 领域的多种应用场景。</p>

<p><b>B、ICM-20948模组</b></p>

<p>ICM-20948是TDK(InvenSense)推出的9轴系列的9轴运动跟踪设备,专为电池供电的高性能消费电子产品设计。</p>

<p>&nbsp;9轴产品系列采用了经过市场验证的MotionFusion以及运行时校准,该校准由InvenSense市场的MPU-65xx系列产品支持。此解决方案已售出数百万台,并经过了市场验证。</p>

<p>&nbsp;9轴运动跟踪已成为包括智能手机、平板电脑和可穿戴设备在内的许多消费电子设备的关键功能。与离散解决方案相比,集成9轴设备的尺寸优势对于空间有限的产品(如智能手机和可穿戴传感器)来说是引人注目的。</p>

<p>&nbsp;InvenSense的9轴设备将3轴陀螺仪、3轴加速计和3轴指南针与车载数字运动处理器结合在一起(DMP) 能够处理复杂的运动融合算法。</p>

<p><b>C、MerryTek MC01-5G</b></p>

<p>MC01-5G是一款5.8G微波感应模块,它支持5~12VDC宽输入电压,工作电流小,待机功耗低。 产品体积小,易于安装。 采用低阻抗专利天线技术,抗干扰能力强。 内置抗微风、细雨多重数字滤波器算法、稳定输出高低电平、PWM、UART等控制信号。 预留灵敏度,延时时间,光控阀值等参数设置脚位,功能设置灵活。</p>

<p>产品具有感应距离远、可内置、无死区、不受温湿度、噪音、灰尘、气流、环境光影响等优点。广泛 应用于感应灯具、自动门控制、智能家居、智能卫浴、小家电、安防、IOT、智能终端等产品,及走廊、 车库、洗手间、庭院、阳台等场所。</p>

<p>&nbsp;</p>

<p><b>二、系统框图</b></p>

<div style="text-align: center;"> &nbsp;</div>

<div style="text-align: center;">&nbsp;</div>

<p><strong>主控模组&nbsp;</strong></p>

<div style="text-align: center;">
<p align="justify">整个系统构成相对简单,采用ESP32-S3-WROOM-1-N16R16V模块作为主控,它是一款拥有2.4 GHz WiFi (802.11 b/g/n) + Bluetooth&reg; 5 (LE)的无线高集成度模组,内置 ESP32S3 系列芯片,Xtensa&reg; 双核 32 位 LX7 处理器 Flash最大可选 16 MB,PSRAM最大大可选 8/16 MB,最多支持36个GPIO,丰富的外设 板上带PCB天线非常便利于集成化设计。开发板上有WS2812,三色LED灯,可用于做用户交互指示。</p>

<div style="text-align: center;"></div>

<p align="justify">&nbsp;</p>
</div>

<p align="justify">整个ESP32-S3-LCD-EV-Board开发板的功能框图如下所示:</p>

<div style="text-align: center;"></div>

<p align="justify">&nbsp;</p>

<p align="justify">板载带有的Audio部分,暂时未有使用到,后续可作为扩展使用。</p>

<p align="justify">&nbsp;</p>

<p align="justify"><strong>传感器ICM20948</strong></p>

<p align="justify">ICM20948是一款来自于TDK InvenSense推出的一款9轴运动检测传感器,它与主控板模块连接比较简单,采用I2C方式进行通信,支持400K Hz通信速率。</p>

<div style="text-align: center;"></div>

<p align="justify">&nbsp;</p>

<p><strong>MC01-5G微波感应模组</strong></p>

<p align="justify">微波感应模块MC01-5G支持5~12V的DC直流电源输入,可取开发板扩展电源5V输入作为工作电源,识别到人体或障碍物时,将通过I/O以电平方式进行输出。针对发射功率、感应延时、环境光探测等均可以通过配置I/O进行输入。其中感应模块支持探测4米的半径范围。</p>

<p align="justify">如下是模组的典型应用电路图:</p>

<div style="text-align: center;"></div>

<p align="justify">&nbsp;</p>

<p><b>三、各部分功能说明</b></p>

<p>整个软件基于ESP32-S3的idf开发环境进行编写和调试,基于SDK中的lvgl_demo这份示例代码进行的代码添加。</p>

<p><b>(1)开发环境</b></p>

<p>IDF开发环境的安装可以从官网下载<a href="https://www.espressif.com.cn/zh-hans/support/download/sdks-demos?keys=&amp;field_type_tid[]=842"><u>SDK 和演示|乐鑫科技</u></a>,在实现一键安装完成。安装完成后有命令行的工具以及IDE的工具,可以根据用户喜好进行选择应用。</p>

<p><b>(2)环境光采集部分</b></p>

<p>环境光照强度采集采用了比较简单和原始的做法,就是通过ADC采集毫米波感应模块上的光敏电阻,通过判断光敏电阻上的电压值,来调节照明LED的点亮和熄灭。</p>

<p>如下截图是ESP32-S3的ADC部分配置及执行代码:</p>

<pre>
<code class="language-cpp">void app_light_sensor_task(void *arg)
{
    //-------------ADC1 Init---------------//
        //ADC转换器初始化
    adc_oneshot_unit_handle_t adc1_handle;
    adc_oneshot_unit_init_cfg_t init_config1 = {
      .unit_id = ADC_UNIT_1,
    };
    ESP_ERROR_CHECK(adc_oneshot_new_unit(&amp;init_config1, &amp;adc1_handle));

    //-------------ADC1 Config---------------//
        //配置ADC转换通道
    adc_oneshot_chan_cfg_t config = {
      .bitwidth = ADC_BITWIDTH_DEFAULT,
      .atten = EXAMPLE_ADC_ATTEN,
    };
    ESP_ERROR_CHECK(adc_oneshot_config_channel(adc1_handle, EXAMPLE_ADC1_CHAN0, &amp;config));

    //-------------ADC1 Calibration Init---------------//
        //ADC转换器校准
    adc_cali_handle_t adc1_cali_chan0_handle = NULL;
    adc_cali_handle_t adc1_cali_chan1_handle = NULL;
    bool do_calibration1_chan0 = example_adc_calibration_init(ADC_UNIT_1, EXAMPLE_ADC1_CHAN0, EXAMPLE_ADC_ATTEN, &amp;adc1_cali_chan0_handle);

    while (1) {
      ESP_ERROR_CHECK(adc_oneshot_read(adc1_handle, EXAMPLE_ADC1_CHAN0, &amp;adc_raw));
      ESP_LOGI(TAG, "ADC%d Channel[%d] Raw Data: %d", ADC_UNIT_1 + 1, EXAMPLE_ADC1_CHAN0, adc_raw);
      if (do_calibration1_chan0) {
            ESP_ERROR_CHECK(adc_cali_raw_to_voltage(adc1_cali_chan0_handle, adc_raw, &amp;voltage));
            ESP_LOGI(TAG, "ADC%d Channel[%d] Cali Voltage: %d mV", ADC_UNIT_1 + 1, EXAMPLE_ADC1_CHAN0, voltage);
                       
                        //根据光敏电阻感应电压调节LED的亮度
                        if (voltage &gt; 1.5)
                        {
                           LED_PowerON((3.3 - voltage)/3.3 * 100);
                        } else {
                           LED_PowerOFF();
                        }
      }
      vTaskDelay(pdMS_TO_TICKS(1000));
    }

    //Tear Down
    ESP_ERROR_CHECK(adc_oneshot_del_unit(adc1_handle));
    if (do_calibration1_chan0) {
      example_adc_calibration_deinit(adc1_cali_chan0_handle);
    }
}</code></pre>

<p>&nbsp;</p>

<p><b>(3)动作检测部分</b></p>

<p align="justify">关于motion sensor -ICM20948的陀螺仪角速度、加速度的数值采集将会复杂一些。通过调用ESP32-S3的I2C驱动API接口实现传感器的数值读取(此处参考了TDK InvenSense MP9250的一些代码)。</p>

<pre>
<code class="language-cpp">/**
* <a href="home.php?mod=space&amp;uid=159083" target="_blank">@brief </a> Read a sequence of bytes from a MPU9250 sensor registers
*/
static esp_err_t mpu9250_register_read(uint8_t reg_addr, uint8_t *data, size_t len)
{
    return i2c_master_write_read_device(I2C_MASTER_NUM, MPU9250_SENSOR_ADDR, &amp;reg_addr, 1, data, len, I2C_MASTER_TIMEOUT_MS / portTICK_PERIOD_MS);
}

/**
* @brief Write a byte to a MPU9250 sensor register
*/
static esp_err_t mpu9250_register_write_byte(uint8_t reg_addr, uint8_t data)
{
    int ret;
    uint8_t write_buf = {reg_addr, data};

    ret = i2c_master_write_to_device(I2C_MASTER_NUM, MPU9250_SENSOR_ADDR, write_buf, sizeof(write_buf), I2C_MASTER_TIMEOUT_MS / portTICK_PERIOD_MS);

    return ret;
}</code></pre>

<p align="justify">初始化传感器部分配置:</p>

<pre>
<code class="language-cpp">void motion_sensor_init(void)
{
    uint8_t data;
    ESP_ERROR_CHECK(i2c_master_init());
    ESP_LOGI(TAG, "I2C initialized successfully");

    /* Read the MPU9250 WHO_AM_I register, on power up the register should have the value 0x71 */
    ESP_ERROR_CHECK(mpu9250_register_read(MPU9250_WHO_AM_I_REG_ADDR, data, 1));
    ESP_LOGI(TAG, "WHO_AM_I = %X", data);

    /* Demonstrate writing by reseting the MPU9250 */
    ESP_ERROR_CHECK(mpu9250_register_write_byte(MPU9250_PWR_MGMT_1_REG_ADDR, 1 &lt;&lt; MPU9250_RESET_BIT));

    /*Set DATA RATE of 1KHz by writing SMPLRT_DIV register*/
    ESP_ERROR_CHECK(mpu9250_register_write_byte(MPU9250_SMPLRT_DIV_REG, 0x07));
   
    /*Set accelerometer configuration in ACCEL_CONFIG Register*/
    /*XA_ST=0,YA_ST=0,ZA_ST=0,FS_SEL=0 -&gt;±2g*/
    ESP_ERROR_CHECK(mpu9250_register_write_byte(MPU9250_ACCEL_CONFIG_REG, 0x00));

    /*Set Gyroscopic configuration in GYRO_CONFIG Register*/
    /*XG_ST=0,YG_ST=0,FS_SEL=0 -&gt;± 250 °/s*/
    ESP_ERROR_CHECK(mpu9250_register_write_byte(MPU9250_GYRO_CONFIG_REG, 0x00));
}</code></pre>

<p align="justify">读取传感器角速度、加速度和温度值:</p>

<pre>
<code class="language-cpp">/*Read 14 BYTES of data starting from ACCEL_XOUT_H register*/

mpu9250_register_read( MPU9250_ACCEL_XOUT_H_REG, Rec_Data, 14);

DataStruct-&gt;Accel_X_RAW = (int16_t) (Rec_Data &lt;&lt; 8 | Rec_Data);
DataStruct-&gt;Accel_Y_RAW = (int16_t) (Rec_Data &lt;&lt; 8 | Rec_Data);
DataStruct-&gt;Accel_Z_RAW = (int16_t) (Rec_Data &lt;&lt; 8 | Rec_Data);

temp = (int16_t) (Rec_Data &lt;&lt; 8 | Rec_Data);

DataStruct-&gt;Gyro_X_RAW = (int16_t) (Rec_Data &lt;&lt; 8 | Rec_Data);
DataStruct-&gt;Gyro_Y_RAW = (int16_t) (Rec_Data &lt;&lt; 8 | Rec_Data);
DataStruct-&gt;Gyro_Z_RAW = (int16_t) (Rec_Data &lt;&lt; 8 | Rec_Data);

DataStruct-&gt;Ax = DataStruct-&gt;Accel_X_RAW / 16384.0;
DataStruct-&gt;Ay = DataStruct-&gt;Accel_Y_RAW / 16384.0;
DataStruct-&gt;Az = DataStruct-&gt;Accel_Z_RAW / ACCEL_Z_CORRECTOR;

DataStruct-&gt;Temperature = (float) ((int16_t) temp / (float) 340.0 + (float) 36.53);

DataStruct-&gt;Gx = DataStruct-&gt;Gyro_X_RAW / 131.0;
DataStruct-&gt;Gy = DataStruct-&gt;Gyro_Y_RAW / 131.0;
DataStruct-&gt;Gz = DataStruct-&gt;Gyro_Z_RAW / 131.0;</code></pre>

<p align="justify">为确保采集到的角度速度和角速度能够稳定,并且融合成姿态角,增加了卡尔曼滤波器进行处理:</p>

<pre>
<code class="language-cpp">/*Kalman angle solve*/
double dt = (double) (xTaskGetTickCount() - timer) / configTICK_RATE_HZ;

timer = xTaskGetTickCount();
double roll;

/*勾股算出重力加速度在X-Z平面的投影长度*/
double roll_sqrt = sqrt(DataStruct-&gt;Accel_X_RAW * DataStruct-&gt;Accel_X_RAW + DataStruct-&gt;Accel_Z_RAW * DataStruct-&gt;Accel_Z_RAW);
if(roll_sqrt != 0.0)
{
    roll = atan(DataStruct-&gt;Accel_Y_RAW / roll_sqrt) * RAD_TO_DEG;
}
else
{
    roll = 0.0;
}
double pitch = atan2(-DataStruct-&gt;Accel_X_RAW, DataStruct-&gt;Accel_Z_RAW) * RAD_TO_DEG;
if((pitch &lt; -90 &amp;&amp; DataStruct-&gt;KalmanAngleY &gt; 90) || (pitch &gt; 90 &amp;&amp; DataStruct-&gt;KalmanAngleY &lt; -90))
{
    KalmanY.angle = pitch;
    DataStruct-&gt;KalmanAngleY = pitch;
}
else
{
    DataStruct-&gt;KalmanAngleY = Kalman_getAngle(&amp;KalmanY, pitch, DataStruct-&gt;Gy, dt);
}
if(fabs(DataStruct-&gt;KalmanAngleY) &gt; 90)
{
    DataStruct-&gt;Gx = -DataStruct-&gt;Gx;
}
DataStruct-&gt;KalmanAngleX = Kalman_getAngle(&amp;KalmanX, roll, DataStruct-&gt;Gy, dt);</code></pre>

<p align="justify"><b>(4)微波感应部分</b></p>

<p align="justify">微波感应模块探测到障碍物将以I/O信号进行输出,引出配置ESP32的GPIO中断进行事件上报。</p>

<pre>
<code class="language-cpp">void app_radar_sensor_task(void)
{
    gpio_input_init();

    //change gpio interrupt type for one pin
    gpio_set_intr_type(GPIO_INPUT_IO_0, GPIO_INTR_ANYEDGE);

    //create a queue to handle gpio event from isr
    gpio_evt_queue = xQueueCreate(10, sizeof(uint32_t));
       
    //start gpio task
    xTaskCreate(radar_gpio_int_task, "gpio_task_example", 2048, NULL, 10, NULL);

    //install gpio isr service
    gpio_install_isr_service(ESP_INTR_FLAG_DEFAULT);
       
    //remove isr handler for gpio number.
    gpio_isr_handler_remove(GPIO_INPUT_IO_0);
       
    //hook isr handler for specific gpio pin again
    gpio_isr_handler_add(GPIO_INPUT_IO_0, gpio_isr_handler, (void*) GPIO_INPUT_IO_0);
}</code></pre>

<p align="justify">检测到I/O中断后以Queue队列的方式从中断发出到任务端,使得任务部分可以作出对应处理。</p>

<pre>
<code class="language-cpp">static QueueHandle_t gpio_evt_queue = NULL;

static void IRAM_ATTR gpio_isr_handler(void* arg)
{
    uint32_t gpio_num = (uint32_t) arg;
    xQueueSendFromISR(gpio_evt_queue, &amp;gpio_num, NULL);
}

static void radar_gpio_int_task(void* arg)
{
    uint32_t io_num;
    for(;;) {
      if(xQueueReceive(gpio_evt_queue, &amp;io_num, portMAX_DELAY)) {
            printf("GPIO[%"PRIu32"] intr, val: %d\n", io_num, gpio_get_level(io_num));
      }
    }
}</code></pre>

<p>&nbsp;</p>

<p><b>(2)、LVGL图形部分</b></p>

<p align="justify">关于ESP32-S3-LCD这个开发板,乐鑫原厂官方原有SDK即有移植好支持LVGL的实例。需要执行UI的开发可以采用调用LVGL的API逐个控件进行布局和显示调试,但是难免效率太低了,所以需要借助UI开发助手Square Line Studio和PC模拟器进行帮助。</p>

<div style="text-align: center;"></div>

<p align="justify">有PC模拟器的加持将会减少反复编译下载到嵌入式端芯片的时间,提高开发效率,直接可实现所见即所得。</p>

<div style="text-align: center;"></div>

<p align="justify">通过Square Line Studio可以将图形UI的界面进行设计完成。</p>

<div style="text-align: center;"></div>

<p align="justify">整个UI的代码文件结构:</p>

<div style="text-align: center;"></div>

<p align="justify">Square Line Studio自动生成以上代码,他们的功能作用分别是:</p>

<table style="border-collapse:collapse; border:none;Times New Roman&quot;">
        <tbody>
                <tr>
                        <td style="border-bottom:1px solid black; border-top:1px solid black; border-right:1px solid black; border-left:1px solid black" valign="top">
                        <p align="justify">Component</p>
                        </td>
                        <td style="border-bottom:1px solid black; border-top:1px solid black; border-right:1px solid black; border-left:1px solid black" valign="top">
                        <p align="justify">功能控件</p>
                        </td>
                        <td style="border-bottom:1px solid black; border-top:1px solid black; border-right:1px solid black; border-left:1px solid black" valign="top">
                        <p align="justify">自动生成,无需修改</p>
                        </td>
                </tr>
                <tr>
                        <td style="border-bottom:1px solid black; border-top:none; border-right:1px solid black; border-left:1px solid black" valign="top">
                        <p align="justify">Fonts</p>
                        </td>
                        <td style="border-bottom:1px solid black; border-top:none; border-right:1px solid black; border-left:1px solid black" valign="top">
                        <p align="justify">字体资源</p>
                        </td>
                        <td style="border-bottom:1px solid black; border-top:none; border-right:1px solid black; border-left:1px solid black" valign="top">
                        <p align="justify">自动生成,无需修改</p>
                        </td>
                </tr>
                <tr>
                        <td style="border-bottom:1px solid black; border-top:none; border-right:1px solid black; border-left:1px solid black" valign="top">
                        <p align="justify">Image</p>
                        </td>
                        <td style="border-bottom:1px solid black; border-top:none; border-right:1px solid black; border-left:1px solid black" valign="top">
                        <p align="justify">图片资源</p>
                        </td>
                        <td style="border-bottom:1px solid black; border-top:none; border-right:1px solid black; border-left:1px solid black" valign="top">
                        <p align="justify">自动生成,无需修改</p>
                        </td>
                </tr>
                <tr>
                        <td style="border-bottom:1px solid black; border-top:none; border-right:1px solid black; border-left:1px solid black" valign="top">
                        <p align="justify">Screen</p>
                        </td>
                        <td style="border-bottom:1px solid black; border-top:none; border-right:1px solid black; border-left:1px solid black" valign="top">
                        <p align="justify">屏幕资源</p>
                        </td>
                        <td style="border-bottom:1px solid black; border-top:none; border-right:1px solid black; border-left:1px solid black" valign="top">
                        <p align="justify">自动生成,无需修改</p>
                        </td>
                </tr>
                <tr>
                        <td style="border-bottom:1px solid black; border-top:none; border-right:1px solid black; border-left:1px solid black" valign="top">
                        <p align="justify">Ui.c/ui_event.c/ui_helpers.c</p>
                        </td>
                        <td style="border-bottom:1px solid black; border-top:none; border-right:1px solid black; border-left:1px solid black" valign="top">
                        <p align="justify">界面交互事件</p>
                        </td>
                        <td style="border-bottom:1px solid black; border-top:none; border-right:1px solid black; border-left:1px solid black" valign="top">
                        <p align="justify">用户交互与硬件逻辑交互的代码添加位置</p>
                        </td>
                </tr>
        </tbody>
</table>

<p align="justify">代码准备好后,可以在idf的集成环境下编译通过,并烧录到开发板上。</p>

<div style="text-align: center;"></div>

<p><b>四、作品源码</b></p>

<div></div>

<div></div>

<p><b>五、</b><b>作品功能演示视频</b></p>

<p><a href="https://bbs.eeworld.com.cn/thread-1290905-1-1.html"><u>【2024DigiKey创意大赛】【自行车智能灯】开箱贴ESP32-S3-LCD-EV-BOARD&amp;ICM2094 - DigiKey得捷技术专区 - 电子工程世界-论坛</u></a></p>

<p>&nbsp;</p>

<p><b>演示视频</b></p>

<p>&nbsp;</p>

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

<p>&nbsp;
<p><b>六、项目总结</b></p>
</p>

<p>本次活动对于本人来说,最大的遗憾是由于工作的原因,并不能在预定的时间内,完全按照最初的功能设想把所有功能和代码调试完整,导致整个功能的演示完整性不高。但是,也有所收获&mdash;&mdash;最大的收获是本次通过ESP32-S3带彩屏LCD的开发板,对于LVGL进行了一些探究,虽然现在离做出美轮美奂的UI界面还有一些距离(之前疑惑:如果嵌入式工程人员,如果用一款好用的切图软件,把UI做得简洁漂亮?B站上,大家探讨和分享的比较多都是一些移植、LVGL的一些控件的一些普通用法。探讨到实操把square line studio用好的比较少干货!)</p>

<p>最后,总结一句,还是非常感谢Digikey和EEWorld给那么好的学习机会和提供了一个大家交流的平台!</p>

<p>&nbsp;</p>

<p><b>七、其他</b></p>

<p>题外话,出于工作因素考虑,可能稍后一段很长时间的Follow Me或DIY创新活动都没法参加了~~~静待闲暇之时!</p>
页: [1]
查看完整版本: 2024DigiKey创意大赛】【自行车智能灯】汇总提交