JH7UBCブログ

アマチュア無線 電子工作 家庭菜園など趣味のブログです

Raspberry Pi Pico MicroPython Si5351A 7MHz VFO

2021-12-08 14:06:16 | Raspberry Pi Pico
 Raspberry Pi Pico MicroPythonの組み合わせで、3チャンネルクロックジェネレータSi5351Aを使った7MHz VFOを作ってみました。

 Si5351 VFOは、これまでPIC,Arduino,STM32,ESP32などで何度も作りました。Si5351Aをコントロールする実験は、JH7UBCホームページのArduinoのページに詳しく掲載していますので、そちらをご覧ください。

 Raspberry Pi Picoでこれまでテストしてきた各デバイスのスクリプトを組み合わせて今回のスクリプトを作りました。

 回路図です。I2Cは、id=0,sda=Pin16,scl=Pin17とし、Si5351AとOLEDをコントロールします。VFO出力は、SI5351AのCLK0です。ロータリーエンコーダは、GPIO0とGPIO1に接続します。周波数STEPスイッチは、GPIO15に接続し、GPIO0,1,15は内部でプルアップします。

ブレッドボードです。


周波数カウンタを接続して、動作を確認しています。期待通りの動作をしました。


スケッチです。(ちょっと長いです。)Si5351Aは個体により若干の周波数のずれがあります。その補正は、dFの値とCrystal Load Capacitanceの値で行います。周波数STEPは、10K→1K→100→10→1Kと押すたびに変更され、循環します。なお、OLEDを使いますので、ssd1306ライブラリーをPicoにインストールしておきます。このスクリプトは、main.pyとしてPicoに保存します。
--------------------------------------------------------------------------------------------
"""
Si5351A test
7MHz VFO OUTPUT CLK0
2021.12.8
JH7UBC Keiji Hata
"""

from machine import I2C,Pin
import ssd1306
import utime

i2c=I2C(0,sda=Pin(16),scl=Pin(17),freq=400000)
oled=ssd1306.SSD1306_I2C(128,64,i2c)

step_sw=Pin(15,Pin.IN,Pin.PULL_UP)
pinA = Pin(0,Pin.IN,Pin.PULL_UP)
pinB = Pin(1,Pin.IN,Pin.PULL_UP)

#Di5351A関係定義
Si5351A_ADDR = 0x60
MSNA_ADDR = 26
MSNB_ADDR = 34
MS0_ADDR = 42
MS1_ADDR = 50
MS2_ADDR = 58
CLK0_CTRL = 16
CLK1_CTRL = 17
CLK2_CTRL = 18
OUTPUT_CTRL = 3
XTAL_LOAD_C = 183
PLL_RESET = 177
XtalFreq = 25000000
df = -62 #周波数補正値
denom = 1048575
frequency = 7000000 #周波数初期値
frequency_old = frequency
step = 10000 #step初期値
old_fH=""
old_fM=""
old_fL=""
f_Max = 7200000 #周波数最大値
f_Min = 7000000 #周波数最小値


#Rotary Encoder関係定義
befDat=0x11
curDat=0
count=0

buf = bytearray(2)

def Si5351_write(reg,data):
     buf[0] = reg
     buf[1] = data
     i2c.writeto(Si5351A_ADDR,buf)
#Si5351A initialize
def Si5351_init():
     Si5351_write(OUTPUT_CTRL,0xFF)#Disable Output
     Si5351_write(CLK0_CTRL,0x80)   #CLK0 Power down
     Si5351_write(CLK1_CTRL,0x80)   #CLK1 Power down
     Si5351_write(CLK2_CTRL,0x80)   #CLK2 Power down
     Si5351_write(XTAL_LOAD_C,0x40)#Crystal Load Capacitance=6pF
     Si5351_write(PLL_RESET,0xA0)   #Reset PLLA and PLLB
     Si5351_write(CLK0_CTRL,0x4F)   #CLK0 Power up 8mA
#     Si5351_write(CLK1_CTRL,0x4F)   #CLK1 Power up 8mA
#     Si5351_write(CLK2_CTRL,0x4F)   #CLK2 Power up 8mA
     Si5351_write(OUTPUT_CTRL,0xFE)#Enable CLOK0

