HackMD 匯入暫存區

03_03

03/04 技術發表會分工,時辰排定 image 贈品製作及詢價 image

IG發文乾枯期 需要有模板,每周OR兩周發文一次(承和負責)

如何從網頁整理資料

如何從網頁整理資料

基礎

Step 1

進階

空速度計

撰寫人: 范紹捷/動力組/5~9代

📌 系統目標

使用 STM32 MCU 從以下來源擷取資料:

🔧 系統架構

感測器/模組 功能 照片
MPXV7002 壓力感測 image
stm32 運算 image
GUI 主機 顯示資料 USARTx_TX (UART 傳輸腳位)

🔌 感測器與接腳

螢幕擷取畫面 2025-05-21 164842

軟體架構

MPXV7002 ⇩ ADC ⇩ 壓力/風速計算 ⇩ STM32 格式化字串 ⇩ UART 傳送給 GUI

🧮 風速計算公式

壓力轉換公式:

pressure_kPa = (voltage - 2.5) / 1.0;  // ±2kPa 對應 0.5V~4.5V

風速計算(使用伯努力定律):

airspeed_mps = sqrt(2 * abs(pressure_kPa) * 1000 / 1.225);
airspeed_kmh = airspeed_mps * 3.6;

🧰 STM32 程式碼片段

1️⃣ ADC 電壓讀取(以 12-bit 為例) 112~114行

HAL_ADC_Start(&hadc1);
HAL_ADC_PollForConversion(&hadc1,100);
if(HAL_IS_BIT_SET(HAL_ADC_GetState(&hadc1),HAL_ADC_STATE_REG_EOC))
ADC_Value = HAL_ADC_GetValue(&hadc1);

2️⃣ 壓力/風速計算 118~121行

ADC_Volt = (float)ADC_Value/4096*3.3;
float pressure = (ADC_Volt - V_OFFSET) / SENSITIVITY;  //kPa
float airspeed = sqrt(2 * fabs(pressure) * 1000.0f / AIR_DENSITY);   
float airspeed_kmh = airspeed * 3.6f;

3️⃣ 格式化字串並透過 UART 傳送 123~126行

if(HAL_GetTick()%100 == 0){ //USRT Send
    char buf[100];
    sprintf(buf, "Volt:%.2lf V \t P:%.2lf kPa \t S:%.2lf Kmh\n", ADC_Volt,pressure,airspeed_kmh);
    HAL_UART_Transmit(&huart1, (uint8_t*)buf, strlen(buf), HAL_MAX_DELAY);
}

🧰 STM32 程式碼

image

空速紀Wurth

專案說明

本文檔示範如何使用 STM32 HAL 同時讀取三顆 Würth WSEN 環境感測器,並透過 Titania 無線模組將感測器資料以 UART 傳輸發送。

支援感測器:

Titania 無線模組預設 UART 波特率 9600,支持命令模式下切換波特率至 115200 提升通信速率。


硬體接線


I²C 地址對應

Sensor 7-bit I²C 地址 備註
WSEN-HIDS 0x44 濕度 + 溫度
WSEN-PADS 0x5C / 0x5D 氣壓 + 溫度 (SAO 腳選)
WSEN-PDUS 0x78 差壓 + 溫度

主要程式架構

1. 讀取感測器數據

I²C讀取感測器數據

HIDS_Read(&hi2c1, &HIDS);
PADS_Read(&hi2c1, &PADS);
PDUS_Read(&hi2c1, &PDUS);

讀取後的數據

Sensor 變數名稱 資料內容
WSEN-HIDS HIDS.temperature_c,HIDS.humidity_rh 濕度 , 溫度
WSEN-PADS PADS.pressure_kpa,PADS.temperature_c 氣壓 , 溫度
WSEN-PDUS PDUS.pressure_kpa,PDUS.temperature_c 差壓 , 溫度

2. 讀取感測器數據詳細函式

1. WSEN‑HIDS (I²C 0x44) 讀取流程

命令 0xFD 為高精度測量,轉換時間約 8.4 ms。 接著讀取 6 bytes:T + CRC + RH + CRC。​

#define HIDS_ADDR (0x44 << 1)
HAL_StatusTypeDef HIDS_Read(I2C_HandleTypeDef *hi2c, SensorData_t *data)
{
    uint8_t cmd = 0xFD;
    uint8_t rx[6];
    HAL_I2C_Master_Transmit(hi2c, HIDS_ADDR, &cmd, 1, HAL_MAX_DELAY);
    HAL_Delay(9); // wait conversion
    HAL_I2C_Master_Receive(hi2c, HIDS_ADDR, rx, 6, HAL_MAX_DELAY);

    uint16_t Traw = (rx[0] << 8) | rx[1];
    uint16_t RHraw = (rx[3] << 8) | rx[4];

    data->temperature_c = -45.0f + 175.0f * (float)Traw / 65535.0f;
    data->humidity_rh = 100.0f * (float)RHraw / 65535.0f;
    return HAL_OK;
}

