mingzhe123 发表于 2024-10-26 23:52

【2024 DigiKey 创意大赛】室内智能照明灯设计-完结篇

本帖最后由 mingzhe123 于 2024-10-29 20:27 编辑

<h2 align="center">【2024 DigiKey 创意大赛】室内智能照明灯设计</h2>

<ol>
        <li>背景介绍</li>
</ol>

<p>物联网技术是指通过互联网将各种设备、传感 器、控制器等连接在一起,形成一个能够实时互通信息的网络。物联网技术的基本原理是通过传感器采集设备产生的数据,并通过控制器进行处理和控制,最终将数据传输到互联网上,实现设备之间的智能交互。物联网技术的核心特点是实时性、数据共享、智能化和互联性。物联网技术的实时性意味着设备和传感器能够即时收集和传输数据,使得用户可以实时了解设备状态和环境情况。数据共享可 以使不同设备之间共享数据,实现更高效的资源利用和协同工作。智能化指的是物联网设备具备处理和分析数据的能力,可以根据用户需求自动调整设备工作模式。互联性表示物联网技术可以实现设备与设备、设备与人之间的无缝连接和交互,实现更强大的功能和用户体验。物联网技术广泛应用于智能家居、智能交通、智慧城市等领域,为人们的生活带来便利和智能化。</p>

<ol start="2">
        <li>室内智能照明灯设计</li>
</ol>

<p>室内照明灯系统硬件如图2.1所示分,为三部分:基于ESP32 S3的服务端、基于ESP32 PICO的传感器端与小爱音箱。其中,ESP32 S3服务端使用的是乐鑫的ESP32 S3 LCD EV开发板。如图2.2所示,主要负责与小爱音箱通信,接收传感器端数据、LCD实时显示传感器数据以及灯光的控制;ESP32 PICO传感器端为单独设计的ESP32板卡,如图2.3所示,主要功能为采集MPU6050数据与SHT30数据应通过BLE传输到服务端;小爱音箱主要是与服务端实现语音交互功能。</p>

<p>&nbsp;</p>

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

<p align="center">图2.1 系统架构图</p>

<p>&nbsp;</p>

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

<p align="center">图2.2ESP32 S3 LCD EV</p>

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

<p align="center">图2.3 传感器端板块</p>

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

<p>室内照明灯系统软件为服务端代码与传感器端代码。服务端代码基于Arduino并通过FreeRTOS实现多任务处理,如图2.4所示。传感器端则基于Arduino框架完成传感器数据采集与蓝牙传输,如图2.5所示。</p>

<p>&nbsp;</p>

<p>&nbsp; &nbsp;服务端代码:</p>

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

<pre>
<code class="language-cpp">#include "BLEDevice.h"
#include &lt;Arduino.h&gt;
#include &lt;lvgl.h&gt;
#include &lt;ESP_Panel_Library.h&gt;
#include &lt;ESP_IOExpander_Library.h&gt;

// #include &lt;examples/lv_examples.h&gt;
//#include &lt;demos/lv_demos.h&gt;

#define BLINKER_WIFI
#define BLINKER_MIOT_LIGHT
#include &lt;Blinker.h&gt;
#include &lt;Adafruit_NeoPixel.h&gt;

char auth[] = "044be84a71f9";
char ssid[] = "C_WIFI";
char pswd[] = "C88888888";

\
ESP_Panel *panel = NULL;

// 蓝牙相关定义
// Default Temperature is in Celsius
// Comment the next line for Temperature in Fahrenheit
#define temperatureCelsius

// BLE Server name (the other ESP32 name running the server sketch)
#define bleServerName "ESP32_HOME"

/* UUID's of the service, characteristic that we want to read*/
// BLE Service
static BLEUUID bmeServiceUUID("91bad492-b950-4226-aa2b-4ede9fa42f59");

// BLE Characteristics
#ifdef temperatureCelsius
// Temperature Celsius Characteristic
static BLEUUID temperatureCharacteristicUUID("cba1d466-344c-4be3-ab3f-189f80dd7518");
#else
// Temperature Fahrenheit Characteristic
static BLEUUID temperatureCharacteristicUUID("f78ebbff-c8b7-4107-93de-889a6a06d408");
#endif

// Humidity Characteristic
static BLEUUID humidityCharacteristicUUID("ca73b3ba-39f6-4ab3-91ae-186dc9577d99");

// LEDSTATE Characteristic
static BLEUUID LEDCharacteristicUUID("553FF727-642D-493B-9D41-62AED7808700");

// Flags stating if should begin connecting and if the connection is up
static boolean doConnect = false;
static boolean connected = false;

