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を時刻同期で撮影すれば全球カメラができそうですね。ヘルメットにつけたりしたら面白いかも。
(^^)