日B视频 亚洲,啪啪啪网站一区二区,91色情精品久久,日日噜狠狠色综合久,超碰人妻少妇97在线,999青青视频,亚洲一区二卡,让本一区二区视频,日韩网站推荐

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

零知派——STM32+SCD41+旋轉(zhuǎn)編碼器:室內(nèi)CO?智能監(jiān)測(cè)系統(tǒng),三環(huán)可視化儀表盤(pán) + 分級(jí)蜂鳴告警

零知實(shí)驗(yàn)室 ? 來(lái)源:PCB56242069 ? 作者:PCB56242069 ? 2026-05-29 10:00 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

目錄

一、系統(tǒng)接線部分

1.1 硬件清單

1.2 接線方案表

1.3 具體接線圖

1.4 連接實(shí)物圖

二、安裝與使用部分

三、代碼講解部分

3.1 Softwire 正確初始化序列

3.2旋轉(zhuǎn)編碼器四態(tài)查表消抖算法

3.3圓環(huán)儀表盤(pán)繪制與局部刷新策略

3.4音量控制及多頻率告警

3.5 SCD4x庫(kù)API使用

① CRC-8 校驗(yàn)原理

②數(shù)據(jù)就緒輪詢機(jī)制

四、項(xiàng)目結(jié)果演示

4.1操作流程

4.2 視頻演示

五、工作原理講解

5.1 SCD41 通信時(shí)序

5.2 自動(dòng)自校準(zhǔn)機(jī)制

5.3旋轉(zhuǎn)編碼器原理

六、常見(jiàn)問(wèn)題解答(FAQ)

Q1:碼器旋轉(zhuǎn)方向反了,或者非常靈敏轉(zhuǎn)一格跳很多頁(yè)?

Q2:蜂鳴器一直響或完全不響?

Q3:為什么CO?數(shù)據(jù)長(zhǎng)時(shí)間顯示"--"?

項(xiàng)目概述

本項(xiàng)目基于零知派標(biāo)準(zhǔn)板(主控 STM32F103RBT6)驅(qū)動(dòng) Sensirion SCD41 NDIR CO?傳感器,配合 ST7789 240×240 TFT 顯示屏、旋轉(zhuǎn)編碼器和無(wú)源蜂鳴器,實(shí)現(xiàn)了一套完整的室內(nèi)空氣質(zhì)量實(shí)時(shí)監(jiān)測(cè)系統(tǒng)。系統(tǒng)采用淺色簡(jiǎn)約主題,以圓環(huán)儀表盤(pán)的形式同屏展示 CO?濃度、溫度、濕度三路數(shù)據(jù),并通過(guò)旋轉(zhuǎn)編碼器在四個(gè)功能頁(yè)面間自由切換,電位器實(shí)時(shí)調(diào)節(jié)告警音量,SW 按鍵一鍵切換靜音

項(xiàng)目難點(diǎn)

問(wèn)題描述:SoftWire 時(shí)序在多外設(shè)共存場(chǎng)景下崩潰,導(dǎo)致 SCD41 無(wú)法初始化

解決方案:啟動(dòng)畫(huà)面不調(diào)用 beep()、 TFT init 后加 100ms 穩(wěn)定延時(shí)、使用全局 Wire 對(duì)象

一、系統(tǒng)接線部分

1.1 硬件清單

序號(hào) 模塊 規(guī)格 數(shù)量
1 零知派標(biāo)準(zhǔn)板 STM32F103RBT6,Arduino 兼容 1
2 CO?傳感器 Sensirion SCD41,I2C,3.3V 1
3 TFT 顯示屏 ST7789,240×240,SPI 1
4 旋轉(zhuǎn)編碼器 EC11,帶按鍵 SW 1
5 無(wú)源蜂鳴器 3.3V,支持 PWM 驅(qū)動(dòng) 1
6 滑動(dòng)變阻器 10kΩ,線性 1
7 杜邦線 母對(duì)母 若干

1.2 接線方案表

嚴(yán)格按照代碼中的宏定義進(jìn)行接線,不得隨意更改,否則編碼器中斷和 ADC 會(huì)失效

①SCD41 CO?傳感器

SCD41 引腳 零知派標(biāo)準(zhǔn)板 代碼定義 說(shuō)明
SDA A4 SoftWire SDA 軟件 I2C 數(shù)據(jù)
SCL A5 SoftWire SCL 軟件 I2C 時(shí)鐘
VDD 5V 供電,注意噪聲
GND GND 接地

旋轉(zhuǎn)編碼器 EC11

編碼器引腳 零知派標(biāo)準(zhǔn)板 代碼定義 說(shuō)明
CLK(A相) D6 #define ENC_CLK 6 接外部中斷
DT(B相) D12 #define ENC_DT 12 接外部中斷
SW(按鍵) D14 #define ENC_SW 14 INPUT_PULLUP
VCC 5V
GND GND

蜂鳴器 & 電位器

器件 零知派標(biāo)準(zhǔn)板 代碼定義 說(shuō)明
蜂鳴器 + D3 #define BUZZER_PIN 3 數(shù)字輸出,PWM
蜂鳴器 ? GND
電位器中間腳 A0 #define VOLUME_PIN A0 模擬輸入,12位ADC
電位器兩端 3.3V / GND 左側(cè)接3.3V / 右側(cè)接GND