def PLLA_set(freq):
     global XtalFreq,divider,df,denom
     freq += df #df=周波数補正値
     divider = int(900000000 / freq)
     divider >> 1 #dividerは整数かつ偶数
     divider << 1
     PllFreq = divider * freq
     mult = PllFreq // XtalFreq
    l = PllFreq % XtalFreq
    f = l * denom
     num = f // XtalFreq
     P1 = int(128 * (num / denom))
     P1 = 128 * mult + P1 - 512
     P2 = int(128 * (num / denom))
     P2 = 128*num - denom * P2
     P3 = denom

     Si5351_write(MSNA_ADDR + 0,(P3 & 0x0000FF00) >> 8)  #MSNA_P3[15:8]
     Si5351_write(MSNA_ADDR + 1,(P3 & 0x000000FF))       #MSNA_P3[7:0]
     Si5351_write(MSNA_ADDR + 2,(P1 & 0x00030000) >> 16) #MSNA_P1[17:16]
     Si5351_write(MSNA_ADDR + 3,(P1 & 0x0000FF00) >> 8)  #MSNA_P1[15:8]
     Si5351_write(MSNA_ADDR + 4,(P1 & 0x000000FF))       #MSNA_P1[7:0]
     Si5351_write(MSNA_ADDR + 5,((P3 & 0x000F0000) >> 12) | ((P2 & 0X000F0000) >> 16))#MSNA_P3[19:16]MSNA_P2[19:16]
     Si5351_write(MSNA_ADDR + 6,(P2 & 0x0000FF00) >> 8)  #MSNA_P2[15:8]
     Si5351_write(MSNA_ADDR + 7,(P2 & 0x000000FF))       #MSNA_P2[7:0]

def MS0_set():
     global divider
     P1=128*divider-512
     P2=0
     P3=1
     Si5351_write(MS0_ADDR + 0,(P3 & 0x0000FF00) >> 8)   #MS0_P3[15:8]
     Si5351_write(MS0_ADDR + 1,(P3 & 0x000000FF))        #MS0_P3[7:0]
     Si5351_write(MS0_ADDR + 2,(P1 & 0x00030000) >> 16)  #MS0_P1[17:16]
     Si5351_write(MS0_ADDR + 3,(P1 & 0x0000FF00) >> 8)   #MS0_P1[15:8]
     Si5351_write(MS0_ADDR + 4,(P1 & 0x000000FF))        #MS0_P1[7:0]
     Si5351_write(MS0_ADDR + 5,((P3 & 0x000F0000) >> 12) | ((P2 & 0X000F0000) >> 16))#MS0_P3[19:16]MS0_P2[19:16]
     Si5351_write(MS0_ADDR + 6,(P2 & 0x0000FF00) >> 8)   #MS0_P2[15:8]
     Si5351_write(MS0_ADDR + 7,(P2 & 0x000000FF))        #MS0_P2[7:0 Si5351_init()

#周波数表示
def Freq_Disp(freq):
     global old_fH,old_fM,old_fL
     fre_txt = str(freq)
     fH=fre_txt[0]
     if fH != old_fH:
         oled.fill_rect(28,16,8,8,0)
         oled.show()
         oled.text(fH,28,16)
         oled.show()
         old_fH=fH
     fM=fre_txt[1:4]
     if fM != old_fM:
         oled.fill_rect(44,16,24,8,0)
         oled.show()
         oled.text(fM,44,16)
         oled.show()
         old_fM=fM
     fL=fre_txt[4:]
     if fL != old_fL:
         oled.fill_rect(73,16,24,8,0)
         oled.show()
         oled.text(fL,76,16)
         oled.show()
         old_fL=fL

#STEP表示
def Step_Disp():
     global step
     oled.fill_rect(24,52,32,8,0)
     oled.show()
     if step == 10000:
         oled.text(" 10K",24,52)
     elif step == 1000:
         oled.text("  1K",24,52)
     elif step == 100:
         oled.text(" 100",24,52)
     elif step == 10:
         oled.text("  10",24,52)
     oled.show()

#STEP変更
def Step_Change():
     global step
     utime.sleep_ms(10)
     if step == 10:
         step = 10000
     else:
         step //= 10
     Step_Disp()
    while step_sw.value() == 0:
         utime.sleep_ms(10)

#周波数変更
def Freq_Change():
     global frequency
     PLLA_set(frequency)
     MS0_set()
     Freq_Disp(frequency)

#回転方向判定
def hantei(p):
     global curDat,befDat,count
     global frequency,step
     global f_Max,f_Min
     curDat=pinA.value() + (pinB.value()<<1)
     if curDat != befDat:
         D = ((befDat<<1)^curDat)&3
         if D<2:
             count = count + 1
         else:
             count = count - 1
         befDat = curDat
         if count >= 3:
             frequency += step
             count=0
         elif count <= -3:
             frequency -= step
             count=0
     if frequency >= f_Max:
         frequency = f_Max
     if frequency <= f_Min:
         frequency = f_Min

#周波数初期値設定
Si5351_init()
PLLA_set(frequency)
MS0_set()

