はじめに
標準電波(JJY※)は、NICTが決定した標準周波数と日本標準時を日本全国に供給するための電波です。
福島長波局(おおたかどや山:40 kHz)
九州長波局(はがね山:60 kHz)
ただ、近畿地方はどちらの基地局の狭間にあり、両方の電波を使える一方、どちらからも遠いということになります。
自宅に電波時計を設置しても、設置場所によっては基準電波を受信することができず、長時間の間で時計の時間がずれてしまうこともあります。せっかくの電波時計の仕組みが有効に機能しないこともあります。せっかく電波時計のがあるり悔しいです。そこで、インターネット上のNTPサーバーから正確な時間を取得して電波時計の形式で送信する装置。いわばローカルJJY基地局みたいなものを作ってみたいと思います。
世の中には共立電子などから「ケイシーズ Wi-Fi式電波時計用リピータKEISEEDS P18-NTPWR」というものが売られているのですが、ちょっと高いかもです。
このWEBページにの写真も掲載されていたけど、マイコンはたぶんESP8266のような感じ。
ちょうど昔買ったESP8266があったので、在庫処分的な意味合いも兼ねて、このマイコンを使います。
“Easy JJY Station”の主な仕様
| 項目 | 内容 | 備考 |
|---|---|---|
| キャリア周波数 | 60kHz | 40kHzは現在未サポート |
| 電源 | USB供給方式 | マイクロUSBタイプ |
| 使用プロセッサ | ESP8266 | ・コア:Xtensa_LX6(32bit) ・クロック:160MHz ・ROM:2MB ・プログラムメモリー[B]:2MB ・GPIO:11 ・UART/USART:1 ・I2C:1 ・SPI:1 ・オシレーター:内蔵 ・無線機能:Wi-Fi ・無線機能詳細:Wi-Fi(802.11b/g/n)2.4GHz |
| 送信電力 | ?? | 実測、バーアンテナ端で20vPPの搬送波。調整はオプション |
| 搬送波発振方式 | タイマーIC555による方形波発振 | 定数を変更することで60kHzにも対応可能 |
| 操作方法(UI) | UARTにより簡易的なシェルコマンド | Teraterm等UART:115200bps |
| オフセット時間設定 | -11h~11h | (オプション) |
| NTPサーバーへの接続 | 接続先ホスト(AP)のSsidとpasswordを設定する | リトライ、接続断発見機能あり |
| パラメータ保存 | あり | 不揮発メモリに保存 |
電波時計のデータ構造
電波時計のデータフォーマットは「標準電波のタイムコード」に詳細が記載されているので、これを参考にします。
秒の信号は、パルス信号の立ち上がりとし、立ち上がり時の55%値(10%値と100%値の中央)が日本標準時の1秒信号に同期します。立ち上がり後、100%値を継続するパルス幅の長さによって、その秒での情報を符号化しています。
パルス幅の定義は次の通りです。
パルス幅 0.8s ±5ms 2進の0
パルス幅 0.5s ±5ms 2進の1
パルス幅 0.2s ±5ms ポジションマーカー (M, P0~P5)
構成ブロック図

装置全体の回路図
過去に作った「ESP8266の評価ボード」+「ベースボード」という感じにします。

H/W製作



ケースの蓋は片方は爪でひっかけてネジ一本で固定するようにした。

バーアンテナ部(共振アンテナ部)
今回の無線キャリアは40kHz,60kHzの一般的にLF(長波帯)に属し、波長が5kmととても長い。
なので、一般的には短縮コイル形状のループアンテナあるいはバーアンテナが一般的に用いられる。バーアンテナはAMラヂヲのアンテナでよく使用されるが、周波数が中波帯(530kHz~)であり、約10倍違う。したがって効率よくアンテナにするためにバーアンテナコアを容量的にも10倍程度になるように巻きなおす。


DE-5000のLCRメータで測定して100kHzのリファレンス周波数で約5mH Q=120くらいものができた!コイルはこんなもんでいいかな。
搬送波発信部
数十kHzの周波数はクリスタルでは低すぎるので、NE555を用いることにする。ここで使用するコンデンサは本来温度特性と漏れ電流が小さいフィルムコンデンサを用いたほうがいいのだが、適当な容量が在庫になかったのでセラミックコンデンサ(B特)を用いることにする。