請(qǐng)注意:ST7789顯示屏直插零知派標(biāo)準(zhǔn)板TFT引腳,無(wú)需單獨(dú)接線

1.3 具體接線圖

wKgZO2oY6m-Aa_PUABDjR7ksHbo355.png

編碼器 CLK和 DT接到支持attachInterrupt外部中斷的引腳D6和D12

1.4 連接實(shí)物圖

wKgZPGoY6muAH9zNAB3cbgeJsEY536.png

二、安裝與使用部分

2.1 開(kāi)源平臺(tái)-輸入"SCD41"并搜索-代碼下載自動(dòng)打開(kāi)

wKgZPGoY6riARkruAAewdEwT76c342.png

2.2 連接-驗(yàn)證-上傳

wKgZO2oY6r2APNKeAAtgWxZKLcQ544.png

2.3 調(diào)試-串口監(jiān)視器

wKgZPGoY6sKAN6B9AAuytJ6rdvY769.png

三、代碼講解部分

本項(xiàng)目代碼基于SparkFun_SCD4x_Arduino_Library(底層使用SoftWire)和Adafruit_ST7789驅(qū)動(dòng)

3.1 Softwire 正確初始化序列

// setup() 中的傳感器初始化序列

// Step 1:TFT 初始化(SPI外設(shè)配置)
tft.init(240, 240);
tft.setRotation(3);
tft.fillScreen(COL_BG);
showSplash();  // ← 純顯示,絕對(duì)不調(diào)用 beep()

// Step 2:等待 SPI 外設(shè)穩(wěn)定,給 I2C 上拉恢復(fù)時(shí)間
delay(100);   // ← 這 100ms 是解決 err=268 的關(guān)鍵

// Step 3:?jiǎn)?dòng) SoftWire 總線
Wire.begin(); // 使用 SoftWire.cpp 末尾定義的全局 Wire 對(duì)象
delay(50);    // I2C 總線電平建立穩(wěn)定時(shí)間

// Step 4:SparkFun 庫(kù)初始化
// begin(wirePort, measBegin, autoCalibrate, skipStop, pollDevType)
bool ok = mySensor.begin(Wire, true, true, false, true);

參數(shù)說(shuō)明:

參數(shù) 含義
wirePort Wire 使用全局 SoftWire 對(duì)象
measBegin true 初始化后立即啟動(dòng)周期測(cè)量
autoCalibrate true 啟用 SCD41 自動(dòng)校準(zhǔn)(ASC)
skipStop false 先執(zhí)行 stopPeriodicMeasurement 確保干凈狀態(tài)
pollDevType true 讀取 feature set 版本,自動(dòng)識(shí)別 SCD40/41

SoftWire 的 NOP-loop 時(shí)序在 STM32 多外設(shè)環(huán)境下不夠穩(wěn)定,導(dǎo)致該命令的 CRC 校驗(yàn)失敗返回 268。SparkFun 的 begin() 通過(guò) getSerialNumber() 的 CRC 校驗(yàn)?zāi)茯?yàn)證通信正常

3.2旋轉(zhuǎn)編碼器四態(tài)查表消抖算法

本項(xiàng)目使用格雷碼查表法,配合累積步數(shù)閾值,實(shí)現(xiàn)準(zhǔn)確的方向判斷

// 16個(gè)狀態(tài)轉(zhuǎn)移,每個(gè)值代表方向變化量(+1/-1/0)
const int8_t encoderTable[] = {
   0,-1, 1, 0,
   1, 0, 0,-1,
  -1, 0, 0, 1,
   0, 1,-1, 0
};

void updateEncoder() {
    uint8_t clk     = digitalRead(ENC_CLK);   // A相
    uint8_t dt      = digitalRead(ENC_DT);    // B相
    uint8_t encoded = (clk = 4) {
            accSteps = 0;
            if (millis() - lastEncTrigTime > ENC_COOLDOWN) {
                pageCW = true;              // 順時(shí)針:下一頁(yè)
                lastEncTrigTime = millis();
            }
        } else if (accSteps <= -4) {
            accSteps = 0;
            if (millis() - lastEncTrigTime > ENC_COOLDOWN) {
                pageCCW = true;             // 逆時(shí)針:上一頁(yè)
                lastEncTrigTime = millis();
            }
        }
    }
    lastEncoded = encoded;
}

// 編碼器通過(guò) attachInterrupt 綁定到兩個(gè)引腳
attachInterrupt(digitalPinToInterrupt(ENC_CLK), updateEncoder, CHANGE);
attachInterrupt(digitalPinToInterrupt(ENC_DT),  updateEncoder, CHANGE);

// 在 loop() 主循環(huán)中,中斷設(shè)置的標(biāo)志位被消費(fèi)
if (pageCW)  
{ 
    pageCW = false;  
    currentPage = (currentPage+1)%PAGE_COUNT; 
    lastPage = -2; 
}
if (pageCCW) 
{ 
    pageCCW = false; 
    currentPage = (currentPage-1+PAGE_COUNT)%PAGE_COUNT; 
    lastPage = -2; 
}

lastPage=-2 是強(qiáng)制全刷新標(biāo)志,翻頁(yè)時(shí)重繪整個(gè)屏幕避免殘影

