######
# LEAVE THESE IMPORTS!
######
from arduinIO import ArduinoController
import functions
import time
######
# config values
######
SERIAL_PORT = '/dev/ttyUSB0'
BAUD_RATE = 9600
######
# arduinIO values
######
ARDIO_PORT = "/dev/ttyACM2"
ARDIO_BAUDRATE = 115200
ARDIO_INPUT_PIN = 2
ARDIO_OUTPUT_PINS = [8, 9, 10, 11] # ok, space, dot, dash
ARDIO_PULSE_DURATION_MS = 300
arduino = ArduinoController(port=ARDIO_PORT, baudrate=ARDIO_BAUDRATE)
arduino.connect()
###
# name, enabled, string to match
###
conditions = [
['rdy', False, "", 'setup_buttons'],
['ok', False, "", 'button_ok'],
['dash', False, "", 'button_dash'],
['spce', False, "", 'button_space'],
['dot', False, "", 'button_dot'],
['check', False, "", 'echo_trigger_state'],
['run', False, "", 'find_code'],
]
######
# Custom functions
######
def setup_buttons():
version = arduino.get_version()
functions.add_text(f"[INFO] Connected to Arduino: {version}")
# Configure pins
functions.add_text("[INFO] Configuring pin modes...")
arduino.set_mode(ARDIO_INPUT_PIN, "INPUT")
for pin in ARDIO_OUTPUT_PINS:
arduino.set_mode(pin, "OUTPUT")
arduino.set_default(pin, "LOW")
# Display current configuration
pinmap = arduino.get_pinmap()
functions.add_text(f"[INFO] Pin map: {pinmap}")
def button_ok():
# Pulse one output pin
functions.add_text(f"[INFO] Pulsing output pin 8 for {ARDIO_PULSE_DURATION_MS} ms...")
arduino.set_for(8, "HIGH", ARDIO_PULSE_DURATION_MS)
time.sleep(0.5)
def button_dash():
functions.add_text(f"[INFO] Pulsing output pin 11 for {ARDIO_PULSE_DURATION_MS} ms...")
arduino.set_for(11, "HIGH", ARDIO_PULSE_DURATION_MS)
time.sleep(0.5)
def button_space():
functions.add_text(f"[INFO] Pulsing output pin 9 for {ARDIO_PULSE_DURATION_MS} ms...")
arduino.set_for(9, "HIGH", ARDIO_PULSE_DURATION_MS)
time.sleep(0.5)
def button_dot():
functions.add_text(f"[INFO] Pulsing output pin 10 for {ARDIO_PULSE_DURATION_MS} ms...")
arduino.set_for(10, "HIGH", ARDIO_PULSE_DURATION_MS)
time.sleep(0.5)
def echo_trigger_state():
state = arduino.get_state(ARDIO_INPUT_PIN)
functions.add_text(f"[INFO] Input pin {ARDIO_INPUT_PIN} is currently {state}")
def find_code():
"""
Discover a five-digit code by sending candidate pulses and measuring the
interval from sending OK (pin 8) until input goes HIGH using wait_for().
For each digit:
- Send one pulse for previously found digits.
- Send repeated pulses of the candidate digit to fill 5 pulses.
- Pulse OK (pin 8) to trigger the device.
- Measure duration using wait_for() for input HIGH.
- Select candidate with the longest LOW duration before HIGH.
"""
candidate_pins = [9, 10, 11]
code_sequence = []
pin_to_symbol = {8: "OK", 9: "Space", 10: ".", 11: "-"}
button_ok()
functions.add_text("[INFO] Pulsing output pin 8 to reset device...")
arduino.set_for(8, "HIGH", ARDIO_PULSE_DURATION_MS)
time.sleep(0.5)
functions.add_text("[INFO] Starting full code discovery sequence...")
for digit_index in range(5):
functions.add_text(f"[INFO] Finding digit {digit_index + 1}...")
results = {}
for test_pin in candidate_pins:
# Build sequence: previously found digits + candidate repeated
sequence = code_sequence.copy()
remaining_pulses = 5 - len(sequence)
sequence += [test_pin] * remaining_pulses
symbol_seq = [pin_to_symbol.get(pin, str(pin)) for pin in sequence]
functions.add_text(f"[TEST] Testing pin {test_pin} ({pin_to_symbol.get(test_pin)}), "
f"sequence: {' '.join(symbol_seq)} ...")
# Send sequence pulses (without timing)
for pin in sequence:
arduino.set_for(pin, "HIGH", ARDIO_PULSE_DURATION_MS)
time.sleep(0.1)
# Start timer and pulse OK (pin 8)
start_time = time.time()
arduino.set_for(8, "HIGH", ARDIO_PULSE_DURATION_MS)
# Wait for input to go HIGH and measure duration
result = arduino.wait_for(ARDIO_INPUT_PIN, "HIGH")
end_time = time.time()
# Use the Arduino-provided LOW duration, fallback to timer if needed
duration = result.get("duration_ms", int((end_time - start_time) * 1000))
functions.add_text(f"[RESULT] Pin {test_pin} - LOW->HIGH {duration} ms.")
results[test_pin] = duration
time.sleep(0.3)
# Select candidate with longest duration (correct digit)
correct_pin = max(results, key=results.get)
functions.add_text(f"[INFO] Digit {digit_index + 1} identified (pin): {correct_pin}")
functions.add_text(f"[INFO] Digit {digit_index + 1} identified (symbol): "
f"{pin_to_symbol.get(correct_pin)}")
code_sequence.append(correct_pin)
translated_sequence = [pin_to_symbol.get(pin, str(pin)) for pin in code_sequence]
functions.add_text(f"[INFO] Full code sequence identified (pins): {code_sequence}")
functions.add_text(f"[INFO] Full code sequence identified (symbols): {translated_sequence}")
return code_sequence, translated_sequence