●マイコン側
オペアンプで増幅して矩形波としたものをmbedに入力し、インプットキャプチャで復調していきます。得られた8bitのデータをシリアルでパソコンに送ってターミナル画面で確認します。
#include "mbed.h" #define SAMPLE_RATE 44100 #define FREQ_LOW 3150 #define FREQ_HIGH 6300 #define BAUD 630 #define HIGH 1 #define LOW 0 #define MID 2 #define IDLE 0 #define RCVCODE 1 #define CHECKCODE 2 Serial pc(USBTX, USBRX); Timer timer; InterruptIn sig(p21); int begin,end,interval; int LowWidth, HighWidth; unsigned char lowFreqCnt, highFreqCnt; unsigned char lowSigCnt, highSigCnt; unsigned char fskSignal; unsigned char bitCnt; unsigned char fskData; unsigned char rcvState; void getData(unsigned char data) { pc.putc(data); } void sigFall() { interval = 0; begin = timer.read_us(); } void sigRise() { end = timer.read_us(); interval = end - begin; timer.reset(); fskSignal = MID; //check wave width if(LowWidth-54 < interval && interval < LowWidth+54) { //lowFreq lowFreqCnt++; highFreqCnt = 0; if(lowFreqCnt == FREQ_LOW/BAUD) { //signal is LOW fskSignal = LOW; lowFreqCnt = 0; } }else if(HighWidth-26 < interval && interval < HighWidth+26) { //highFreq highFreqCnt++; lowFreqCnt = 0; if(highFreqCnt == FREQ_HIGH/BAUD) { //signal is HIGH fskSignal = HIGH; highFreqCnt = 0; } }else { //should ignore rcvState = IDLE; lowFreqCnt = highFreqCnt = lowSigCnt = highSigCnt = 0; fskSignal = MID; } //check data switch(rcvState) { case IDLE: if(fskSignal == LOW) { lowSigCnt++; }else if(fskSignal ==HIGH) { if(lowSigCnt == 8) { //detect header and start bit rcvState = RCVCODE; fskData = 0; bitCnt = 0; } } break; case RCVCODE: if(fskSignal == LOW) { fskData <<= 1; bitCnt++; }else if(fskSignal == HIGH) { bitCnt++; if(bitCnt == 9) { //stop bit bitCnt = 0; rcvState = IDLE; lowFreqCnt = highFreqCnt = lowSigCnt = highSigCnt = 0; getData(fskData); fskData = 0; }else { fskData <<= 1; fskData += 1; } } break; default: break; } } int main() { LowWidth = 1000000/FREQ_LOW/2; HighWidth = 1000000/FREQ_HIGH/2; lowFreqCnt = highFreqCnt = 0; timer.start(); sig.rise(&sigRise); sig.fall(&sigFall); while(1) { } }