#初期画面設定
oled.text("RP2 7MHz VFO",16,0)
oled.rect(24,12,80,16,1)
oled.text(" .   .",28,16)
oled.text("STEP",24,40)
oled.text(" 10K",24,52)
oled.show()
Freq_Disp(frequency)

#ピン状態変化割込み設定
pinA.irq(trigger=Pin.IRQ_FALLING|Pin.IRQ_RISING,handler=hantei)
pinB.irq(trigger=Pin.IRQ_FALLING|Pin.IRQ_RISING,handler=hantei)

#loop
while True:
     if step_sw.value() == 0:
         Step_Change()
     if frequency != frequency_old:
         Freq_Change()
        frequency_old = frequency
     utime.sleep_ms(10)
--------------------------------------------------------------------------------------------
 今回は、周波数を7MHzとしましたが、このプログラムで500KHz~150MHz の周波数を発生させることができます。

FCWA CW QSOパーティ終了

2021-12-05 15:57:53 | アマチュア無線
 昨日12月4日(土)9:00~21:00に行われた第13回FCWA CW QSOパーティが終了しました。

 当局JH7UBCは、ちょっと遅れて9時半過ぎからスタート。今年はアンテナの都合で、7MHzから始めました。既に多くの局が「CQ FQP」を出しています。まずは、呼び回りで周波数の低い方(7.010MHz)から1局ずつコールしていきます。

 コンディションは、まずまずでたくさんの局が聞こえます。このところ太陽黒点数も20から30程度で一時の黒点数0の時代は脱したようで、そろそろサイクル25に向かっているような気がします。7.025MHzくらいまで上がったら、空いている周波数を見つけて、「QRL?」を出し、CQランニングを始めました。(ちなみに、QRL?は、どなたかこの周波数を使っていますか?の意味)

 今回もロギングソフトは、CTESTWINを使いました。が、パソコンを新しくして初めてのコンテストで、初期設定に手間取りました。というか使い方を少し忘れています。CTESTWINを使えば、パドルや電鍵をまったく触らなくても運用ができるのですが、それでは味気ないので、CQだけは、CTESTWINで出し、応答はなるべくパドルで手打ちで行いました。このところ、縦振電鍵ばかり使っていたので、パドルの打ち方がへたくそになり、ミスタッチが多く、各局にはご迷惑をおかけしました。

 2時間ほど7MHzを運用して、昼食を兼ねてひと休み。午後は、13時過ぎから再び7MHzを運用。2時間ほど運用して7MHzで午前と合わせて合計100局以上のQSOができました。良いペースです。

 早めに夕食をとって、夜の部は18時過ぎから3.5MHzを運用しました。こちらも多くの局と交信できました。19時ころから1.9MHz帯をのぞきました。コンテスト周波数に指定されている1.801MHz~1.820MHzに各局が出ています。しかし、当局のアンテナはこの範囲でマッチングがとれていません。ままよ、と無理やり電波を出して2局ほど交信しましたが、あきらめて、3.5MHzに戻り、20時半まで運用してパーティ参加を終了しました。交信をいただいた各局ありがとうございました。

 パーティが終わり、各局からぞくぞくとログが提出されています。今回は10MHz以上での交信も多く、コンディションの回復が感じられます。ログを提出いただいた局は、FCWAのホームページに掲載しています。FQPに参加された局は、ぜひログの提出をお願いします。締め切りは12月31日です。

  FCWA CW QSOパーティ マネージャー JH7UBC 畠

第13回FCWA CW QSOパーティ

2021-12-01 18:44:07 | アマチュア無線
 今週末の12月4日(土)9:00~21:00に福島CW愛好会(FCWA)主催の第13回FCWA CW QSOパーティ(略してFQP)が開催されます。規約はこちら

 FQPは、2009年に第1回が開催され、早いもので今年で13回目を迎えます。2008年に亡くなられたJA7SSB故齋藤氏の功績をたたえると同時に、氏が心血を注いで取り組まれたCW交信の普及を目的として企画されたCW QSOパーティです。

 バンドは1.9MHz~28MHz,交換ナンバーは、RST+オペレータネームです。一般部門とQRP部門(5W以下)で交信局数を競いますが、QSOパーティという名前の通り、CW交信を楽しんでいただくのが主旨ですので、気軽にご参加いただきたいと思います。

 参加いただいた局には、ぜひログの提出をお願いします。師走の忙しい時期ではありますが、各局の生活ペースに合わせて、出られる時間帯に出られる周波数でCW交信を楽しんでください。

 では、お空でお会いしましょう。

       FQPマネージャー JH7UBC 畠 惠治