// Address of the peripheral device. Address will be found during scanning...
static BLEAddress *pServerAddress;

// Characteristicd that we want to read
static BLERemoteCharacteristic *temperatureCharacteristic;
static BLERemoteCharacteristic *humidityCharacteristic;
static BLERemoteCharacteristic *LEDStateCharacteristic; // Led控制存储变量

// Activate notify
const uint8_t notificationOn[] = {0x1, 0x0};
const uint8_t notificationOff[] = {0x0, 0x0};

// Variables to store temperature and humidity
String temperatureChar;
String humidityChar;
String LEDStateChar;

String Humidity = "00000";
String Temper = "00000";

lv_obj_t *title_label;
lv_obj_t *temp_label;
lv_obj_t *humi_label;
String Humidity_text;
String Temper_test;

// Flags to check whether new temperature and humidity readings are available
boolean newTemperature = false;
boolean newHumidity = false;
boolean newLEDState = false;

int flag = 2;

#define LV_BUF_SIZE (ESP_PANEL_LCD_H_RES * 20)

#define RGB_1 "RGBKey"
BlinkerRGB WS2812(RGB_1);

#define PIN 4
#define NUMPIXELS 1
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_RGB + NEO_KHZ800);

uint8_t colorR, colorG, colorB;

uint8_t colorW; // 获取亮度
uint8_t colorT; // 获取色温
uint8_t cold;   // 白光输出值
uint8_t warm;   // 黄光输出值

bool wsState;
bool COLORM;   // 彩灯模式
bool READINGM; // 阅读模式
uint8_t wsMode = BLINKER_CMD_MIOT_DAY;

/*定义信号量*/
SemaphoreHandle_t lvgl_mux = NULL; // LVGL mutex

/*线程入口声明*/
void TaskAPPStart();
void ThreadBlinkerEntry(void *pvParameters); // Binker线程入口
void ThreadLVGLEntry(void *pvParameters);    // LVGL线程入口
void ThreadSensorEntry(void *pvParameters);// Sensor线程入口

/*定义线程句柄*/
TaskHandle_t ThreadBlinker; // Blinker线程
TaskHandle_t ThreadLVGL;    // LVGL线程
TaskHandle_t ThreadSensor;// Sensor线程

void pixelShow() // RGB控制函数
{
    pixels.setBrightness(colorW);

    for (int i = 0; i &lt; NUMPIXELS; i++)
    {
      pixels.setPixelColor(i, colorR, colorG, colorB);
    }
    pixels.show();
}

void LedControl(float x, int y) // CW控制函数(X:亮度、Y:色温)
{
    y = 100 - y;
    cold = x / 100 * y;         // cold_tmp是PWM冷灯珠的占空比
    warm = x / 100 * (100 - y); // warm_tmp是PWM冷灯珠的占空比:
}

void ws2812_callback(uint8_t r_value, uint8_t g_value, uint8_t b_value, uint8_t bright_value) // RGB2812回调函数
{
    digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
    BLINKER_LOG("R value: ", r_value);
    BLINKER_LOG("G value: ", g_value);
    BLINKER_LOG("B value: ", b_value);
    BLINKER_LOG("Rrightness value: ", bright_value);

    colorR = r_value;
    colorG = g_value;
    colorB = b_value;
    colorW = bright_value;

    pixelShow();
}

uint32_t getColor()
{
    uint32_t color = colorR &lt;&lt; 16 | colorG &lt;&lt; 8 | colorB;

    return color;
}

void miotPowerState(const String &amp;state) // 用户自定义电源类操作的回调函数:
{
    BLINKER_LOG("need set power state: ", state);

    if (state == BLINKER_CMD_ON)
    {
      digitalWrite(LED_BUILTIN, HIGH);

      BlinkerMIOT.powerState("on");
      BlinkerMIOT.print();

      wsState = true;

      if (colorW == 0)
            colorW = 255;
    }
    else if (state == BLINKER_CMD_OFF)
    {
      digitalWrite(LED_BUILTIN, LOW);

      BlinkerMIOT.powerState("off");
      BlinkerMIOT.print();

      wsState = false;

      colorW = 0;
    }

    pixelShow();
}

void miotColor(int32_t color) // 用户自定义颜色设置的回调函数:
{
    BLINKER_LOG("need set color: ", color);

    colorR = color &gt;&gt; 16 &amp; 0xFF;
    colorG = color &gt;&gt; 8 &amp; 0xFF;
    colorB = color &amp; 0xFF;

    BLINKER_LOG("colorR: ", colorR, ", colorG: ", colorG, ", colorB: ", colorB);

    pixelShow();

    BlinkerMIOT.color(color);
    BlinkerMIOT.print();
}

