SPRESENSE の RTC をGPS 時計に設定して時報アプリを作ってみた! [SPRESENSE]
SPRESENSEはGPSを受信できるので、正確な時間を取得できます。それならその時間をRTCに設定してみて、時報アプリを作れないかなと思い作ってみました。
時報の音源は次のURLの「Sine波 予報音3回」のMP3ファイルを拝借させていただきました。
時報音の音源
https://ultra.zone/jihou.ja
スケッチは、メインループと "pthread" で構成されています。メインループはGPS時間を取得をしてRTCを更新し、"pthread" は RTCの時間を監視して1分毎に時報を鳴らすというものです。
もともとは、task_create でスレッドを生成していたのですが、なぜかPANICが起きるので pthread に置きかえました。^^;
わざわざスレッドにしなくてもいいんじゃないかというコードではありますが、スレッドにすることでRTC の効用を少し分かりやすくしてみたつもりです。^^;
SPRESENSEはGPS時刻を取得できるので、複数のカメラ付きSPRESENSEを時刻同期で撮影すれば全球カメラができそうですね。ヘルメットにつけたりしたら面白いかも。
(^^)
時報の音源は次のURLの「Sine波 予報音3回」のMP3ファイルを拝借させていただきました。
時報音の音源
https://ultra.zone/jihou.ja
スケッチは、メインループと "pthread" で構成されています。メインループはGPS時間を取得をしてRTCを更新し、"pthread" は RTCの時間を監視して1分毎に時報を鳴らすというものです。
もともとは、task_create でスレッドを生成していたのですが、なぜかPANICが起きるので pthread に置きかえました。^^;
#include <GNSS.h> #include <RTC.h> #include <SDHCI.h> #include <Audio.h> #include <pthread.h> static SDClass theSD; static SpGnss Gnss; AudioClass *theAudio = AudioClass::getInstance(); #define JST_IN_SECONDS (9 * 60 * 60); static File myFile; static bool bTimeFixed = false; static void time_signal_thread(void *arg) { while(true) { usleep(100000); if (bTimeFixed == false) continue; RtcTime now = RTC.getTime(); if (now.second() != 56) continue; myFile = theSD.open("jihou.mp3"); if (!myFile) { Serial.println("File open error"); while(1); } theAudio->writeFrames(AudioClass::Player0, myFile); theAudio->setVolume(-60); theAudio->startPlayer(AudioClass::Player0); while (true) { sleep(1); // To ensure not re-entering the audio routine. int err = theAudio->writeFrames(AudioClass::Player0, myFile); if (err == AUDIOLIB_ECODE_FILEEND) { theAudio->stopPlayer(AudioClass::Player0); myFile.close(); break; } } } return 0; } void setup() { int result; Serial.begin(115200); theSD.begin(); sleep(3); /* Wait HW initialization done. */ theAudio->begin(); theAudio->setRenderingClockMode(AS_CLKMODE_NORMAL); theAudio->setPlayerMode(AS_SETPLAYER_OUTPUTDEVICE_SPHP, AS_SP_DRV_MODE_LINEOUT); theAudio->initPlayer(AudioClass::Player0, AS_CODECTYPE_MP3, "/mnt/sd0/BIN" , AS_SAMPLINGRATE_AUTO, AS_CHANNEL_MONO); Serial.println("Audio initialized"); Gnss.begin(); Gnss.select(GPS); Gnss.start(COLD_START); Serial.println("Gnss start..."); int policy; struct sched_param param; pthread_t m_pid = pthread_self(); pthread_getschedparam(m_pid, &policy, &param); Serial.println("Main Priority is : " + String(param.sched_priority)); pthread_t t_pid; pthread_create(&t_pid, NULL, time_signal_thread, NULL); param.sched_priority = 130; pthread_setschedparam(t_pid, policy, &param); Serial.println("time_signal_thread start: " + String(param.sched_priority)); } void loop() { if (!Gnss.waitUpdate(-1)) return; SpNavData NavData; Gnss.getNavData(&NavData); Serial.println("numSat: " + String(NavData.numSatellites)); if (NavData.time.year == 1980) return; bTimeFixed = true; /* Create RTC time */ RtcTime gtime(NavData.time.year, NavData.time.month, NavData.time.day , NavData.time.hour, NavData.time.minute, NavData.time.sec , NavData.time.usec * 1000 /* RtcTime requires nsec */); gtime += JST_IN_SECONDS; /* convert UTC to JST */ printf("%04d/%02d/%02d %02d:%02d:%02d\n" , gtime.year(), gtime.month(), gtime.day() , gtime.hour(), gtime.minute(), gtime.second()); /* When time is different more than 1 sec, update RTC time */ if (abs(RTC.getTime() - gtime) >= 1) { RTC.setTime(gtime); Serial.println(" * Updated RTC time * "); } }
わざわざスレッドにしなくてもいいんじゃないかというコードではありますが、スレッドにすることでRTC の効用を少し分かりやすくしてみたつもりです。^^;
SPRESENSEはGPS時刻を取得できるので、複数のカメラ付きSPRESENSEを時刻同期で撮影すれば全球カメラができそうですね。ヘルメットにつけたりしたら面白いかも。
(^^)
2019-11-24 23:06
nice!(25)
コメント(2)
拙ブログにコメントを頂きありがとうございます。
アドセンスで何かご質問があれば気軽に聞いてください。何かお役に立てるかもしれません。
by ピストン (2019-11-25 02:47)
ピストンさん、おかげ様で復活しました!ありがとうございます。
by ys_taro (2019-12-01 22:36)