3.3圓環(huán)儀表盤(pán)繪制與局部刷新策略

圓環(huán)繪制是本項(xiàng)目視覺(jué)效果的核心,也是性能優(yōu)化的重點(diǎn)

// 基礎(chǔ)弧段繪制:從 startDeg 到 endDeg(以正上方為0°,順時(shí)針)
void drawArcSection(int16_t cx, int16_t cy, int16_t r,
                    int16_t startDeg, int16_t endDeg, uint16_t color) {
    for (int16_t deg = startDeg; deg <= endDeg; deg++) {
        // 坐標(biāo)系旋轉(zhuǎn):-90° 使 0° 指向正上方
        float rad = (deg - 90) * PI / 180.0f;
        tft.drawPixel(cx + (int16_t)(r * cosf(rad)),
                      cy + (int16_t)(r * sinf(rad)), color);
    }
}

// 圓環(huán)(多層弧段疊加形成寬度)
void drawRingArc(int16_t cx, int16_t cy,
                 int16_t innerR, int16_t outerR,
                 int16_t startDeg, int16_t endDeg, uint16_t color) {
    for (int16_t r = innerR; r <= outerR; r++)
        drawArcSection(cx, cy, r, startDeg, endDeg, color);
}

圓環(huán)繪制

// Step1:擦除整個(gè)圓環(huán)區(qū)域(用背景色填充外圓)
tft.fillCircle(cx, cy, outerR+2, COL_BG);

// Step2:繪制底層灰色軌道(300°滿量程)
drawRingArc(cx, cy, innerR, outerR, 0, 300, COL_RING_BG);

// Step3:繪制有色填充弧(根據(jù)數(shù)據(jù)值映射到0~300°)
int16_t arc = (int16_t)map(constrain(co2, 400, 2500), 400, 2500, 0, 300);
if (arc > 0) drawRingArc(cx, cy, innerR, outerR, 0, arc, co2Color(co2));

// Step4:填充圓心區(qū)域(遮住innerR以內(nèi)的像素,恢復(fù)白底)
tft.fillCircle(cx, cy, innerR-1, COL_BG);

局部刷新策略

// 只有首次進(jìn)入頁(yè)面或強(qiáng)制刷新時(shí)(full=true)才重繪靜態(tài)背景
void drawPageCO2(bool full) {
    if (full) {
        tft.fillScreen(COL_BG);    // 僅此處全屏清空
        drawTopBar("CO2 Detail");
        drawBottomBar("TURN to switch");
    }
    // 以下每次循環(huán)都執(zhí)行:只刷新圓環(huán)和數(shù)值區(qū)域
    // 數(shù)值文字前先精確擦除其占用矩形
    tft.fillRect(cx-48, labelY-12, 88, 16, COL_BG);  // 擦除等級(jí)標(biāo)簽
    // 再重繪
    tft.print(co2Label(co2));
}

bool full = (currentPage != lastPage);
lastPage = currentPage;

full 為 true 只在翻頁(yè)瞬間,之后每幀都是 false,只刷新有數(shù)據(jù)變化的區(qū)域,大幅減少 SPI 傳輸量

3.4音量控制及多頻率告警

蜂鳴器通過(guò)軟件 PWM(手動(dòng)控制高低電平時(shí)間)實(shí)現(xiàn)不同頻率,由電位器 ADC 值控制占空比從而調(diào)節(jié)響度

void updateVolume() {
    int adc = analogRead(VOLUME_PIN);  // STM32 12位ADC:0~4095
    // 映射到 10%~90% 占空比,防止0%(無(wú)聲)和100%(直流,損壞蜂鳴器)
    volumePercent = (uint8_t)map(adc, 0, 4095, 10, 90);
}

void beep(uint16_t freq, uint16_t dur) {
    if (freq == 0 || muteEnabled) return;
    uint32_t period   = 1000000UL / freq;          // 周期(微秒)
    uint32_t highTime = period * volumePercent / 100; // 高電平時(shí)間
    uint32_t lowTime  = period - highTime;            // 低電平時(shí)間
    uint32_t cycles   = (uint32_t)dur * 1000UL / period; // 總循環(huán)次數(shù)
    
    for (uint32_t i = 0; i < cycles; i++) {
        digitalWrite(BUZZER_PIN, HIGH);
        delayMicroseconds(highTime);
        digitalWrite(BUZZER_PIN, LOW);
        delayMicroseconds(lowTime);
    }
}

三檔告警頻率對(duì)應(yīng)表:

CO? 范圍 等級(jí) 圓環(huán)顏色 告警行為
0~400 ppm WAIT 灰色(數(shù)據(jù)未就緒) 無(wú)
400~800 ppm GOOD 綠色 0x07C0 無(wú)告警
800~1000 ppm FAIR 青綠 0x0454 單次 440Hz 短鳴
1000~1500 ppm POOR 琥珀黃 0xFEA0 雙次 440Hz 鳴叫
1500~2000 ppm BAD 橙色 0xFC40 三次 280Hz 告警
>2000 ppm CRIT 紅色 0xF800 三次 280Hz 急促告警