void miotMode(uint8_t mode) // 用户自定义模式设置的回调函数:
{
    BLINKER_LOG("need set mode: ", mode);

    if (mode == BLINKER_CMD_MIOT_DAY)
    { // 日光(10,25,41)
      // Your mode function
      COLORM = 0;
      colorR = 10;
      colorG = 255;
      colorB = 41;
    }
    else if (mode == BLINKER_CMD_MIOT_NIGHT)
    { // 月光 自定义
      // Your mode function
      COLORM = 0;
      COLORM = 0;
      colorR = 0;
      colorG = 0;
      colorB = 0;
    }
    else if (mode == BLINKER_CMD_MIOT_COLOR)
    { // 彩光
      // Your mode function
      COLORM = 1;
    }
    else if (mode == BLINKER_CMD_MIOT_WARMTH)
    { // 温馨
      // Your mode function
      COLORM = 0;
      colorR = 10;
      colorG = 255;
      colorB = 41;
    }
    else if (mode == BLINKER_CMD_MIOT_TV)
    { // 电视模式
      // Your mode function
      COLORM = 0;
    }
    else if (mode == BLINKER_CMD_MIOT_READING)
    { // 阅读模式
      // Your mode function
      COLORM = 0;
      colorR = 0;
      colorG = 0;
      colorB = 0;
    }
    else if (mode == BLINKER_CMD_MIOT_COMPUTER)
    { // 电脑模式
      // Your mode function
      COLORM = 0;
      colorR = 0;
      colorG = 0;
      colorB = 0;
      LedControl(colorW, colorT);
    }

    wsMode = mode;

    BlinkerMIOT.mode(mode);
    BlinkerMIOT.print();
}

void miotBright(const String &amp;bright) // 用户自定义亮度控制的回调函数:
{
    BLINKER_LOG("need set brightness: ", bright);

    colorW = bright.toInt();

    BLINKER_LOG("now set brightness: ", colorW);

    pixelShow();

    BlinkerMIOT.brightness(colorW);
    BlinkerMIOT.print();
}

void miotColoTemp(int32_t colorTemp) // 用户自定义色温控制的回调函数:
{
    BLINKER_LOG("need set colorTemperature: ", colorTemp);
    ;

    BLINKER_LOG("需要设置色温: ", colorTemp);
    colorT = map(colorTemp, 1000, 10000, 0, 100);
    BlinkerMIOT.colorTemp(colorT);
    BlinkerMIOT.print();
}

void miotQuery(int32_t queryCode) // 用户自定义设备查询的回调函数:
{
    BLINKER_LOG("MIOT Query codes: ", queryCode);

    switch (queryCode)
    {
    case BLINKER_CMD_QUERY_ALL_NUMBER:
      BLINKER_LOG("MIOT Query All");
      BlinkerMIOT.powerState(wsState ? "on" : "off");
      BlinkerMIOT.color(0);
      BlinkerMIOT.mode(0);
      BlinkerMIOT.colorTemp(1000);
      BlinkerMIOT.brightness(1);
      BlinkerMIOT.print();
      break;
    case BLINKER_CMD_QUERY_POWERSTATE_NUMBER:
      BLINKER_LOG("MIOT Query Power State");
      BlinkerMIOT.powerState(wsState ? "on" : "off");
      BlinkerMIOT.print();
      break;
    case BLINKER_CMD_QUERY_COLOR_NUMBER:
      BLINKER_LOG("MIOT Query Color");
      BlinkerMIOT.color(0);
      BlinkerMIOT.print();
      break;
    case BLINKER_CMD_QUERY_MODE_NUMBER:
      BLINKER_LOG("MIOT Query Mode");
      BlinkerMIOT.mode(0);
      BlinkerMIOT.print();
      break;
    case BLINKER_CMD_QUERY_COLORTEMP_NUMBER:
      BLINKER_LOG("MIOT Query ColorTemperature");
      BlinkerMIOT.colorTemp(1000);
      BlinkerMIOT.print();
      break;
    case BLINKER_CMD_QUERY_BRIGHTNESS_NUMBER:
      BLINKER_LOG("MIOT Query Brightness");
      BlinkerMIOT.brightness(1);
      BlinkerMIOT.print();
      break;
    default:
      BlinkerMIOT.powerState(wsState ? "on" : "off");
      BlinkerMIOT.color(0);
      BlinkerMIOT.mode(0);
      BlinkerMIOT.colorTemp(1000);
      BlinkerMIOT.brightness(1);
      BlinkerMIOT.print();
      break;
    }
}

