CWビーコン送出プログラム(Python)
2017.3.13 JH7UBC
ラズベリーパイのPythonでの自作プログラム第1号です。
LED点滅プログラム(通称Lチカ)の応用です。
GPIO25のLEDの代わりにキーイング回路を付ければ、TX(送信機)からCW(モールス信号)を送信することができます。
今回は、決まったメッセージを繰り返し送信するCWビーコンを送出するプログラムを作りました。
ビーコン送出のアルゴリズムを簡単に説明します。
まず、モールス符号を内部コードに変換します。
例えば、Aは、・−(トツー)ですから、短点(ト)を0、長点(ツー)を1とし、最下位ビットから順に符号の順に並べ、最後にストップピット1を加えます。
つまり、2進表現でA=110となります。これは、10進であらわせば、6です。
このように、0〜9、A〜Zのモールス符号を内部コードを2進と10進で表し、ASCIIコード順に表にすると次のようになります。
文字 | モールス符号 | 2進 | 10進 | ASCIIコード(10進) |
0 | −−−−− | 111111 | 63 | 48 |
1 | ・−−−− | 111110 | 62 | 49 |
2 | ・・−−− | 111100 | 60 | 50 |
・・・ | ||||
9 | −−−−・ | 101111 | 47 | 57 |
・・・ | ||||
A | ・− | 110 | 6 | 65 |
B | −・・・ | 10001 | 17 | 66 |
・・・ | ||||
Y | −・−− | 11101 | 29 | 89 |
Z | −−・・ | 10011 | 19 | 90 |
アスキーコード順に内部コードのリストを作ります。ただし、使用しない文字の内部コードは、1とします。
Morse_Code =[63,62,60,56,48,32,33,35,39,47,1,1,1,1,1,1,1,6,17,21,9,2,20,11,16,4,30,13,18,7,5,15,22,27,10,8,3,12,24,14,25,29,19]
文字のアスキーコードから48を引けば、要素のインデックスとなり、文字のアスキーコードから簡単に文字に対応する内部コードを取り出すことができます。
Pythonで、文字のアスキーコードを取り出す関数は、ord(文字)です。
次に、内部コードからモールス信号を送り出す方法は、次のようにおこないます。
例えば、Aの場合、内部コードは、110です。最下位ビットを1とのANDをとって取り出します。
結果が0なら短点を1なら長点を送出します。(GPIOをHIGHにします)
次に内部コードを右に1ビットシフトします。再び短点か長点を判断し、送出します。
この繰り返しを行います。内部コードが1になったら終了です。
今回は、送出スピードは固定で、短点0.1s、長点0.3秒とし、短点と短点、短点と長点などの間隔は、短点と同じで0.1sにしました。
文字と文字の間隔は、0.3s、文と文の間隔は0.7sとしました。
messageの文字列の左から1文字ずつ取り出して、そのアスキーコードに対応した内部コードをリストから取り出して、送出すれば、CWビーコンが送出されます。これを繰り返します。
Raspberry PiのIDLE Python2を使って、プログラムを作りました。
左側が、Python2.7.9 Shell 右側がエディタのウインドウです。
プログラムリストです。
import RPi.GPIO as GPIO
from time import sleep GPIO.setmode(GPIO.BCM)
GPIO.setup(25,GPIO.OUT) Morse_Code =[63,62,60,56,48,32,33,35,39,47,1,1,1,1,1,1,1,6,17,21,9,2,20,11,16,4,30,13,18,7,5,15,22,27,10,8,3,12,24,14,25,29,19]
message='VVV VVV DE JH7UBC JH7UBC PM97WR' message_len=len(message) def dot():
GPIO.output(25,GPIO.HIGH) sleep(0.1) GPIO.output(25,GPIO.LOW) def dash(): GPIO.output(25,GPIO.HIGH) sleep(0.3) GPIO.output(25,GPIO.LOW) def space(): sleep(0.6) try: while True: for i in range(message_len): char_code = ord(message[i]) if char_code == 0x20:#space code space() else: Mcode = Morse_Code[char_code - 48] while Mcode != 1: mark = Mcode & 1 if mark == 0: dot() else: dash() sleep(0.1) Mcode >>=1 sleep(0.3) sleep(0.7) except KeyboardInterrupt: pass GPIO.cleanup() |
送信機とのインタ―フェースです。
モールス練習機と接続して動作を確認しました。