void handleBuzzer() {
    if (!dataValid) return;
    // 節(jié)流:最快每 4 秒告警一次,避免持續(xù)噪音
    if (millis() - lastBeepTime < BEEP_INTERVAL) return;
    
    if      (co2 > CO2_BAD)  { beepPattern(BEEP_CRIT, 3, 200, 150); lastBeepTime=millis(); }
    else if (co2 > CO2_POOR) { beepPattern(BEEP_WARN, 2, 150, 120); lastBeepTime=millis(); }
    else if (co2 > CO2_FAIR) { beepPattern(BEEP_WARN, 1, 100,   0); lastBeepTime=millis(); }
}

系統(tǒng)流程圖

wKgZPGoY6vuAX7VWAATe74KmrIg816.png

3.5 SCD4x庫(kù)API使用

API 調(diào)用時(shí)機(jī) 內(nèi)部原理
mySensor.begin(Wire, true, true, false, true) setup() 一次 stopPeriodic→CRC序列號(hào)驗(yàn)證→ASC設(shè)置→startPeriodic
mySensor.readMeasurement() loop() 輪詢 內(nèi)部先調(diào) getDataReadyStatus(),bit[10:0]≠0才讀;一次讀取 9 字節(jié)含3組 CRC
mySensor.getCO2() 數(shù)據(jù)就緒后 返回 uint16_t,單位 ppm,范圍 400~5000
mySensor.getTemperature() 數(shù)據(jù)就緒后 返回 float,公式:-45 + 175×rawT/65535
mySensor.getHumidity() 數(shù)據(jù)就緒后 返回 float,公式:100×rawH/65535

① CRC-8 校驗(yàn)原理