void dataRead(const String &amp;data)
{
    BLINKER_LOG("Blinker readString: ", data);

    Blinker.vibrate();

    uint32_t BlinkerTime = millis();

    Blinker.print("millis", BlinkerTime);
}

#if ESP_PANEL_LCD_BUS_TYPE == ESP_PANEL_BUS_TYPE_RGB
/* Display flushing */
void my_disp_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p)
{
    panel-&gt;getLcd()-&gt;drawBitmap(area-&gt;x1, area-&gt;y1, area-&gt;x2 + 1, area-&gt;y2 + 1, color_p);
    lv_disp_flush_ready(disp);
}
#endif

#if ESP_PANEL_USE_LCD_TOUCH
/* Read the touchpad */
void my_touchpad_read(lv_indev_drv_t *indev, lv_indev_data_t *data)
{
    panel-&gt;getLcdTouch()-&gt;readData();

    bool touched = panel-&gt;getLcdTouch()-&gt;getTouchState();
    if (!touched)
    {
      data-&gt;state = LV_INDEV_STATE_REL;
    }
    else
    {
      TouchPoint point = panel-&gt;getLcdTouch()-&gt;getPoint();

      data-&gt;state = LV_INDEV_STATE_PR;
      /*Set the coordinates*/
      data-&gt;point.x = point.x;
      data-&gt;point.y = point.y;

      // Serial.printf("Touch point: x %d, y %d\n", point.x, point.y);
    }
}
#endif

bool lv_port_lock(uint32_t timeout_ms)
{
    const TickType_t timeout_ticks = (timeout_ms == 0) ? portMAX_DELAY : pdMS_TO_TICKS(timeout_ms);
    return xSemaphoreTakeRecursive(lvgl_mux, timeout_ticks) == pdTRUE;
}

void lv_port_unlock(void)
{
    xSemaphoreGiveRecursive(lvgl_mux);
}

void event_handler(lv_event_t *e)
{
    lv_event_code_t code = lv_event_get_code(e);

    if (code == LV_EVENT_CLICKED)
    {
      LV_LOG_USER("Clicked");
    }
    else if (code == LV_EVENT_VALUE_CHANGED)
    {
      LV_LOG_USER("Toggled");
    }
}

void lv_example_btn_1(void)
{
    Temper_test = "Temperature: ";
    Temper_test += Temper;
    Temper_test += "'C";
   
    Humidity_text = "Humidity: ";
    Humidity_text += Humidity;
    Humidity_text += "%";

   

    lv_obj_t* title = lv_obj_create(lv_scr_act());

    lv_obj_set_size(title, 480, 120);
    lv_obj_set_style_bg_color(title, lv_color_hex(0x00FF00), LV_STATE_DEFAULT);
    title_label = lv_label_create(title);
    static char title_str[] = "Indoor Lighting System";
    lv_label_set_text(title_label, title_str);
    lv_obj_align(title_label, LV_ALIGN_CENTER, 0, 0);
    lv_obj_set_style_text_font(title_label, &amp;lv_font_montserrat_36, LV_STATE_DEFAULT);

    //*温度 * /
    lv_obj_t* temp = lv_obj_create(lv_scr_act());
    lv_obj_set_style_bg_color(temp, lv_color_hex(0x00FF00), LV_STATE_DEFAULT);
    lv_obj_set_size(temp, 480, 80);
    lv_obj_set_pos(temp, 0, 110);
    temp_label = lv_label_create(temp);
    // lv_label_set_text(temp_label, Temper_test.c_str());

    lv_label_set_text(temp_label, Temper_test.c_str());
    lv_obj_align(temp_label, LV_ALIGN_OUT_LEFT_MID, 0, 0);
    lv_obj_set_style_text_font(temp_label, &amp;lv_font_montserrat_30, LV_STATE_DEFAULT);

    /*湿度*/
    lv_obj_t* humi = lv_obj_create(lv_scr_act());
    lv_obj_set_style_bg_color(humi, lv_color_hex(0x0000FF), LV_STATE_DEFAULT);
    lv_obj_set_size(humi, 480, 80);
    lv_obj_set_pos(humi, 0, 180);
    humi_label = lv_label_create(humi);
    // lv_label_set_text(humi_label, Humidity_text.c_str());

    lv_label_set_text(humi_label, Humidity_text.c_str());
    lv_obj_align(humi_label, LV_ALIGN_OUT_LEFT_MID, 0, 0);
    lv_obj_set_style_text_font(humi_label, &amp;lv_font_montserrat_30, LV_STATE_DEFAULT);
}

///////////////////////////蓝牙相关//////////////////////////////////

