added dac

This commit is contained in:
Ayzen
2026-02-18 16:04:20 +03:00
parent 8ca2fe39d0
commit 12cf9d6716
7 changed files with 92 additions and 1 deletions

Binary file not shown.

View File

@ -27,10 +27,13 @@ INITIAL_CURRENT_2 = 35 # 64.0879 max # Set initial current for Laser 2, in mA
AD9833_FREQ_DEFAULT_KHZ = 125.0 AD9833_FREQ_DEFAULT_KHZ = 125.0
AD9833_MCLK_DEFAULT_MHZ = 20.0 AD9833_MCLK_DEFAULT_MHZ = 20.0
DS1809_MAX_STEP = 63 DS1809_MAX_STEP = 63
DS1809_DEFAULT_STEP = 0 DS1809_DEFAULT_STEP = 3
DS1809_INIT_HOME_PULSES = 64 DS1809_INIT_HOME_PULSES = 64
DS1809_INIT_PULSE_MS = 2 DS1809_INIT_PULSE_MS = 2
DS1809_INIT_STARTUP_DELAY_S = 0.35 DS1809_INIT_STARTUP_DELAY_S = 0.35
STM32_DAC_VREF = 2.5
STM32_DAC_MAX_CODE = 4095
PA4_DAC_DEFAULT_VOLT = 0.0
#### ---- Functions #### ---- Functions
@ -94,6 +97,16 @@ def format_ds1809_status(step):
return f"{step}/{DS1809_MAX_STEP} шагов" return f"{step}/{DS1809_MAX_STEP} шагов"
def voltage_to_dac_code(voltage_v):
if voltage_v is None:
return 0
if voltage_v < 0.0:
voltage_v = 0.0
if voltage_v > STM32_DAC_VREF:
voltage_v = STM32_DAC_VREF
return int(round((voltage_v / STM32_DAC_VREF) * STM32_DAC_MAX_CODE))
def initialize_ds1809_position(prt, default_step): def initialize_ds1809_position(prt, default_step):
default_step = clamp_int(int(default_step), 0, DS1809_MAX_STEP) default_step = clamp_int(int(default_step), 0, DS1809_MAX_STEP)
@ -154,6 +167,8 @@ def set_initial_params():
params['Ad9833Triangle'] = True params['Ad9833Triangle'] = True
params['DS1809Step'] = DS1809_DEFAULT_STEP params['DS1809Step'] = DS1809_DEFAULT_STEP
params['DS1809Status'] = format_ds1809_status(DS1809_DEFAULT_STEP) params['DS1809Status'] = format_ds1809_status(DS1809_DEFAULT_STEP)
params['PA4DacVolt'] = str(PA4_DAC_DEFAULT_VOLT)
params['PA4DacStatus'] = f"0 / {STM32_DAC_MAX_CODE}"
return params return params
def update_data_lists(): def update_data_lists():
@ -570,6 +585,21 @@ if __name__ == "__main__":
params['DS1809Step'] = ds1809_step params['DS1809Step'] = ds1809_step
params['DS1809Status'] = format_ds1809_status(ds1809_step) params['DS1809Status'] = format_ds1809_status(ds1809_step)
window['-DS1809Status-'].update(params['DS1809Status']) window['-DS1809Status-'].update(params['DS1809Status'])
elif event == '-SetPA4Dac-':
voltage_v = parse_optional_float(values.get('-PA4DacVolt-'))
if voltage_v is None:
print('Invalid PA4 DAC voltage value.')
else:
if voltage_v < 0.0:
voltage_v = 0.0
if voltage_v > STM32_DAC_VREF:
voltage_v = STM32_DAC_VREF
dac_code = voltage_to_dac_code(voltage_v)
dev.set_stm32_dac(prt, dac_code=dac_code, enable=True)
params['PA4DacVolt'] = f"{voltage_v:.3f}"
params['PA4DacStatus'] = f"{dac_code} / {STM32_DAC_MAX_CODE}"
window['-PA4DacVolt-'].update(params['PA4DacVolt'])
window['-PA4DacStatus-'].update(params['PA4DacStatus'])
elif event == '-StopCycle-': elif event == '-StopCycle-':
window['-StopCycle-'].update(disabled = True) window['-StopCycle-'].update(disabled = True)
current_and_temperature_settings_available = True current_and_temperature_settings_available = True

