零知開源——基于STM32F103RBT6的智能風扇控制系統設計與實現

??零知IDE 是一個真正屬于國人自己的開源軟件平臺,在開發效率上超越了Arduino平臺并且更加容易上手,大大降低了開發難度。零知開源在軟件方面提供了完整的學習教程和豐富示例代碼,讓不懂程序的工程師也能非常輕而易舉的搭建電路來創作產品,測試產品。快來動手試試吧!

?訪問零知實驗室,獲取更多實戰項目和教程資源吧!

www.lingzhilab.com

目錄

一、硬件連接部分

1.1 硬件清單

1.2 接線方案

1.3 具體接線圖

1.4 接線實物圖

二、關鍵代碼解析

2.1 主循環設計

2.2?紅外信號處理

2.3?顯示更新優化

2.4 風扇驅動控制

2.5 系統完整代碼

三、項目結果演示

3.1 操作流程

3.2 界面展示

3.3 視頻演示

四、JQC-3FF-S-Z工作原理

4.1 基本結構

4.2 動作機制

五、常見問題解答

Q1: 如何調整光控的靈敏度?

Q2: 如何修改定時時間?

Q3: 舵機轉動不流暢怎么辦?


(1)項目概述

????????本項目基于STM32F103RBT6主控芯片(零知標準板),設計并實現了一個功能豐富的智能風扇控制系統。融合了紅外遙控、自動光控、定時關閉、睡眠模式等多種智能控制方式。系統采用JQC-3FF-S-Z繼電器作為主要控制元件,通過紅外遙控器實現遠程控制,同時集成了光敏傳感器實現環境光線自適應控制。

(2)項目難點及解決方案

? ? ? ?問題描述:系統需要同時處理紅外信號接收、舵機控制、傳感器數據采集和顯示更新等多個任務。

解決方案:?采用基于millis()的時間管理方法,避免使用delay(),確保系統響應及時

一、硬件連接部分

1.1 硬件清單

組件名稱型號/規格數量備注
主控板零知標準板(STM32F103RBT6)1核心控制單元
繼電器模塊JQC-3FF-S-Z1控制風扇電源
TFT顯示屏ST7789 240x2401用戶界面顯示
紅外控制模塊IR Receiver紅外接收模塊1接收紅外信號
舵機SG901實現風扇搖頭功能
光敏電阻光敏電阻模塊1環境光線檢測
直流電機3.3V1被控對象

1.2 接線方案

? ? ? ? 注意:JQC-3FF-S-Z的D+接5V,其他器件電源接3.3V

組件零知標準板引腳說明
繼電器IN6繼電器控制引腳
紅外接收DATA3紅外信號輸入
舵機信號5舵機控制
TFT_SCL13顯示屏時鐘線
TFT_SDA11顯示屏數據輸入
TFT_CS10顯示屏片選
TFT_DC9顯示屏數據/命令
TFT_RST8顯示屏復位
光敏電阻OUT0光線傳感器信號

1.3 具體接線圖

? ? ? ? PS:直流電機的其中一極接3.3V電源,另一極接JQC-3FF-S-Z繼電器的COM公共端

1.4 接線實物圖

二、關鍵代碼解析

2.1 主循環設計

void loop() {// 處理紅外信號if (irrecv.decode(&results)) {handleIRCommand(results.value);irrecv.resume();redrawNeeded = true;}// 處理舵機擺動handleSwing();// 處理定時器handleTimer();// 處理睡眠模式handleSleepMode();// 讀取光線傳感器數據readLightSensor();// 自動模式處理if (operationMode == MODE_LIGHT_AUTO) {handleAutoMode();}// 更新顯示updateDisplay();delay(100); // 短暫延遲以減少CPU使用率
}

????????主循環采用非阻塞設計,通過狀態標志控制各功能的執行,確保系統響應及時。

2.2?紅外信號處理

