JH7UBCブログ

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

Raspberry Pi Pico CircuitPython AD8307 テスト

2022-06-03 21:09:09 | Raspberry Pi Pico
 Raspberry Pi Pico CircuitPython Mu IDE環境で、ログアンプAD8307のテストをします。
 ログアンプAD8307のスペックは、
 測定範囲-75dBm~+17dBm
 DC~500MHzで動作
 傾き25mV/dB
 切片-84dBm
 グラフにすると下の図のようになります。

 入力電力Pin(dBm)と出力電圧Vout(mV)の関係とP(dBm)をP(mW)に変換する式にまとめると次のようになります。


 Raspberry Pi PicoとAD8307の接続回路図です。
 AD8307の出力は、ADC0(Pin30)に接続します。

 スクリプトです。AD8307の出力電圧と入力電力をシェルに表示します。
 出力電圧はV単位で表示し、入力電力PはdBmで表示し、それをmWに変換して表示します。
  PdBm = (Vout(V)-2.1)*1000/25=(Vout(V)-2.1)*40として計算しています。
-----------------------------------------------------------------------------
"""
Raspberry Pi Pico CircuitPython
AD8307 test
2022.06.03
JH7UBC Keiji Hata
"""

from board import *
import analogio
import time
import math

#setup
a = analogio.AnalogIn(A0)#from AD8307 output

#main loop
while True:
    V = a.value*3.3/65535
     print('V= {:.2f}'.format(V))
     Pdbm = (V - 2.1)*40
     print('PdBm = {:.2f}'.format(Pdbm))
     Pmw = 10 ** (Pdbm/10)
     print('Pmw = {:.2f}'.format(Pmw))
     time.sleep(1)
-----------------------------------------------------------------------------
 シェルに表示されたAD8307の出力です。
 入力は、自作の簡易SGで、入力の値を変化させています。


ブレッドボードです。


 この後、OLED表示器に表示するようにして、キャリブレーション回路を付加して、RFパワーメータに仕上げてみようと思います。

Raspberry Pi Pico CircuitPython エレキー

2022-05-28 22:11:37 | Raspberry Pi Pico
 Raspberry Pi Picoを使ったエレキーは、MicroPython + Mu IDE環境で既に試作しました。記事はこちら
 今回は、CircuitPython + Mu IDE環境でエレキーを作ってみます。アルゴリズムは同じですが、CircuitPythonでは割込みが使えないので、割込みを使わない方法に変更しました。
 回路図です。MIcroPythonの時と同じです。
 パドルは、GP0とGP1に接続します。(GP0とGP1は、ソフトでプルアップします)


スクリプトです。
--------------------------------------------------------------------------
"""
Raspberry Pi Pico CircuitPython Elekey
2022.5.28
JH7UBC Keiji Hata
"""

from board import *
import digitalio
import analogio
import time
import pwmio

#setup
Dot_key = digitalio.DigitalInOut(GP0)
Dot_key.direction = digitalio.Direction.INPUT
Dot_key.pull = digitalio.Pull.UP
Dash_key = digitalio.DigitalInOut(GP1)
Dash_key.direction = digitalio.Direction.INPUT
Dash_key.pull = digitalio.Pull.UP

LED = digitalio.DigitalInOut(GP16)
LED.direction = digitalio.Direction.OUTPUT
LED.value = False

TX = digitalio.DigitalInOut(GP13)
TX.direction = digitalio.Direction.OUTPUT
TX.value = False

Side_tone = pwmio.PWMOut(GP15,frequency = 700)
Side_tone.duty_cycle = 0

a = analogio.AnalogIn(A0)#速度調整用

Dot_flag = False
Dash_flag = False

def Space_out():
     global dot_time
     LED.value = False
     TX.value = False
     Side_tone.duty_cycle = 0
    c = dot_time
     while c:
         c = c - 1
         time.sleep(0.001)

def Dot_out():#dotとspaceを出力
     global dot_time,Dash_flag
     LED.value = True
     TX.value = True
     Side_tone.duty_cycle = 32768
    c = dot_time
     while c:
         if Dash_key.value == False:
             Dash_flag = True
         c = c - 1
         time.sleep(0.001)
     Space_out()


def Dash_out():#dashとspaceを出力
     global dash_time,Dot_flag
     LED.value = True
     TX.value = True
     Side_tone.duty_cycle = 32768
    c = dash_time
     while c:
         if Dot_key.value == False:
             Dot_flag = True
         c = c - 1
         time.sleep(0.001)
     Space_out()