//x^8+x^5+x^4+1 = 0x31
uint8_t SCD4x::computeCRC8(uint8_t data[], uint8_t len)
{
  uint8_t crc = 0xFF; //Init with 0xFF

  for (uint8_t x = 0; x < len; x++)
  {
    crc ^= data[x]; // XOR-in the next input byte

    for (uint8_t i = 0; i < 8; i++)
    {
      if ((crc & 0x80) != 0)
        crc = (uint8_t)((crc 

SCD41 每?jī)勺止?jié)數(shù)據(jù)后附一字節(jié) CRC,多項(xiàng)式為 x?+x?+x?+1 = 0x31,初始值 0xFF。SparkFun 庫(kù)在每次 I2C 讀取后自動(dòng)驗(yàn)證,校驗(yàn)失敗則 readMeasurement() 返回 false

②數(shù)據(jù)就緒輪詢機(jī)制

bool SCD4x::readMeasurement(void)
{
  //Verify we have data from the sensor
  if (getDataReadyStatus() == false)
    return (false);

  scd4x_unsigned16Bytes_t tempCO2;
  tempCO2.unsigned16 = 0;
  scd4x_unsigned16Bytes_t  tempHumidity;
  tempHumidity.unsigned16 = 0;
  scd4x_unsigned16Bytes_t  tempTemperature;
  tempTemperature.unsigned16 = 0;

  _i2cPort->beginTransmission(SCD4x_ADDRESS);
  _i2cPort->write(SCD4x_COMMAND_READ_MEASUREMENT >> 8);   //MSB
  _i2cPort->write(SCD4x_COMMAND_READ_MEASUREMENT & 0xFF); //LSB
  if (_i2cPort->endTransmission() != 0)
    return (false); //Sensor did not ACK

  delay(1); //Datasheet specifies this

  #if SCD4x_ENABLE_DEBUGLOG
  uint8_t receivedBytes = (uint8_t)
  #endif // if SCD4x_ENABLE_DEBUGLOG
  _i2cPort->requestFrom((uint8_t)SCD4x_ADDRESS, (uint8_t)9);
  bool error = false;
  if (_i2cPort->available())
  {
    byte bytesToCrc[2];
    for (byte x = 0; x < 9; x++)
    {
      byte incoming = _i2cPort-?>read();

      switch (x)
      {
      case 0:
      case 1:
        tempCO2.bytes[x == 0 ? 1 : 0] = incoming; // Store the two CO2 bytes in little-endian format
        bytesToCrc[x] = incoming; // Calculate the CRC on the two CO2 bytes in the order they arrive
        break;
      case 3:
      case 4:
        tempTemperature.bytes[x == 3 ? 1 : 0] = incoming; // Store the two T bytes in little-endian format
        bytesToCrc[x % 3] = incoming; // Calculate the CRC on the two T bytes in the order they arrive
        break;
      case 6:
      case 7:
        tempHumidity.bytes[x == 6 ? 1 : 0] = incoming; // Store the two RH bytes in little-endian format
        bytesToCrc[x % 3] = incoming; // Calculate the CRC on the two RH bytes in the order they arrive
        break;
      default: // x == 2, 5, 8
        //Validate CRC
        uint8_t foundCrc = computeCRC8(bytesToCrc, 2); // Calculate what the CRC should be for these two bytes
        if (foundCrc != incoming) // Does this match the CRC byte from the sensor?
        {
          #if SCD4x_ENABLE_DEBUGLOG
          if (_printDebug == true)
          {
            _debugPort->print(F("SCD4x::readMeasurement: found CRC in byte "));
            _debugPort->print(x);
            _debugPort->print(F(", expected 0x"));
            _debugPort->print(foundCrc, HEX);
            _debugPort->print(F(", got 0x"));
            _debugPort->println(incoming, HEX);
          }
          #endif // if SCD4x_ENABLE_DEBUGLOG
          error = true;
        }
        break;
      }
    }
  }
  else
  {
    #if SCD4x_ENABLE_DEBUGLOG
    if (_printDebug == true)
    {
      _debugPort->print(F("SCD4x::readMeasurement: no SCD4x data found from I2C, I2C claims we should receive "));
      _debugPort->print(receivedBytes);
      _debugPort->println(F(" bytes"));
    }
    #endif // if SCD4x_ENABLE_DEBUGLOG
    return (false);
  }

  if (error)
  {
    #if SCD4x_ENABLE_DEBUGLOG
    if (_printDebug == true)
      _debugPort->println(F("SCD4x::readMeasurement: encountered error reading SCD4x data."));
    #endif // if SCD4x_ENABLE_DEBUGLOG
    return (false);
  }
  //Now copy the int16s into their associated floats
  co2 = (float)tempCO2.unsigned16;
  temperature = -45 + (((float)tempTemperature.unsigned16) * 175 / 65536);
  humidity = ((float)tempHumidity.unsigned16) * 100 / 65536;

  //Mark our global variables as fresh
  co2HasBeenReported = false;
  humidityHasBeenReported = false;
  temperatureHasBeenReported = false;

  return (true); //Success! New data available in globals.
}

寄存器 bit[10:0] 全為 0 表示數(shù)據(jù)未就緒,任意一位為 1 表示可讀

四、項(xiàng)目結(jié)果演示

4.1操作流程

初始化上電

wKgZPGoY7AiAJnNfAB6DmLcWIU8108.png

TFT 顯示啟動(dòng)畫(huà)面(CO? MONITOR + Lingzhi Lab 2026),約 1 秒后發(fā)出兩聲短鳴提示初始化成功

顯示 "SCD41 Running..." 動(dòng)態(tài)圓點(diǎn),約 5 秒后第一幀數(shù)據(jù)到達(dá),主界面自動(dòng)切換為實(shí)時(shí)數(shù)據(jù)顯示

主界面(Page 0)

上方 CO? 大圓環(huán) + 下方溫度/濕度小圓環(huán)同時(shí)展示,圓環(huán)顏色隨數(shù)值實(shí)時(shí)變化,右側(cè)等級(jí)標(biāo)簽跟隨更新

wKgZO2oY7A2ABlQdACDMF4kPIsU801.png

旋轉(zhuǎn)編碼器右轉(zhuǎn):翻到下一頁(yè)(CO?詳情 → 溫濕度詳情 → 系統(tǒng)信息 → 循環(huán)回主界面)

旋轉(zhuǎn)編碼器左轉(zhuǎn):翻到上一頁(yè)

SW 按鍵按下

底欄 LIVE 切換為 MUTE(橙色),蜂鳴器靜音;再次按下恢復(fù) LIVE(綠色)

wKgZPGoY7AaANbMJAAWfWYN0uPg608.png

旋轉(zhuǎn)電位器

可以調(diào)節(jié)蜂鳴器告警音量(最小 10% 占空比細(xì)聲,最大 90% 占空比響亮)

wKgZPGoY7A6AMxeuAB2EWruGOxw639.png

CO?溶度超過(guò) 1000ppm蜂鳴器單次告警;超過(guò) 1500ppm 雙次;超過(guò) 2000ppm 三次急促告警,圓環(huán)變紅

4.2 視頻演示

https://live.csdn.net/v/528726?spm=1001.2014.3001.5501

本視頻展示基于零知派標(biāo)準(zhǔn)板驅(qū)動(dòng) Sensirion SCD41 CO?傳感器的完整室內(nèi)空氣質(zhì)量監(jiān)測(cè)系統(tǒng)。演示內(nèi)容包括:系統(tǒng)上電初始化流程、ST7789 TFT 淺色主題三環(huán)儀表盤(pán)實(shí)時(shí)刷新效果、旋轉(zhuǎn)編碼器左右翻頁(yè)切換四個(gè)顯示界面(主界面/CO?詳情/溫濕度露點(diǎn)/系統(tǒng)信息)、電位器實(shí)時(shí)調(diào)節(jié)蜂鳴器音量、SW 按鍵靜音切換、以及模擬高CO?環(huán)境時(shí)的分級(jí)告警蜂鳴效果

五、工作原理講解

SCD41 采用光聲光譜(PAS)技術(shù),是一種基于 NDIR 的 CO?測(cè)量方案。其工作核心是CO?分子對(duì)波長(zhǎng)約 4.26 μm 的紅外光有強(qiáng)烈的選擇性吸收

wKgZPGoY7BGAOdJBAAVj_eV4rRI427.png

傳感器內(nèi)部:

紅外光源周期性發(fā)射寬譜紅外光

光穿過(guò)含有待測(cè)氣體的腔體

特定波長(zhǎng)的光被 CO?分子吸收,剩余光被探測(cè)器接收

通過(guò) Beer-Lambert 定律計(jì)算 CO?濃度

A = ε × c × L
A: 吸光度 ε: 摩爾消光系數(shù)(CO?固有屬性) c: 濃度(即我們要測(cè)的值) L: 光程長(zhǎng)度(腔體固定)

5.1 SCD41 通信時(shí)序

SCD41 的 I2C 地址固定為 0x62,不可更改。通信采用標(biāo)準(zhǔn) I2C 協(xié)議,命令格式為 16 位命令字(MSB 先發(fā))

①寫(xiě)命令時(shí)序

wKgZPGoY7RKAfiYDAABDjMLWTlE693.png

②基礎(chǔ)命令

wKgZO2oY7S6ADuLzAACdn0U_1bY735.png

start_periodic_measurement(0x21B1)發(fā)出后必須等待 5 秒才能讀取,發(fā)送其他命令(如 stop_periodic_measurement 0x3F86)后需等待 500ms 才能繼續(xù)操作

③讀數(shù)據(jù)時(shí)序

wKgZO2oY7w-AeCZ5AABObsq_NPU491.png

④一次完整測(cè)量讀取的數(shù)據(jù)幀格式

總計(jì) 9 字節(jié),每?jī)勺止?jié)數(shù)據(jù)附一字節(jié) CRC-8

wKgZPGoY7yCANX9XAALw6jkkgFQ237.png

溫度換算

wKgZPGoY7y6ALUo-AAASs_PePnE533.png

濕度換算

wKgZO2oY7zSAfKiPAAASQDm82IE602.png

5.2 自動(dòng)自校準(zhǔn)機(jī)制

SCD41 內(nèi)置 ASC 算法,假設(shè)傳感器在使用期間至少每周會(huì)暴露一次室外新鮮空氣(約 400ppm)。ASC 會(huì)統(tǒng)計(jì)歷史測(cè)量中的最低 CO?值,并以此為基準(zhǔn)自動(dòng)漂移校準(zhǔn)

wKgZPGoY7zyAYJcXAADHute8pKU933.png

5.3旋轉(zhuǎn)編碼器原理

EC11 是一種機(jī)械式增量旋轉(zhuǎn)編碼器,內(nèi)部有兩組相位差 90° 的觸點(diǎn)(A相/CLK 和 B相/DT)。旋轉(zhuǎn)時(shí)兩相產(chǎn)生交替的高低電平變化,通過(guò)判斷兩相的相位超前/滯后關(guān)系確定旋轉(zhuǎn)方向

光電編碼原理

wKgZO2oY70qAQvrhAAAndoD-H60889.png

編碼器內(nèi)部有一個(gè)帶有柵格的光碼盤(pán),紅外發(fā)射管和接收管分別位于碼盤(pán)兩側(cè)、旋轉(zhuǎn)時(shí),柵格交替遮擋光線,產(chǎn)生脈沖信號(hào)

②A/B相信號(hào)產(chǎn)生

正交編碼:兩個(gè)光電傳感器安裝位置相差1/4個(gè)柵格間距,產(chǎn)生相位差90°的A相和B相信號(hào)

wKgZomUnpXiAPhdvAAX24toIEmk322.gif

正轉(zhuǎn):A 相脈沖的上升沿 / 下降沿超前B 相 90°, A 相先變化,B 相后變化
反轉(zhuǎn):B 相脈沖的上升沿 / 下降沿超前A 相 90°, B 相先變化,A 相后變化

③格雷碼編碼

將 A、B 兩相的當(dāng)前值拼成 2 位二進(jìn)制(encoded = CLK<<1 | DT),與上一次狀態(tài)一起組成 4 位索引((last<<2)|current),查 16 格表直接得到方向值 {+1/-1/0}

順時(shí)針旋轉(zhuǎn)時(shí),A 引腳先于 B 引腳接地,格雷碼按00→01→11→10→00的順序循環(huán)

wKgZO2oY73eAAXILAABOIIG6hCA641.png


逆時(shí)針旋轉(zhuǎn)時(shí),B 引腳先于 A 引腳接地,格雷碼按00→10→11→01→00的順序循環(huán)

wKgZO2oY74GAFtMVAABPA5ezPAY554.png

每旋轉(zhuǎn)一格產(chǎn)生 4 個(gè)有效邊沿,累積滿 ±4 才確認(rèn)一次有效旋轉(zhuǎn)

六、常見(jiàn)問(wèn)題解答(FAQ)

Q1:碼器旋轉(zhuǎn)方向反了,或者非常靈敏轉(zhuǎn)一格跳很多頁(yè)?

A:方向反:交換 CLK 和 DT 的接線,或?qū)?+1/-1 查表結(jié)果對(duì)換。跳頁(yè)過(guò)多:檢查 accSteps 閾值是否為 4,以及 ENC_COOLDOWN 是否設(shè)為 400ms