// Callback function that gets called, when another device's advertisement has been received
class MyAdvertisedDeviceCallbacks : public BLEAdvertisedDeviceCallbacks
{
    void onResult(BLEAdvertisedDevice advertisedDevice)
    {
      if (advertisedDevice.getName() == bleServerName)
      {                                                                   // Check if the name of the advertiser matches
            advertisedDevice.getScan()-&gt;stop();                           // Scan can be stopped, we found what we are looking for
            pServerAddress = new BLEAddress(advertisedDevice.getAddress()); // Address of advertiser is the one we need
            doConnect = true;                                             // Set indicator, stating that we are ready to connect
            Serial.println("Device found. Connecting!");
      }
    }
};

// When the BLE Server sends a new temperature reading with the notify property
static void temperatureNotifyCallback(BLERemoteCharacteristic *pBLERemoteCharacteristic,
                                    uint8_t *pData, size_t length, bool isNotify)
{
    // store temperature value
    temperatureChar = (char *)pData;
    newTemperature = true;
}

// When the BLE Server sends a new humidity reading with the notify property
static void humidityNotifyCallback(BLERemoteCharacteristic *pBLERemoteCharacteristic,
                                 uint8_t *pData, size_t length, bool isNotify)
{
    // store humidity value
    humidityChar = (char *)pData;
    newHumidity = true;
   // Serial.print(newHumidity);
}

// When the BLE Server sends a new humidity reading with the notify property
static void LEDStateNotifyCallback(BLERemoteCharacteristic *pBLERemoteCharacteristic,
                                 uint8_t *pData, size_t length, bool isNotify)
{
    // store humidity value
    LEDStateChar = (char *)pData;
    newLEDState = true;
//   Serial.print(newLEDState);
}

// Connect to the BLE Server that has the name, Service, and Characteristics
bool connectToServer(BLEAddress pAddress)
{
    BLEClient *pClient = BLEDevice::createClient();

    // Connect to the remove BLE Server.
    pClient-&gt;connect(pAddress);
    Serial.println(" - Connected to server");

    // Obtain a reference to the service we are after in the remote BLE server.
    BLERemoteService *pRemoteService = pClient-&gt;getService(bmeServiceUUID);
    if (pRemoteService == nullptr)
    {
      Serial.print("Failed to find our service UUID: ");
      Serial.println(bmeServiceUUID.toString().c_str());
      return (false);
    }

    // Obtain a reference to the characteristics in the service of the remote BLE server.
    temperatureCharacteristic = pRemoteService-&gt;getCharacteristic(temperatureCharacteristicUUID);
    humidityCharacteristic = pRemoteService-&gt;getCharacteristic(humidityCharacteristicUUID);
    LEDStateCharacteristic = pRemoteService-&gt;getCharacteristic(LEDCharacteristicUUID);

    if (temperatureCharacteristic == nullptr || humidityCharacteristic == nullptr || LEDStateCharacteristic == nullptr)
    {
      Serial.print("Failed to find our characteristic UUID");
      return false;
    }
    Serial.println(" - Found our characteristics");

    // Assign callback functions for the Characteristics
    temperatureCharacteristic-&gt;registerForNotify(temperatureNotifyCallback);
    humidityCharacteristic-&gt;registerForNotify(humidityNotifyCallback);
    LEDStateCharacteristic-&gt;registerForNotify(LEDStateNotifyCallback);
    return true;
}

