from time import sleep, ticks_ms
from optical_encoder import OpticalEncoder
from pico_i2c_lcd import I2cLcd
from machine import ADC, SoftI2C, Pin
import math
# Инициализация компонентов
encoder = OpticalEncoder(pin_a=4, pin_b=5, counts_per_rev=360)
prev_angle = encoder.get_angle()
i2c = SoftI2C(scl=Pin(48), sda=Pin(47))
lcd = I2cLcd(i2c, 0x27, 2, 16)
button_step_pin = Pin(6, Pin.IN, Pin.PULL_UP)
button_mode_pin = Pin(20, Pin.IN, Pin.PULL_UP)
button_rit_pin = Pin(21, Pin.IN, Pin.PULL_UP)
adc = ADC(Pin(7))
adc.atten(ADC.ATTN_11DB)
adc_s = ADC(Pin(3))
adc_s.atten(ADC.ATTN_11DB)
mode_output_pin = Pin(18, Pin.OUT)
tx_pin = Pin(19, Pin.IN, Pin.PULL_UP)
led_pin = Pin(17, Pin.OUT)
# Функции
def init_bar():
right_empty = bytearray([0b11111, 0b00001, 0b00001, 0b00001, 0b00001, 0b00001, 0b00001, 0b11111])
left_empty = bytearray([0b11111, 0b10000, 0b10000, 0b10000, 0b10000, 0b10000, 0b10000, 0b11111])
center_empty = bytearray([0b11111, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b11111])
lcd.custom_char(0, left_empty)
lcd.custom_char(1, center_empty)
lcd.custom_char(2, right_empty)
def update_bar():
value = adc_s.read()
fill_percent = min(100, value * 100 // 4095)
bar_length = 9
infill = math.ceil(bar_length * fill_percent / 100)
lcd.move_to(0, 1)
if infill == 0:
lcd.putchar(chr(0))
else:
lcd.putchar(chr(255))
for n in range(1, bar_length - 1):
lcd.putchar(chr(255) if n < infill else chr(1))
lcd.putchar(chr(255) if infill == bar_length else chr(2))
def show_freq(freq, lcd):
mhz = freq // 1000000
khz = (freq % 1000000) // 1000
hz = (freq % 1000) // 100
lcd.move_to(0, 0)
lcd.putstr(f"{mhz:02d}.{khz:03d}.{hz:01d}")
def show_step(step, lcd):
lcd.move_to(11, 0)
lcd.putstr(f"{step}Hz " if not encoder_locked else "TX ")
def show_mode(mode, lcd):
lcd.move_to(11, 1)
lcd.putstr(f"{mode} ")
mode_output_pin.value(0 if mode == "SSB" else 1)
def show_rit_status(rit_mode, lcd):
lcd.move_to(9, 0) # Перемещаем курсор на 10-ю позицию первой строки (индексация с 0)
if rit_mode:
lcd.putchar('R') # Отображаем 'R' при включенном RIT
else:
lcd.putchar(' ') # Очищаем символ (заменяем пробелом) при выключенном RIT
def read_rit_offset():
return int((adc.read() / 4095) * 4000 - 2000)
# Переменные
rx = 14100000
saved_frequency = rx
enc_inc = 50
current_mode = "SSB"
rit_mode = False
rit_offset = 0
encoder_locked = False
debounce_times = {button_step_pin: 0, button_mode_pin: 0, button_rit_pin: 0}
debounce_interval = 200
# Инициализация
init_bar()
lcd.clear()
lcd.putstr('Syntez 1.1')
sleep(2)
lcd.clear()
show_freq(rx, lcd)
show_step(enc_inc, lcd)
show_mode(current_mode, lcd)
# Основной цикл
while True:
update_bar()
now = ticks_ms()
# Обработка TX/RX
if not tx_pin.value(): # TX
if not encoder_locked:
encoder_locked = True
led_pin.on()
rx = saved_frequency
show_freq(rx, lcd)
show_step(enc_inc, lcd)
else: # RX
if encoder_locked:
encoder_locked = False
led_pin.off()
rx = saved_frequency + rit_offset if rit_mode else saved_frequency
show_freq(rx, lcd)
show_step(enc_inc, lcd)
# Энкодер
if not encoder_locked:
current_angle = encoder.get_angle()
angle_diff = (current_angle - prev_angle) % 360
if angle_diff > 180:
angle_diff -= 360
if abs(angle_diff) > 2:
freq_change = int(angle_diff * (enc_inc / 3.6))
saved_frequency = max(14000000, min(14350000, saved_frequency + freq_change))
rx = saved_frequency + rit_offset if rit_mode else saved_frequency
show_freq(rx, lcd)
prev_angle = current_angle
# RIT
if rit_mode and not encoder_locked:
rit_offset = read_rit_offset()
rx = max(14000000, min(14350000, saved_frequency + rit_offset))
show_freq(rx, lcd)
# Кнопки
if not button_step_pin.value() and not rit_mode and not encoder_locked:
if now - debounce_times[button_step_pin] > debounce_interval:
debounce_times[button_step_pin] = now
while not button_step_pin.value(): sleep(0.01)
enc_inc = 100 if enc_inc == 50 else 50
show_step(enc_inc, lcd)
if not button_mode_pin.value() and not encoder_locked:
if now - debounce_times[button_mode_pin] > debounce_interval:
debounce_times[button_mode_pin] = now
while not button_mode_pin.value(): sleep(0.01)
current_mode = "CW" if current_mode == "SSB" else "SSB"
show_mode(current_mode, lcd)
if not button_rit_pin.value() and not encoder_locked:
if now - debounce_times[button_rit_pin] > debounce_interval:
debounce_times[button_rit_pin] = now
while not button_rit_pin.value(): sleep(0.01)
rit_mode = not rit_mode
show_rit_status(rit_mode, lcd) # Отображаем или убираем 'R'
rx = saved_frequency + rit_offset if rit_mode else saved_frequency
show_freq(rx, lcd)
sleep(0.01)