倉鼠的飼主遇到以下幾個問題:
1.忘記餵食飼料
2.觀察倉鼠有無按時吃飯
3.觀察倉鼠的活動量
每隔固定時間投放飼料,同時感測倉鼠有無站在飼料區前進食,若無則發出聲音提示
透過滾輪的圈數計算倉鼠的運動量,使用紅外線感應器,搭配滾輪上的擋板,檢測滾輪圈數。
使用紅外線檢測,易於按裝在現有飼養盒中
運用 LCD 面板顯示倉鼠的相關資訊
Evaluation Boards: STM32F407G-DISC1
IDE: STM32CubeIDE
OS: FreeRTOS
Language: C
在原有的滾輪上加裝擋板,用於紅外線的感測。每當紅外線感測到檔板時增加圈數,並且是當狀態改變時才增加,避免檔板剛好停在感應處,造成一直增加圈數的問題。
objectDetected
:感測到檔板
RunningLap
:實際的圈數
task
用於紀錄切換的模式,count
紀錄按鈕按壓次數
這裡切換顯示模式的方法,是透過檢查 count 是奇數或是偶數來切換,再透過 MsgQueue 將切換的資訊傳遞給其他任務,最後為了減少切換的延遲,使用 taskYIELD()
將 CPU 釋放給其他需要的任務。
透過藍色按鈕切換兩種顯示模式,顯示餵食狀況與運動狀況
實作方法:
運用 i2c-lcd.h
和 i2c-lcd.c
控制 LCD 面板。
並接收來
分為兩個模式顯示根據 displaymode 決定,
這裡使用 for (;;)
讓畫面一直更新顯示內容,並透過 MsgQueue
接收 ButtonTask()
的訊號,當數值改變時跳出顯示迴圈,切換顯示模式。
主要是透過 GPIO_PIN_RESET
發出聲音,以及 GPIO_PIN_SET
停止聲音,來控制蜂鳴器的聲響
這裡應該改以使用
vTaskDelay()
的方式等待,蜂鳴器不需要太精確的時間控制。
利用 PWM 控制馬達的運行
if (timeCounter % FEEDING_INTERVAL_SECONDS ==0)
控制餵食頻率,此專案設定每 15 秒投放一次飼料。
初始化馬達 HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_4)
,
轉動馬達分為三個步驟,首先是快速轉動閥門,接著短暫的停頓,再將閥門快速關閉。
__HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_4, 150)
控制馬達的轉速,目的是將馬達轉動 90 度並稍微停頓後轉回,模擬到飼料的情境。
這裡使用 while(HAL_GetTick() - From_begin_time < 500 / portTICK_RATE_MS){}
不是使用 vTaskDelay(500)
是因為 vTaskDelay(500)
會受到其他任務執行時間的影響,而馬達轉動需要較精確的時間控制,所以使用此 busy waiting 的方式
原本的設計是希望透過兩個閥門控制,第一個閥門(下閥)用於控制倒出飼料,第二的閥門(上閥)用於將飼料填滿兩個閥門之間的空間,而這個空間就是每次飼料的投放量。(最後僅實作一個)
我們選擇使用軟體的方式來計算時間,雖然 STM32 也有內建硬體計時器可以使用,但由於需要將時間計算與馬達等模組的硬體設置進行同步,因此決定使用軟體計算方式來保持一致性。
使用硬體中斷 call back 函數,並在函數內部判斷 GPIO_Pin 來處理不同的 GPIO 中斷。
當觸摸壓力感測器,表示有進食因此重設未進食時間,同時用黃燈警示。
touch = 1
這裡使用數值而非布林值是因為 FreeRTOS 沒有布林值的數值型態。
當觸發時會中斷前的任務,然後執行此中斷函式,稍微減緩同步問題。
SYS -> Timebase Source : TIM7
因為需要連接 5 個設備,有些設備的 VCC 不是接建議的 5V ,但是還是可以運作
LCD screen | STM board |
---|---|
GND | GND |
VCC | 5V |
SDA | PB9 |
SCL | PB6 |
馬達 SG-90 | STM board |
---|---|
GND (棕色) | GND |
VCC (紅色) | 5V |
PWM 輸入 (橘色) | PA3 |
紅外線 | STM board |
---|---|
GND | GND |
VCC | VDD |
OUT | PC4 |
蜂鳴器 | STM board |
---|---|
GND | GND |
VCC | 3V |
I/O | PA1 |
壓力感測器 | STM board |
---|---|
GND | GND |
VCC | VDD |
SIG | PC5 |