void Display_init()
{
    String LVGL_Arduino = "Hello LVGL! ";
    LVGL_Arduino += String('V') + lv_version_major() + "." + lv_version_minor() + "." + lv_version_patch();

    Serial.println(LVGL_Arduino);
    Serial.println("I am ESP32_Display_Panel");

    panel = new ESP_Panel();

    /* Initialize LVGL core */
    lv_init();

    /* Initialize LVGL buffers */
    static lv_disp_draw_buf_t draw_buf;
    /* Using double buffers is more faster than single buffer */
    /* Using internal SRAM is more fast than PSRAM (Note: Memory allocated using `malloc` may be located in PSRAM.) */
    uint8_t *buf = (uint8_t *)heap_caps_calloc(1, LV_BUF_SIZE * sizeof(lv_color_t), MALLOC_CAP_INTERNAL);
    assert(buf);
    lv_disp_draw_buf_init(&amp;draw_buf, buf, NULL, LV_BUF_SIZE);

    /* Initialize the display device */
    static lv_disp_drv_t disp_drv;
    lv_disp_drv_init(&amp;disp_drv);
    /* Change the following line to your display resolution */
    disp_drv.hor_res = ESP_PANEL_LCD_H_RES;
    disp_drv.ver_res = ESP_PANEL_LCD_V_RES;
    disp_drv.flush_cb = my_disp_flush;
    disp_drv.draw_buf = &amp;draw_buf;
    lv_disp_drv_register(&amp;disp_drv);

#if ESP_PANEL_USE_LCD_TOUCH
    /* Initialize the input device */
    static lv_indev_drv_t indev_drv;
    lv_indev_drv_init(&amp;indev_drv);
    indev_drv.type = LV_INDEV_TYPE_POINTER;
    indev_drv.read_cb = my_touchpad_read;
    lv_indev_drv_register(&amp;indev_drv);
#endif

    /* There are some extral initialization for ESP32-S3-LCD-EV-Board */
#ifdef ESP_PANEL_BOARD_ESP32_S3_LCD_EV_BOARD
    /* Initialize IO expander */
    ESP_IOExpander *expander = new ESP_IOExpander_TCA95xx_8bit(ESP_PANEL_LCD_TOUCH_BUS_HOST_ID, ESP_IO_EXPANDER_I2C_TCA9554_ADDRESS_000, ESP_PANEL_LCD_TOUCH_I2C_IO_SCL, ESP_PANEL_LCD_TOUCH_I2C_IO_SDA);
    expander-&gt;init();
    expander-&gt;begin();
    /* Add into panel for 3-wire SPI */
    panel-&gt;addIOExpander(expander);
    /* For the newest version sub board, need to set `ESP_PANEL_LCD_RGB_IO_VSYNC` to high before initialize LCD */
    pinMode(ESP_PANEL_LCD_RGB_IO_VSYNC, OUTPUT);
    digitalWrite(ESP_PANEL_LCD_RGB_IO_VSYNC, HIGH);
#endif
    /* Initialize bus and device of panel */
    panel-&gt;init();
#if ESP_PANEL_LCD_BUS_TYPE != ESP_PANEL_BUS_TYPE_RGB
    /* Register a function to notify LVGL when the panel is ready to flush */
    /* This is useful for refreshing the screen using DMA transfers */
    panel-&gt;getLcd()-&gt;setCallback(notify_lvgl_flush_ready, &amp;disp_drv);
#endif
    /* Start panel */
    panel-&gt;begin();

}

void Bluetooth_Init()
{

    Serial.println("Starting Arduino BLE Client application...");

    // Init BLE device
    BLEDevice::init("");
    delay(1000);
    // Retrieve a Scanner and set the callback we want to use to be informed when we
    // have detected a new device.Specify that we want active scanning and start the
    // scan to run for 30 seconds.
    BLEScan *pBLEScan = BLEDevice::getScan();
    pBLEScan-&gt;setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
    pBLEScan-&gt;setActiveScan(true);
    pBLEScan-&gt;start(2);
    delay(1000);
}

void Blinker_Init()
{
    /*Bllier 初始化*/
    BLINKER_DEBUG.stream(Serial);
    BLINKER_DEBUG.debugAll();

    pinMode(LED_BUILTIN, OUTPUT);
    digitalWrite(LED_BUILTIN, LOW);

    Blinker.begin(auth, ssid, pswd);
    Blinker.attachData(dataRead);

    BlinkerMIOT.attachPowerState(miotPowerState);
    BlinkerMIOT.attachColor(miotColor);
    BlinkerMIOT.attachMode(miotMode);
    BlinkerMIOT.attachBrightness(miotBright);
    BlinkerMIOT.attachColorTemperature(miotColoTemp);
    BlinkerMIOT.attachQuery(miotQuery);

    colorR = 255;
    colorG = 255;
    colorB = 255;
    colorW = 0;
    colorT = 0;
    wsState = true;

    pixels.begin();
    pixels.setBrightness(colorW);
    WS2812.attach(ws2812_callback);
    pixelShow();
}

