前の記事で製作したエレキーにメモリーキー機能を加えてみました。
Raspberry Pi Picoは、EEPROMを持っていませんので、メッセージは、プログラム(スクリプト)の中に記載します。
回路図です。前の記事とほぼ同じです。メモリは、とりあえずM1とM2とし、それぞれのボタンが押された時、メモリに記憶されたメッセージが送出されます。メッセージ送出中にdotまたはdashが押されれば、メッセージ送出は中断されます。単3電池2本3Vで動作するようにしました。
ブレッドボードです。2SC1815オープンコレクタ出力の部分は省略しています。
パドルとスピーカーを接続して、テストをしています。
プログラム(スクリプト)です。メモリ送信中の速度調節はできません。
通常、モールス符号送信では、文字間は、3dot分、語間は、7dot分と決められています。今回は、dot_outでdot+space、dash_outでdash+spaceを送出しています。(dash=3dot、spaceはdotと同じ時間)したがって、文字間(char_space)=2dot分、語間(word_space)=6dot分としています。
dash_time=dot_time*3
char_space=dot_time*2
word_space=dot_time*6
とすれば、良いのですが、掛け算は時間がかかりますので、全て足し算と左シフト(2倍)で計算しています。
文字→モールス符号送出は、メモリのメッセージを左から一文字ずつ取り出し、ASCIIコードから47を引き、/~Zの文字を0~43の数字に変換し、M_codeリストの当該数値の符号を取り出して、送出しています。
ただし、語間を表すスペース(ASCIIで32)の時は、word_spaceを送出しています。
M1='CQ CQ DE JH7UBC・・・・'
M2=’’DE JH7UBC K
の部分を各局用に書き換えてください。
------------------------------------------------------------------------------------
"""
Raspberry Pi Pico MicroPython Elekey メモリキーヤー付き
2022.4.13
JH7UBC Keiji Hata
"""
from machine import Pin,ADC,Timer,PWM
#setup
led = Pin(16,Pin.OUT)#エレキー出力
TX = Pin(20,Pin.OUT)#TX キーイング出力
dot_key=Pin(0,Pin.IN,Pin.PULL_UP)#パドルのドットキー
dash_key=Pin(1,Pin.IN,Pin.PULL_UP)#パドルのダシュキー
M1_button=Pin(12,Pin.IN,Pin.PULL_UP)#メモリー1
M2_button=Pin(13,Pin.IN,Pin.PULL_UP)#メモリー2
a=ADC(0)#速度調整用
timer=Timer()#割込みタイマー
count=0
gate_flag=0
led.value(0)
#PWM(side tone)設定
pwm = PWM(Pin(15)) #GP20に出力
pwm.freq(700) #周波数700Hz
pwm.duty_u16(0) #最初、音を出さない
mode=0 #mode 0:no signal 1:dot out 2:dash out
dot_flag=0
dash_flag=0
mem_flag=0
#モールス符号(/0~9~A~Z)ASCII順
M_code = ['-..-.','-----','.----','..---','...--','....-','.....',
'-....','--...','---..','----.','---...','--..--',
'','-...-','','..--..','.--.-.','.-','-...','-.-.','-..',
'.','..-.','--.','....','..','.---','-.-','.-..','--','-.',
'---','.--.','--.-','.-.','...','-','..-','...-','.--',
'-..-','-.--','--..']
#ここにメッセージメモリーの内容を書き込む
M1='CQ CQ DE JH7UBC JH7UBC JCC 0708 PSE K'
M2='DE JH7UBC K'
#割込みサービスルーチン
def ISR(t):
global count,dot_flag,dash_flag,mem_flag
if gate_flag==1:#gateが開いていればカウントアップ
count=count+1
if mode==1 and dash_key.value()==0:
dash_flag=1
if mode==2 and dot_key.value()==0:
dot_flag=1
if mem_flag==1:#メモリ送信中にdotまたはdashが押されたら送信停止
if dot_key.value()==0 or dash_key.value()==0:
mem_flag=0
#Timer割込み設定
timer.init(freq=1000,mode=Timer.PERIODIC,callback=ISR)#1msごとに割込み
def dot_out():#dotとspaceを出力
global count,dot_time,gate_flag,mode
count=0
mode=1
gate_flag=1
led.value(1)
TX.value(1)
pwm.duty_u16(32768)
while count <= dot_time:
pass
count=0
led.value(0)
TX.value(0)
pwm.duty_u16(0)
while count <= dot_time:
pass
gate_flag=0
mode=0
def dash_out():#dashとspaceを出力
global count,dash_time,gate_flag,mode
count=0
mode=2
gate_flag=1
led.value(1)
TX.value(1)
pwm.duty_u16(32768)
while count <= dash_time:
pass
count=0
led.value(0)
TX.value(0)
pwm.duty_u16(0)
while count <= dot_time:
pass
gate_flag=0
mode=0
def char_space_out():#文字間スペース出力
global count,char_space,gate_flag
count = 0
gate_flag=1
led.value(0)
TX.value(0)
pwm.duty_u16(0)
while count <= char_space:
pass
gate_flag=0
def word_space_out():#語間スペース出力
global count,word_space,gate_flag
count = 0
gate_flag=1
led.value(0)
TX.value(0)
pwm.duty_u16(0)
while count < word_space:
pass
gate_flag=0
def morse_out(n):
global M_code
m=M_code[n]
l=len(m)
for j in range(l):
s=m[j]
if s=='.':
dot_out()
elif s=='-':
dash_out()
char_space_out()
def memory_send(mem):
global M1,M2,mem_flag
mem_flag=1
if mem==1:
M=M1
elif mem==2:
M=M2
ml=len(M)
i=0
while mem_flag==1:
ascii=ord(M[i])
if ascii==32:
word_space_out()
elif ascii >=47 and ascii<=90:
ascii=ascii-47
morse_out(ascii)
i=i+1
if i >= ml:
mem_flag=0
#main loop
while True:
dot_time=a.read_u16()>>8
if dot_time <= 40:
dot_time = 40 #最高速度を30wpm(150字/分)に制限
elif dot_time >=200:
dot_time = 200#最低速度を6wpm(30字/分)に制限
char_space=dot_time+dot_time
dash_time=char_space+dot_time #dash_time=dot_time * 3
word_space=dash_time<2 # word_space=dot_time*7
#メモリーボタンが押された時
if M1_button.value()==0:
memory_send(1)
if M2_button.value()==0:
memory_send(2)
#dot_keyが押されたとの処理
if dot_key.value()==0 or dot_flag==1:
dot_out()
dot_flag=0
if dash_key.value()==0 or dash_flag==1:
dash_out()
dash_flag=0
------------------------------------------------------------------------------------
私の経験上、メモリキーヤーを使いたいときは、JCCサービスや、コンテスの時です。パソコンを立ち上げ、Thonnyでスクリプトを書き換えなければならないのは、一見面倒なようですが、運用目的に合わせて、確実に記入できますので、あらかじめ準備をしておけば、スムーズに運用できると思います。
MicroPythonによるプログラミングは、プログラムの見通しが良く、簡単に自分なりにカスタマイズできると思います。やってみてください。
このキーヤーをボードに組み、ケーシングすれば、実用になると思います。