共振アンテナ

40kHzの場合 1/(5mH(2*3.14*40k)^2)=3169pF 60kHzの場合 1/(5mH(2*3.14*60k)^2)=1407pF
まずはコンデンサの容量として一般的な1500pFをつけてみる。
AnalogDiscovery2のネットワーク測定を用いて共振特性を測定する。

発振回路制御および出力波形


S/W編 JJY 時間データ生成とキャリア変調
セットアップルーチン
// --- Setup ---
void setup() {
Serial.begin(SERIAL_BAUDRATE); // シリアルポートの初期化
pinMode(jjyOutPin, OUTPUT); // GPIOピンの初期化
digitalWrite(jjyOutPin, LOW);
EEPROM.begin(256);
EEPROM.get(0, Ntcwave);
u8g2.begin(); // OLED表示器用の文字フォント初期化
u8g2.setFont(u8g2_font_ncenB14_tr);
//WiFi.begin(ssid, password); // Wifiネットワークの接続
//WiFi.begin(Ntcwave.ssid, Ntcwave.pass); // Wifiネットワークの接続
// 500msごとにステートマシンを進める
wifiTicker.attach_ms(500, checkWiFiState);
Serial.println("Starting WiFi state machine...");
timeClient.begin(); // NTPサーバーから時刻情報取得
timeClient.update();
time_t now = timeClient.getEpochTime();
struct tm* t = localtime(&now);
encodeJJY(t, jjyBits); // JJYフォーマットデータ生成
printJJYBits(t,jjyBits); // 送信ビット列表示
usbif_init();
Serial.println("ESP8266 Serial Console Ready");
}
JJY データエンコーダー