2. WSEN‑PADS (I²C 0x5C) 氣壓與溫度

壓力暫存器 0x28–0x2A (24 bit),溫度 0x2B–0x2C (16 bit)。 壓力轉換式:P(Pa) = raw / 40960.0f,溫度:T(°C) = raw * 0.01f。

#define PADS_ADDR (0x5C << 1)

void PADS_Init(I2C_HandleTypeDef *hi2c)
{
    uint8_t cfg[2] = {0x10, 0b00011000}; // ODR=25Hz, 連續模式
    HAL_I2C_Master_Transmit(hi2c, PADS_ADDR, cfg, 2, 100);
}

HAL_StatusTypeDef PADS_Read(I2C_HandleTypeDef *hi2c, SensorData_t *data)
{
    uint8_t reg = 0x28;
    uint8_t rx[5];
    HAL_I2C_Master_Transmit(hi2c, PADS_ADDR, &reg, 1, 100);
    HAL_I2C_Master_Receive(hi2c, PADS_ADDR, rx, 5, 100);

    int32_t Praw = (int32_t)((rx[2] << 16) | (rx[1] << 8) | rx[0]);
    int16_t Traw = (int16_t)((rx[4] << 8) | rx[3]);
    data->pressure_kpa = Praw / 4096.0f / 10.0f; // convert Pa → kPa
    data->temperature_c = Traw * 0.01f;
    return HAL_OK;
}

3. WSEN‑PDUS (I²C 0x78) 差壓與溫度

每 2.2 ms 更新,4 byte:P + T (各 15 bit)。​ 氣壓轉換式: P(kPa) = (rawP - OUTPMIN) × SENP + PMIN 溫度: T(°C) = (rawT - 8192) × 4.272e-3

以下以型號 2513130810301 (0‑100 kPa @ 5 V) 為例:

#define PDUS_ADDR (0x78 << 1)
#define OUTPMIN  3277
#define SENP     3.815e-3
#define PMIN     0.0

HAL_StatusTypeDef PDUS_Read(I2C_HandleTypeDef *hi2c, SensorData_t *data)
{
    uint8_t rx[4];
    HAL_I2C_Master_Receive(hi2c, PDUS_ADDR, rx, 4, 100);

    uint16_t Praw = ((rx[0] << 8) | rx[1]) & 0x7FFF;
    uint16_t Traw = ((rx[2] << 8) | rx[3]) & 0x7FFF;

    data->pressure_kpa = (Praw - OUTPMIN) * SENP + PMIN;
    data->temperature_c = (Traw - 8192) * 4.272e-3f;
    return HAL_OK;
}

2. Titania UART 波特率修改指令

HAL_StatusTypeDef Titania_SetBaudRate115200(UART_HandleTypeDef *huart)
{
uint8_t cmd[] = {
0x02, // Start
0x09, // CMDSETREQ
0x06, // Length
0x50, // Memory address UARTBaudrate
0x04, // Data length 4 bytes
0x00, 0xC2, 0x01, 0x00, // 115200 LSB first
0x00 // Checksum placeholder
};
uint8_t cs = 0;
for(int i=0; i<sizeof(cmd)-1; i++) cs ^= cmd[i];
cmd[sizeof(cmd)-1] = cs;


return HAL_UART_Transmit(huart, cmd, sizeof(cmd), HAL_MAX_DELAY);
}

text

3. 主程示範流程

int main(void) { HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_I2C1_Init();

text // 初始 UART 設定為 9600bps MX_USART1_UART_Init_9600();

SensorData_t HIDS, PADS, PDUS;

// 初始化 Titania (如果需要) // ...

// 傳送改波特率指令 if(Titania_SetBaudRate115200(&huart1) == HAL_OK) { HAL_Delay(100); // 等待模組切換

// MCU UART 也切換 115200
MX_USART1_UART_Init_115200();

}

while(1) { HIDS_Read(&hi2c1, &HIDS); PADS_Read(&hi2c1, &PADS); PDUS_Read(&hi2c1, &PDUS);

// 整合資料格式
char payload;
int len = snprintf(payload, sizeof(payload),
    "HIDS: %.2fC %.1f%%, PADS: %.2fkPa %.2fC, PDUS: %.2fkPa %.2fC",
    HIDS.temperature_c, HIDS.humidity_rh,
    PADS.pressure_kpa, PADS.temperature_c,
    PDUS.pressure_kpa, PDUS.temperature_c);

// 傳送資料到 Titania
HAL_UART_Transmit(&huart1, (uint8_t*)payload, len, HAL_MAX_DELAY);

HAL_Delay(500);

} }

text

4. UART 初始化函式 (示意)

