Aitendo 電波時計モジュール(40/60KHz)[MAS6181-DB] を使うためのプログラムです。 どちらかというと、JJY信号の学習用です。手軽に時間を扱いたい人は、デジタルで出力してくれるモジュールを探した方がよいと思います。

Dependencies:   mbed-rtos mbed

Information

このプログラムはJJYの信号や処理の参考になりますが、正確な時間や手軽に扱いたい人には不向きです。

概要

Aitendoの電波時計モジュール[MAS6181-DB]からの信号を受信して処理を行う方法の一つの例を示します。
JJYの信号はhttp://jjy.nict.go.jp/QandA/reference/Lfsymposium1.pdfの10ページを参考にしました。
1秒で一つの信号を送り60秒かけて時間情報を送信します。
信号は、マーカ、1、0の三種類です。
マーカは0.2s ON 0.8s OFF
1は0.5s ON 0.5s OFF
0は0.8s ON 0.2s OFF
です。

ハードウエアの設定

電波時計モジュールは、1.1-3.6Vで動作します。mbedの出力電圧3.3Vで動作するので、そのまま接続することもできます。

出力は、信号を受信していない場合はLow
信号を受信している場合はLow
信号を受信していない場合はHigh
になっています。

なお、JJY受信モジュールの出力インピーダンスが高いので、mbedとは直接接続できませんでした。接続した状態でオシロスコープを見るとほとんど0Vの状態です。
したがって、オペアンプやトランジスタなどのバッファを仲介する必要があります。
今回は下記の回路で実行しています。この回路だと、信号が反転するので、ちょうど信号を受信しているときは1、していないときは0になりました。
/media/uploads/yueee_yt/jjy_---.jpg 信号が受信できると以下のような信号を得られます。
/media/uploads/yueee_yt/jjy-osc.jpg

Warning

受信モジュールはノイズに弱いみたいなので、信号の弱い場所では電池での駆動がよいです。PCからmbed経由での電源供給でも、PCにACアダプタを挿すと受信できなくなることがありました。

プログラムの説明

RTOSを利用してデータの受信は別スレッドで10ms毎に動くようにしています。つまり、1信号(1秒)あたり100回の信号を取っています。
リングバッファrcvにデータを保存します。
この辺りは、電波の強弱やMPUの能力で最適値に変更すると良いと思います、
なお、受信スレッドには、timingの位置でメッセージキューにデータを置き、メインスレッドにタイミングを伝えています。

プログラムは2段階で動作するようにしています。
1.同期ポイントを探る
2.信号から時間を得る

同期ポイントは20秒受信します。受信しながらバッファの総和を求めます。
データは10回に1回以上がマーカなので、
0.0-0.2sがONになるのは100%(マーカ+0+1)
0.2-0.5sがOnになるのは 90%以下(0+1)
0.5-0.8sがOnになるのは ?%(0)
0.8-1.0sは100%でOFFになるはずです。

したがって、度数分布を作成し、受信した信号が90%より上(今回は20回受信するので19回以上受信した点)がマーカの信号の位置になります。
処理が終了後、変数timingに値を書き、メインスレッドとの同期点を変更します。
後の処理は1秒受信してそのONの比率でマーカ、1、0の判別を行いますので、同期点がマーカの位置であれば時間の誤差(0.2秒以内)が生じますが、データ処理には問題が生じません。

信号から時間を得る部分は、ステートマシンで表しています。
state=0でマーカが2回続く同期点(0秒になる点)を待ちます。
あとは1信号ごとに処理しています。信号が0もしくは1になる個所はデータをチェックし、マーカや不明が来たらstate=0にしマーカ待ちに戻します。

実行

LED0は受信状況を表します。
LED1は”マーカ”を受信
LED2は”1”を受信
LED3は”0”を受信
信号不明時はLED1,2,3を同時点灯
になります。

