
前回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の音が聞こえんぜよ。
ドライヤーを止めたらブザーの音が聞こえました。
なんだドライヤーの音が大きくてブザー音がかき消されてたのね。大丈夫か耳も悪くなってないか。