void handleIRCommand(unsigned long value) {Serial.print("IR Code Received: 0x");Serial.println(value, HEX);switch(value) {case BTN_POWER:togglePower();break;// 其他按鍵處理...}
}

????????紅外信號處理函數通過switch-case結構解析不同按鍵的功能,代碼結構清晰易懂。

2.3?顯示更新優化

void updateDisplay() {// 只在需要時重繪if (!redrawNeeded) {// 對于定時器模式,每秒更新一次時間顯示if (operationMode == MODE_TIMER && timerActive) {unsigned long currentTime = millis();if (currentTime - lastTimerUpdate >= 1000) {lastTimerUpdate = currentTime;updateTimerDisplay();}}// 省略其他模式...return;}// 全屏刷新邏輯...
}

????????顯示更新函數通過redrawNeeded標志控制刷新頻率,避免不必要的屏幕刷新,提高系統效率。

2.4 風扇驅動控制

void turnOffFan() {digitalWrite(RELAY_PIN, HIGH);fanState = FAN_OFF;swingState = SWING_OFF; // 關閉風扇時也停止擺動timerActive = false; // 取消定時sleepActive = false; // 取消睡眠模式Serial.println("Fan Turned OFF");
}void turnOnFan() {digitalWrite(RELAY_PIN, LOW);fanState = FAN_ON;Serial.println("Fan Turned ON");
}void handleSwing() {if (swingState == SWING_OFF) return;unsigned long currentTime = millis();if (currentTime - lastSwingTime >= swingSpeed) {lastSwingTime = currentTime;// 擺動范圍 20-160 度static int direction = 1; // 1為增加角度,-1為減少角度swingAngle += direction;myservo.write(swingAngle);// 到達邊界時改變方向if (swingAngle >= 160 || swingAngle <= 20) {direction = -direction;}}
}

? ? ? ? JQC-3FF-S-Z繼電器模塊控制風扇電源并設置標志位

2.5 系統完整代碼

#include "IRremote.h"
#include "Servo.h"
#include <Adafruit_GFX.h>
#include <Adafruit_ST7789.h>// 引腳定義
#define IR_RECV_PIN 3     // 紅外接收 DAT 引腳
#define RELAY_PIN 6       // 繼電器控制引腳
#define SERVO_PIN 5       // 舵機控制引腳
#define TFT_CS 10         // TFT顯示屏片選引腳
#define TFT_DC 9          // TFT顯示屏數據/命令引腳
#define TFT_RST 8         // TFT顯示屏復位引腳
#define LIGHT_SENSOR A0   // 光敏電阻引腳// 紅外按鍵編碼
enum IR_CODES {BTN_POWER = 0xFF30CF,   // 按鍵1 - 電源開關BTN_SWING = 0xFF18E7,   // 按鍵2 - 搖頭開關BTN_TIMER_10 = 0xFF7A85, // 按鍵3 - 10秒定時BTN_TIMER_30 = 0xFF10EF, // 按鍵4 - 30秒定時BTN_MODE = 0xFF38C7,    // 按鍵5 - 模式切換BTN_SLEEP = 0xFF4AB5    // 按鍵8 - 睡眠模式
};// 系統狀態
enum FAN_STATE {FAN_OFF,FAN_ON
};enum SWING_STATE {SWING_OFF,SWING_ON
};enum OPERATION_MODE {MODE_NORMAL,MODE_LIGHT_AUTO,MODE_TIMER,MODE_SLEEP
};// 全局變量
IRreceiver irrecv(IR_RECV_PIN);
IRdecode_results results;
Servo myservo;
Adafruit_ST7789 tft = Adafruit_ST7789(TFT_CS, TFT_DC, TFT_RST);int fanState = FAN_OFF;
int swingState = SWING_OFF;
int operationMode = MODE_NORMAL;
int swingAngle = 90;     // 舵機角度
int swingSpeed = 15;     // 舵機速度 (ms延遲,值越小越快)
unsigned long lastSwingTime = 0;
unsigned long timerStartTime = 0;
unsigned long timerDuration = 0;
bool timerActive = false;
unsigned long sleepStartTime = 0;
unsigned long sleepDuration = 5 * 1000; // 8小時睡眠模式  8 * 60 * 60 * 1000
bool sleepActive = false;
int lightLevel = 0;
int lastLightLevel = 0;
unsigned long lastTimerUpdate = 0;
bool redrawNeeded = true;// 顯示區域定義
#define STATUS_AREA 40
#define DATA_AREA 80
#define LIGHT_THRESHOLD 500 // 光線閾值void setup() {Serial.begin(9600);// 初始化引腳pinMode(RELAY_PIN, OUTPUT);digitalWrite(RELAY_PIN, HIGH);  // 初始關閉繼電器// 初始化紅外接收和舵機irrecv.enableIRIn();myservo.attach(SERVO_PIN);myservo.write(swingAngle);      // 初始位置// 初始化顯示屏tft.init(240, 240);tft.setRotation(1);tft.fillScreen(ST77XX_BLACK);// 初始化光敏電阻pinMode(LIGHT_SENSOR, INPUT);// 顯示準備界面showReadyScreen();Serial.println("\nSmart Fan Control System Started");
}void loop() {// 處理紅外信號if (irrecv.decode(&results)) {handleIRCommand(results.value);irrecv.resume();redrawNeeded = true;}// 處理舵機擺動handleSwing();// 處理定時器handleTimer();// 處理睡眠模式handleSleepMode();// 讀取光線傳感器數據readLightSensor();// 自動模式處理if (operationMode == MODE_LIGHT_AUTO) {handleAutoMode();}// 更新顯示updateDisplay();delay(100); // 短暫延遲以減少CPU使用率
}void showReadyScreen() {tft.fillScreen(ST77XX_BLACK);// 顯示標題tft.setCursor(60, 80);tft.setTextColor(ST77XX_CYAN);tft.setTextSize(3);tft.println("READY");// 繪制進度條tft.drawRect(20, 120, 200, 20, ST77XX_WHITE);for (int i = 0; i <= 100; i += 5) {tft.fillRect(20, 120, i * 2, 20, ST77XX_BLUE);delay(50);}delay(1000);tft.fillScreen(ST77XX_BLACK);redrawNeeded = true;
}void handleIRCommand(unsigned long value) {Serial.print("IR Code Received: 0x");Serial.println(value, HEX);switch(value) {case BTN_POWER:togglePower();break;case BTN_SWING:toggleSwing();break;case BTN_TIMER_10:setTimer(10);break;case BTN_TIMER_30:setTimer(30);break;case BTN_MODE:switchMode();break;case BTN_SLEEP:toggleSleepMode();break;default:Serial.println("Unknown Command");break;}
}void togglePower() {if (fanState == FAN_OFF) {turnOnFan();} else {turnOffFan();}
}void turnOffFan() {digitalWrite(RELAY_PIN, HIGH);fanState = FAN_OFF;swingState = SWING_OFF; // 關閉風扇時也停止擺動timerActive = false; // 取消定時sleepActive = false; // 取消睡眠模式Serial.println("Fan Turned OFF");
}void turnOnFan() {digitalWrite(RELAY_PIN, LOW);fanState = FAN_ON;Serial.println("Fan Turned ON");
}void toggleSwing() {if (fanState == FAN_OFF) {Serial.println("Please Turn ON Fan First");return;}swingState = !swingState;Serial.print("Swing Function ");Serial.println(swingState ? "Enabled" : "Disabled");
}void setTimer(int seconds) {if (fanState == FAN_OFF) {Serial.println("Please Turn ON Fan First");return;}timerDuration = seconds * 1000; // 轉換為毫秒timerStartTime = millis();timerActive = true;operationMode = MODE_TIMER;redrawNeeded = true;Serial.print("Timer Set: ");Serial.print(seconds);Serial.println(" seconds");
}void switchMode() {if (operationMode == MODE_NORMAL) {operationMode = MODE_LIGHT_AUTO;} else if (operationMode == MODE_LIGHT_AUTO) {operationMode = MODE_NORMAL;} else {// 如果是定時器或睡眠模式,切換到普通模式operationMode = MODE_NORMAL;}redrawNeeded = true;if (operationMode == MODE_NORMAL) {Serial.println("Normal Mode");} else if (operationMode == MODE_LIGHT_AUTO) {Serial.println("Light Auto Mode");}
}void toggleSleepMode() {if (fanState == FAN_OFF) {Serial.println("Please Turn ON Fan First");return;}sleepActive = !sleepActive;if (sleepActive) {sleepStartTime = millis();operationMode = MODE_SLEEP;Serial.println("Sleep Mode Activated - Fan will turn off at 6 AM");} else {operationMode = MODE_NORMAL;Serial.println("Sleep Mode Deactivated");}redrawNeeded = true;
}void handleSwing() {if (swingState == SWING_OFF) return;unsigned long currentTime = millis();if (currentTime - lastSwingTime >= swingSpeed) {lastSwingTime = currentTime;// 擺動范圍 20-160 度static int direction = 1; // 1為增加角度,-1為減少角度swingAngle += direction;myservo.write(swingAngle);// 到達邊界時改變方向if (swingAngle >= 160 || swingAngle <= 20) {direction = -direction;}}
}void handleTimer() {if (!timerActive) return;unsigned long currentTime = millis();unsigned long elapsedTime = currentTime - timerStartTime;if (elapsedTime >= timerDuration) {turnOffFan();operationMode = MODE_NORMAL;Serial.println("Timer Finished - Fan Turned OFF");redrawNeeded = true;}
}void handleSleepMode() {if (!sleepActive) return;unsigned long currentTime = millis();unsigned long elapsedTime = currentTime - sleepStartTime;// 模擬6點關閉(8小時睡眠時間)if (elapsedTime >= sleepDuration) {turnOffFan();sleepActive = false;operationMode = MODE_NORMAL;Serial.println("Sleep Mode Finished - Fan Turned OFF");redrawNeeded = true;}
}void readLightSensor() {// 讀取光線強度int newLightLevel = analogRead(LIGHT_SENSOR);// 添加一些濾波以減少噪聲lightLevel = (lightLevel * 0.7) + (newLightLevel * 0.3);
}void handleAutoMode() {if (operationMode != MODE_LIGHT_AUTO) return;if (fanState == FAN_OFF && lightLevel < LIGHT_THRESHOLD) {turnOnFan();Serial.println("Low Light - Auto ON");redrawNeeded = true;}if (fanState == FAN_ON && lightLevel >= LIGHT_THRESHOLD) {turnOffFan();Serial.println("Bright Light - Auto OFF");redrawNeeded = true;}
}void updateDisplay() {// 只在需要時重繪if (!redrawNeeded) {// 對于定時器模式,每秒更新一次時間顯示if (operationMode == MODE_TIMER && timerActive) {unsigned long currentTime = millis();if (currentTime - lastTimerUpdate >= 1000) {lastTimerUpdate = currentTime;updateTimerDisplay();}}// 對于睡眠模式,每分鐘更新一次時間顯示else if (operationMode == MODE_SLEEP && sleepActive) {unsigned long currentTime = millis();if (currentTime - lastTimerUpdate >= 10000) {lastTimerUpdate = currentTime;updateSleepDisplay();}}return;}lastLightLevel = lightLevel;// 清除整個屏幕tft.fillScreen(ST77XX_BLACK);// 繪制標題和模式指示器tft.setCursor(20, 10);tft.setTextColor(ST77XX_CYAN);tft.setTextSize(2);tft.println("SMART FAN");// 繪制模式指示器uint16_t modeColor;String modeText;switch(operationMode) {case MODE_NORMAL:modeColor = ST77XX_BLUE;modeText = "NORM";break;case MODE_LIGHT_AUTO:modeColor = ST77XX_GREEN;modeText = "AUTO";break;case MODE_TIMER:modeColor = ST77XX_YELLOW;modeText = "TIMER";break;case MODE_SLEEP:modeColor = ST77XX_MAGENTA;modeText = "SLEEP";break;}tft.fillRect(180, 10, 50, 20, modeColor);tft.setCursor(185, 15);tft.setTextColor(ST77XX_WHITE);tft.setTextSize(1);tft.println(modeText);// 繪制分隔線tft.drawFastHLine(10, 35, 220, ST77XX_WHITE);// 根據模式更新顯示switch(operationMode) {case MODE_NORMAL:updateNormalModeDisplay();break;case MODE_LIGHT_AUTO:updateLightModeDisplay();break;case MODE_TIMER:updateTimerDisplay();break;case MODE_SLEEP:updateSleepDisplay();break;}redrawNeeded = false;lastTimerUpdate = millis();
}void updateNormalModeDisplay() {// 清除數據區域tft.fillRect(10, STATUS_AREA, 220, 200, ST77XX_BLACK);// 顯示風扇狀態tft.setCursor(20, 50);tft.setTextColor(ST77XX_WHITE);tft.setTextSize(2);tft.print("FAN: ");tft.setTextColor(fanState == FAN_ON ? ST77XX_GREEN : ST77XX_RED);tft.println(fanState == FAN_ON ? "ON" : "OFF");// 顯示搖頭狀態tft.setCursor(20, 80);tft.setTextColor(ST77XX_WHITE);tft.print("SWING: ");tft.setTextColor(swingState == SWING_ON ? ST77XX_GREEN : ST77XX_RED);tft.println(swingState == SWING_ON ? "ON" : "OFF");// 顯示舵機速度tft.setCursor(20, 110);tft.setTextColor(ST77XX_WHITE);tft.print("SPEED: ");tft.setTextColor(ST77XX_YELLOW);tft.print(swingSpeed);tft.println("ms");// 顯示光線數據tft.setCursor(20, 140);tft.setTextColor(ST77XX_WHITE);tft.print("LIGHT: ");tft.setTextColor(ST77XX_GREEN);tft.println(lightLevel);// 底部狀態欄tft.fillRect(0, 220, 240, 20, ST77XX_BLUE);tft.setCursor(70, 225);tft.setTextColor(ST77XX_WHITE);tft.setTextSize(1);tft.print("NORMAL MODE");
}void updateLightModeDisplay() {// 清除數據區域tft.fillRect(10, STATUS_AREA, 220, 200, ST77XX_BLACK);// 顯示標題tft.setCursor(20, 50);tft.setTextColor(ST77XX_WHITE);tft.setTextSize(2);tft.println("LIGHT CONTROL");// 顯示光線數據tft.setCursor(20, 80);tft.setTextColor(ST77XX_WHITE);tft.print("LIGHT: ");tft.setTextColor(ST77XX_GREEN);tft.println(lightLevel);// 顯示閾值信息tft.setCursor(20, 110);tft.setTextColor(ST77XX_WHITE);tft.print("THRESHOLD: ");tft.setTextColor(ST77XX_YELLOW);tft.println(LIGHT_THRESHOLD);// 顯示控制狀態tft.setCursor(20, 140);tft.setTextColor(ST77XX_WHITE);tft.print("CONTROL: ");if (lightLevel < LIGHT_THRESHOLD) {tft.setTextColor(ST77XX_GREEN);tft.println("FAN ON");} else {tft.setTextColor(ST77XX_RED);tft.println("FAN OFF");}// 顯示當前風扇狀態tft.setCursor(20, 170);tft.setTextColor(ST77XX_WHITE);tft.print("FAN: ");tft.setTextColor(fanState == FAN_ON ? ST77XX_GREEN : ST77XX_RED);tft.println(fanState == FAN_ON ? "ON" : "OFF");// 底部狀態欄tft.fillRect(0, 220, 240, 20, ST77XX_GREEN);tft.setCursor(70, 225);tft.setTextColor(ST77XX_WHITE);tft.setTextSize(1);tft.print("AUTO LIGHT MODE");
}void updateTimerDisplay() {// 清除數據區域tft.fillRect(10, STATUS_AREA, 220, 200, ST77XX_BLACK);// 顯示標題tft.setCursor(20, 50);tft.setTextColor(ST77XX_WHITE);tft.setTextSize(2);tft.println("TIMER MODE");// 顯示剩余時間tft.setCursor(20, 80);tft.setTextColor(ST77XX_WHITE);tft.print("TIME LEFT: ");if (timerActive) {unsigned long remaining = (timerDuration - (millis() - timerStartTime)) / 1000;tft.setTextColor(ST77XX_YELLOW);tft.print(remaining);tft.println("s");} else {tft.setTextColor(ST77XX_RED);tft.println("INACTIVE");}// 顯示風扇狀態tft.setCursor(20, 110);tft.setTextColor(ST77XX_WHITE);tft.print("FAN: ");tft.setTextColor(fanState == FAN_ON ? ST77XX_GREEN : ST77XX_RED);tft.println(fanState == FAN_ON ? "ON" : "OFF");// 底部狀態欄tft.fillRect(0, 220, 240, 20, ST77XX_YELLOW);tft.setCursor(90, 225);tft.setTextColor(ST77XX_BLACK);tft.setTextSize(1);tft.print("TIMER MODE");
}void updateSleepDisplay() {// 清除數據區域tft.fillRect(10, STATUS_AREA, 220, 200, ST77XX_BLACK);// 顯示標題tft.setCursor(20, 50);tft.setTextColor(ST77XX_WHITE);tft.setTextSize(2);tft.println("SLEEP MODE");// 顯示剩余時間tft.setCursor(20, 80);tft.setTextColor(ST77XX_WHITE);tft.print("TIME LEFT: ");if (sleepActive) {unsigned long remaining = (sleepDuration - (millis() - sleepStartTime)) / 1000;unsigned long hours = remaining / 3600;unsigned long minutes = (remaining % 3600) / 60;tft.setTextColor(ST77XX_MAGENTA);tft.print(hours);tft.print("h ");tft.print(minutes);tft.println("m");} else {tft.setTextColor(ST77XX_RED);tft.println("INACTIVE");}// 顯示關閉時間tft.setCursor(20, 110);tft.setTextColor(ST77XX_WHITE);tft.print("TURNS OFF: ");tft.setTextColor(ST77XX_YELLOW);tft.println("6:00 AM");// 顯示風扇狀態tft.setCursor(20, 140);tft.setTextColor(ST77XX_WHITE);tft.print("FAN: ");tft.setTextColor(fanState == FAN_ON ? ST77XX_GREEN : ST77XX_RED);tft.println(fanState == FAN_ON ? "ON" : "OFF");// 底部狀態欄tft.fillRect(0, 220, 240, 20, ST77XX_MAGENTA);tft.setCursor(90, 225);tft.setTextColor(ST77XX_WHITE);tft.setTextSize(1);tft.print("SLEEP MODE");
}
模塊名稱核心職責關鍵函數
紅外遙控接收并解析紅外按鍵指令,映射到對應功能handleIRCommand()togglePower()
風扇動作控制控制風扇電源(繼電器)和搖頭(舵機)turnOnFan()turnOffFan()等
模式控制管理普通、光線自動、定時、睡眠 4 種工作模式switchMode()handleAutoMode()
傳感器數據讀取并濾波光敏傳感器數據,為自動模式提供依據readLightSensor()
顯示驅動控制 TFT 屏顯示系統狀態(定時 / 睡眠剩余時間)updateTimerDisplay()等

三、項目結果演示

3.1 操作流程

(1)系統啟動

????????上電后系統顯示準備界面,完成自檢后進入主界面

(2)系統控制

? ? ? ? "電源鍵:開關風扇、"搖頭鍵:啟用/禁用搖頭功能、"模式鍵:切換普通/光控模式? ? ? ? ????????定時功能:設置10秒 / 30秒后系統自動關閉、啟用睡眠模式 8 小時自動關閉

3.2 界面展示

(1)普通模式界面

????????顯示風扇狀態、搖頭狀態、舵機速度和光線值

(2)光控模式界面

????????顯示光線值、閾值和控制狀態

(3)定時模式界面

????????顯示剩余時間和風扇狀態

(4)睡眠模式界面

????????顯示剩余時間和關閉時間

3.3 視頻演示

JQC-3FF-S-Z繼電器驅動小風扇

紅外遙控操作控制智能風扇實現自動光控功能、搖頭功能、模式切換以及系統定時功能

四、JQC-3FF-S-Z工作原理

4.1 基本結構

????????繼電器主要由電磁線圈、鐵芯、鐵片(銜鐵)、復位彈簧、常開觸點和常閉觸點等部分組成。

4.2 動作機制

????????根據觸點的動作形式,可分為常閉式和常開式。常閉式繼電器在未通電時觸點閉合,通電后斷開;常開式繼電器在未通電時觸點斷開,通電后閉合。

????????電器的動作機制基于電磁感應原理。當線圈通電后,產生的磁場使鐵心運動,帶動與鐵心相連的觸點動作。

五、常見問題解答

Q1: 如何調整光控的靈敏度?

A: 修改代碼中的LIGHT_THRESHOLD值:

????????值越小,對光線越敏感(更容易觸發)。值越大,需要更暗的環境才會觸發

Q2: 如何修改定時時間?

A: 在setTimer函數中修改時間參數,或者添加更多的定時選項:

void setTimer(int seconds) {// 修改這里的seconds參數即可timerDuration = seconds * 1000;// ...
}

Q3: 舵機轉動不流暢怎么辦?

A: 調整swingSpeed參數:

????????值越小,轉動越快。值越大,轉動越慢(建議范圍5-30ms)

項目資源整合

????????繼電器數據手冊:JQC-3FF-S-Z

????????顯示屏數據手冊:ST7789

????????通過本項目的學習,讀者可以掌握STM32開發的基本技能,了解繼電器控制原理,并學會如何設計用戶友好的交互界面。歡迎各位讀者在此基礎上進行擴展和改進,創造出更多有趣的智能家居應用!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/95733.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/95733.shtml
英文地址,請注明出處:http://en.pswp.cn/web/95733.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

ReACT Agent概述

目錄 1. 核心思想&#xff1a;解決傳統方法的局限性 2. ReACT 的工作原理&#xff1a;一個循環過程 3. 技術實現的關鍵要素 4. ReACTAgent 在任務中的具體工作流程 5. 優勢與重要性 6. 挑戰與局限性 總結 ReACT 是一個非常重要的框架&#xff0c;它代表了構建能夠推理&a…

必知!機器人的分類與應用:RPA、人形與工業機器人

每當提及“機器人”這三個字&#xff0c;許多人的第一反應或許仍是科幻電影中那種具備人類外形、可自由行走與對話的仿生裝置。然而&#xff0c;一個值得深入探討的科技現實是&#xff1a;我們對于人形機器人的迷戀&#xff0c;更多源自文化敘事與情感投射&#xff0c;而非真實…

最快的 C 語言 JSON 庫 - yyjson

文章目錄DOM 模式下的性能比對一、AWS EC2 (AMD EPYC 7R32, gcc 9.3)二、iPhone (Apple A14, clang 12)持續更新中 持續更新中 持續更新中一個用 ANSI C(C89) 編寫的高性能 JSON 庫 API.md DOM 模式下的性能比對 DOM 模式&#xff0c;即構建完整 JSON 內存結構后訪問數據的模…

TP8 模型save更新不成功

一、User文件頭部代碼class User extends Model {const TITLE_NAME 用戶;//名稱//不能刪除protected $name user_; //表名 protected $connection \app\services\database\model\DbConnModel::CONN_DB_SITE; //數據庫的連接二、更新部分我要更新user_1用戶表中的用戶信息$se…

中囯移動電視盒子(魔百和)B860AV2.1-A2和CM311-5-zg刷機手記

文章目錄B860AV2.1-A2電視盒子情況打開隱藏或屏蔽的功能進入Recovery模式打開WiFi&#xff08;如果被隱藏&#xff09;打開運維調試打開ADB調試安裝第三方應用、設置第三方桌面等&#xff08;Fiddler抓包替換官方App安裝包&#xff09;開啟ADB和使用ADB禁止“首次啟動設置”刷機…

【系統架構設計(14)】項目管理下:軟件質量與配置管理:構建可靠軟件的基礎保障

文章目錄一、核心思想二、軟件質量屬性&#xff1a;定義"好軟件"的標準三、質量保證與控制&#xff1a;實現質量標準的方法四、CMMI模型&#xff1a;組織質量能力的演進路徑五、軟件配置管理&#xff1a;質量成果的保護機制六、軟件工具&#xff1a;質量管理的技術支…

碼農的“必修課”:深度解析Rust的所有權系統(與C++內存模型對比)

在軟件開發的世界里&#xff0c;內存管理是至關重要的一個環節。它是程序運行的基礎&#xff0c;直接關系到程序的性能、穩定性和安全性。一個糟糕的內存管理策略&#xff0c;可能導致內存泄漏、野指針、緩沖區溢出等一系列令人頭疼的問題&#xff0c;甚至帶來災難性的安全漏洞…

Java全棧學習筆記30

# MySQL 卸載安裝版電腦管家/360/控制面板卸載mysql服務即可刪除ProgramData中的MySQL目錄解壓版winr 輸入 services.msc 打開服務管理。查看是否存在MySQL&#xff0c;如果存在則刪除注冊表 winR regedit 打開注冊表計算機\HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Servic…

Transformers 學習入門:前置知識補漏

在學習 Transformers 之前&#xff0c;打好神經網絡和自然語言處理的基礎至關重要。本文整理了需要掌握的核心前置知識&#xff0c;用通俗的例子幫你快速理解復雜概念&#xff0c;為后續學習鋪平道路。? 一、神經網絡基礎? 1. 多層感知機&#xff08;MLP&#xff09;&#xf…

雙攝工業相機的主要特點和應用場景

雙攝工業相機&#xff08;雙目攝像頭&#xff09;在工業領域中的應用非常廣泛&#xff0c;其核心優勢在于通過雙鏡頭模擬人眼立體視覺&#xff0c;能夠獲取深度信息并實現高精度三維重建。 一、雙攝工業相機的核心優勢 深度感知與三維重建 雙目攝像頭通過兩個鏡頭從不同角度拍…

YOLOv11改進:FocalModulation替換SPPF(精度更高的空間金字塔池化)

YOLOv11&#xff1a;FocalModulation替換SPPF&#xff08;精度更高的空間金字塔池化&#xff09; 引言 在目標檢測領域&#xff0c;YOLO系列算法以其高效性和準確性廣受歡迎。作為YOLO系列的最新成員之一&#xff0c;YOLOv11在多個方面進行了優化和改進。其中&#xff0c;空間金…

LLM與數據工程的融合:衡石Data Agent的語義層與Agent框架設計

在數字經濟浪潮中&#xff0c;企業數據智能正經歷從"工具輔助"到"智能協同"的范式躍遷。傳統BI系統受限于靜態報表與預設指標&#xff0c;難以應對動態業務場景的復雜需求。衡石科技發布的HENGSHI SENSE 6.0通過"Data AI Agent"架構創新&#x…

假設一個算術表達式中包含圓括號、方括號和花括號3種類型的括號,編寫一個算法來判別,表達式中的括號是否配對,以字符“\0“作為算術表達式的結束符

思想:這道題是棧的應用類型&#xff0c;我們可以建立一個棧來保存(,[,{,通過遍歷字符串如果是三個左括號其中一個則入棧&#xff0c;當遇到)]}則出棧配對&#xff0c;如果左右匹配&#xff0c;則遍歷下一個元素&#xff0c;如果不匹配直接返回&#xff0c;如果遍歷字符串結束&a…

鴻蒙Next的UI國際化與無障礙適老化實踐:構建全球包容的數字世界

科技不應讓任何人掉隊&#xff0c;鴻蒙Next正將這一理念變為現實在全球化日益深入的今天&#xff0c;應用的國際化與無障礙設計不再是"錦上添花"&#xff0c;而是不可或缺的核心競爭力。華為鴻蒙Next系統從設計之初就深入考慮了這些需求&#xff0c;為開發者提供了完…

深度學習——遷移學習

遷移學習作為深度學習領域的一項革命性技術&#xff0c;正在重塑我們構建和部署AI模型的方式。本文將帶您深入探索遷移學習的核心原理、詳細實施步驟以及實際應用中的關鍵技巧&#xff0c;幫助您全面掌握這一強大工具。遷移學習的本質與價值遷移學習的核心思想是"站在巨人…

RAG|| LangChain || LlamaIndex || RAGflow

大模型&#xff1a;預訓練模型 外掛知識庫&#xff1a;知識庫->向量數據庫 輸入-》預處理成向量 提示詞-》llm歸納總結 離線&#xff1a;企業原文本存到向量數據庫 向量&#xff1a; 同一個向量模型&#xff08;第二代檢索&#xff0c;推薦&#xff0c;個人助理&#xff0c;…

mcp_clickhouse代碼學習

引言:當ClickHouse遇上MCP 作為一個基于Model Context Protocol(MCP)框架的ClickHouse查詢服務器,mcp_clickhouse不僅在技術實現上展現了優雅的設計思路,更在架構層面提供了許多值得借鑒的解決方案。 一、項目概覽:架構初探 mcp_clickhouse是一個專為ClickHouse數據庫設計…

前端三件套+springboot后端連通嘗試

本文承接自跨域請求問題淺解-CSDN博客 后端&#xff1a; //主啟動類 SpringBootApplication public class DemoApplication {public static void main(String[] args) {SpringApplication.run(DemoApplication.class, args);}} //控制類 RestController RequestMapping(&quo…

決策樹、ID3決策樹(信息熵、信息增益)

目錄 一、決策樹簡介 決策樹建立過程 二、ID3決策樹 核心思想&#xff1a;決策樹算法通過計算??信息增益??來選擇最佳分裂特征 1、信息熵 2、信息熵的計算方法 3、信息增益 4、信息增益的計算&#xff08;難點&#xff09; 5、ID3決策樹構建案例 三、總結 一、決策樹簡介 決…

SpringBoot文件下載(多文件以zip形式,單文件格式不變)

SpringBoot文件下載&#xff08;多文件以zip形式&#xff0c;單文件格式不變&#xff09;初始化文件服務器&#xff08;我的是minio&#xff09;文件下載# 樣例# # 單文件# # 多文件初始化文件服務器&#xff08;我的是minio&#xff09; private static MinioClient minioClie…