#main loop
while True:
     dot_time=a.value >> 8
     if dot_time <= 40:
         dot_time = 40 #最高速度を30wpm(150字/分)に制限
     elif dot_time >=200:
         dot_time = 200#最低速度を6wpm(30字/分)に制限
     dash_time=dot_time+dot_time
     dash_time=dash_time+dot_time #dash_time=dot_time * 3
     #dot_key,dash_keyが押された時、またはflagが立った時の処理
     if Dot_key.value == False or Dot_flag == True:
         Dot_out()
         Dot_flag = False
     if Dash_key.value == False or Dash_flag == True:
         Dash_out()
         Dash_flag = False
--------------------------------------------------------------------------
ブレッドボードです。
送信時にLEDが点灯します。


パドル、スピーカ、テスターを接続してテストしました。


 MicroPython エレキーと同様に問題なく動作しました。

Raspberry Pi Pico CircuitPython Si5351A 7MHz VFO その2

2022-05-25 11:45:43 | Raspberry Pi Pico
 前の記事の続きです。
 KEYをGP14に接続します。(GP14はソフトでプルアップします。)
 SIDE TONEを聞くためのスピーカをGP13に接続します。(700HzのPWMを出力します。)
 この回路のVFO OUTにバッファとファイナルをつなげば、りっぱなCW送信機になります。
 

スクリプトです。
------------------------------------------------------------------
"""
Raspberry Pi Pico CircuitPython Si5351A 7MHz VFO
2022.05.25
JH7UBC Keiji Hata
"""
from board import *
import rotaryio
import busio
import time
import digitalio
import adafruit_si5351
import adafruit_ssd1306
import pwmio

# Create the I2C interface.
i2c = busio.I2C(GP21, GP20)

# Initialize SI5351.
si5351 = adafruit_si5351.SI5351(i2c)

#Pull up for step SW
STEP_button = digitalio.DigitalInOut(GP15)
STEP_button.direction = digitalio.Direction.INPUT
STEP_button.pull = digitalio.Pull.UP

#Pull up for KEY
KEY = digitalio.DigitalInOut(GP14)
KEY.direction = digitalio.Direction.INPUT
KEY.pull = digitalio.Pull.UP

#LED port
LED = digitalio.DigitalInOut(GP16)
LED.direction = digitalio.Direction.OUTPUT

oled = adafruit_ssd1306.SSD1306_I2C(128, 64, i2c)
#OLED clear
oled.fill(0)

#VFO 初期値設定
frequency = 7000000
old_frequency = 9999999
step = 10000
f_Max = 7200000 #周波数最大値
f_Min = 7000000 #周波数最小値
df = -60 #周波数補正値

#Si5351A関係設定
XtalFreq = 25000000
denom = 1048575
#Si5351 Xtal Load Capacitance=6pF
si5351._write_u8(183,0x40)
#si5351.outputs_enabled = False
si5351._write_u8(3,0x0F)#output disable

#SIDE TONE関係設定
SIDE_TONE = pwmio.PWMOut(GP13,frequency = 700)
SIDE_TONE.duty_cycle = 0 # SIDE TONE off

#タイトル等表示
oled.text("RP2 Si5351A 7MHz VFO",5,0,1)
oled.rect(15,15,100,18,1)
oled.text(".",38,20,1)
oled.text(".",70,20,1)
oled.text("STEP",30,40,1)
oled.show()

#Rotary Encoder setup
encoder = rotaryio.IncrementalEncoder(GP0,GP1)
last_position = 0

#周波数表示
def Freq_display():
     global frequency,old_frequency
     fre_text = str(frequency)
     oldfre_text = str(old_frequency)
    x = 30
    y = 20
     for i in range(7):
         if fre_text[i] != oldfre_text[i]:
             oled.fill_rect(x,y,7,8,0)
             oled.text(fre_text[i],x,y,1)
             oled.show()
         if i == 0 or i == 3:
             x = x + 16
         else:
             x = x + 8
     old_frequency = frequency

#STEP表示
def Step_display(s):
     if s == 10000:
         step_text = "10K"
     elif s == 1000:
         step_text = " 1K"
     elif s == 100:
         step_text = "100"
     elif s == 10:
         step_text = " 10"
     oled.fill_rect(70,40,20,12,0)
     oled.show()
     oled.text(step_text,70,40,1)
     oled.show()

#周波数出力
def Freq_out(f):
     divider =900000000 // f
     if divider % 2:
         divider = divider - 1
     #PLLA周波数設定
     PllFreq = divider * f
     mult = PllFreq // XtalFreq
    L = PllFreq % XtalFreq
     num = (L * denom) // XtalFreq
     #PLL セット
     si5351.pll_a.configure_fractional(mult,num,denom)
     #CLOCK0出力周波数
    si5351.clock_0.configure_integer(si5351.pll_a, divider)