Q2:蜂鳴器一直響或完全不響?

A:確認(rèn)使用的是無(wú)源蜂鳴器,有源蜂鳴器只能響單一固定頻率,無(wú)法響應(yīng) PWM。完全不響檢查 muteEnabled 是否為 true(底欄顯示 MUTE),以及 D3 引腳接線

Q3:為什么CO?數(shù)據(jù)長(zhǎng)時(shí)間顯示"--"?

A:SCD41 startPeriodicMeasurement 后首幀數(shù)據(jù)需要 5 秒。若超過(guò) 15 秒仍無(wú)數(shù)據(jù),檢查 A4/A5 接線和 供電??膳R時(shí)開(kāi)啟 SparkFun 庫(kù)的 Debug 輸出:mySensor.enableDebugging(Serial)

項(xiàng)目資源整合

SCD41 數(shù)據(jù)手冊(cè): SCD4x Data Sheet

SCD4x庫(kù)文件: sparkfun/SparkFun_SCD4x_Arduino_Library

審核編輯 黃宇

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • STM32
    +關(guān)注

    關(guān)注

    2315

    文章

    11223

    瀏覽量

    375708
  • 監(jiān)測(cè)系統(tǒng)

    關(guān)注

    8

    文章

    3124

    瀏覽量

    84800
  • 蜂鳴器
    +關(guān)注

    關(guān)注

    12

    文章

    901

    瀏覽量

    47959
  • 旋轉(zhuǎn)編碼器
    +關(guān)注

    關(guān)注

    5

    文章

    164

    瀏覽量

    27621