Committer:
yueee_yt
Date:
Tue Apr 23 09:00:09 2013 +0000
Revision:
0:f111c5224cd0
Child:
1:d9553f32e949
Initial Version

Who changed what in which revision?

UserRevisionLine numberNew contents of line
yueee_yt 0:f111c5224cd0 1 #include "mbed.h"
yueee_yt 0:f111c5224cd0 2 #include "rtos.h"
yueee_yt 0:f111c5224cd0 3 DigitalOut led1(LED1);
yueee_yt 0:f111c5224cd0 4 DigitalOut led2(LED2);
yueee_yt 0:f111c5224cd0 5 DigitalOut led3(LED3);
yueee_yt 0:f111c5224cd0 6 DigitalOut led4(LED4);
yueee_yt 0:f111c5224cd0 7
yueee_yt 0:f111c5224cd0 8 Queue<uint32_t, 5> queue;
yueee_yt 0:f111c5224cd0 9
yueee_yt 0:f111c5224cd0 10 DigitalIn jjy(p20);
yueee_yt 0:f111c5224cd0 11
yueee_yt 0:f111c5224cd0 12 Serial pc(USBTX, USBRX);
yueee_yt 0:f111c5224cd0 13
yueee_yt 0:f111c5224cd0 14 char rcv[100];
yueee_yt 0:f111c5224cd0 15 char timing=0;
yueee_yt 0:f111c5224cd0 16 void jjy_rcv(void const *n)
yueee_yt 0:f111c5224cd0 17 {
yueee_yt 0:f111c5224cd0 18 static int count=0;
yueee_yt 0:f111c5224cd0 19 if(jjy) {
yueee_yt 0:f111c5224cd0 20 rcv[count]=1;
yueee_yt 0:f111c5224cd0 21 } else {
yueee_yt 0:f111c5224cd0 22 rcv[count]=0;
yueee_yt 0:f111c5224cd0 23 }
yueee_yt 0:f111c5224cd0 24 led1=rcv[count];
yueee_yt 0:f111c5224cd0 25 if(count==timing) {
yueee_yt 0:f111c5224cd0 26 queue.put((uint32_t*)1);
yueee_yt 0:f111c5224cd0 27 //printf("thread out timing=%d \n\r",timing);
yueee_yt 0:f111c5224cd0 28 }
yueee_yt 0:f111c5224cd0 29 // pc.printf("%d %d \n\r",count,rcv[count]);
yueee_yt 0:f111c5224cd0 30 if(count==99)
yueee_yt 0:f111c5224cd0 31 count=0;
yueee_yt 0:f111c5224cd0 32 else
yueee_yt 0:f111c5224cd0 33 count++;
yueee_yt 0:f111c5224cd0 34 }
yueee_yt 0:f111c5224cd0 35
yueee_yt 0:f111c5224cd0 36 int main()
yueee_yt 0:f111c5224cd0 37 {
yueee_yt 0:f111c5224cd0 38 unsigned char state=0;
yueee_yt 0:f111c5224cd0 39 unsigned char sig,old_sig;
yueee_yt 0:f111c5224cd0 40 unsigned char count1=0;
yueee_yt 0:f111c5224cd0 41 bool flag1,flag2;
yueee_yt 0:f111c5224cd0 42 char m,h;
yueee_yt 0:f111c5224cd0 43 char mm[3];
yueee_yt 0:f111c5224cd0 44 int i,j;
yueee_yt 0:f111c5224cd0 45 char sum_rcv[100];
yueee_yt 0:f111c5224cd0 46 pc.baud(115200);
yueee_yt 0:f111c5224cd0 47 flag1=true;
yueee_yt 0:f111c5224cd0 48 flag2=true;
yueee_yt 0:f111c5224cd0 49 old_sig=9;
yueee_yt 0:f111c5224cd0 50 m=0;h=0;
yueee_yt 0:f111c5224cd0 51 for(i=0; i<100; i++)sum_rcv[i]=0;
yueee_yt 0:f111c5224cd0 52 RtosTimer jjy_rcv_timer(jjy_rcv, osTimerPeriodic,(void *)0);
yueee_yt 0:f111c5224cd0 53 jjy_rcv_timer.start(10); //10mS
yueee_yt 0:f111c5224cd0 54 printf("*********************stage1 (Sync)*********************\n\r");
yueee_yt 0:f111c5224cd0 55 while (flag1) {
yueee_yt 0:f111c5224cd0 56 osEvent evt = queue.get();
yueee_yt 0:f111c5224cd0 57 if (evt.status == osEventMessage) {
yueee_yt 0:f111c5224cd0 58 printf("%d thread out timing=%d \n\r",count1,timing);
yueee_yt 0:f111c5224cd0 59 for(i=0; i<100; i++)sum_rcv[i]+=rcv[i];
yueee_yt 0:f111c5224cd0 60 //for(i=0; i<100; i++)printf("%d %d \n\r",count1,sum_rcv[i]);
yueee_yt 0:f111c5224cd0 61 if(count1==20) {
yueee_yt 0:f111c5224cd0 62 for(i=0; i<100; i++)printf("%d %d \n\r",i,sum_rcv[i]);
yueee_yt 0:f111c5224cd0 63 printf("------------------------------------\n\r");
yueee_yt 0:f111c5224cd0 64 for(i=1; i<100; i++) {
yueee_yt 0:f111c5224cd0 65 if(sum_rcv[i]>18) {
yueee_yt 0:f111c5224cd0 66 timing=i-1;
yueee_yt 0:f111c5224cd0 67 flag1=false;
yueee_yt 0:f111c5224cd0 68 printf("break\n\r");
yueee_yt 0:f111c5224cd0 69 break;
yueee_yt 0:f111c5224cd0 70 }
yueee_yt 0:f111c5224cd0 71 }
yueee_yt 0:f111c5224cd0 72 if(flag1==true) {
yueee_yt 0:f111c5224cd0 73 count1=0;
yueee_yt 0:f111c5224cd0 74 for(i=0; i<100; i++)sum_rcv[i]=0;
yueee_yt 0:f111c5224cd0 75 }
yueee_yt 0:f111c5224cd0 76 } else {
yueee_yt 0:f111c5224cd0 77 count1++;
yueee_yt 0:f111c5224cd0 78 }
yueee_yt 0:f111c5224cd0 79 }
yueee_yt 0:f111c5224cd0 80 }
yueee_yt 0:f111c5224cd0 81 //for(i=0; i<100; i++)printf("%d %d \n\r",i,sum_rcv[i]);
yueee_yt 0:f111c5224cd0 82 printf("*********************stage1 end*****************************\n\r");
yueee_yt 0:f111c5224cd0 83 printf("timing= %d\n\r",timing);
yueee_yt 0:f111c5224cd0 84 osEvent evt = queue.get();
yueee_yt 0:f111c5224cd0 85 printf("*********************stage2 time setting********************\n\r");
yueee_yt 0:f111c5224cd0 86 state=0;
yueee_yt 0:f111c5224cd0 87 while (flag2) {
yueee_yt 0:f111c5224cd0 88 osEvent evt = queue.get();
yueee_yt 0:f111c5224cd0 89 if (evt.status == osEventMessage) {
yueee_yt 0:f111c5224cd0 90 j=0;
yueee_yt 0:f111c5224cd0 91 for(i=0; i<100; i++)j+=rcv[i];
yueee_yt 0:f111c5224cd0 92 if(j<30) {
yueee_yt 0:f111c5224cd0 93 sig=2;
yueee_yt 0:f111c5224cd0 94 strcpy(mm,"M");
yueee_yt 0:f111c5224cd0 95 led2=1;
yueee_yt 0:f111c5224cd0 96 led3=0;
yueee_yt 0:f111c5224cd0 97 led4=0;
yueee_yt 0:f111c5224cd0 98 } else {
yueee_yt 0:f111c5224cd0 99 if(j<65) {
yueee_yt 0:f111c5224cd0 100 sig=1;
yueee_yt 0:f111c5224cd0 101 strcpy(mm,"1");
yueee_yt 0:f111c5224cd0 102 led2=0;
yueee_yt 0:f111c5224cd0 103 led3=1;
yueee_yt 0:f111c5224cd0 104 led4=0;
yueee_yt 0:f111c5224cd0 105 } else {
yueee_yt 0:f111c5224cd0 106 if(j<90) {
yueee_yt 0:f111c5224cd0 107 sig=0;
yueee_yt 0:f111c5224cd0 108 strcpy(mm,"0");
yueee_yt 0:f111c5224cd0 109 led2=0;
yueee_yt 0:f111c5224cd0 110 led3=0;
yueee_yt 0:f111c5224cd0 111 led4=1;
yueee_yt 0:f111c5224cd0 112 } else {
yueee_yt 0:f111c5224cd0 113 sig=9;
yueee_yt 0:f111c5224cd0 114 strcpy(mm,"?");
yueee_yt 0:f111c5224cd0 115 led2=1;
yueee_yt 0:f111c5224cd0 116 led3=1;
yueee_yt 0:f111c5224cd0 117 led4=1;
yueee_yt 0:f111c5224cd0 118 }
yueee_yt 0:f111c5224cd0 119 }
yueee_yt 0:f111c5224cd0 120 }
yueee_yt 0:f111c5224cd0 121 printf("Signal %d %s\n\r",j,mm);
yueee_yt 0:f111c5224cd0 122
yueee_yt 0:f111c5224cd0 123 switch(state) {
yueee_yt 0:f111c5224cd0 124 case 0:
yueee_yt 0:f111c5224cd0 125 if((old_sig==2)&&(sig==2)) {
yueee_yt 0:f111c5224cd0 126 state=1;
yueee_yt 0:f111c5224cd0 127 }
yueee_yt 0:f111c5224cd0 128 break;
yueee_yt 0:f111c5224cd0 129 case 1:
yueee_yt 0:f111c5224cd0 130 if((sig==0)||(sig==1)) {
yueee_yt 0:f111c5224cd0 131 m=40*sig;
yueee_yt 0:f111c5224cd0 132 state=2;
yueee_yt 0:f111c5224cd0 133 } else {
yueee_yt 0:f111c5224cd0 134 state=0;
yueee_yt 0:f111c5224cd0 135 }
yueee_yt 0:f111c5224cd0 136 break;
yueee_yt 0:f111c5224cd0 137 case 2:
yueee_yt 0:f111c5224cd0 138 if((sig==0)||(sig==1)) {
yueee_yt 0:f111c5224cd0 139 m+=20*sig;
yueee_yt 0:f111c5224cd0 140 state=3;
yueee_yt 0:f111c5224cd0 141 } else {
yueee_yt 0:f111c5224cd0 142 state=0;
yueee_yt 0:f111c5224cd0 143 }
yueee_yt 0:f111c5224cd0 144 break;
yueee_yt 0:f111c5224cd0 145 case 3:
yueee_yt 0:f111c5224cd0 146 if((sig==0)||(sig==1)) {
yueee_yt 0:f111c5224cd0 147 m+=10*sig;
yueee_yt 0:f111c5224cd0 148 state=4;
yueee_yt 0:f111c5224cd0 149 } else {
yueee_yt 0:f111c5224cd0 150 state=0;
yueee_yt 0:f111c5224cd0 151 }
yueee_yt 0:f111c5224cd0 152 break;
yueee_yt 0:f111c5224cd0 153 case 4:
yueee_yt 0:f111c5224cd0 154 if((sig==0)||(sig==1)) {
yueee_yt 0:f111c5224cd0 155 state=5;
yueee_yt 0:f111c5224cd0 156 } else {
yueee_yt 0:f111c5224cd0 157 state=0;
yueee_yt 0:f111c5224cd0 158 }
yueee_yt 0:f111c5224cd0 159 break;
yueee_yt 0:f111c5224cd0 160 case 5:
yueee_yt 0:f111c5224cd0 161 if((sig==0)||(sig==1)) {
yueee_yt 0:f111c5224cd0 162 m+=8*sig;
yueee_yt 0:f111c5224cd0 163 state=6;
yueee_yt 0:f111c5224cd0 164 } else {
yueee_yt 0:f111c5224cd0 165 state=0;
yueee_yt 0:f111c5224cd0 166 }
yueee_yt 0:f111c5224cd0 167 break;
yueee_yt 0:f111c5224cd0 168 case 6:
yueee_yt 0:f111c5224cd0 169 if((sig==0)||(sig==1)) {
yueee_yt 0:f111c5224cd0 170 m+=4*sig;
yueee_yt 0:f111c5224cd0 171 state=7;
yueee_yt 0:f111c5224cd0 172 } else {
yueee_yt 0:f111c5224cd0 173 state=0;
yueee_yt 0:f111c5224cd0 174 }
yueee_yt 0:f111c5224cd0 175 break;
yueee_yt 0:f111c5224cd0 176 case 7:
yueee_yt 0:f111c5224cd0 177 if((sig==0)||(sig==1)) {
yueee_yt 0:f111c5224cd0 178 m+=2*sig;
yueee_yt 0:f111c5224cd0 179 state=8;
yueee_yt 0:f111c5224cd0 180 } else {
yueee_yt 0:f111c5224cd0 181 state=0;
yueee_yt 0:f111c5224cd0 182 }
yueee_yt 0:f111c5224cd0 183 break;
yueee_yt 0:f111c5224cd0 184 case 8:
yueee_yt 0:f111c5224cd0 185 if((sig==0)||(sig==1)) {
yueee_yt 0:f111c5224cd0 186 m+=sig;
yueee_yt 0:f111c5224cd0 187 state=9;
yueee_yt 0:f111c5224cd0 188 } else {
yueee_yt 0:f111c5224cd0 189 state=0;
yueee_yt 0:f111c5224cd0 190 }
yueee_yt 0:f111c5224cd0 191 break;
yueee_yt 0:f111c5224cd0 192 case 9:
yueee_yt 0:f111c5224cd0 193 state=10;
yueee_yt 0:f111c5224cd0 194 break;
yueee_yt 0:f111c5224cd0 195 case 10:
yueee_yt 0:f111c5224cd0 196 if((sig==0)||(sig==1)) {
yueee_yt 0:f111c5224cd0 197 state=11;
yueee_yt 0:f111c5224cd0 198 } else {
yueee_yt 0:f111c5224cd0 199 state=0;
yueee_yt 0:f111c5224cd0 200 }
yueee_yt 0:f111c5224cd0 201 break;
yueee_yt 0:f111c5224cd0 202 case 11:
yueee_yt 0:f111c5224cd0 203 if((sig==0)||(sig==1)) {
yueee_yt 0:f111c5224cd0 204 state=12;
yueee_yt 0:f111c5224cd0 205 } else {
yueee_yt 0:f111c5224cd0 206 state=0;
yueee_yt 0:f111c5224cd0 207 }
yueee_yt 0:f111c5224cd0 208 break;
yueee_yt 0:f111c5224cd0 209 case 12:
yueee_yt 0:f111c5224cd0 210 if((sig==0)||(sig==1)) {
yueee_yt 0:f111c5224cd0 211 h=20*sig;
yueee_yt 0:f111c5224cd0 212 state=13;
yueee_yt 0:f111c5224cd0 213 } else {
yueee_yt 0:f111c5224cd0 214 state=0;
yueee_yt 0:f111c5224cd0 215 }
yueee_yt 0:f111c5224cd0 216 break;
yueee_yt 0:f111c5224cd0 217 case 13:
yueee_yt 0:f111c5224cd0 218 if((sig==0)||(sig==1)) {
yueee_yt 0:f111c5224cd0 219 h+=10*sig;
yueee_yt 0:f111c5224cd0 220 state=14;
yueee_yt 0:f111c5224cd0 221 } else {
yueee_yt 0:f111c5224cd0 222 state=0;
yueee_yt 0:f111c5224cd0 223 }
yueee_yt 0:f111c5224cd0 224 break;
yueee_yt 0:f111c5224cd0 225 case 14:
yueee_yt 0:f111c5224cd0 226 if((sig==0)||(sig==1)) {
yueee_yt 0:f111c5224cd0 227 state=15;
yueee_yt 0:f111c5224cd0 228 } else {
yueee_yt 0:f111c5224cd0 229 state=0;
yueee_yt 0:f111c5224cd0 230 }
yueee_yt 0:f111c5224cd0 231 break;
yueee_yt 0:f111c5224cd0 232 case 15:
yueee_yt 0:f111c5224cd0 233 if((sig==0)||(sig==1)) {
yueee_yt 0:f111c5224cd0 234 h+=8*sig;
yueee_yt 0:f111c5224cd0 235 state=16;
yueee_yt 0:f111c5224cd0 236 } else {
yueee_yt 0:f111c5224cd0 237 state=0;
yueee_yt 0:f111c5224cd0 238 }
yueee_yt 0:f111c5224cd0 239 break;
yueee_yt 0:f111c5224cd0 240 case 16:
yueee_yt 0:f111c5224cd0 241 if((sig==0)||(sig==1)) {
yueee_yt 0:f111c5224cd0 242 h+=4*sig;
yueee_yt 0:f111c5224cd0 243 state=17;
yueee_yt 0:f111c5224cd0 244 } else {
yueee_yt 0:f111c5224cd0 245 state=0;
yueee_yt 0:f111c5224cd0 246 }
yueee_yt 0:f111c5224cd0 247 break;
yueee_yt 0:f111c5224cd0 248 case 17:
yueee_yt 0:f111c5224cd0 249 if((sig==0)||(sig==1)) {
yueee_yt 0:f111c5224cd0 250 h+=2*sig;
yueee_yt 0:f111c5224cd0 251 state=18;
yueee_yt 0:f111c5224cd0 252 } else {
yueee_yt 0:f111c5224cd0 253 state=0;
yueee_yt 0:f111c5224cd0 254 }
yueee_yt 0:f111c5224cd0 255 break;
yueee_yt 0:f111c5224cd0 256 case 18:
yueee_yt 0:f111c5224cd0 257 if((sig==0)||(sig==1)) {
yueee_yt 0:f111c5224cd0 258 h+=sig;
yueee_yt 0:f111c5224cd0 259 state=19;
yueee_yt 0:f111c5224cd0 260 } else {
yueee_yt 0:f111c5224cd0 261 state=0;
yueee_yt 0:f111c5224cd0 262 }
yueee_yt 0:f111c5224cd0 263 break;
yueee_yt 0:f111c5224cd0 264 case 19:
yueee_yt 0:f111c5224cd0 265 flag2=0;
yueee_yt 0:f111c5224cd0 266 state=0;
yueee_yt 0:f111c5224cd0 267 break;
yueee_yt 0:f111c5224cd0 268 }
yueee_yt 0:f111c5224cd0 269 printf("%d %02d:%02d \n\r",state,h,m);
yueee_yt 0:f111c5224cd0 270 old_sig=sig;
yueee_yt 0:f111c5224cd0 271 }
yueee_yt 0:f111c5224cd0 272 }
yueee_yt 0:f111c5224cd0 273 jjy_rcv_timer.stop();
yueee_yt 0:f111c5224cd0 274 printf("Now = %02d:%02d:20 \n\r",h,m);
yueee_yt 0:f111c5224cd0 275 }