/*======================================= TaskAPPStart ====================================*/
/*
* @brief: 启动创建任务
* @param:none
* @retval:none
*/
void TaskAPPStart()
{
    /*创建Blinker线程*/
    BaseType_t status;
    status = xTaskCreatePinnedToCore(
      (TaskFunction_t)ThreadBlinkerEntry,// Weather线程入口
      (const char *const)"Thread_Blinker", // 线程名称
      (const uint32_t)4096 * 2,            // 线程栈
      (void *const)NULL,                   // Weather线程入口参数
      (UBaseType_t)6,                      // 线程优先级 0-24 数值越大优先级越高
      (TaskHandle_t *)&amp;ThreadBlinker,      // 线程句柄
      (const BaseType_t)APP_CPU_NUM);      // 指定内核1
    if (status == pdPASS)
    {
      Serial.println("Blinker线程创建成功...");
    }
    else
    {
      Serial.println("Blinker线程创建失败...");
    }

    /*创建Sensor线程*/
    status = xTaskCreatePinnedToCore(
      (TaskFunction_t)ThreadSensorEntry,// Sensor线程入口
      (const char *const)"Thread_Sensor", // 线程名称
      (const uint32_t)4096 * 1,         // 线程栈
      (void *const)NULL,                  // Sensor线程入口参数
      (UBaseType_t)6,                     // 线程优先级 0-24 数值越大优先级越高
      (TaskHandle_t *)&amp;ThreadSensor,      // 线程句柄
      (const BaseType_t)PRO_CPU_NUM);   // 指定内核0
    if (status == pdPASS)
    {
      Serial.println("Sensor线程创建成功...");
    }
    else
    {
      Serial.println("Sensor线程创建失败...");
    }

    /* Create a task to run the LVGL task periodically */
    lvgl_mux = xSemaphoreCreateRecursiveMutex();
    //   xTaskCreate(lvgl_task, "lvgl", 8192, NULL, 1, NULL);

    /**
   * To avoid errors caused by multiple tasks simultaneously accessing LVGL,
   * should acquire a lock before operating on LVGL.
   */
   lv_port_lock(0);

   lv_example_btn_1();
    // lv_demo_music();            // NOK
    /*创建LVGL线程*/
    status = xTaskCreatePinnedToCore(
      (TaskFunction_t)ThreadLVGLEntry,// OLED线程
      (const char *const)"Thread_LVGL", // 线程名称
      (const uint32_t)4096 * 2,         // 线程栈
      (void *const)NULL,                // OLED线程入口参数
      (UBaseType_t)8,                   // 线程优先级 0-24 数值越大优先级越高
      (TaskHandle_t *)&amp;ThreadLVGL,      // 线程句柄
      (const BaseType_t)PRO_CPU_NUM);   // 指定内核1
    if (status == pdPASS)
    {
      Serial.println("LVGL线程创建成功...");
    }
    else
    {
      Serial.println("LVGL线程创建失败...");
    }
    /**
   * Try an example. Don't forget to uncomment header.
   * See all the examples online: https://docs.lvgl.io/master/examples.html
   * source codes: https://github.com/lvgl/lvgl/tree/e7f88efa5853128bf871dde335c0ca8da9eb7731/examples
   */


   lv_port_unlock();

    delay(1000);
}


/*
* @brief:Blinker线程入口
* @param:none
* @retval:none
*/
void ThreadBlinkerEntry(void *pvParameters)
{
    //   xSemaphoreTake(sem_Blinker, portMAX_DELAY);

    while (1)
    {


         if (LEDStateChar == 'O' &amp;&amp; LEDStateChar == 'N' &amp;&amp; flag == 2)
            {
                Serial.println("OK");    //起床打开灯
                colorR = 255;
                colorG = 255;
                colorB = 255;
                colorW = 100;

                pixelShow();
                delay(100);
                wsState = true;

                flag = 1;
                /* code */
            }
            else if(LEDStateChar == 'O' &amp;&amp; LEDStateChar == 'F' &amp;&amp; LEDStateChar == 'F' &amp;&amp; flag == 1)
            {
                Serial.println("NO!");    //躺下关闭灯
                colorW = 0;
         
                pixelShow();
                delay(100);
                wsState = false;
                flag = 2;
                /* code */
            }
            else
            {
               // flag = 2;
            }
            Blinker.run();

      vTaskDelay(1 / portTICK_PERIOD_MS);
    }
}

/*
* @brief:LVGL线程入口
* @param:none
* @retval:none
*/
void ThreadLVGLEntry(void *pvParameter)
{
    // xSemaphoreTake(sem_LVGL, portMAX_DELAY);
    while (1)
    {
      lv_port_lock(0);

      Temper_test = "Temperature: ";
      Temper_test += Temper;
      Temper_test += "'C";

      Humidity_text = "Humidity: ";
      Humidity_text += Humidity;
      Humidity_text += "%";
      lv_label_set_text(temp_label, Temper_test.c_str());
      lv_label_set_text(humi_label, Humidity_text.c_str());
      lv_task_handler();
   //   lv_timer_handler(); /* let the GUI do its work */
      lv_port_unlock();
   //   Serial.println("updata");   
      delay(1000);
    }
}

