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:
Wed Apr 24 03:10:33 2013 +0000
Revision:
1:d9553f32e949
Parent:
0:f111c5224cd0
Debug Line Delete

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 if(count1==20) {
yueee_yt 0:f111c5224cd0 61 for(i=1; i<100; i++) {
yueee_yt 0:f111c5224cd0 62 if(sum_rcv[i]>18) {
yueee_yt 0:f111c5224cd0 63 timing=i-1;
yueee_yt 0:f111c5224cd0 64 flag1=false;
yueee_yt 0:f111c5224cd0 65 break;
yueee_yt 0:f111c5224cd0 66 }
yueee_yt 0:f111c5224cd0 67 }
yueee_yt 0:f111c5224cd0 68 if(flag1==true) {
yueee_yt 0:f111c5224cd0 69 count1=0;
yueee_yt 0:f111c5224cd0 70 for(i=0; i<100; i++)sum_rcv[i]=0;
yueee_yt 0:f111c5224cd0 71 }
yueee_yt 0:f111c5224cd0 72 } else {
yueee_yt 0:f111c5224cd0 73 count1++;
yueee_yt 0:f111c5224cd0 74 }
yueee_yt 0:f111c5224cd0 75 }
yueee_yt 0:f111c5224cd0 76 }
yueee_yt 0:f111c5224cd0 77 //for(i=0; i<100; i++)printf("%d %d \n\r",i,sum_rcv[i]);
yueee_yt 0:f111c5224cd0 78 printf("*********************stage1 end*****************************\n\r");
yueee_yt 0:f111c5224cd0 79 printf("timing= %d\n\r",timing);
yueee_yt 0:f111c5224cd0 80 osEvent evt = queue.get();
yueee_yt 0:f111c5224cd0 81 printf("*********************stage2 time setting********************\n\r");
yueee_yt 0:f111c5224cd0 82 state=0;
yueee_yt 0:f111c5224cd0 83 while (flag2) {
yueee_yt 0:f111c5224cd0 84 osEvent evt = queue.get();
yueee_yt 0:f111c5224cd0 85 if (evt.status == osEventMessage) {
yueee_yt 0:f111c5224cd0 86 j=0;
yueee_yt 0:f111c5224cd0 87 for(i=0; i<100; i++)j+=rcv[i];
yueee_yt 0:f111c5224cd0 88 if(j<30) {
yueee_yt 0:f111c5224cd0 89 sig=2;
yueee_yt 0:f111c5224cd0 90 strcpy(mm,"M");
yueee_yt 0:f111c5224cd0 91 led2=1;
yueee_yt 0:f111c5224cd0 92 led3=0;
yueee_yt 0:f111c5224cd0 93 led4=0;
yueee_yt 0:f111c5224cd0 94 } else {
yueee_yt 0:f111c5224cd0 95 if(j<65) {
yueee_yt 0:f111c5224cd0 96 sig=1;
yueee_yt 0:f111c5224cd0 97 strcpy(mm,"1");
yueee_yt 0:f111c5224cd0 98 led2=0;
yueee_yt 0:f111c5224cd0 99 led3=1;
yueee_yt 0:f111c5224cd0 100 led4=0;
yueee_yt 0:f111c5224cd0 101 } else {
yueee_yt 0:f111c5224cd0 102 if(j<90) {
yueee_yt 0:f111c5224cd0 103 sig=0;
yueee_yt 0:f111c5224cd0 104 strcpy(mm,"0");
yueee_yt 0:f111c5224cd0 105 led2=0;
yueee_yt 0:f111c5224cd0 106 led3=0;
yueee_yt 0:f111c5224cd0 107 led4=1;
yueee_yt 0:f111c5224cd0 108 } else {
yueee_yt 0:f111c5224cd0 109 sig=9;
yueee_yt 0:f111c5224cd0 110 strcpy(mm,"?");
yueee_yt 0:f111c5224cd0 111 led2=1;
yueee_yt 0:f111c5224cd0 112 led3=1;
yueee_yt 0:f111c5224cd0 113 led4=1;
yueee_yt 0:f111c5224cd0 114 }
yueee_yt 0:f111c5224cd0 115 }
yueee_yt 0:f111c5224cd0 116 }
yueee_yt 0:f111c5224cd0 117 printf("Signal %d %s\n\r",j,mm);
yueee_yt 0:f111c5224cd0 118
yueee_yt 0:f111c5224cd0 119 switch(state) {
yueee_yt 0:f111c5224cd0 120 case 0:
yueee_yt 0:f111c5224cd0 121 if((old_sig==2)&&(sig==2)) {
yueee_yt 0:f111c5224cd0 122 state=1;
yueee_yt 0:f111c5224cd0 123 }
yueee_yt 0:f111c5224cd0 124 break;
yueee_yt 0:f111c5224cd0 125 case 1:
yueee_yt 0:f111c5224cd0 126 if((sig==0)||(sig==1)) {
yueee_yt 0:f111c5224cd0 127 m=40*sig;
yueee_yt 0:f111c5224cd0 128 state=2;
yueee_yt 0:f111c5224cd0 129 } else {
yueee_yt 0:f111c5224cd0 130 state=0;
yueee_yt 0:f111c5224cd0 131 }
yueee_yt 0:f111c5224cd0 132 break;
yueee_yt 0:f111c5224cd0 133 case 2:
yueee_yt 0:f111c5224cd0 134 if((sig==0)||(sig==1)) {
yueee_yt 0:f111c5224cd0 135 m+=20*sig;
yueee_yt 0:f111c5224cd0 136 state=3;
yueee_yt 0:f111c5224cd0 137 } else {
yueee_yt 0:f111c5224cd0 138 state=0;
yueee_yt 0:f111c5224cd0 139 }
yueee_yt 0:f111c5224cd0 140 break;
yueee_yt 0:f111c5224cd0 141 case 3:
yueee_yt 0:f111c5224cd0 142 if((sig==0)||(sig==1)) {
yueee_yt 0:f111c5224cd0 143 m+=10*sig;
yueee_yt 0:f111c5224cd0 144 state=4;
yueee_yt 0:f111c5224cd0 145 } else {
yueee_yt 0:f111c5224cd0 146 state=0;
yueee_yt 0:f111c5224cd0 147 }
yueee_yt 0:f111c5224cd0 148 break;
yueee_yt 0:f111c5224cd0 149 case 4:
yueee_yt 0:f111c5224cd0 150 if((sig==0)||(sig==1)) {
yueee_yt 0:f111c5224cd0 151 state=5;
yueee_yt 0:f111c5224cd0 152 } else {
yueee_yt 0:f111c5224cd0 153 state=0;
yueee_yt 0:f111c5224cd0 154 }
yueee_yt 0:f111c5224cd0 155 break;
yueee_yt 0:f111c5224cd0 156 case 5:
yueee_yt 0:f111c5224cd0 157 if((sig==0)||(sig==1)) {
yueee_yt 0:f111c5224cd0 158 m+=8*sig;
yueee_yt 0:f111c5224cd0 159 state=6;
yueee_yt 0:f111c5224cd0 160 } else {
yueee_yt 0:f111c5224cd0 161 state=0;
yueee_yt 0:f111c5224cd0 162 }
yueee_yt 0:f111c5224cd0 163 break;
yueee_yt 0:f111c5224cd0 164 case 6:
yueee_yt 0:f111c5224cd0 165 if((sig==0)||(sig==1)) {
yueee_yt 0:f111c5224cd0 166 m+=4*sig;
yueee_yt 0:f111c5224cd0 167 state=7;
yueee_yt 0:f111c5224cd0 168 } else {
yueee_yt 0:f111c5224cd0 169 state=0;
yueee_yt 0:f111c5224cd0 170 }
yueee_yt 0:f111c5224cd0 171 break;
yueee_yt 0:f111c5224cd0 172 case 7:
yueee_yt 0:f111c5224cd0 173 if((sig==0)||(sig==1)) {
yueee_yt 0:f111c5224cd0 174 m+=2*sig;
yueee_yt 0:f111c5224cd0 175 state=8;
yueee_yt 0:f111c5224cd0 176 } else {
yueee_yt 0:f111c5224cd0 177 state=0;
yueee_yt 0:f111c5224cd0 178 }
yueee_yt 0:f111c5224cd0 179 break;
yueee_yt 0:f111c5224cd0 180 case 8:
yueee_yt 0:f111c5224cd0 181 if((sig==0)||(sig==1)) {
yueee_yt 0:f111c5224cd0 182 m+=sig;
yueee_yt 0:f111c5224cd0 183 state=9;
yueee_yt 0:f111c5224cd0 184 } else {
yueee_yt 0:f111c5224cd0 185 state=0;
yueee_yt 0:f111c5224cd0 186 }
yueee_yt 0:f111c5224cd0 187 break;
yueee_yt 0:f111c5224cd0 188 case 9:
yueee_yt 0:f111c5224cd0 189 state=10;
yueee_yt 0:f111c5224cd0 190 break;
yueee_yt 0:f111c5224cd0 191 case 10:
yueee_yt 0:f111c5224cd0 192 if((sig==0)||(sig==1)) {
yueee_yt 0:f111c5224cd0 193 state=11;
yueee_yt 0:f111c5224cd0 194 } else {
yueee_yt 0:f111c5224cd0 195 state=0;
yueee_yt 0:f111c5224cd0 196 }
yueee_yt 0:f111c5224cd0 197 break;
yueee_yt 0:f111c5224cd0 198 case 11:
yueee_yt 0:f111c5224cd0 199 if((sig==0)||(sig==1)) {
yueee_yt 0:f111c5224cd0 200 state=12;
yueee_yt 0:f111c5224cd0 201 } else {
yueee_yt 0:f111c5224cd0 202 state=0;
yueee_yt 0:f111c5224cd0 203 }
yueee_yt 0:f111c5224cd0 204 break;
yueee_yt 0:f111c5224cd0 205 case 12:
yueee_yt 0:f111c5224cd0 206 if((sig==0)||(sig==1)) {
yueee_yt 0:f111c5224cd0 207 h=20*sig;
yueee_yt 0:f111c5224cd0 208 state=13;
yueee_yt 0:f111c5224cd0 209 } else {
yueee_yt 0:f111c5224cd0 210 state=0;
yueee_yt 0:f111c5224cd0 211 }
yueee_yt 0:f111c5224cd0 212 break;
yueee_yt 0:f111c5224cd0 213 case 13:
yueee_yt 0:f111c5224cd0 214 if((sig==0)||(sig==1)) {
yueee_yt 0:f111c5224cd0 215 h+=10*sig;
yueee_yt 0:f111c5224cd0 216 state=14;
yueee_yt 0:f111c5224cd0 217 } else {
yueee_yt 0:f111c5224cd0 218 state=0;
yueee_yt 0:f111c5224cd0 219 }
yueee_yt 0:f111c5224cd0 220 break;
yueee_yt 0:f111c5224cd0 221 case 14:
yueee_yt 0:f111c5224cd0 222 if((sig==0)||(sig==1)) {
yueee_yt 0:f111c5224cd0 223 state=15;
yueee_yt 0:f111c5224cd0 224 } else {
yueee_yt 0:f111c5224cd0 225 state=0;
yueee_yt 0:f111c5224cd0 226 }
yueee_yt 0:f111c5224cd0 227 break;
yueee_yt 0:f111c5224cd0 228 case 15:
yueee_yt 0:f111c5224cd0 229 if((sig==0)||(sig==1)) {
yueee_yt 0:f111c5224cd0 230 h+=8*sig;
yueee_yt 0:f111c5224cd0 231 state=16;
yueee_yt 0:f111c5224cd0 232 } else {
yueee_yt 0:f111c5224cd0 233 state=0;
yueee_yt 0:f111c5224cd0 234 }
yueee_yt 0:f111c5224cd0 235 break;
yueee_yt 0:f111c5224cd0 236 case 16:
yueee_yt 0:f111c5224cd0 237 if((sig==0)||(sig==1)) {
yueee_yt 0:f111c5224cd0 238 h+=4*sig;
yueee_yt 0:f111c5224cd0 239 state=17;
yueee_yt 0:f111c5224cd0 240 } else {
yueee_yt 0:f111c5224cd0 241 state=0;
yueee_yt 0:f111c5224cd0 242 }
yueee_yt 0:f111c5224cd0 243 break;
yueee_yt 0:f111c5224cd0 244 case 17:
yueee_yt 0:f111c5224cd0 245 if((sig==0)||(sig==1)) {
yueee_yt 0:f111c5224cd0 246 h+=2*sig;
yueee_yt 0:f111c5224cd0 247 state=18;
yueee_yt 0:f111c5224cd0 248 } else {
yueee_yt 0:f111c5224cd0 249 state=0;
yueee_yt 0:f111c5224cd0 250 }
yueee_yt 0:f111c5224cd0 251 break;
yueee_yt 0:f111c5224cd0 252 case 18:
yueee_yt 0:f111c5224cd0 253 if((sig==0)||(sig==1)) {
yueee_yt 0:f111c5224cd0 254 h+=sig;
yueee_yt 0:f111c5224cd0 255 state=19;
yueee_yt 0:f111c5224cd0 256 } else {
yueee_yt 0:f111c5224cd0 257 state=0;
yueee_yt 0:f111c5224cd0 258 }
yueee_yt 0:f111c5224cd0 259 break;
yueee_yt 0:f111c5224cd0 260 case 19:
yueee_yt 0:f111c5224cd0 261 flag2=0;
yueee_yt 0:f111c5224cd0 262 state=0;
yueee_yt 0:f111c5224cd0 263 break;
yueee_yt 0:f111c5224cd0 264 }
yueee_yt 0:f111c5224cd0 265 printf("%d %02d:%02d \n\r",state,h,m);
yueee_yt 0:f111c5224cd0 266 old_sig=sig;
yueee_yt 0:f111c5224cd0 267 }
yueee_yt 0:f111c5224cd0 268 }
yueee_yt 0:f111c5224cd0 269 jjy_rcv_timer.stop();
yueee_yt 0:f111c5224cd0 270 printf("Now = %02d:%02d:20 \n\r",h,m);
yueee_yt 0:f111c5224cd0 271 }