#周波数変更
def Freq_change():
     global frequency,step,df
     if position - last_position > 0:
         frequency = frequency + step
         if frequency >= f_Max:
             frequency = f_Max
     else:
         frequency = frequency - step
         if frequency <= f_Min:
             frequency = f_Min
     Freq_display()
     Freq_out(frequency+df)


#STEP変更
def Step_change():
     global step
     time.sleep(0.01)
     if step == 10:
         step = 10000
     else:
         step //= 10
     Step_display(step)
     while STEP_button.value == False:
         time.sleep(0.01)

#初期値表示及び出力
Freq_display()
Freq_out(frequency+df)
Step_display(step)
TX_flag = False
TX_bef_flag = False

#main loop
while True:
     position = encoder.position
     if position != last_position:
         Freq_change()
         last_position = position
     if STEP_button.value == False:
         Step_change()
     if KEY.value == False:
         TX_flag = True
         if TX_flag != TX_bef_flag:
             si5351._write_u8(3,0x0C) #CLOCK0 output
             LED.value = True
             SIDE_TONE.duty_cycle = 32768
     else:
         TX_flag = False
         if TX_flag != TX_bef_flag:
             si5351._write_u8(3,0x0F) # output disable
            LED.value = False
             SIDE_TONE.duty_cycle = 0
     TX_bef_flag = TX_flag
     time.sleep(0.01)

------------------------------------------------------------------
 SI5351Aの出力をコントロールするのは、Si5351Aのレジスタ3のbit2,bit1,bit0の値です。
bit0=0でCLK0がon
bit1=0でCLK1がon
bit2=0でCLK2がonです。
 今回は、CLK0使いませんので、0x0Fで全ての出力off、0x0CでCLK0 onになります。

ブレッドボードです。KEYの代わりにタクトスイッチ(右側の黄色いスイッチ)をつけてテストしています。KEYが押された時にLEDが点灯し、SIDE TONEをスピーカに出力し、CLK0に周波数が出力されます。


 

 スピーカをつけてテストしています。出力は、CLK0につけたリード線から漏れてくる微弱電波をハンディ機で受信してモニタしました。


Raspberry Pi Pico CircuitPython Si5351A 7MHz VFOテスト

2022-05-21 20:30:54 | Raspberry Pi Pico
 家庭菜園等に費やす時間が増えた一方、マイコン遊びの時間が少なくなってきました。

 先日の「Rasoberry Pi Pico CircuitPython Si5351A テストその2」の記事に書いたRaspberry Pi Pico CircuitPython Si5351A 7MHz VFOを作って、テストそてみました。

 回路図です。GP0,GP1にロータリーエンコーダを接続します。
 Si5351AとOLEDは、I2C接続です。DCL=GP21,SDA=GP20としました。
 周波数STEPの変更SWは、GP15に接続します。
 SI5351AのCLK0をVFO出力とします。
 I2C用のプルアップ抵抗は、OLEDに内蔵されているので、外付けしていません。

 準備として、各デバイスを使うためのライブラリーをPico(CIRCUITPY )のlibフォルダ内にコピーします。具体的には、これまでの記事を参照してください。
 スクリプトです。
 STEP SWを接続するGP15はPULLUPしておきます。
-------------------------------------------------------------------------------------
"""
Raspberry Pi Pico CircuitPython Si5351A 7MHz VFO
2022.05.21
JH7UBC Keiji Hata
"""
from board import *
import rotaryio
import busio
import time
import digitalio
import adafruit_si5351
import adafruit_ssd1306

# Create the I2C interface.
i2c = busio.I2C(GP21, GP20)

# Initialize SI5351.
si5351 = adafruit_si5351.SI5351(i2c)

#Pull up for STEP SW
STEP_button = digitalio.DigitalInOut(GP15)
STEP_button.direction = digitalio.Direction.INPUT
STEP_button.pull = digitalio.Pull.UP

oled = adafruit_ssd1306.SSD1306_I2C(128, 64, i2c)
#OLED clear
oled.fill(0)

#VFO 初期値設定
frequency = 7000000
old_frequency = 9999999
step = 10000
f_Max = 7200000 #周波数最大値
f_Min = 7000000 #周波数最小値
df = -60 #周波数補正値

#Si5351A関係設定
XtalFreq = 25000000
denom = 1048575
#Si5351 Xtal Load Capacitance=6pF
si5351._write_u8(183,0x40)
si5351.outputs_enabled = True

#タイトル等表示
oled.text("RP2 Si5351A 7MHz VFO",5,0,1)
oled.rect(15,15,100,18,1)
oled.text(".",38,20,1)
oled.text(".",70,20,1)
oled.text("STEP",30,40,1)
oled.show()

#Rotary Encoder setup
encoder = rotaryio.IncrementalEncoder(GP0,GP1)
last_position = 0

