なんやかやでそこそこ慌ただしくしてることもあり、それやこれやが全くなんも進んでない状態ですが。
そんな中、TR-8200用に製作したVFOをTR-1300につないでみようと思い立ち、ソフト(スケッチ)を微調整してみることに。
何しろ上蓋を開けるだけですぐ書き換えできる(しかもその上蓋も手で開け閉めできる)お手軽さなので、こういう楽しみ方にはうってつけ。
表示はとりあえずこんな感じに。
目論見通り接続は無加工でいけるしレベル的にも問題ない模様。
で、結論からいいますと使えるのは使えるんですが、残念ながらバンド全体がノイズっぽいし、メータが振るくらいのスプリアスも数箇所ある感じ。
さすがにこのままでは面白くないんで、試しに発振部をシールド化してみようかな。ってI2Cラインに貫通コンデンサ入れてもいいのかな。
…いかん、早速面倒に思えてきた(^^;
とりあえずスケッチはこんな感じにしてみました。
TR-8200の時と同様、表示周波数を発振周波数に変換する部分が3箇所もあるのがアレなんですが。
それと今回ボタン内蔵LEDは未使用なんですが、その部分の宣言などは消さずに残してます(特に意味なし)。
/* * Arduino Si5351A 7MHz VFO OLED Display * 2020.12.29 * JH7UBC Keiji Hata * * Modified for TR-1300 * by Sugi JI3KDH * Aug. 26, 2023 */ #include <Wire.h> #include <SSD1306AsciiAvrI2c.h> #include <Rotary.h> SSD1306AsciiAvrI2c oled; Rotary r = Rotary(2, 3); //initialize digital pin output const int LED_PIN = 13; void setup_LED() { pinMode(LED_PIN, OUTPUT); } //initialize Si5351A #define Si5351A_ADDR 0x60 #define MSNA_ADDR 26 #define MSNB_ADDR 34 #define MS0_ADDR 42 #define MS1_ADDR 50 #define MS2_ADDR 58 #define CLK0_CTRL 16 #define CLK1_CTRL 17 #define CLK2_CTRL 18 #define OUTPUT_CTRL 3 #define XTAL_LOAD_C 183 #define PLL_RESET 177 uint32_t XtalFreq = 25000000; uint32_t divider; uint32_t PllFreq; uint8_t mult; uint32_t num; uint32_t denom; uint32_t l; float f; uint32_t P1; uint32_t P2; uint32_t P3; char PLL; uint8_t PLL_ADDR; uint8_t MS_ADDR; //frequency STEP #define SW_STEP 4 //frequency STEP button //setting frequencies const long LOW_FREQ = 50000000; //freq low limit const long HI_FREQ = 50700000; //freq high limit unsigned long FREQ = 50110000; //freq default unsigned long FREQ_OLD = FREQ; //freq previous value unsigned long FREQ_OUT = FREQ - 50000000 + 8200000; //freq output for TR-1300 int dF = 194; //freq delta-f unsigned long STEP = 100; //STEP default //Rotary Encoder external break-in routine void rotary_encoder(){ unsigned char result = r.process(); if(result){ if(result == DIR_CW){ FREQ = FREQ + STEP; }else{ FREQ = FREQ - STEP; } } FREQ = constrain(FREQ,LOW_FREQ,HI_FREQ); //bandwidth limits } //when STEP SW is turned ON void Fnc_Stp() { if(STEP == 10){ STEP = 10000; } else{ STEP /= 10; } delay(10); Step_Disp(STEP); while(digitalRead(SW_STEP) == LOW){ delay(10); } } void setup() { r.begin(); //initial setting for rotaly encorder attachInterrupt(0,rotary_encoder,CHANGE); //external breakin setting attachInterrupt(1,rotary_encoder,CHANGE); pinMode(SW_STEP,INPUT_PULLUP); //set as input for STEP SW with pullup oled.begin(&Adafruit128x64, 0x3C); //OLED initiarize Si5351_init(); //Si5351A initiarize FREQ_OUT = FREQ - 50000000 + 8200000; //freq output for TR-1300 PLL_Set('A',FREQ_OUT + dF); //default freq setting for VFO MS_Set(0); //default screen settings oled.setFont(X11fixed7x14B); oled.setCursor(5,0); oled.print("50."); oled.setFont(font5x7); oled.setCursor(5,7); oled.print("STEP"); Freq_Disp(FREQ); //freq display Step_Disp(STEP); //STEP display Freq_out_Disp(FREQ_OUT); //freq_out display } //Main program void loop() { if(digitalRead(SW_STEP) == LOW){Fnc_Stp();} //change STEP when STEP SW on if(FREQ != FREQ_OLD){ //change freq of Si5351A when FREQ is changed FREQ_OUT = FREQ - 50000000 + 8200000; //freq output for TR-1300 PLL_Set('A',FREQ_OUT + dF); MS_Set(0); Freq_Disp(FREQ); //displaying freq Freq_out_Disp(FREQ_OUT); FREQ_OLD = FREQ; //saving chagned freq } delay(10); } //freq display void Freq_Disp(unsigned long Fre){ String freqt = String(Fre); oled.setFont(CalBlk36); oled.setCursor(3,2); oled.print(freqt.substring(2,5) + "." + freqt.substring(5,7) + " "); } //freq_out display void Freq_out_Disp(unsigned long Fre_out){ String freqt_out = String(Fre_out); if (freqt_out.substring(0,1) != "1"){ freqt_out = " " + freqt_out; } else{ ; } oled.setFont(font5x7); oled.setCursor(70,7); oled.print(freqt_out.substring(0,2) + "." + freqt_out.substring(2)); } //step display void Step_Disp(int Stp){ oled.setFont(font5x7); oled.setCursor(30,7); if(Stp == 10000){ oled.print(" 10k"); }else if(Stp == 1000){ oled.print(" 1k "); }else if(Stp == 100){ oled.print(" 100"); }else{ oled.print(" 10 "); } } //set 1 byte to register void Si5351_write(byte Reg , byte Data){ Wire.beginTransmission(Si5351A_ADDR); Wire.write(Reg); Wire.write(Data); Wire.endTransmission(); } //initiarize Si5351A void Si5351_init(){ Si5351_write(OUTPUT_CTRL,0xFF); //Disable Output Si5351_write(CLK0_CTRL,0x80); //CLOCK0 Power down Si5351_write(CLK1_CTRL,0x80); //CLOCK1 Power down Si5351_write(CLK2_CTRL,0x80); //CLOCK2 Power down Si5351_write(XTAL_LOAD_C,0x80); //Crystal Load Capasitance=8pF Si5351_write(PLL_RESET,0xA0); //Reset PLLA and PLLB Si5351_write(CLK0_CTRL,0x4F); //CLOCK0 Power up 8mA Si5351_write(CLK1_CTRL,0x4F); //CLOCK1 Power up Si5351_write(CLK2_CTRL,0x4F); //CLOCK2 Power up Si5351_write(OUTPUT_CTRL,0xFE); //Enable CLOCK0 } //setting PLL void PLL_Set(char Pll,uint32_t Frequency){ divider = 900000000 / Frequency; if (divider % 2) divider--; PllFreq = divider * Frequency; mult = PllFreq / XtalFreq; l = PllFreq % XtalFreq; f = l; f *= 1048575; f /= XtalFreq; num = f; denom = 1048575; P1 = (uint32_t)(128 * ((float)num /(float)denom)); P1 = (uint32_t)(128 * (uint32_t)(mult) + P1 - 512); P2 = (uint32_t)(128 * ((float)num / (float)denom)); P2 = (uint32_t)(128 * num -denom * P2); P3=denom; if (Pll == 'A'){ PLL_ADDR = MSNA_ADDR; }else{ PLL_ADDR = MSNB_ADDR; } Parameter_write(PLL_ADDR,P1,P2,P3); } //setting MultiSynth (bunshuuki) void MS_Set(uint8_t MS_No){ P1 = 128 * divider - 512; P2 = 0; P3 = 1; switch(MS_No){ case 0: MS_ADDR = MS0_ADDR; break; case 1: MS_ADDR = MS1_ADDR; break; case 2: MS_ADDR = MS2_ADDR; break; default: MS_ADDR = MS0_ADDR; } Parameter_write(MS_ADDR,P1,P2,P3); } //write paramators P1,P2,P3 into register void Parameter_write(uint8_t REG_ADDR,uint32_t Pa1,uint32_t Pa2,uint32_t Pa3) { Si5351_write(REG_ADDR + 0,(Pa3 & 0x0000FF00) >> 8); Si5351_write(REG_ADDR + 1,(Pa3 & 0x000000FF)); Si5351_write(REG_ADDR + 2,(Pa1 & 0x00030000) >> 16); Si5351_write(REG_ADDR + 3,(Pa1 & 0x0000FF00) >> 8); Si5351_write(REG_ADDR + 4,(Pa1 & 0x000000FF)); Si5351_write(REG_ADDR + 5,((Pa3 & 0x000F0000) >> 12) | ((Pa2 & 0X000F0000) >> 16)); Si5351_write(REG_ADDR + 6,(Pa2 & 0x0000FF00) >> 8); Si5351_write(REG_ADDR + 7,(Pa2 & 0x000000FF)); }
9/4追記:
バンド内のノイズについて、VFOに併設した昭和のスイッチング電源が発信源かもと外部のリニア電源で動作させてみたところ、状況変わらず。やはり発振部(もしくはプログラム?)に原因がありそうな感じ。
arduino nanoにもレギュレーターが...
あとはsi5351aの信号と電源をフォトカプラで分けるとか...?
ふと思いつきました。
SSD1306のようなディスプレイは高速で1/0を切り替えるのでそこでノイズが発生しているのかもしれません。
それこそ電源と信号を分けるなどしたらいいかもしれません。
コメントありがとうございます。
ここの電源入力は7~12Vとありますので実際13.8Vでも動かないことはないんでしょうけど、内蔵レギュレータの負担を考えるととてもとても、と思いましたんでこのようにしました。どうせ使い切れないくらいの手持ちがありますし(^^;
スプリアスはまだしもノイズっぽいのは、あるいはご指摘いただいたあたりも原因かも知れませんね。そのあたりも含め、まずは出力部をシールドしながらボチボチ触ってみようと思ってます。