收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    ——STM32+SCD41+旋轉(zhuǎn)編碼器室內(nèi)CO?智能監(jiān)測(cè)系統(tǒng),三環(huán)可視化儀表盤(pán) + 分級(jí)告警

    的完整室內(nèi)空氣質(zhì)量監(jiān)測(cè)系統(tǒng)。演示內(nèi)容包括:系統(tǒng)上電初始流程、ST7789 TFT 淺色主題三環(huán)
    發(fā)表于 05-29 14:32

    ——STM32+BMP180結(jié)合旋轉(zhuǎn)編碼器多頁(yè)儀表盤(pán)+ESP-01無(wú)線上位機(jī),級(jí)告警全鏈路IoT氣象監(jiān)控系統(tǒng)

    序列、主界面路數(shù)據(jù)實(shí)時(shí)顯示、旋轉(zhuǎn)編碼器多頁(yè)切換(含水平滑入動(dòng)畫(huà))、溫度/氣壓/海拔個(gè)詳情頁(yè)的圓弧儀表盤(pán)與歷史波形、深色/亮色主題切換、手
    發(fā)表于 06-04 11:39

    虛擬儀表盤(pán)是未來(lái)的趨勢(shì)嗎?

    `昨天聽(tīng)了一場(chǎng)富士通半導(dǎo)體的虛擬儀表盤(pán)解決方案,曾經(jīng)高大上的虛擬儀表盤(pán)正在低成本、低設(shè)計(jì)難度地走入國(guó)產(chǎn)汽車(chē)的design in日程,據(jù)富士通的Speaker說(shuō)捷豹XJL和路虎攬勝就用很早用了他們
    發(fā)表于 09-25 09:43

    汽車(chē)儀表盤(pán)電源設(shè)計(jì)

    PEPS系統(tǒng)始終處于接通狀態(tài),它一直會(huì)從電池中汲取待機(jī)靜態(tài)電流。在儀表盤(pán)中,有幾個(gè)電路會(huì)始終接通,這一點(diǎn)與PEPS系統(tǒng)中的情況是一樣的。比如說(shuō)實(shí)時(shí)時(shí)鐘、CAN/LIN收發(fā)和微控制
    發(fā)表于 09-04 11:48

    【課程筆記】儀表盤(pán)和數(shù)字圖的應(yīng)用

    這期我們的主要任務(wù)是學(xué)習(xí)OurwayBI數(shù)據(jù)可視化工具上的儀表盤(pán)和數(shù)字圖。從作用上來(lái)說(shuō),這兩個(gè)可視化圖表都是用于分析展示關(guān)鍵指標(biāo)或異常指標(biāo),且通常放在報(bào)表前端,便于瀏覽者一眼掌握關(guān)鍵指標(biāo)。廢話不多
    發(fā)表于 05-14 14:59

    一般圖表做不了的分析,BI數(shù)據(jù)可視化圖表可以

    分析場(chǎng)景的可視化圖表,比如上面提到的評(píng)分圖、路線地圖、進(jìn)度儀表盤(pán),又比如地鐵圖、3D地圖、電量百分比圖等。這些可視化圖表極大地彌補(bǔ)了一般圖表做不了的細(xì)致分析展示,已經(jīng)上線就迅速被應(yīng)用于各行各業(yè)
    發(fā)表于 01-15 10:22

    一文淺析汽車(chē)儀表盤(pán)

      汽車(chē)儀表盤(pán)  汽車(chē)儀表盤(pán)是反映車(chē)輛各系統(tǒng)工作狀況的裝置。常見(jiàn)的有燃油指示燈、清洗液指示燈、電子油門(mén)指示燈、前后霧燈指示燈及報(bào)警燈。  不同汽車(chē)的儀表不盡相同。但是一般汽車(chē)的常規(guī)
    發(fā)表于 08-31 06:27

    集成TPMS功能的儀表盤(pán)設(shè)計(jì)方案解析

    、儀表盤(pán)的工作原理及其集成方式分析了系統(tǒng)結(jié)構(gòu)、TPMS天線設(shè)計(jì)和儀表盤(pán)軟件設(shè)計(jì)。采用SP37設(shè)計(jì)TPMS發(fā)射,通過(guò)獨(dú)特的天線設(shè)計(jì)解決了發(fā)射效率和使用壽命的問(wèn)題,通過(guò)設(shè)計(jì)自適應(yīng)控制算法
    發(fā)表于 11-20 15:34 ?2次下載
    集成TPMS功能的<b class='flag-5'>儀表盤(pán)</b>設(shè)計(jì)方案解析

    集成TPMS功能的電動(dòng)汽車(chē)儀表盤(pán)設(shè)計(jì)解析

    的工作原理及其集成方式分析了系統(tǒng)結(jié)構(gòu)、TPMS天線設(shè)計(jì)和儀表盤(pán)軟件設(shè)計(jì)。采用SP37設(shè)計(jì)TPMS發(fā)射,通過(guò)獨(dú)特的天線設(shè)計(jì)解決了發(fā)射效率和使用壽命的問(wèn)題,通過(guò)設(shè)計(jì)自適應(yīng)控制算法解決了儀表盤(pán)
    發(fā)表于 11-21 10:57 ?2次下載
    集成TPMS功能的電動(dòng)汽車(chē)<b class='flag-5'>儀表盤(pán)</b>設(shè)計(jì)解析

    汽車(chē)儀表盤(pán)維修_汽車(chē)儀表盤(pán)可以修理嗎_汽車(chē)儀表盤(pán)維修多少錢(qián)

    汽車(chē)儀表盤(pán)是反映車(chē)輛各系統(tǒng)工作狀況的裝置。常見(jiàn)的有燃油指示燈、清洗液指示燈、電子油門(mén)指示燈、前后霧燈指示燈及報(bào)警燈。
    發(fā)表于 01-11 10:45 ?6.5w次閱讀

    儀表盤(pán)液晶發(fā)展趨勢(shì)_奧迪在打什么算盤(pán)?

    現(xiàn)在很多汽車(chē)廠家開(kāi)始使用液晶儀表盤(pán),更將多媒體導(dǎo)航娛樂(lè)系統(tǒng)集成在儀表盤(pán)上,為什么會(huì)有這樣的變化?會(huì)影響行車(chē)安全嗎?儀表盤(pán)液晶是近年來(lái)一個(gè)很
    發(fā)表于 03-13 11:17 ?2386次閱讀

    手把手教你完成數(shù)據(jù)儀表盤(pán)的設(shè)計(jì)步驟

    數(shù)據(jù)可視化設(shè)計(jì)是利用可視化工具將數(shù)據(jù)通過(guò)大屏幕放映來(lái)進(jìn)行匯報(bào),以幫助企業(yè)規(guī)避商業(yè)風(fēng)險(xiǎn)并做出良好的業(yè)務(wù)決策。儀表盤(pán)則是作為一個(gè)輔助工具,利用數(shù)據(jù)可視化,將繁瑣復(fù)雜的數(shù)據(jù)以更為直觀地方式展
    的頭像 發(fā)表于 03-25 18:05 ?8934次閱讀
    手把手教你完成數(shù)據(jù)<b class='flag-5'>儀表盤(pán)</b>的設(shè)計(jì)步驟

    克服汽車(chē)儀表盤(pán)電源設(shè)計(jì)難題

    克服汽車(chē)儀表盤(pán)電源設(shè)計(jì)難題
    發(fā)表于 11-03 08:04 ?3次下載
    克服汽車(chē)<b class='flag-5'>儀表盤(pán)</b>電源設(shè)計(jì)難題

    環(huán)編碼器:精準(zhǔn)定位與高效旋轉(zhuǎn)控制的創(chuàng)新解決方案

    在當(dāng)今高度自動(dòng)智能化的工業(yè)領(lǐng)域,每一個(gè)微小的運(yùn)動(dòng)控制都承載著關(guān)鍵的任務(wù)與期望。磁環(huán)編碼器,作為旋轉(zhuǎn)位置檢測(cè)領(lǐng)域的明星產(chǎn)品,正以其卓越的性
    的頭像 發(fā)表于 02-28 08:54 ?1344次閱讀

    先積電源產(chǎn)品在電動(dòng)車(chē)儀表盤(pán)領(lǐng)域的應(yīng)用

    兩輪車(chē)的“智能交互中樞”兩輪車(chē)儀表盤(pán),是集成行駛數(shù)據(jù)顯示、功能控制與信息交互的核心車(chē)載設(shè)備,核心價(jià)值在于“以可視化界面實(shí)現(xiàn)騎行狀態(tài)監(jiān)測(cè)智能
    的頭像 發(fā)表于 11-12 10:52 ?755次閱讀
    先積電源產(chǎn)品在電動(dòng)車(chē)<b class='flag-5'>儀表盤(pán)</b>領(lǐng)域的應(yīng)用
    郸城县| 财经| 汉源县| 盐亭县| 横峰县| 赤壁市| 望都县| 保德县| 博白县| 布尔津县| 六安市| 章丘市| 庆阳市| 镇平县| 高州市| 台中县| 鲁甸县| 大邑县| 汉川市| 绍兴市| 酒泉市| 富宁县| 鄂州市| 平湖市| 康马县| 舞钢市| 邢台市| 萨嘎县| 光泽县| 新平| 南丰县| 大丰市| 安多县| 丰县| 大埔县| 中宁县| 开鲁县| 城口县| 天全县| 龙州县| 治县。|