前回AD22100温度センサで「温度監視」。といいながら温度をOLEDに表示するだけでお茶を濁してました。何か監視した結果っぽいアクションを起こしたいデス(形だけですが。)そこでブザー(パッシブ型)を接続、規定温度を超えたらブザーを鳴らして警告するようにしてみました。タスク間の通知にNotification使用。
※「モダンOSのお砂場」投稿順Indexはこちら
※Arduino IDE上で「スケッチ」形式のソースからFreeRTOSを使って実験してみてます。ターゲット機はArduino UNO R4 Minima。泣く子も黙る?ArmコアのルネサスRA4M1マイコン搭載機です。
ブザー(Passive)
手元にはActive型、Passive型ともに圧電ブザーの在庫あり。どっちを使用かと迷ったのですが、別シリーズの以下の回で「Groveモジュール」化されたPassive型ブザーを使ってました(自分のやったことなのに年寄には記憶なく、検索してみつけましたぞ。忘却力。)
部品屋根性(27) ActiveブザーとPassiveブザー
Groveコネクタから配線引き出し用のコネクタ付ケーブルを相当昔に自作してあるので、Groveコネクタ付のモジュールは接続がお楽。接続は電源、グラウンドとSIGの3端子。Passive型なので、PWMなど使ってテキトーな波形をSIG端子に印加しないと鳴りませぬ。
今回実験の回路
前回の回路にPassive型ブザーモジュールを追加しただけです。UNO R4はArduino UNO3と互換性通りの端子にPWM可能な信号が出ているので、D6端子で制御することにいたしました。
今回実験のソースコード
Arduino式(.ino形式「スケッチ」)ソース全文が以下に。いつもの通り、前回ソースの「チョイ変」です。Task3というタスクを追加して、これをブザーの制御に割り当てました。Task3は、
-
- 誰か他のTaskからNotificationが到来するのを待つ(Take)
- Nortificationが到来するとブザーを3秒ならす
- その後、Notification待ちに戻る
上記だけのタスクです。一方前回温度センサを監視するお役目を与えたTask2には、前回同様の以下の1だけでなく、2のお仕事も与えました。
-
- 測定した温度をOLED表示タスクにQueue経由で送る
- 測定した温度が40℃を超えたらブザーが鳴るようにTask3にNotificationをGiveする。
なお、Arduino環境の場合、PWM波形はanalogWrite()関数で簡単に出力できるのでお楽(周波数はキメウチだけれども。)
ソースが以下に。
#include <Arduino_FreeRTOS.h> #include <U8x8lib.h> #define AWAITMAX1 (1000) #define AWAITMAX2 (2000) #define BuzzorON (128) #define BuzzorOFF (0) #define BuzzorWait (3000) U8X8_SSD1306_128X64_NONAME_HW_I2C u8x8(/* reset=*/ U8X8_PIN_NONE); TaskHandle_t oled_task, task1, task2, task3; const uint8_t queueSize = 1; QueueHandle_t msgQueue1, msgQueue2; int msg1, msg2; int ad22100pin = A3; int ad22100val = 0; int buzzor = 6; int getTemperature() { ad22100val = analogRead(ad22100pin); return -(562650-2000*ad22100val)/9207; } void setup() { Serial.begin(115200); while (!Serial) { } u8x8.begin(); u8x8.setPowerSave(0); msgQueue1 = xQueueCreate(queueSize, sizeof(int)); msgQueue2 = xQueueCreate(queueSize, sizeof(int)); auto const rc_oled = xTaskCreate ( oled_thread_func, static_cast<const char*>("OLED Thread"), 512 / 4, nullptr, 1, &oled_task ); if (rc_oled != pdPASS) { Serial.println("Failed to create 'OLED' thread."); return; } auto const rc_task1 = xTaskCreate ( task1_func, static_cast<const char*>("Task1"), 512 / 4, nullptr, 1, &task1 ); if (rc_task1 != pdPASS) { Serial.println("Failed to create 'task1' thread"); return; } auto const rc_task2 = xTaskCreate ( task2_func, static_cast<const char*>("Task2"), 512 / 4, nullptr, 1, &task2 ); if (rc_task2 != pdPASS) { Serial.println("Failed to create 'task2' thread"); return; } auto const rc_task3 = xTaskCreate ( task3_func, static_cast<const char*>("Task3"), 512 / 4, nullptr, 1, &task3 ); if (rc_task3 != pdPASS) { Serial.println("Failed to create 'task3' thread"); return; } u8x8.setFont(u8x8_font_chroma48medium8_r); u8x8.setInverseFont(1); u8x8.drawString(0,0,"TASK->OLED"); u8x8.setInverseFont(0); u8x8.drawString(0,1,"TASK1: "); u8x8.drawString(0,2,"TEMP : "); Serial.println("Starting scheduler ..."); vTaskStartScheduler(); for( ;; ); /* Never! */ } /* NEVER CALLED! */ void loop() { Serial.println(millis()); vTaskDelay(configTICK_RATE_HZ); } void oled_thread_func(void *pvParameters) { char buf[16]; int ts1, ts2; while (1) { if (xQueueReceive(msgQueue1, (void *)&ts1, 0) == pdTRUE) { sprintf(buf, "%d", ts1); u8x8.drawString(7,1,buf); } if (xQueueReceive(msgQueue2, (void *)&ts2, 0) == pdTRUE) { sprintf(buf, "%d", ts2); u8x8.drawString(7,2,buf); } sprintf(buf, "%d", ad22100val); u8x8.drawString(0,3,buf); u8x8.refreshDisplay(); taskYIELD(); } } void task1_func(void *pvParameters) { int count = 0; while (1) { msg1 = count; if (xQueueSend(msgQueue1, (void*)&msg1, 2) == pdTRUE) { count++; } vTaskDelay(AWAITMAX1); } } void task2_func(void *pvParameters) { int ecount = 0; while (1) { msg2 = getTemperature(); if (msg2 > 40) { xTaskNotifyGive(task3); } if (xQueueSend(msgQueue2, (void*)&msg2, 2) != pdTRUE) { ecount++; } vTaskDelay(AWAITMAX2); } } void task3_func(void *pvParameters) { while (1) { ulTaskNotifyTake(pdTRUE, portMAX_DELAY); analogWrite(buzzor, BuzzorON); vTaskDelay(BuzzorWait); analogWrite(buzzor, BuzzorOFF); } }
実機動作確認
以下写真のAD22100付近に、ドライヤーで熱風を吹きかけました。
OLEDに表示される温度はぐんぐん上昇します。40℃超えた、60℃近いのだけれど、Buzzorの音が聞こえんぜよ。
ドライヤーを止めたらブザーの音が聞こえました。
なんだドライヤーの音が大きくてブザー音がかき消されてたのね。大丈夫か耳も悪くなってないか。