Try   HackMD

2024 嵌入式作業系統分析與實做 Final Project

實作內容:
自動餵食器 Automatic feeder

動機:

倉鼠的飼主遇到以下幾個問題:
1.忘記餵食飼料
2.觀察倉鼠的健康狀況 (透過倉鼠有無按時吃飯)
3.觀察倉鼠的活動量

餵食模組:

每隔固定時間進行餵食,同時感測倉鼠有無站在飼料盒前方進食,若無則發出聲音提示

運動計時模組:

透過滾輪的圈數來了解倉鼠的運動量,允用紅外線感應搭配滾輪上的擋板檢測圈數

顯示模組:

運用 LCD 面板顯示倉鼠的資訊
1.進食次數與多久未進食
2.所跑圈數

所有的任務列表

  MsgQueue = xQueueCreate(1, sizeof(unsigned int));  // sign for switch display mode
  xTaskCreate(InfraredTask, "InfraredTask", 128, NULL, 1, NULL);   // detect running lap
  xTaskCreate(ButtonTask, "ButtonTask", 128, NULL, 1, NULL);       // switch lcd displaymode
  xTaskCreate(Display, "Display", 128, NULL, 1, NULL);             // show lcd content
  xTaskCreate(BuzzerTask, "BuzzerTask", 128, NULL, 1, NULL);       // sound beep to remind eating
  xTaskCreate(Motor_Task, "Motor_Task", 128, NULL, 1, NULL);       // check if have eaten
  xTaskCreate(TimerTask, "TimerTask", configMINIMAL_STACK_SIZE, NULL, 1, &xTimerTaskHandle);  // Timer

LCD 螢幕顯示

透過藍色按鈕切換顯示模式,用顯示餵食狀況說明並運用 i2c-lcd.hi2c-lcd.c 控制 LCD 面板,lcd_put_cur(0, 0); 可以控制要從 LCD 螢幕中哪個位置開始輸出,(0, 0) 為第一列第一個。

#include "i2c-lcd.h" // for LCD module
if(displaymode == 0){
    for (;;) {
        lcd_clear();  // clear screen
        lcd_put_cur(0, 0);   // go to printing place
        sprintf(buffer, "eat: %u    %lu", eat, timeCounter);   // push output string to buffer
        lcd_send_string(buffer);  // show string 

        lcd_put_cur(1, 0);   // go to printing place
        memset(buffer, 0, sizeof(buffer));  // reset buffer
        sprintf(buffer, "noneat time: %lu", wait_timeCounter);
        lcd_send_string(buffer);

        xQueueReceive(MsgQueue, &displaymode, 0);
        vTaskDelay(10);
        if(displaymode == 1) break;
    }
}

紅外線感測滾輪圈數

在原有的滾輪上加裝擋板,當紅外線感測到檔板時計一圈,並且是當狀態改變的時候增加一圈,避免檔板剛好停在感應處,造成一直增加圈數的問題。
objectDetected :感測到檔板
RunningLap :實際的圈數

void InfraredTask(void *pvParameters)
{
    for (;;)
    {
         if (HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_4) == GPIO_PIN_RESET) {
            if (objectDetected == 0) {
                objectDetected = 1;
                RunningLap++;
            }
         }
         else
            objectDetected = 0;
        vTaskDelay(10);
    }
}

馬達驅動餵食器

利用 PWM 控制馬達的運行
if (timeCounter % FEEDING_INTERVAL_SECONDS ==0) 控制餵食頻率,接著初始化馬達 HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_4); ,再透過 __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_4, 150); 控制馬達的轉速,目的是將馬達轉動 90 度並稍微停頓後轉回,模擬到飼料的情境

void Motor_Task(void *pvParameters){
    for (;;){
        if (timeCounter % FEEDING_INTERVAL_SECONDS ==0){
        HAL_GPIO_WritePin(GPIOD, GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15, GPIO_PIN_RESET);
        HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_4);

        uint32_t From_begin_time = HAL_GetTick();
        __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_4, 150);
        while(HAL_GetTick() - From_begin_time < 500 / portTICK_RATE_MS){}

        From_begin_time = HAL_GetTick();
        __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_4, 50);
        while(HAL_GetTick() - From_begin_time < 500 / portTICK_RATE_MS){}

        From_begin_time = HAL_GetTick();
        __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_4, 150);
        while(HAL_GetTick() - From_begin_time < 500 / portTICK_RATE_MS){}
        }
    }
}

壓力感測模組

作為 GPIO 外部中斷 call back 函數,當觸摸壓力感測器,表示有進食因此重設未進食時間並停止蜂鳴器,同時有用黃燈顯示幫助觀察

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) //  touch pressure sensor
{
    if (GPIO_Pin == GPIO_PIN_5)
    {
        HAL_GPIO_TogglePin(GPIOD, GPIO_PIN_12);  // yellow light
        touch = 1;                               // set torch to True(1)
        wait_timeCounter = 0;                    // reset wait_timeCounter
    }
}

硬體設定與腳位

SYS -> Timebase Source : TIM7

驅動馬達的硬體設置

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

pin 腳

因為需要連接 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