自作中のラズパイ7桁時計に関して、欲しかった機能をテスト中です。
それは、ntpq -p 実行結果からNTPサーバー参照同期中の印である *(アスタリスク)を検索して、見つかればLEDを点灯させたいのです。
時計表示用のプログラムとは別なプログラムとして作ります。理由は実行に時間がかかる、約0.6秒くらいかかるのでダイナミック表示に支障があるからです。
今回はGPIOを動かすのにWiringPiを使用しました。先に時計表示にpigpioを使用しているのですが、このプログラムでもpigpioライブラリを使用しようとすると「既に使用中で使えません」みたいな事になってしまいましたので。
本当はプロセス間通信とか共有メモリを利用して、LED点灯は時計表示用のプログラムに任せたいのですが、私には難しくて組めません。
↓ このソースコードは無知の私が書いた物なので、全てが間違いかも知れません。その事を承知の上で参考にして下さい。
/*
* ntpCheck.cpp
*
* ntpq -p の実行結果から参照同期中の文字 * を検索
* 見つからない場合は見つかるまで、5秒毎にntpq -p 実行し検索
* 見つかった場合はLEDを10分間点灯させて、最初に戻り繰り返す。
*
*/
#include <iostream>
#include <string.h>
#include <wiringPi.h>
#include <unistd.h>
#define PIN 5
// using namespace std;
int mainLoop(void);
int main(void)
{
if (daemon(0, 0) == 0) { // デーモン関数
mainLoop();
} else {
// cout << "error" << endl;
}
return 0;
}
int mainLoop(void)
{
char str[512], *ptr;
FILE *fp;
if (wiringPiSetupGpio() == -1) return 1;
pinMode(PIN, OUTPUT);
// (A) 無限ループ
while (1) {
if ((fp=popen("ntpq -p", "r"))==NULL) {
fprintf(stderr, "error!!!\n");
exit(1); // 異常終了
}
while (1) {
fgets(str, 512, fp); // 一行毎に読み込む
if (feof(fp)) {
sleep(5);
break; // 検索文字が無くファイルの終わりに達して
// ループを抜ける->(B)
}
ptr=strchr(str, '*'); // 検索文字は参照同期中の*
if (ptr!=NULL) {
// cout << "OK ----------" << endl;
digitalWrite(PIN, HIGH); // 検索文字有りLED点灯
sleep(600); // 10分間点灯維持
digitalWrite(PIN, LOW); // LED消灯
break; // ループを抜ける->(B)
}
// cout << "NG" << endl;
}
// (B)
pclose(fp);// ->(A)
}
// return 0;
}
$ g++ -Wall -o ntpCheck ntpCheck.cpp -lwiringPi
$ sudo ./ntpCheck