/*
* @brief:Sensor线程入口
* @param:none
* @retval:none
*/
void ThreadSensorEntry(void *pvParameters)
{
    while (1)
    {
      // Serial.print("Temperature:");

      if (doConnect == true)
      {
            if (connectToServer(*pServerAddress))
            {
                Serial.println("We are now connected to the BLE Server.");
                // Activate the Notify property of each Characteristic
                temperatureCharacteristic-&gt;getDescriptor(BLEUUID((uint16_t)0x2902))-&gt;writeValue((uint8_t *)notificationOn, 2, true);
                humidityCharacteristic-&gt;getDescriptor(BLEUUID((uint16_t)0x2902))-&gt;writeValue((uint8_t *)notificationOn, 2, true);
                LEDStateCharacteristic-&gt;getDescriptor(BLEUUID((uint16_t)0x2902))-&gt;writeValue((uint8_t *)notificationOn, 2, true);
                connected = true;
            }
            else
            {
                Serial.println("We have failed to connect to the server; Restart your device to scan for nearby BLE server again.");
            }
            doConnect = false;
      }
      // if new temperature readings are available, print in the OLED
      if (newTemperature &amp;&amp; newHumidity &amp;&amp; newLEDState)
      {
            newTemperature = false;
            newHumidity = false;
            newLEDState = false;
            
            Temper = temperatureChar.substring(0, 6);


            // Temperature Celsius
            // Serial.print("Temperature:");
            // Serial.print(temperatureChar);
            // Serial.println("C");

            // Serial.print("Temperature:");
            // Serial.print(Temper);
            // Serial.println("C");


            // // display humidity
            // Serial.print("Humidity:");
            // Serial.print(humidityChar);
            // Serial.println("%");


            Humidity = humidityChar.substring(0, 6);


            // Temperature Celsius

            // Serial.print("Humidity:");
            // Serial.print(Humidity);
            // Serial.println("%");

            // // display LEDState
            // Serial.print("LEDState:");
            // Serial.println(LEDStateChar);
         
            
            
      }
      vTaskDelay(10 / portTICK_PERIOD_MS);
    }
}

void setup()
{

    Serial.begin(115200); /* prepare for possible serial debug */

    Blinker_Init();

    Display_init();

    Bluetooth_Init();

    TaskAPPStart();

    Serial.println("Setup done");
}

void loop()
{

    //   Serial.println("Loop");
    //sleep(1);
}
</code></pre>

<p>&nbsp;</p>

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

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

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

<p align="center">图2.4 服务端代码流程</p>

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

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

<p align="center">图2.5 传感器端流程图</p>

<ol start="3">
        <li>作品资料</li>
</ol>

<p>作品源码:</p>

<p><a href="https://bbs.eeworld.com.cn/my/home.php?cur=myhome&amp;act=download" target="_blank">https://bbs.eeworld.com.cn/my/home.php?cur=myhome&amp;act=download</a></p>

<p>&nbsp;</p>

<p>作品演示视频:</p>

<p><iframe allowfullscreen="true" frameborder="0" height="450" src="//player.bilibili.com/player.html?bvid=1FA1bYeEcL&amp;page=1" style="background:#eee;margin-bottom:10px;" width="700"></iframe><br />
4、项目总结</p>

<p>&nbsp; &nbsp; &nbsp;<a href="https://bbs.eeworld.com.cn/thread-1290998-1-1.html" target="_blank">https://bbs.eeworld.com.cn/thread-1290998-1-1.html</a><br />
&nbsp; &nbsp; &nbsp;<a href="https://bbs.eeworld.com.cn/thread-1291483-1-1.html" target="_blank">https://bbs.eeworld.com.cn/thread-1291483-1-1.html</a><br />
&nbsp; &nbsp; &nbsp;<a href="https://bbs.eeworld.com.cn/thread-1292193-1-1.html" target="_blank">https://bbs.eeworld.com.cn/thread-1292193-1-1.html</a><br />
&nbsp; &nbsp;&nbsp;<a href="https://bbs.eeworld.com.cn/thread-1295979-1-1.html" target="_blank">https://bbs.eeworld.com.cn/thread-1295979-1-1.html</a></p>

<p>&nbsp;</p>

<p>&nbsp;</p>

<p>感谢EEworld提供的平台,有机会向各位朋友分享自己的DIY成果,谢谢!!!</p>

秦天qintian0303 发表于 2024-10-27 12:27

<p>ESP32 S3做服务器是不是有点性能弱啊&nbsp; &nbsp;</p>

mingzhe123 发表于 2024-10-27 13:27

秦天qintian0303 发表于 2024-10-27 12:27
ESP32 S3做服务器是不是有点性能弱啊&nbsp; &nbsp;

<p>数据量不大。功能比较初级。如果在家里布局智能家居,这个只能作为一个子节点</p>
页: [1]
查看完整版本: 【2024 DigiKey 创意大赛】室内智能照明灯设计-完结篇