jjy encode関数
// ------------ JJY Bit Encoder ----------------------
void encodeJJY(struct tm* t, int* bits) {
memset(bits, 0, sizeof(int) * 60);
const int markers[] = {0, 9, 19, 29, 39, 49, 59};
for (int i = 0; i < sizeof(markers)/sizeof(int); i++) {
bits[markers[i]] = JJY_MARKER;
}
int minbcd = bin2bcd(t->tm_min);
bits[8] = minbcd & 1;
bits[7] = (minbcd >> 1) & 1;
bits[6] = (minbcd >> 2) & 1;
bits[5] = (minbcd >> 3) & 1;
bits[3] = (minbcd >> 4) & 1;
bits[2] = (minbcd >> 5) & 1;
bits[1] = (minbcd >> 6) & 1;
int hourbcd = bin2bcd(t->tm_hour);
bits[18] = hourbcd & 1;
bits[17] = (hourbcd >> 1) & 1;
bits[16] = (hourbcd >> 2) & 1;
bits[15] = (hourbcd >> 3) & 1;
bits[13] = (hourbcd >> 4) & 1;
bits[12] = (hourbcd >> 5) & 1;
int daysOfYearbcd = bin2bcd(dayOfYear(t->tm_year + 1900, t->tm_mon + 1, t->tm_mday));
bits[38] = 0;
bits[37] = bits[1] ^ bits[2] ^ bits[3] ^ bits[5] ^ bits[6] ^ bits[7] ^ bits[8]; //分のParity
bits[36] = bits[12] ^ bits[13] ^ bits[15] ^ bits[16] ^ bits[17] ^ bits[18]; //時間のParity
bits[35] = 0;
bits[34] = 0;
bits[33] = (daysOfYearbcd ) & 1;
bits[32] = (daysOfYearbcd >> 1) & 1;
bits[31] = (daysOfYearbcd >> 2) & 1;
bits[30] = (daysOfYearbcd >> 3) & 1;
bits[28] = (daysOfYearbcd >> 4) & 1;
bits[27] = (daysOfYearbcd >> 5) & 1;
bits[26] = (daysOfYearbcd >> 6) & 1;
bits[25] = (daysOfYearbcd >> 7) & 1;
bits[23] = (daysOfYearbcd >> 8) & 1;
bits[22] = (daysOfYearbcd >> 9) & 1;
bits[21] = 0;
bits[20] = 0;
int yearbsc = bin2bcd(t->tm_year + 1900);
bits[48] = (yearbsc ) & 1;;
bits[47] = (yearbsc >> 1) & 1;
bits[46] = (yearbsc >> 2) & 1;
bits[45] = (yearbsc >> 3) & 1;
bits[44] = (yearbsc >> 4) & 1;
bits[43] = (yearbsc >> 5) & 1;
bits[42] = (yearbsc >> 6) & 1;
bits[41] = (yearbsc >> 7) & 1;
int wday = t->tm_wday;
bits[52] = wday & 1;
bits[51] = (wday >> 1) & 1;
bits[50] = (wday >> 2) & 1;
}
搬送波60kHzをjjy encodeされたビット列(60bit)で変調生成する部分
// --- JJY Signal Output State Machine ---
void updateJJY() {
unsigned long now = millis();
static int bit = 0; // スコープの外で宣言
time_t nowT;
struct tm* t;
switch (state) {
case SETUP:
nowT = timeClient.getEpochTime();
t = localtime(&nowT);
if(t->tm_sec == 0){
encodeJJY(t, jjyBits);
printJJYBits(t,jjyBits);
currentBit = 0;
state = IDLE;
}
break;
case IDLE:
if (currentBit >= 60) {
timeClient.update();
nowT = timeClient.getEpochTime();
t = localtime(&nowT);
if(t->tm_sec != 0) {
state = SETUP;
break;
}
encodeJJY(t, jjyBits);
printJJYBits(t,jjyBits);
currentBit = 0;
}
bit = jjyBits[currentBit];
switch (bit) {
case JJY_0: bitOnDuration = 800; break;
case JJY_1: bitOnDuration = 500; break;
case JJY_MARKER: bitOnDuration = 200; break;
}
digitalWrite(jjyOutPin, HIGH);
bitStartTime = now;
state = ON;
break;
case ON:
if (now - bitStartTime >= bitOnDuration) {
digitalWrite(jjyOutPin, LOW);
state = OFF;
}
break;
case OFF:
if (now - bitStartTime >= 1000) {
currentBit++;
state = IDLE;
}
break;
}
}
Wifi接続管理
接続先アクセスポイントの設定されたSSID、パスワードをもとにWifi接続を行う。
接続中何らかのトラブルで接続断したとしても、再度APが接続可能となれば自動復帰する。ただし、一度切断すると、NTPサーバーから正しい時間を取得し、JJYのデータ更新境界(0秒)で同期するまで2分程度時間を要する。

装置設定、ユーザーインターフェースと動作パラメータ管理

以下のように個別にWifiアクセスポイントへの接続設定を行い、その設定内容を装置に記憶する。
> set <<Set Parameter List>> ssid:Pixel_5704 pass:****** freq(0:40kHz/1:60kHz)(NA):1 power(NA):4 toffset(h)(NA):0 >
実証動作確認
①電波時計の電池抜いて処理状態に戻す。
②電波時計の電池を入れると、長針、短針、秒針がすべて「00時00分」に揃えられる。
③「Easy JJY Station」の電源をONにする。
④しばらくするとOLDLED表示器に日付、時刻とJJYカウント(0~60)表示される。
⑤電波時計は5分くらいしたら電波時計は「Easy JJY Station」がOLE表示器に示す時刻になってる。動作良好!

消費電力


まとめ
今回原理試作という位置づけで製作おこなったため、機能としては最低必要なものを実装するにとどまった。オプション機能として
| 考えられる追加機能 | 変更手法 |
|---|---|
| ①キャリア周波数の選択(40kHz/60kHz) | 搬送波を作っているMC555のコンデンサの切替機能追加 バーアンテナ共振定数コンデンサの切替機能追加 |
| ②送信電力の変更 | 供給電圧の可変機能/切替機能追加 |
| ③時間オフセット設定 | ソフトフェアによる変数パラメータの追加 |
①②はH/Wの変更を伴う内容であり、今後は本件の反響具合により進めたいと考えています。
その際は専用基板を起こすかも・・ではまたその機会があったらお会いしましょう!さよオナラ・・・・👋

