# touch_keyer.py for QT PY connected to 6 touch pads and output
# via one digital line
# touch pads are best small (< 1/2" square) and wired directly to QT PY
# NJP 20 November 2020
# added anti bounce to commands msg0, msg1, up, down
# NJP 22 November 2020
# NJP 2 December 2020 changed timing of msg0, ms1, rdown and rup to debounce
import time
from touchio import TouchIn
from digitalio import DigitalInOut, Direction
import board
import rotaryio
global dash_length
global dot_length
global ratio
global rate

rate = 20  # initial rate
minrate = 5
baserate = 15
maxrate = 25
dot_length = 1.6/rate
ratio = 3  #   between dot and dash length
dash_length = ratio * dot_length
# key output on D10 (M0) pin
keyed = DigitalInOut(board.D10)
keyed.direction = Direction.OUTPUT
# rotary encoder for CW speed
encoder = rotaryio.IncrementalEncoder(board.D5, board.D6) # rate encoder
last_position = None
# the rest are touch keys
dash = TouchIn(board.SDA)
dot = TouchIn(board.D4)
msg0 = TouchIn(board.SCL)#  preprogrammed message0
msg1 = TouchIn(board.TX) #  preprogrammed message1

# morse code converter dictionary o = dot, a = dash
code = { ' ':'','A': 'oa', 'B':'aooo', 'C':'aoao','D':'aoo', 'E':'o',
'F':'ooao' ,'G':'aao', 'H':'oooo','I':'oo','J':'oaaa',
'K':'aoa','L':'oaoo', 'M':'aa', 'N':'ao', 'O':'aaa','P':'ooao',
'Q':'aaoa','R':'oao','S':'ooo','T':'a','U':'ooa','V':'oooa',
'W':'oaa','X':'oaao','Y':'aoaa', 'Z':'aaoo','0':'aaaaa','1':'oaaaa',
'2':'ooaaa','3':'oooaa','4':'ooooa','5':'ooooo','6':'aoooo','7':'aaooo',
'8':'aaaoo','9':'aaaao','?':'ooaaoo',',':'aaooaa','.':'oaoaoa'}

# message0 = 'CQ CQ CQ DE WB0VGI WB0VGI WB0VGI K'  #  extend these to make a full message
# message1 = 'RST 599 599 QTH HARRIS, MN HARRIS, MN OP NOEL NOEL BTU DE WB0VGI KN'
message0 = 'CQ' # short versions for testing remove # above for full messages
message1 = 'RST'

def adj_rate():  # set rate by setting the dot and dash length
    global rate
    global dot_length
    global dash_length
    if rate > maxrate:
        rate = maxrate
    if rate < minrate:
        rate = minrate
    dot_length = 1.6/rate
    dash_length = 3.0 * dot_length
    print('CW rate ', rate, ' wpm')

def check_rotary():
    global position
    global last_position
    global rate
    position = encoder.position   # check to see if rate changed
    if position != last_position:
        rate = baserate - position # rotary connection is reversed so subtract
        adj_rate()                  # set new dot and dash length
    last_position = position

def letter(letin):  # convert a string to morse code
    for i in range(0, len(letin)):
        mcode = code[letin[i]]
        if letin[i] == '':
            print('word space')
        else:
            for j in range(0, len(mcode)):
                if mcode[j] == 'a':
                    my_dash()
                else:
                    my_dot()
            print('char space')
            time.sleep(dash_length) # intercharacter length

def key(length): # this is the key down command with interbit length
    global dot_length
    keyed.value = True
    time.sleep(length)
    keyed.value = False
#  check_rotary()
    time.sleep(dot_length) # inter bit length

def my_dash():
    print('dash')
    key(dash_length)

def my_dot():
    print('dot')
    key(dot_length)

keyed.value = False
print('waiting')
while True:
    if dot.value:
        my_dot()
    if dash.value:
        my_dash()
    if msg0.value:
        print('message0')
        letter(message0)
        time.sleep(1.0)
    if msg1.value:
        print('message1')
        letter(message1)
        time.sleep(1.0)
    check_rotary()