2016年6月1日水曜日

50円で作るFMラジオ - Rasberry Pi&Node.js偏

 RRD-102 v2.0(FM ステレオ ラジオ RDA5807M ワイヤレス モジュール) をRasberry Pi&Node.js(Johnny-Five)で制御してみました。RRD-102 v2.0は、AliexEress50円程度で購入できます。
 
○回路、配線図
 

・使用部品(ゼロから揃えると、50円では、収まりませんが....)
   電解コンデンサ 4.7μF × 2
 ※アンテナは電波状況が良いところなら、ジャンパワイヤー等で代用できます。

○プログラム 
var FREQ_STEPS = 10,
RADIO_REG_CHIPID = 0x00,
RADIO_REG_CTRL = 0x02,
RADIO_REG_CTRL_OUTPUT = 0x8000,
RADIO_REG_CTRL_UNMUTE = 0x4000,
RADIO_REG_CTRL_MONO = 0x2000,
RADIO_REG_CTRL_BASS = 0x1000,
RADIO_REG_CTRL_SEEKUP = 0x0200,
RADIO_REG_CTRL_SEEK = 0x0100,
RADIO_REG_CTRLSKMODE = 0x0080,
RADIO_REG_CTRL_RDS = 0x0008;
RADIO_REG_CTRL_NEW = 0x0004,
RADIO_REG_CTRL_RESET = 0x0002,
RADIO_REG_CTRL_ENABLE = 0x0001
var RADIO_REG_CHAN = 0x03,
RADIO_REG_CHAN_SPACE = 0x0003,
RADIO_REG_CHAN_SPACE_100 = 0x0000,
RADIO_REG_CHAN_BAND = 0x000C,
RADIO_REG_CHAN_BAND_FM = 0x0000,
RADIO_REG_CHAN_BAND_FMJAPAN = 0x0004,
RADIO_REG_CHAN_BAND_FMWORLD = 0x0008,
RADIO_REG_CHAN_TUNE = 0x0010,
RADIO_REG_CHAN_TEST = 0x0020,
RADIO_REG_CHAN_NR = 0x7FC0
var RADIO_REG_R4 = 0x04,
RADIO_REG_R4_EM50 = 0x0800,
RADIO_REG_R4_SOFTMUTE = 0x0200,
RADIO_REG_R4_AFC = 0x0100
var RADIO_REG_VOL = 0x05,
RADIO_REG_VOL_VOL = 0x000F
var RADIO_REG_RA = 0x0A,
RADIO_REG_RA_RDS = 0x8000,
RADIO_REG_RA_RDSBLOCK = 0x0800,
RADIO_REG_RA_STEREO = 0x0400,
RADIO_REG_RA_NR = 0x03FF
var RADIO_REG_RB = 0x0B,
RADIO_REG_RB_FMTRUE = 0x0100,
RADIO_REG_RB_FMREADY = 0x0080
var RADIO_REG_RDSA = 0x0C,
RADIO_REG_RDSB = 0x0D,
RADIO_REG_RDSC = 0x0E,
RADIO_REG_RDSD = 0x0F
// I2C-Address RDA Chip for sequential Access
var I2C_SEQ = 0x10;
// I2C-Address RDA Chip for Index Access
var I2C_INDX = 0x11;
var RADIO_BAND_FM = 0 ///< FM band 87.5 ・108 MHz (USA, Europe) selected.
var RADIO_BAND_FMJAPAN = 4 ///< FM band 76 ・91 MHz (Japan) selected.
var RADIO_BAND_FMWORLD = 8 ///< FM band 76 ・108 MHz (Japan, Worldwide) selected.
var raspi = require('raspi-io');
var five = require('johnny-five');
var board = new five.Board({
io: new raspi()
});
board.on('ready', function() {
board.io.i2cConfig({delay: 500});
init();
setBand(RADIO_BAND_FMJAPAN);
setFrequency(8180);
//seekUp(true);
setVolume(0x05)
getFrequency();
//getRegister(RADIO_REG_CTRL);
board.io.i2cRead(I2C_INDX, RADIO_REG_CTRL,0x00,function(data){});;
});
var init = function(){
console.log("init...")
// initialize all registers
var dat = RADIO_REG_CTRL_OUTPUT | RADIO_REG_CTRL_UNMUTE | RADIO_REG_CTRL_BASS | RADIO_REG_CTRL_SEEKUP | RADIO_REG_CTRL_RDS | RADIO_REG_CTRL_NEW | RADIO_REG_CTRL_ENABLE;
var hbyte = dat >> 8;
var lbyte = dat & 0xFF;
board.io.i2cWrite(I2C_INDX,RADIO_REG_CTRL,[hbyte,lbyte]);
}
var setBand = function(newBand){
setTimeout(function() {
board.io.i2cReadOnce(I2C_INDX, RADIO_REG_CHAN, 0x2,function(data){
var chain = (data[0] << 8 | data[1]);
var hbyte = chain >> 8;
var lbyte = chain & 0xFF & ~0xC | newBand;
setRegister(RADIO_REG_CHAN, hbyte, lbyte);
});
},100);
}
var setFrequency = function(newF){
setTimeout(function() {
board.io.i2cReadOnce(I2C_INDX, RADIO_REG_CHAN, 0x2,function(data){
var regChannel =(data[0] << 8 | data[1]) & (RADIO_REG_CHAN_SPACE | RADIO_REG_CHAN_BAND);
if (newF < 7600) newF = 7600;
if (newF > 9100) newF = 9100;
var newChannel = (newF - 7600) / 10;
regChannel += RADIO_REG_CHAN_TUNE; // enable tuning
regChannel |= newChannel << 6;
var hbyte = regChannel >> 8;
var lbyte = regChannel & 0xFF;
setRegister(RADIO_REG_CHAN, hbyte, lbyte);
});
},100);
}
var getFrequency = function(){
board.io.i2cRead(I2C_SEQ,RADIO_REG_RA, 0x2,function(data){
var ch = (data[0] << 8 | data[1]) & RADIO_REG_RA_NR;
var freq = 7600 + ch * 10;
console.log(freq / 100 + "MHz" );
});
}
var setVolume = function(newVolume){
console.log("Voleme set...");
var vol = newVolume;
setTimeout(function() {
board.io.i2cReadOnce(I2C_INDX, RADIO_REG_VOL, 0x2,function(data){
var volume = data[0] << 8 | data[1] & ~RADIO_REG_VOL_VOL | (vol & RADIO_REG_VOL_VOL);
var hbyte = volume >> 8;
var lbyte = volume & 0xFF;
setRegister(RADIO_REG_VOL,hbyte, lbyte);
});
},100);
}
var seekUp = function(wrap){
console.log("Seek Up...");
setTimeout(function() {
board.io.i2cReadOnce(I2C_INDX, RADIO_REG_CTRL, 0x2,function(data){
var mask = RADIO_REG_CTRL_SEEKUP | RADIO_REG_CTRL_SEEK | RADIO_REG_CTRLSKMODE;
var value = RADIO_REG_CTRL_SEEKUP| RADIO_REG_CTRL_SEEK | (wrap ? 0x00 : RADIO_REG_CTRLSKMODE);
var seek = data[0] << 8 | data[1] & ~mask | value;
var hbyte = seek >> 8;
var lbyte = seek & 0xFF;
setRegister(RADIO_REG_CTRL,hbyte, lbyte);
});
},100);
}
var seekDown = function(wrap){
console.log("Seek Down...");
setTimeout(function() {
board.io.i2cReadOnce(I2C_INDX, RADIO_REG_CTRL, 0x2,function(data){
var mask = RADIO_REG_CTRL_SEEKUP | RADIO_REG_CTRL_SEEK | RADIO_REG_CTRLSKMODE;
var value = 0x00 | RADIO_REG_CTRL_SEEK | (wrap ? 0x00 : RADIO_REG_CTRLSKMODE);
var seek = data[0] << 8 | data[1] & ~mask | value;
var hbyte = seek >> 8;
var lbyte = seek & 0xFF;
setRegister(RADIO_REG_CTRL,hbyte, lbyte);
});
},100);
}
var setRegister = function(reg, hbyte, lbyte){
board.io.i2cWrite(I2C_INDX,reg,[hbyte,lbyte]);
}
var getRegister = function(reg){
board.io.i2cRead(I2C_INDX, reg, 0x2,function(data){
var result = data[0] << 8 | data[1];
console.log(result.toString(2))
});
}
view raw FmRadio-pi.js hosted with ❤ by GitHub
 受信周波数を直接指定する場合には、「setFrequency」関数を使います。引数に受信周波数(×100)を指定してください。たとえば、81.8MHzを受信したい場合は、「setFrequency(8180)」と指定します。シーク機能で選局するには、「seekUp」「seekDown」関数を使用します。音量は「setVolume」関数で設定します。設定範囲は、0x00~0x0Fです。

0 件のコメント:

コメントを投稿