void MX_USART1_UART_Init_9600(void) { huart1.Instance = USART1; huart1.Init.BaudRate = 9600; huart1.Init.WordLength = UART_WORDLENGTH_8B; huart1.Init.StopBits = UART_STOPBITS_1; huart1.Init.Parity = UART_PARITY_NONE; huart1.Init.Mode = UART_MODE_TX_RX; huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE; huart1.Init.OverSampling = UART_OVERSAMPLING_16; HAL_UART_Init(&huart1); }

void MX_USART1_UART_Init_115200(void) { huart1.Instance = USART1; huart1.Init.BaudRate = 115200; huart1.Init.WordLength = UART_WORDLENGTH_8B; huart1.Init.StopBits = UART_STOPBITS_1; huart1.Init.Parity = UART_PARITY_NONE; huart1.Init.Mode = UART_MODE_TX_RX; huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE; huart1.Init.OverSampling = UART_OVERSAMPLING_16; HAL_UART_Init(&huart1); }

text


注意事項


參考資料


新車手須知與訓練方式

前言

學生方程式賽車跟卡丁車非常不一樣,實際駕駛方式介於競賽用卡丁車與大馬力實車中間,重心轉移比卡丁車明顯很多,動力相較於卡丁車有相當顯著的提升,因此請控制好你的右腳,體驗並習慣車輛過彎時帶來的G力。

[!Tip] 保車不保人,車輛安全第一,車手第二。

一、第一次駕駛賽車:

1.定圓:

主要目標:感受車輛過彎極限

進階項:嘗試在Oversteer後救車

車輛設定如下,

[!Tip] 定轉角緩加油門及定油門緩加轉角 Spin或推頭都沒關係,請習慣賽車過彎時的G力並嘗試將車輛保持在過彎極限


2.賽道試走:

主要目標:熟悉油門煞車

油門煞車熟悉後可嘗試做秒數。 場地:大賽道(K1、瑪吉斯、永安等),不用擺角錐

車輛設定如下,

[!Tip] 第一圈請熟悉賽道路線 第二圈開始熟悉油門煞車,建議先試煞車後試油門,試煞車請在直線盡力重煞,嘗試在輪胎不鎖死下用最短的距離將車輛停下,油門深度請盡自己所能,目的在感受有多少動力可以使用,全油時間不用久,老話一句保車不保人。


二、比賽項目練習

3.Skidpad:

主要目標:熟悉輪胎回饋與車輛動態

場地:空地,角錐擺完整Skidpad,周圍留緩衝空間(可參考澳洲賽) 車輛設定如下,

[!Tip] 第一趟請熟悉Skidpad Layout以及前翼、內側後輪與角錐的距離,撞到會加秒因此請以不撞到為目標 距離抓好後開始做秒數,彎中先以定速或緩加速為目標盡量維持穩態轉向 每一趟都要記時並留下紀錄


4.AutoX:

主要目標:快速記路線、熟知角錐擺放方式與意義

場地:擺放AutoX完整layout

車輛設定如下,

[!Tip] 在開賽車前請用滑板車或步行方式走完賽道,並記住路線與進彎點、決定好自由繞錐左進或右進、感受路面鋪裝品質。 實際上場前只有約兩趟賽道試走機會,請在兩趟內決定並記好路線。 第一圈一樣建議先以熟悉賽道為主,熟悉後可自行決定開車節奏

零件整理說明(20250731)

請幫我依照以下步驟

  1. 打開NAS裡的編號整理表
  2. 複製MOUSER編號到搜尋欄
  3. 查看零件資訊
  4. 登記表單

📘 步驟一:打開「編號整理表」

請先開啟「文件整理表單」,確認您要處理的零件項目,點開型號整理文件網址。 image image image


🔍 步驟二:複製 MOUSER 編號並前往官網搜尋

複製表中的 MOUSER 編號。 進入 MOUSER 官網,將編號貼上至搜尋欄並查詢零件資訊。 MOUSERE官網 image


📄 步驟三:查看零件詳細資訊

查詢後,請確認下列資訊: 零件圖片與描述是否正確,技術規格與型號是否與需求相符 image


📝 步驟四:填寫 NAS 零件表單

請回到 NAS 零件表單連結,並依照下列項目填寫: 零件名稱 MOUSER 編號 描述(如規格、封裝、品牌等) 備註(如用途或替代品) NAS表單連結 image


✅ 注意事項:

請逐筆核對資料,避免誤填或遺漏。 若遇缺貨、無資料或型號不符,請在「備註」欄標註並回報負責人。 如需協助,請聯絡專案負責人。感謝您的配合!

Hackmd訪談

  1. 使用人數增 已提交
  2. 使用情況
  3. 團隊公開頁改版2週內
  4. 更多的社群頁面
  5. 11月會有更多的頁面像FB?
  6. 可以轉FB
  7. 詢問招生規模
  8. 出席大活動經驗

Tip