#include <Arduino_FreeRTOS.h>
#include <Servo.h>
#include <semphr.h>
#define BUZZER 2
TaskHandle_t TaskA_Handler;
TaskHandle_t TaskB_Handler;
TaskHandle_t TaskC_Handler;
SemaphoreHandle_t xMutex;
char input;
int noteDuration; // 音符の長さ
int notes[]; // 音階の配列
int length; // 配列の長さを初期化
int* durations; // 音符の長さの配列
int playFlag = 0;
// 各メロディーの音階と音符の長さ
int happyBirthday[] = {262, 262, 294, 262, 349, 330, 262, 262, 294, 262, 392, 349, 262, 262, 523, 440, 349, 330, 294, 466, 466, 440, 349, 392, 349};
int noteDurationsHappy[] = {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2};
int maryHadALittleLamb[] = {330, 294, 262, 294, 330, 330, 330, 294, 294, 294, 330, 392, 392, 330, 294, 262, 294, 330, 330, 330, 330, 294, 294, 330, 294, 262};
int noteDurationsMary[] = {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4};
int twinkleTwinkle[] = {262, 262, 392, 392, 440, 440, 392, 349, 349, 330, 330, 294, 294, 262, 392, 392, 349, 349, 330, 330, 294, 294, 262, 262, 262, 262, 392, 392, 440, 440, 392, 349, 349, 330, 330, 294, 294, 262};
int noteDurationsTwinkle[] = {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4};
int starMelody[] = {262, 294, 330, 392, 330, 294, 262, 349, 330, 294, 262, 392, 440, 392, 330, 294, 330, 392, 440, 392, 349, 262, 294, 330, 349, 330, 294, 262};
int noteDurationsStar[] = {8, 8, 8, 4, 8, 8, 4, 4, 8, 8, 8, 4, 8, 8, 4, 4, 8, 8, 8, 4, 8, 8, 4, 4, 8, 8, 8, 4, 8, 4};
void setup() {
// put your setup code here, to run once:
Serial.begin( 115200 );
Serial.println( "***START***" );
notes = happyBirthday;
notes = starMelody;
//Serial.println("番号を入力してください");
//Serial.println("1バースデー 2メリー 3きらきら 4星に願いを 終了は q");
xMutex = xSemaphoreCreateMutex();
xTaskCreate(TaskA, "Serial Task", 128, NULL, 1, &TaskA_Handler);
xTaskCreate(TaskB, "Motor Task", 128, NULL, 1, &TaskB_Handler);
xTaskCreate(TaskC, "Melody Task", 128, NULL, 1, &TaskC_Handler);
vTaskStartScheduler();
}
void loop() {
// put your main code here, to run repeatedly:
}
void TaskA( void *pvParameters ) {
while ( true ) {
Serial.println("受付中");
if(Serial.available() > 0){
// if(xSemaphoreTake(xMutex, portMAX_DELAY) == pdTRUE) {
input = Serial.read();
Serial.print( "input: " );
Serial.println( input );
if(input == '\n' || input == '\r'){
continue;
}
// }
}
vTaskDelay(1000 / portTICK_PERIOD_MS); // 1秒ごとに表示
Serial.println("動作中..."); // 定期的にメッセージを表示
switch (input) {
case '1':
Serial.println("ハッピーバースデーを再生します");
notes = happyBirthday;
// durations = noteDurationsHappy;
// length = sizeof(noteDurationsHappy) / sizeof(noteDurationsHappy[0]);
// notes = (int*)malloc(length * sizeof(int));
// durations = (int*)malloc(length * sizeof(int));
// memcpy(notes, happyBirthday, length * sizeof(int));
// memcpy(durations, noteDurationsHappy, length * sizeof(int));
// playFlag = 1;
break;
case '2':
Serial.println("メリーさんのヒツジを再生します");
notes = maryHadALittleLamb;
// durations = noteDurationsMary;
// length = sizeof(noteDurationsMary) / sizeof(noteDurationsMary[0]);
// notes = (int*)malloc(length * sizeof(int));
// durations = (int*)malloc(length * sizeof(int));
// memcpy(notes, maryHadALittleLamb, length * sizeof(int));
// memcpy(durations, noteDurationsMary, length * sizeof(int));
// playFlag = 1;
break;
case '3':
Serial.println("きらきら星を再生します");
notes = twinkleTwinkle;
// durations = noteDurationsTwinkle;
// length = sizeof(noteDurationsTwinkle) / sizeof(noteDurationsTwinkle[0]);
// notes = (int*)malloc(length * sizeof(int));
// durations = (int*)malloc(length * sizeof(int));
// memcpy(notes, twinkleTwinkle, length * sizeof(int));
// memcpy(durations, noteDurationsTwinkle, length * sizeof(int));
// playFlag = 1;
break;
case '4':
Serial.println("星に願いをを再生します");
// notes = starMelody;
// durations = noteDurationsStar;
// length = sizeof(noteDurationsStar) / sizeof(noteDurationsStar[0]);
// notes = (int*)malloc(length * sizeof(int));
// durations = (int*)malloc(length * sizeof(int));
// memcpy(notes, starMelody, length * sizeof(int));
// memcpy(durations, noteDurationsStar, length * sizeof(int));
// playFlag = 1;
break;
case 'q':
Serial.println("曲の再生を停止します");
// noTone(BUZZER); // 曲の再生を停止
break;
default:
Serial.println("無効な入力です");
break;
}
///ミューテックスのアンロック
// xSemaphoreGive(xMutex);
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
}
void TaskB( void *pvParameters ) {
while ( true ) {
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
}
void TaskC( void *pvParameters ) {
while ( true ) {
Serial.println( "TaskC" );
if(playFlag == 1){
for (int i = 0; i < length; i++) {
noteDuration = 1000 / durations[i];
tone(BUZZER, notes[i], noteDuration);
vTaskDelay(noteDuration * 1.3); // 音と音の間に少し休符を追加
noTone(BUZZER);
}
// 使用したメモリを解放
// free(notes);
// free(durations);
playFlag = 0;
}
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
}