mingzhe123

  • 2024-10-27
  • 回复了主题帖: 【2024 DigiKey 创意大赛】室内智能照明灯设计-完结篇

    秦天qintian0303 发表于 2024-10-27 12:27 ESP32 S3做服务器是不是有点性能弱啊    数据量不大。功能比较初级。如果在家里布局智能家居,这个只能作为一个子节点

  • 2024-10-26
  • 发表了主题帖: 【2024 DigiKey 创意大赛】室内智能照明灯设计-完结篇

    本帖最后由 mingzhe123 于 2024-10-29 20:27 编辑 【2024 DigiKey 创意大赛】室内智能照明灯设计 背景介绍 物联网技术是指通过互联网将各种设备、传感 器、控制器等连接在一起,形成一个能够实时互通信息的网络。物联网技术的基本原理是通过传感器采集设备产生的数据,并通过控制器进行处理和控制,最终将数据传输到互联网上,实现设备之间的智能交互。物联网技术的核心特点是实时性、数据共享、智能化和互联性。物联网技术的实时性意味着设备和传感器能够即时收集和传输数据,使得用户可以实时了解设备状态和环境情况。数据共享可 以使不同设备之间共享数据,实现更高效的资源利用和协同工作。智能化指的是物联网设备具备处理和分析数据的能力,可以根据用户需求自动调整设备工作模式。互联性表示物联网技术可以实现设备与设备、设备与人之间的无缝连接和交互,实现更强大的功能和用户体验。物联网技术广泛应用于智能家居、智能交通、智慧城市等领域,为人们的生活带来便利和智能化。 室内智能照明灯设计 室内照明灯系统硬件如图2.1所示分,为三部分:基于ESP32 S3的服务端、基于ESP32 PICO的传感器端与小爱音箱。其中,ESP32 S3服务端使用的是乐鑫的ESP32 S3 LCD EV开发板。如图2.2所示,主要负责与小爱音箱通信,接收传感器端数据、LCD实时显示传感器数据以及灯光的控制;ESP32 PICO传感器端为单独设计的ESP32板卡,如图2.3所示,主要功能为采集MPU6050数据与SHT30数据应通过BLE传输到服务端;小爱音箱主要是与服务端实现语音交互功能。   图2.1 系统架构图   图2.2ESP32 S3 LCD EV 图2.3 传感器端板块   室内照明灯系统软件为服务端代码与传感器端代码。服务端代码基于Arduino并通过FreeRTOS实现多任务处理,如图2.4所示。传感器端则基于Arduino框架完成传感器数据采集与蓝牙传输,如图2.5所示。      服务端代码:      #include "BLEDevice.h" #include <Arduino.h> #include <lvgl.h> #include <ESP_Panel_Library.h> #include <ESP_IOExpander_Library.h> // #include <examples/lv_examples.h> //#include <demos/lv_demos.h> #define BLINKER_WIFI #define BLINKER_MIOT_LIGHT #include <Blinker.h> #include <Adafruit_NeoPixel.h> 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 < 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 << 16 | colorG << 8 | colorB; return color; } void miotPowerState(const String &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 >> 16 & 0xFF; colorG = color >> 8 & 0xFF; colorB = color & 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 &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 &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->getLcd()->drawBitmap(area->x1, area->y1, area->x2 + 1, area->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->getLcdTouch()->readData(); bool touched = panel->getLcdTouch()->getTouchState(); if (!touched) { data->state = LV_INDEV_STATE_REL; } else { TouchPoint point = panel->getLcdTouch()->getPoint(); data->state = LV_INDEV_STATE_PR; /*Set the coordinates*/ data->point.x = point.x; data->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, &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, &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, &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()->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->connect(pAddress); Serial.println(" - Connected to server"); // Obtain a reference to the service we are after in the remote BLE server. BLERemoteService *pRemoteService = pClient->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->getCharacteristic(temperatureCharacteristicUUID); humidityCharacteristic = pRemoteService->getCharacteristic(humidityCharacteristicUUID); LEDStateCharacteristic = pRemoteService->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->registerForNotify(temperatureNotifyCallback); humidityCharacteristic->registerForNotify(humidityNotifyCallback); LEDStateCharacteristic->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(&draw_buf, buf, NULL, LV_BUF_SIZE); /* Initialize the display device */ static lv_disp_drv_t disp_drv; lv_disp_drv_init(&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 = &draw_buf; lv_disp_drv_register(&disp_drv); #if ESP_PANEL_USE_LCD_TOUCH /* Initialize the input device */ static lv_indev_drv_t indev_drv; lv_indev_drv_init(&indev_drv); indev_drv.type = LV_INDEV_TYPE_POINTER; indev_drv.read_cb = my_touchpad_read; lv_indev_drv_register(&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->init(); expander->begin(); /* Add into panel for 3-wire SPI */ panel->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->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->getLcd()->setCallback(notify_lvgl_flush_ready, &disp_drv); #endif /* Start panel */ panel->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->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks()); pBLEScan->setActiveScan(true); pBLEScan->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 *)&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 *)&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 *)&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[0] == 'O' && LEDStateChar[1] == 'N' && flag == 2) { Serial.println("OK"); //起床打开灯 colorR = 255; colorG = 255; colorB = 255; colorW = 100; pixelShow(); delay(100); wsState = true; flag = 1; /* code */ } else if(LEDStateChar[0] == 'O' && LEDStateChar[1] == 'F' && LEDStateChar[2] == 'F' && 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->getDescriptor(BLEUUID((uint16_t)0x2902))->writeValue((uint8_t *)notificationOn, 2, true); humidityCharacteristic->getDescriptor(BLEUUID((uint16_t)0x2902))->writeValue((uint8_t *)notificationOn, 2, true); LEDStateCharacteristic->getDescriptor(BLEUUID((uint16_t)0x2902))->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 && newHumidity && 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); }                                                   图2.4 服务端代码流程   图2.5 传感器端流程图 作品资料 作品源码: https://bbs.eeworld.com.cn/my/home.php?cur=myhome&act=download   作品演示视频: 4、项目总结      https://bbs.eeworld.com.cn/thread-1290998-1-1.html      https://bbs.eeworld.com.cn/thread-1291483-1-1.html      https://bbs.eeworld.com.cn/thread-1292193-1-1.html     https://bbs.eeworld.com.cn/thread-1295979-1-1.html     感谢EEworld提供的平台,有机会向各位朋友分享自己的DIY成果,谢谢!!!

  • 上传了资料: 【2024 DigiKey 创意大赛】室内智能照明灯设计代码与PCB文件

  • 2024-10-13
  • 发表了主题帖: 【2024 DigiKey 创意大赛】室内智能照明灯设计---进度篇3

    10.1假期后继续对室内照明灯的程序继续开发,完整了主题程序架构的设计,目前只剩下温度传感器与MPU6050程序未开发。整理架构采用FreeRtos系统,将整体功能分为不同的线程处理,保证整体功能的实时性。 。。。。。。本来也想将温度传感器加入其中,但是发现D6T-1A-2C的IO电平为5V,与ESP32开发板电平不兼容,故后期考虑采用HT-30温湿度传感器开发。     当前,系统已经集成LCD屏幕与小爱同学功能,具体程序如下: void UI_Init() { lv_obj_t *scr = lv_scr_act(); //创建scr lv_obj_set_pos(scr,0,0); lv_scr_load(scr); label_1 =lv_label_create(scr);//创建label lv_label_set_recolor(label_1,1);//颜色可变换 lv_label_set_long_mode(label_1,LV_LABEL_LONG_SCROLL_CIRCULAR);//设置滚动模式 lv_obj_set_pos(label_1,100,100);//设置位置 lv_obj_set_size(label_1,160,30);//设定大小 lv_label_set_text(label_1, "This is a GUI thread yes");//设定文本内容 label_2 =lv_label_create(scr);//创建labe2 lv_label_set_recolor(label_2,1);//颜色可变换 lv_label_set_long_mode(label_2,LV_LABEL_LONG_SCROLL_CIRCULAR);//设置滚动模式 lv_obj_set_pos(label_2,100,400);//设置位置 lv_obj_set_size(label_2,160,40);//设定大小 lv_label_set_text(label_2, "#ff0000 red#");//设定文本内容 } /** * [url=home.php?mod=space&uid=159083]@brief[/url] 初始化 * @param 无 * @retval 无 */ void My_Init() { Serial.begin(115200); Serial.println(title + " start"); /*Bllier 初始化*/ Serial.begin(115200); 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(); /* 屏幕初始化 */ Serial.println("Initialize panel device"); ESP_Panel *panel = new ESP_Panel(); panel->init(); #if LVGL_PORT_AVOID_TEAR // When avoid tearing function is enabled, configure the RGB bus according to the LVGL configuration ESP_PanelBus_RGB *rgb_bus = static_cast<ESP_PanelBus_RGB *>(panel->getLcd()->getBus()); rgb_bus->configRgbFrameBufferNumber(LVGL_PORT_DISP_BUFFER_NUM); rgb_bus->configRgbBounceBufferSize(LVGL_PORT_RGB_BOUNCE_BUFFER_SIZE); #endif panel->begin(); /* lvgl初始化 */ Serial.println("Initialize LVGL"); lvgl_port_init(panel->getLcd(), panel->getTouch()); UI_Init(); } /*======================================= TaskAPPStart ====================================*/ /* * @brief: 启动创建任务 * @param:none * @retval:none */ void TaskAPPStart() { // sem_Blinker = xSemaphoreCreateCounting(1, 0); // if (sem_Blinker == NULL) // { // Serial.println("Blinker信号量创建失败......"); // } // else // { // Serial.println("Blinker信号量创建成功......"); // } // sem_LVGL = xSemaphoreCreateCounting(1, 0); // if (sem_LVGL == NULL) // { // Serial.println("LVGL信号量创建失败......"); // } // else // { // Serial.println("LVGL信号量创建成功......"); // } /*创建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 *)&ThreadBlinker, //线程句柄 (const BaseType_t)APP_CPU_NUM); //指定内核1 if (status == pdPASS) { Serial.println("Blinker线程创建成功..."); } else { Serial.println("Blinker线程创建失败..."); } /*创建LVGL线程*/ status = xTaskCreatePinnedToCore( (TaskFunction_t)ThreadLVGLEntry, //OLED线程 (const char *const) "Thread_LVGL", //线程名称 (const uint32_t)4096 * 8, //线程栈 (void *const)NULL, //OLED线程入口参数 (UBaseType_t)2, //线程优先级 0-24 数值越大优先级越高 (TaskHandle_t *)&ThreadLVGL, //线程句柄 (const BaseType_t)APP_CPU_NUM); //指定内核1 if (status == pdPASS) { Serial.println("LVGL线程创建成功..."); } else { Serial.println("LVGL线程创建失败..."); } /*连接网络提示定时器*/ TimeAlarmLED = xTimerCreate( "TIM_Alarm_LED", //定时器名称 pdMS_TO_TICKS(100), //定时器定时时间 pdTRUE, //pdTRUE = 周期性 , pdFALSE = 一次性 0, //定时器ID TIMAlarmLEDEntry); //定时器回调函数 xTimerStart(TimeAlarmLED, 0); delay(1000); } /* * @brief:Blinker线程入口 * @param:none * @retval:none */ void ThreadBlinkerEntry(void *pvParameters) { // xSemaphoreTake(sem_Blinker, portMAX_DELAY); while (1) { Blinker.run(); for(int i = 0; i < NUMPIXELS; i++){ pixels.setPixelColor(i, colorR, colorG, colorB); } pixels.show(); LedControl(colorW,colorT); // Serial.println("===================== POST ====================="); vTaskDelay(pdMS_TO_TICKS(10)); } } /* * @brief:LVGL线程入口 * @param:none * @retval:none */ void ThreadLVGLEntry(void *pvParameters) { // xSemaphoreTake(sem_LVGL, portMAX_DELAY); ESP_LOGD(TAG, "Starting LVGL task"); uint32_t task_delay_ms = LVGL_PORT_TASK_MAX_DELAY_MS; while (1) { if (lvgl_port_lock(-1)) { task_delay_ms = lv_timer_handler(); lvgl_port_unlock(); } if (task_delay_ms > LVGL_PORT_TASK_MAX_DELAY_MS) { task_delay_ms = LVGL_PORT_TASK_MAX_DELAY_MS; } else if (task_delay_ms < LVGL_PORT_TASK_MIN_DELAY_MS) { task_delay_ms = LVGL_PORT_TASK_MIN_DELAY_MS; } vTaskDelay(pdMS_TO_TICKS(task_delay_ms)); } } /* * @brief:空闲线程入口 * @param:none * @retval:none */ void TIMAlarmLEDEntry(TimerHandle_t xTimer) { // digitalWrite(LED, !digitalRead(LED)); } void loop() { }  

  • 发表了日志: 【2024 DigiKey 创意大赛】室内智能照明灯设计---进度篇3

  • 2024-09-01
  • 发表了主题帖: 【2024 DigiKey 创意大赛】室内智能照明灯设计---进度篇2

    本帖最后由 mingzhe123 于 2024-9-1 16:24 编辑 有幸进阶得捷创意大赛,趁着周末,对当时的项目进行了一部分开发。目前进度已经完成RGB灯光控制,以及小爱音箱的控制。 下面是详细的代码: #define BLINKER_WIFI #define BLINKER_MIOT_LIGHT #include <Blinker.h> #include <Arduino.h> char auth[] = "044be84a71f9"; char ssid[] = "C_WIFI"; char pswd[] = "C88888888"; // Download Adafruit_NeoPixel library here: // https://github.com/adafruit/Adafruit_NeoPixel #include <Adafruit_NeoPixel.h> #define PIN 4 #define NUMPIXELS 1 Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_RGB + NEO_KHZ800); #define RGB_1 "RGBKey" BlinkerRGB WS2812(RGB_1); // BlinkerSlider Slider1(Slider_1); // BlinkerSlider Slider2(Slider_2); 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; void pixelShow() //RGB控制函数 { pixels.setBrightness(colorW); for(int i = 0; i < 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 slider1_callback(int32_t value) // { // //设置冷光亮度 // ledcWrite(2, value); // BLINKER_LOG("C value: ", value); // } // void slider2_callback(int32_t value) // { // //设置暖光亮度 // ledcWrite(1, value); // BLINKER_LOG("W value: ", value); // } 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 << 16 | colorG << 8 | colorB; return color; } void miotPowerState(const String & 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 >> 16 & 0xFF; colorG = color >> 8 & 0xFF; colorB = color & 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 & 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 & data) { BLINKER_LOG("Blinker readString: ", data); Blinker.vibrate(); uint32_t BlinkerTime = millis(); Blinker.print("millis", BlinkerTime); } void setup() { Serial.begin(115200); 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); // pinMode(14, OUTPUT); // digitalWrite(14, HIGH); // pinMode(15, OUTPUT); // digitalWrite(15, HIGH); colorR = 255; colorG = 255; colorB = 255; colorW = 0; colorT = 0; wsState = true; pixels.begin(); pixels.setBrightness(colorW); WS2812.attach(ws2812_callback); pixelShow(); // Slider1.attach(slider1_callback); // Slider2.attach(slider2_callback); } void loop() { Blinker.run(); for(int i = 0; i < NUMPIXELS; i++){ pixels.setPixelColor(i, colorR, colorG, colorB); } pixels.show(); LedControl(colorW,colorT); } 通过该代码可以实现点灯上位机软件对RGB灯光的控制,并可以通过小爱音箱调整RGB颜色、色温、亮度以及开关等;还可以通过小爱音箱控制不同的工作模式。  

  • 发表了日志: 【2024 DigiKey 创意大赛】室内智能照明灯设计---进度篇2

  • 2024-08-25
  • 发表了主题帖: 【2024 DigiKey 创意大赛】室内智能照明灯设计---进度篇_1

    收到室内智能照明灯设计的物料已经差不都熬了,趁着这个周末有时间赶紧跟各位大大汇报一下任务进度。 首先,整个智能灯的框架已经确认了。主要使用ESP32 Board同时控制温度传感器读取温度,并通过MPU6050与小爱同学控制RGB灯光的状态,其中小爱同学的控制主要使用点灯平台进行互联。具体架构如下:   对于小爱同学部分的代码直接参照点灯官网源码开发即可https://diandeng.tech/doc/getting-start-ble。 对于D6T-1A-02 的ARDUINO代码,则可直接参照GitHub的源码即可 https://github.com/omron-devhub/d6t-2jcieev01-arduino 好了,这周就进行这么多了,下周等D6T-1A-02的接插件到了开始代码调试。

  • 2024-08-19
  • 发表了主题帖: 【2024 DigiKey 创意大赛】室内智能照明灯设计---物料开箱

    时隔几天,设计的资料终于收到了,首先感谢DigiKey提供的物料,也感谢电子工程世界论坛的鼎立支持。 接下来就到激动人心的开箱环节了,哈哈哈。 确认过,DigiKey的包装就是给力   继续开开箱,内部包装也是给力,防静电袋,泡沫带,给力。   本次活动一共申请了2颗物料分别为ESP32开发板,屏幕非常给力。另一颗为欧姆龙的温度传感器。另外需要的陀螺仪我这边本身就有,接下来就利用esp32开发板、温度传感器与陀螺仪进行项目开发了。    

最近访客

< 1/1 >

统计信息

已有4人来访过

  • 芯积分:26
  • 好友:--
  • 主题:5
  • 回复:1

留言

你需要登录后才可以留言 登录 | 注册


现在还没有留言