備忘の為スケッチ掲載.
I2Cでコントロール出来るラジオ用IC : Si4730 は値段も安く、AM / FM が受信出来て便利なICでは有るのだが、このラジオを作った当時、参考になるスケッチが無かったので、データシート見ながら自分で関数作った覚えがある。余り参考にならないと思うが備忘をかねてスケッチを掲載する事にした。このスケッチは Arduino IDE 1.8.16 でコンパイル出来る事は確認したのだが、保証は出来ないので悪しからず。
/*------------------------------------------ Si4730 FM/AM Radio use aitendo Si4730-M for Teke Bar Version Writen JH3DRN 2020/08/20 Fix Ver PORTB (Digital pin 8 to 13) PORTC (Analog pin) PORTD (Digital pin 0 to 7) Pin 2 Interrupt 0 (use this case) Pin 3 Interrupt 1 (not use) Use Arduino IDE Version is 1.8.16 -------------------------------------------*/ #define SCL_PIN 5 // SCL=pin A5 #define SCL_PORT PORTC #define SDA_PIN 4 // SDA=pin A4 #define SDA_PORT PORTC #define I2C_FASTMODE 1 #include <SoftI2CMaster.h> #define si4370_add 0xc6 // if use Wire.h Val=0x63 #define Mode_sel 9 // Freq select DipSW 1 #define Mode_AM 0 #define Mode_FM 1 #define Reset_Pin 3 // Module reset pin #define CHATR_CHK 15 // Chattaring check count #define CH_MAX_TOKYO 8 // Recive ch MAX Count of Tokyo #define CH_MAX_KYOTO 10 // Recive ch MAX Count of Kyoto #define CH_MAX_OSAKA 11 #define Tokyo 0 // Area code Tokyo #define Kyoto 1 #define Osaka 2 // variables will change: int buttonState = 0; // variable for reading the pushbutton status int ch_pos; // Ch Position int ch_max; // Ch Count Max Value int area_code; // 0=Tokyo,1=Kyoto etc char printBuffer[32]; // Need 50 byte int ch_pos_now; // Now Chanel Possition int ch_pos_befo; // Beffore Chanel Possition int mode_now; // Default Band is FM=1 AM=0 int mode_befo; // Before Band int mode_cnt=0; unsigned char Cmd_Si4730_power_up[] = {0x01,0x41,0x05}; // Power on unsigned char Cmd_FM_power_up[] = {0x01,0x10,0x05}; // Power on FM Band unsigned char Cmd_AM_power_up[] = {0x01,0x11,0x05}; // POwer on AM Band unsigned char Cmd_FM_Freq_Tune[] = {0x20,0x00,0x24,0x54,0x00}; // 93.00MHz Init Freq unsigned char Cmd_AM_Freq_Tune[] = {0x40,0x00,0x04,0x6e,0x00}; // 1134KHz Init Freq unsigned char Cmd_FM_DeemP[] = {0x12,0x00,0x11,0x00,0x00,0x01}; // Deemph 50μS unsigned char Cmd_FM_Antena_In[] = {0x12,0x00,0x11,0x07,0x00,0x01}; // FM Antena Input unsigned char Cmd_Set_Vol[] = {0x12,0x00,0x40,0x00,0x00,0x3f}; // Volume Control Max=0x3F uint16_t Stations_kyoto_FM[CH_MAX_KYOTO] = {7650, 7700, 8100, 8150, 8400, 8940, 9190, 9490}; uint16_t Stations_kyoto_AM[CH_MAX_KYOTO] = {558, 666, 828, 945, 1008, 1143, 1215, 1242}; uint16_t *defaultStations; /* TBS Rsdio 954khz Bunka Hoso 1134khz Nippon Hoso 1242khz NHK No1 594khz NHK No2 693khz Eagle810 810khz RadioNippon 1422khz */ void setup() { pin_mode_init(); // Set Pin mode to init i2c_init(); Serial.begin(115200); Serial.println("Start init"); RadioModule_Reset(); // Chip Reset delay(100); freq_mode_set(); ch_pos=0; // Set Chanel possition is 0 Set_Chanel(mode_now, ch_pos); } void loop() { char option; char vol = 15; uint8_t Retbtn; byte current_vol; ch_pos_befo = ch_pos; mode_befo = mode_now; while(1) { if(digitalRead(Mode_sel) == HIGH) // Mode AM? { if(mode_now == Mode_FM) { mode_now=Mode_AM; mode_setting_AM(); } }else if(mode_now == Mode_AM) { mode_now=Mode_FM; mode_setting_FM(); } Retbtn=read_freq_dipsw(); // Read Dip SW ch_pos = Retbtn; // Save now ch Serial.print(Retbtn); Serial.println(); if(ch_pos_befo != Retbtn) { Set_Chanel(mode_now, ch_pos); ch_pos_befo = ch_pos; } delay(1500); } delay(100); } void RadioModule_Reset(void) { pinMode(Reset_Pin, OUTPUT); // Reset pin D9 is output digitalWrite(Reset_Pin,LOW); _delay_ms(1); digitalWrite(Reset_Pin,HIGH); _delay_ms(1); // PORT_LOW(PORTB,RADIO_RESET); // _delay_ms(1); // PORT_HIGH(PORTB,RADIO_RESET); // _delay_ms(1); } void Chip_Power_Down(void) { // 'パワーダウン 受信モードを変える場合、一度電源落とす unsigned char pow_off[]={0x11}; Si4730_Cmd_Write(pow_off,1); delay(300); } uint8_t Read_Status(void) // CTS が0x80になるまで待つ { uint8_t msb,lsb; uint8_t retdt,i; for(i=0;i<10;i++) // 10回待って駄目なら諦める { i2c_start(si4370_add | I2C_READ); lsb = i2c_read(false); msb = i2c_read(true); i2c_stop(); // Serial.print(msb,HEX); Serial.print(" "); // Serial.print(lsb,HEX); Serial.println(" "); if( lsb == 0x80) break; // if ACK Recive delay(100); } return(lsb); } uint8_t Si4730_Cmd_Write(unsigned char *cmd,int len) { uint8_t ret; int i; i2c_start(si4370_add | I2C_WRITE); // write mode for(i=0;i<len;i++) { i2c_write(cmd[i]); // I2cwbyte &H2c 'max 0x3f } i2c_stop(); ret=Read_Status(); return(ret); // I2cstop } void Set_Chanel_Tune(int mode,unsigned int freq_int) { // Serial.print("freq="); Serial.print(freq_int,DEC); // Serial.print("mode="); Serial.print(mode,DEC); switch(mode) // AM = mode0,FM = mode1 { case Mode_AM: Cmd_AM_Freq_Tune[2]=(freq_int & 0xff00) >> 8; Cmd_AM_Freq_Tune[3]=(freq_int & 0x00ff); Si4730_Cmd_Write(Cmd_AM_Freq_Tune,sizeof(Cmd_AM_Freq_Tune)); break; case Mode_FM: Cmd_FM_Freq_Tune[2]=(freq_int & 0xff00) >> 8; Cmd_FM_Freq_Tune[3]=(freq_int & 0x00ff); Si4730_Cmd_Write(Cmd_FM_Freq_Tune,sizeof(Cmd_FM_Freq_Tune)); break; default: break; } } void pin_mode_init(void) { pinMode(10, INPUT); // Dip SW port D10=12Mode sel pinMode(11, INPUT); // D11-13 Freq select pinMode(12, INPUT); pinMode(9, INPUT); // D9 = Freq AM/FM pinMode(Reset_Pin, OUTPUT); // Board reset port (D3) pinMode(5, OUTPUT); // LED port D5 = Mode sel pinMode(6, OUTPUT); // D6-D8 Freq. sel sw pinMode(7, OUTPUT); pinMode(8, OUTPUT); digitalWrite(5,HIGH); // all LED off digitalWrite(6,HIGH); digitalWrite(7,HIGH); digitalWrite(8,HIGH); } /* TBS Rsdio 954khz Bunka Hoso 1134khz Nippon Hoso 1242khz NHK No1 594khz NHK No2 693khz Eagle810 810khz RadioNippon 1422khz */ void Set_Chanel(int mode, int pos) // mode AM/FM pos ch possition { // Serial.print(pos,HEX); Serial.println(" pos "); Set_Chanel_Tune(mode,defaultStations[pos]); // Start Freqncy setup } //--------------BAND SWITCH -------------------------- void mode_setting_AM() { Chip_Power_Down(); // Chip Power down Si4730_Cmd_Write(Cmd_AM_power_up,sizeof(Cmd_AM_power_up)); defaultStations = Stations_kyoto_AM; // Kyoto Frequncy set ch_max = CH_MAX_KYOTO; ch_pos=0; Set_Chanel(mode_now,ch_pos); digitalWrite(10,LOW); } void mode_setting_FM() { Chip_Power_Down(); // Chip Power down Si4730_Cmd_Write(Cmd_FM_power_up,sizeof(Cmd_FM_power_up)); ch_max = CH_MAX_TOKYO; ch_pos=0; defaultStations = Stations_kyoto_FM; // Kyoto Frequncy set Set_Chanel(mode_now,ch_pos); digitalWrite(10,HIGH); } uint8_t read_freq_dipsw() // Read Dip SW Value & Set LED { uint8_t retval; retval = 0x00; // init val set if (digitalRead(10) == HIGH) { retval = retval | 0b0001; digitalWrite(8,LOW); } else digitalWrite(8,HIGH); if (digitalRead(11) == HIGH) { retval = retval | 0b0010; digitalWrite(7,LOW); } else digitalWrite(7,HIGH); if (digitalRead(12) == HIGH) { retval = retval | 0b0100; digitalWrite(6,LOW); } else digitalWrite(6,HIGH); return(retval); } /* Freq Mode set */ void freq_mode_set() { if ( digitalRead(Mode_sel) == HIGH ) // Mode AM ? { mode_now=Mode_AM; mode_setting_AM(); } else { mode_now=Mode_FM; // Default Band is FM mode_setting_FM(); } mode_now = mode_befo; }