View File

@ -16,6 +16,8 @@ AD9833_CMD_TOTAL_LENGTH = 10 # Total bytes when sending AD9833 command
AD9833_CMD_HEADER = "9999" AD9833_CMD_HEADER = "9999"
DS1809_CMD_TOTAL_LENGTH = 10 # Total bytes when sending DS1809 UC/DC pulse command DS1809_CMD_TOTAL_LENGTH = 10 # Total bytes when sending DS1809 UC/DC pulse command
DS1809_CMD_HEADER = "AAAA" DS1809_CMD_HEADER = "AAAA"
STM32_DAC_CMD_TOTAL_LENGTH = 10 # Total bytes when sending STM32 DAC command
STM32_DAC_CMD_HEADER = "BBBB"
AD9102_SAW_STEP_DEFAULT = 1 AD9102_SAW_STEP_DEFAULT = 1
AD9102_PAT_PERIOD_DEFAULT = 0xFFFF AD9102_PAT_PERIOD_DEFAULT = 0xFFFF
AD9102_PAT_PERIOD_BASE_DEFAULT = 0x02 AD9102_PAT_PERIOD_BASE_DEFAULT = 0x02
@ -31,6 +33,9 @@ AD9833_MCLK_HZ_DEFAULT = 20_000_000
DS1809_FLAG_UC = 0x0001 DS1809_FLAG_UC = 0x0001
DS1809_FLAG_DC = 0x0002 DS1809_FLAG_DC = 0x0002
DS1809_PULSE_MS_DEFAULT = 2 DS1809_PULSE_MS_DEFAULT = 2
STM32_DAC_FLAG_ENABLE = 0x0001
STM32_DAC_CODE_MAX = 4095
STM32_DAC_VREF_DEFAULT = 3.3
class TaskType(IntEnum): class TaskType(IntEnum):
Manual = 0x00 Manual = 0x00
@ -203,6 +208,17 @@ def send_DS1809(prt, bytestring):
print("Sent: DS1809 pulse command.") print("Sent: DS1809 pulse command.")
def send_STM32_DAC(prt, bytestring):
''' Set STM32 internal DAC output on PA4 (0xBBBB + ...).
Expected device answer: STATE.
'''
if len(bytestring) != STM32_DAC_CMD_TOTAL_LENGTH:
print("Error. Wrong parameter string for STM32 DAC command.")
return None
prt.write(bytestring)
print("Sent: STM32 DAC command.")
# ---- Getting data # ---- Getting data
@ -496,6 +512,28 @@ def create_DS1809_pulse_command(uc: bool = False,
return bytearray.fromhex(data) return bytearray.fromhex(data)
def create_STM32_DAC_command(dac_code: int, enable: bool = True):
if dac_code is None:
dac_code = 0
if dac_code < 0:
dac_code = 0
if dac_code > STM32_DAC_CODE_MAX:
dac_code = STM32_DAC_CODE_MAX
flags = STM32_DAC_FLAG_ENABLE if enable else 0
param0 = int(dac_code) & 0x0FFF
param1 = 0
crc_word = flags ^ param0 ^ param1
data = flipfour(STM32_DAC_CMD_HEADER) # Word 0 (header)
data += flipfour(int_to_hex(flags))
data += flipfour(int_to_hex(param0))
data += flipfour(int_to_hex(param1))
data += flipfour(int_to_hex(crc_word))
return bytearray.fromhex(data)
def encode_Input(params): def encode_Input(params):
if params is None: if params is None:

View File

@ -147,6 +147,13 @@ def start_ad9833_ramp(prt, freq_hz=None, mclk_hz=None, triangle=True, enable=Tru
return _print_state_reply(cmd.get_STATE(prt)) return _print_state_reply(cmd.get_STATE(prt))
def set_stm32_dac(prt, dac_code, enable=True):
hexstring = cmd.create_STM32_DAC_command(dac_code=dac_code, enable=enable)
cmd.send_STM32_DAC(prt, hexstring)
time.sleep(WAIT_AFTER_SEND)
return _print_state_reply(cmd.get_STATE(prt))
def _wait_for_min_bytes(prt, expected_len, timeout_s, poll_s=0.01): def _wait_for_min_bytes(prt, expected_len, timeout_s, poll_s=0.01):
deadline = time.time() + timeout_s deadline = time.time() + timeout_s
while time.time() < deadline: while time.time() < deadline:

16
gui.py
View File

@ -59,6 +59,10 @@ SET_DS1809_SECTION_TEXT = 'DS1809 (UC/DC)'
SET_DS1809_UC_BUTTON_TEXT = 'UC импульс' SET_DS1809_UC_BUTTON_TEXT = 'UC импульс'
SET_DS1809_DC_BUTTON_TEXT = 'DC импульс' SET_DS1809_DC_BUTTON_TEXT = 'DC импульс'
SET_DS1809_STATUS_TEXT = 'Позиция DS1809:' SET_DS1809_STATUS_TEXT = 'Позиция DS1809:'
SET_STM32_DAC_SECTION_TEXT = 'STM32 DAC (PA4)'
SET_STM32_DAC_VOLT_TEXT = 'Напряжение DAC PA4 (В, 0..2.5):'
SET_STM32_DAC_BUTTON_TEXT = 'Установить DAC'
SET_STM32_DAC_STATUS_TEXT = 'Код DAC PA4:'
GRAPH_POINTS_NUMBER = 100 # Number of most recent data points shown on charts GRAPH_POINTS_NUMBER = 100 # Number of most recent data points shown on charts
@ -296,6 +300,18 @@ def setup_gui(params):
[sg.HSeparator(pad=H_SEPARATOR_PAD)], [sg.HSeparator(pad=H_SEPARATOR_PAD)],
[sg.Text(SET_STM32_DAC_SECTION_TEXT, size=(SET_TEXT_WIDTH_NEW,1))],
[sg.Text(SET_STM32_DAC_VOLT_TEXT, size=(SET_TEXT_WIDTH_NEW,1)),
sg.Input(params.get('PA4DacVolt', '0.0'), size=(SET_INPUT_WIDTH,1), key='-PA4DacVolt-')],
[sg.Button(SET_STM32_DAC_BUTTON_TEXT, key='-SetPA4Dac-', disabled_button_color=("Gray22", "Blue"))],
[sg.Text(SET_STM32_DAC_STATUS_TEXT, size=(SET_TEXT_WIDTH_NEW,1)),
sg.Text(params.get('PA4DacStatus', '0 / 4095'), key='-PA4DacStatus-', size=(20,1))],
[sg.HSeparator(pad=H_SEPARATOR_PAD)],
[sg.Button(SET_START_BUTTON_TEXT, key='-StartCycle-', disabled_button_color=("Gray22", "Blue"), disabled=True), sg.Button(SET_STOP_BUTTON_TEXT, disabled_button_color=("Gray22", "Blue"), key='-StopCycle-', disabled=True), sg.Button(SET_RAMP_BUTTON_TEXT, key='-StartRamp-', disabled_button_color=("Gray22", "Blue")), sg.Button(SET_AD9833_BUTTON_TEXT, key='-StartRamp9833-', disabled_button_color=("Gray22", "Blue"))]] [sg.Button(SET_START_BUTTON_TEXT, key='-StartCycle-', disabled_button_color=("Gray22", "Blue"), disabled=True), sg.Button(SET_STOP_BUTTON_TEXT, disabled_button_color=("Gray22", "Blue"), key='-StopCycle-', disabled=True), sg.Button(SET_RAMP_BUTTON_TEXT, key='-StartRamp-', disabled_button_color=("Gray22", "Blue")), sg.Button(SET_AD9833_BUTTON_TEXT, key='-StartRamp9833-', disabled_button_color=("Gray22", "Blue"))]]