#周波数表示
def Freq_display():
     global frequency,old_frequency
     fre_text = str(frequency)
     oldfre_text = str(old_frequency)
    x = 30
    y = 20
     for i in range(7):
         if fre_text[i] != oldfre_text[i]:
             oled.fill_rect(x,y,7,8,0)
             oled.text(fre_text[i],x,y,1)
             oled.show()
         if i == 0 or i == 3:
             x = x + 16
         else:
             x = x + 8
     old_frequency = frequency

#STEP表示
def Step_display(s):
     if s == 10000:
         step_text = "10K"
     elif s == 1000:
         step_text = " 1K"
     elif s == 100:
         step_text = "100"
     elif s == 10:
         step_text = " 10"
     oled.fill_rect(70,40,20,12,0)
     oled.show()
     oled.text(step_text,70,40,1)
     oled.show()

#周波数出力
def Freq_out(f):
     divider =900000000 // f
     if divider % 2:
         divider = divider - 1
     #PLLA周波数設定
     PllFreq = divider * f
     mult = PllFreq // XtalFreq
    L = PllFreq % XtalFreq
     num = (L * denom) // XtalFreq
     #PLL セット
     si5351.pll_a.configure_fractional(mult,num,denom)
     #CLOCK0出力周波数
     si5351.clock_0.configure_integer(si5351.pll_a, divider)

#周波数変更
def Freq_change():
     global frequency,step,df
     if position - last_position > 0:
         frequency = frequency + step
         if frequency >= f_Max:
             frequency = f_Max
     else:
         frequency = frequency - step
         if frequency <= f_Min:
             frequency = f_Min
     Freq_display()
     Freq_out(frequency+df)


#STEP変更
def Step_change():
     global step
     time.sleep(0.01)
     if step == 10:
         step = 10000
     else:
         step //= 10
     Step_display(step)
     while STEP_button.value == False:
         time.sleep(0.01)

#初期値表示及び出力
Freq_display()
Freq_out(frequency+df)
Step_display(step)

#main loop
while True:
     position = encoder.position
     if position != last_position:
         Freq_change()
         last_position = position
     if STEP_button.value == False:
         Step_change()
     time.sleep(0.01)
-------------------------------------------------------------------------------------
 今回は、Xtal Load Capacitanceは、6pFとしています。
 dfは、周波数補正値です。
 STEP SWを押すたびに、10K→1K→100→10→10Kと循環します。
 ブレッドボードです。



 出力周波数を測定しています。7060000Hzに設定した時の周波数です。
 周波数の細かい調整は、dfの値で行います。


 このVFOにキーイングやサイドトーン発生のスクリプトを加えると、送信機として使用できるスクリプトになります。
 これも近日中にテストしてみたいと思います。

Raspberry Pi Pico CircuitPython Si5351A テストその2

2022-05-11 13:06:56 | Raspberry Pi Pico
 前の記事の続きです。

 Raspberry Pi Pico CircuitPythonで、Si5351Aに任意の周波数を出力させるテストをします。
 この方法については、JH7UBCホームページのArduinoのページのこちらに詳しい説明をしています。なお、簡単な説明を下に示します。


 7.000000MHzをCLOCK0に出力するスクリプトです。
 Xtal Load Capacitanceを変更する関数がなかったので、レジスタ番号183に、6pFにするためのデータ0x40を書き込んでいます。
 因みに8pFにする場合は、0x80を10pFにする場合は0xC0を書き込みます。
 
----------------------------------------------------------------------------
"""
Raspberry Pi Pico CIrcuitPython Si5351 test
2022.5.11
JH7UBC Keiji Hata

"""

from board import *
import busio

import adafruit_si5351

SCL = GP17
SDA = GP16

# Initialize I2C bus.
i2c = busio.I2C(SCL, SDA)

# Initialize SI5351.
si5351 = adafruit_si5351.SI5351(i2c)
#Si5351 Xtal Load Capacitance=6pF
si5351._write_u8(183,0x40)

frequency = 7000000
XtalFreq = 25000000
denom = 1048575
divider =900000000 // frequency
if divider % 2:
     divider = divider - 1

#PLLA周波数設定
PllFreq = divider * frequency
mult = PllFreq // XtalFreq
L = PllFreq % XtalFreq
num = (L * denom) // XtalFreq

si5351.pll_a.configure_fractional(mult,num,denom)

#CLOCK0出力周波数
si5351.clock_0.configure_integer(si5351.pll_a, divider)

# After configuring PLLs and clocks, enable the outputs.
si5351.outputs_enabled = True

----------------------------------------------------------------------------

 周波数を測定してみました。若干高い周波数を出力します。