├── .github └── workflows │ ├── push-test.yml │ ├── python-publish.yml │ └── update_pages.yml ├── .gitignore ├── .prospector.yaml ├── CCBL.txt ├── LICENSE ├── README.md ├── docs ├── class_diagram.drawio.svg ├── datalogger.drawio.svg ├── datalogger.md ├── migration_guide.md └── pages │ ├── Makefile │ ├── make.bat │ ├── requirements.txt │ └── source │ ├── conf.py │ ├── index.md │ └── user_guide.md ├── examples ├── evalboards │ ├── MAX22215 │ │ ├── basic_usage.py │ │ ├── brake_release_example.py │ │ └── read_all_register_and_fields.py │ ├── MAX22216 │ │ ├── datalogger_check.py │ │ ├── otp_burn.py │ │ ├── plunger_move.py │ │ └── ramdebug.py │ ├── TMC2100 │ │ ├── register_dump.py │ │ └── rotate_demo.py │ ├── TMC2130 │ │ ├── register_dump.py │ │ └── rotate_demo.py │ ├── TMC2160 │ │ ├── register_dump.py │ │ └── rotate_demo.py │ ├── TMC2208 │ │ ├── register_dump.py │ │ └── rotate_demo.py │ ├── TMC2209 │ │ ├── register_dump.py │ │ └── rotate_demo.py │ ├── TMC2224 │ │ ├── register_dump.py │ │ └── rotate_demo.py │ ├── TMC2225 │ │ ├── register_dump.py │ │ └── rotate_demo.py │ ├── TMC2240 │ │ ├── register_dump.py │ │ └── rotate_demo.py │ ├── TMC2300 │ │ ├── register_dump.py │ │ └── rotate_demo.py │ ├── TMC2590 │ │ ├── register_dump.py │ │ └── rotate_demo.py │ ├── TMC2660 │ │ ├── register_dump.py │ │ └── rotate_demo.py │ ├── TMC4361 │ │ ├── TMC4331_eval_TMC2130_eval_rotateDemo.py │ │ └── register_dump.py │ ├── TMC4671 │ │ ├── README.md │ │ ├── TMC4671_eval_BLDC_ABN_encoder.py │ │ ├── TMC4671_eval_BLDC_ABN_encoder_offset_estimation.py │ │ ├── TMC4671_eval_BLDC_open_loop.py │ │ ├── TMC4671_eval_TMC6100_eval_BLDC_ABN_encoder.py │ │ ├── TMC4671_eval_TMC6100_eval_BLDC_ABN_encoder_position_mode_linear_ramp.py │ │ ├── TMC4671_eval_TMC6100_eval_BLDC_ABN_encoder_velocity.py │ │ ├── TMC4671_eval_TMC6100_eval_BLDC_digital_hall_velocity.py │ │ ├── TMC4671_eval_TMC6100_eval_BLDC_open_loop.py │ │ ├── TMC4671_eval_TMC6100_eval_current_adc_graph.py │ │ ├── TMC4671_eval_TMC6200_eval_BLDC_ABN_encoder.py │ │ ├── TMC4671_eval_TMC6200_eval_BLDC_open_loop.py │ │ ├── TMC4671_eval_adc_offset_calibration.py │ │ ├── TMC4671_eval_baud_rate_change.py │ │ ├── TMC4671_eval_baud_rate_change_BLDC_open_loop.py │ │ ├── TMC4671_eval_datalogger_check.py │ │ ├── TMC4671_eval_datalogger_demo.py │ │ ├── TMC4671_eval_read_AGPI_A_and_AGPI_B.py │ │ ├── TMC4671_eval_read_VM.py │ │ └── TMC4671_eval_register_dump.py │ ├── TMC5031 │ │ ├── TMC5031_stallGuardDemo.py │ │ ├── register_dump.py │ │ └── rotate_demo.py │ ├── TMC5041 │ │ ├── TMC5041_stallGuardDemo.py │ │ ├── register_dump.py │ │ └── rotate_demo.py │ ├── TMC5062 │ │ ├── register_dump.py │ │ └── rotate_demo.py │ ├── TMC5072 │ │ ├── register_dump.py │ │ ├── rotate_demo.py │ │ ├── rotate_demo_direct.py │ │ ├── stop_switch_R1_AP.py │ │ └── stop_switch_R1_register_access.py │ ├── TMC5130 │ │ ├── StallGuard2_demo2.py │ │ ├── TMC5130_MicroStep.py │ │ ├── register_dump.py │ │ ├── rotate_demo.py │ │ └── six_point_ramp_demo.py │ ├── TMC5160 │ │ ├── register_dump.py │ │ └── rotate_demo.py │ ├── TMC5160_shield │ │ ├── StallGuard.py │ │ ├── TMC5160_coolStep_demo.py │ │ ├── TMC5160_coolStep_demo_min.py │ │ ├── TMC5160_shield_register_dump.py │ │ ├── TMC5160_stallGuard_demo.py │ │ └── TMC5160_stallGuard_demo_min.py │ ├── TMC5240 │ │ ├── StallGuard2_demo2.py │ │ └── rotate_demo.py │ ├── TMC5271 │ │ ├── register_dump.py │ │ └── rotate_demo.py │ ├── TMC5272 │ │ ├── register_dump.py │ │ └── rotate_demo.py │ ├── TMC6140 │ │ ├── hall_demo.py │ │ └── openloop_demo.py │ ├── TMC6300 │ │ ├── hall_demo.py │ │ └── openloop_demo.py │ ├── TMC7300 │ │ ├── register_dump.py │ │ └── rotate_demo.py │ └── TMC9660 │ │ ├── param │ │ ├── dual_use │ │ │ ├── demo_datalogger.py │ │ │ ├── demo_flags.py │ │ │ ├── demo_read_choice.py │ │ │ ├── tmc9660_3ph_eval_QBL_closed_loop_rpm.py │ │ │ ├── tmc9660_3ph_eval_QBL_current_mode.py │ │ │ ├── tmc9660_3ph_eval_QBL_spi_enc.py │ │ │ ├── tmc9660_3ph_eval_QBL_spi_enc.toml │ │ │ ├── tmc9660_3ph_eval_QBL_torque_mode.py │ │ │ └── tmc9660_3ph_eval_QBL_voltage_mode_heartbeat.py │ │ ├── headless │ │ │ ├── tmc9660_3ph_eval_QBL_voltage_mode.py │ │ │ └── tmc9660_any_eval_supply_voltage.py │ │ └── with_landungsbruecke │ │ │ ├── demo_gpio.py │ │ │ ├── tmc9660_3ph_eval_QBL_closed_loop.py │ │ │ └── tmc9660_3ph_eval_QBL_voltage_mode.py │ │ └── reg │ │ ├── create_reg_map.py │ │ ├── dual_use │ │ ├── read_all_mcc_register_and_fields.py │ │ ├── tmc9660_3ph_eval_QBL_voltage_mode.py │ │ └── tmc9660_3ph_eval_QBL_voltage_mode_check_currents.py │ │ ├── headless │ │ └── tmc9660_3ph_eval_min_demo.py │ │ └── with_landungsbruecke │ │ ├── tmc9660_3ph_eval_datalogger_demo.py │ │ └── tmc9660_3ph_eval_min_demo.py ├── modules │ ├── Landungsbruecke │ │ ├── connected_eval_information.py │ │ ├── multi_eval.py │ │ ├── write_drv_id_eeprom.py │ │ └── write_mc_id_eeprom.py │ ├── TMCC160 │ │ └── TMCL │ │ │ ├── encoder_position_mode.py │ │ │ └── hall_digital_analog_input.py │ ├── TMCM1021 │ │ └── TMCL │ │ │ ├── CoolStep_demo.py │ │ │ ├── StallGuard2_demo.py │ │ │ └── rotate_demo.py │ ├── TMCM1110 │ │ └── TMCL │ │ │ ├── CoolStep_demo.py │ │ │ ├── StallGuard2_demo.py │ │ │ └── rotate_demo.py │ ├── TMCM1111 │ │ └── TMCL │ │ │ └── rotate_demo.py │ ├── TMCM1140 │ │ └── TMCL │ │ │ ├── CoolStep_demo.py │ │ │ ├── StallGuard2_demo.py │ │ │ └── rotate_demo.py │ ├── TMCM1160 │ │ └── TMCL │ │ │ └── rotate_demo.py │ ├── TMCM1161 │ │ └── TMCL │ │ │ └── rotate_demo.py │ ├── TMCM1210 │ │ └── TMCL │ │ │ ├── rotate_demo.py │ │ │ └── six_point_ramp_demo.py │ ├── TMCM1211 │ │ └── TMCL │ │ │ ├── rotate_demo.py │ │ │ └── six_point_ramp_demo.py │ ├── TMCM123x_0_1 │ │ ├── CANopen │ │ │ ├── StallGuard2_demo_using_sdo.py │ │ │ ├── TMCM-1230.eds │ │ │ ├── TMCM-1231.eds │ │ │ ├── rotate_demo_using_pdo.py │ │ │ ├── rotate_demo_using_sdo.py │ │ │ └── six_point_ramp_demo_using_pdo.py │ │ ├── TMCL │ │ │ ├── StallGuard2_demo.py │ │ │ └── rotate_demo.py │ │ └── readme.txt │ ├── TMCM1240 │ │ ├── CANopen │ │ │ ├── tmcm_1240_profile_position_mode_demo.py │ │ │ └── tmcm_1240_profile_velocity_mode_demo.py │ │ └── TMCL │ │ │ ├── StallGuard2_demo.py │ │ │ └── rotate_demo.py │ ├── TMCM1241 │ │ └── TMCL │ │ │ ├── StallGuard2_demo.py │ │ │ └── rotate_demo.py │ ├── TMCM1260 │ │ └── TMCL │ │ │ └── rotate_demo.py │ ├── TMCM1270 │ │ └── TMCL │ │ │ └── rotate_demo.py │ ├── TMCM1276 │ │ └── TMCL │ │ │ ├── rotate_demo.py │ │ │ ├── six_point_ramp_demo.py │ │ │ └── stop_switch_demo.py │ ├── TMCM1278 │ │ └── TMCL │ │ │ ├── rotate_demo.py │ │ │ ├── six_point_ramp_demo.py │ │ │ └── stop_switch_demo.py │ ├── TMCM1290 │ │ └── TMCL │ │ │ ├── eight_point_ramp_demo.py │ │ │ ├── rotate_demo.py │ │ │ └── stop_switch_demo.py │ ├── TMCM1311 │ │ └── TMCL │ │ │ ├── closed_loop_demo.py │ │ │ └── rotate_demo.py │ ├── TMCM1316 │ │ └── TMCL │ │ │ ├── rotate_demo.py │ │ │ └── s_shaped_ramp_demo.py │ ├── TMCM1321 │ │ └── TMCL │ │ │ ├── rotate_demo.py │ │ │ └── s_shaped_ramp_demo.py │ ├── TMCM1370 │ │ └── TMCL │ │ │ ├── rotate_demo.py │ │ │ └── s_shaped_ramp_demo.py │ ├── TMCM1378 │ │ └── TMCL │ │ │ ├── rotate_demo.py │ │ │ └── s_shaped_ramp_demo.py │ ├── TMCM1617 │ │ └── TMCL │ │ │ ├── encoder_position_mode.py │ │ │ ├── hall_digital_input.py │ │ │ ├── hall_position_mode.py │ │ │ └── register_access.py │ ├── TMCM1630 │ │ └── TMCL │ │ │ ├── encoder_analog_input.py │ │ │ ├── encoder_position_mode.py │ │ │ ├── hall_digital_input.py │ │ │ └── hall_position_mode.py │ ├── TMCM1633 │ │ └── TMCL │ │ │ ├── encoder_analog_input.py │ │ │ ├── encoder_position_mode.py │ │ │ ├── hall_digital_input.py │ │ │ └── hall_position_mode.py │ ├── TMCM1636 │ │ ├── CANopen │ │ │ └── PV │ │ │ │ └── pv_position_moves_using_pdo.py │ │ └── TMCL │ │ │ ├── datalogger_demo.py │ │ │ ├── datalogger_minimal.py │ │ │ ├── encoder_position_mode.py │ │ │ ├── hall_digital_input.py │ │ │ ├── hall_endstop.py │ │ │ ├── hall_position_mode.py │ │ │ ├── multi_module.py │ │ │ ├── position_abn_abs.py │ │ │ └── tmcl_script_load.py │ ├── TMCM1637 │ │ └── TMCL │ │ │ ├── encoder_position_mode.py │ │ │ └── hall_position_mode.py │ ├── TMCM1638 │ │ └── TMCL │ │ │ ├── encoder_position_mode.py │ │ │ └── hall_position_mode.py │ ├── TMCM1640 │ │ └── TMCL │ │ │ ├── encoder_analog_input.py │ │ │ ├── encoder_position_mode.py │ │ │ ├── hall_digital_input.py │ │ │ └── hall_position_mode.py │ ├── TMCM1670 │ │ └── TMCL │ │ │ ├── encoder_n_channel.py │ │ │ ├── limit_switches.py │ │ │ └── position_mode.py │ ├── TMCM1690 │ │ └── TMCL │ │ │ ├── abn_encoder_position_mode.py │ │ │ ├── abn_encoder_velocity_mode.py │ │ │ ├── abs_encoder_position_mode.py │ │ │ ├── abs_encoder_velocity_mode.py │ │ │ ├── hall_position_mode.py │ │ │ └── hall_velocity_mode.py │ ├── TMCM2611 │ │ ├── agv_brake_ctrl.py │ │ ├── agv_demo.py │ │ ├── copy_axis_0_settings_to_axis_1.py │ │ ├── encoder_velocity_mode.py │ │ ├── hall_velocity_mode.py │ │ └── print_settings.py │ ├── TMCM3110 │ │ └── TMCL │ │ │ └── rotate_demo.py │ ├── TMCM3216 │ │ └── TMCL │ │ │ ├── eight_point_ramp_demo.py │ │ │ ├── rotate_demo.py │ │ │ └── stop_switch_demo.py │ ├── TMCM3312 │ │ └── TMCL │ │ │ └── rotate_demo.py │ ├── TMCM3351 │ │ └── TMCL │ │ │ └── rotate_demo.py │ ├── TMCM6110 │ │ └── TMCL │ │ │ └── rotate_demo.py │ ├── TMCM6212 │ │ └── TMCL │ │ │ └── rotate_demo.py │ ├── TMCM6214 │ │ ├── CANopen │ │ │ ├── TMCM-6214.eds │ │ │ └── rotate_demo_using_sdo_2-axis.py │ │ └── TMCL │ │ │ ├── StallGuard2_demo.py │ │ │ ├── rotate_demo.py │ │ │ └── six_point_ramp_demo.py │ └── tests │ │ ├── README.md │ │ ├── test_tmcm1140_tmcl_examples.py │ │ ├── test_tmcm1617_tmcl_examples.py │ │ ├── test_tmcm1636_tmcl_examples.py │ │ └── test_tmcm6110_tmcl_examples.py ├── referencedesigns │ └── TMC4671_LEV_REF │ │ └── TMCL │ │ ├── rotate_hall.py │ │ └── rotate_openloop.py └── tools │ ├── FirmwareUpdate.py │ ├── LoadTMCLBinary.py │ └── test.bin ├── pyproject.toml ├── pytrinamic ├── RAMDebug.py ├── __init__.py ├── cli │ ├── __init__.py │ └── tmclfwupload.py ├── connections │ ├── __init__.py │ ├── can_tmcl │ │ ├── __init__.py │ │ ├── ixxat_tmcl_interface.py │ │ ├── kvaser_tmcl_interface.py │ │ ├── pcan_tmcl_interface.py │ │ ├── slcan_tmcl_interface.py │ │ └── socketcan_tmcl_interface.py │ ├── can_tmcl_interface.py │ ├── connection_manager.py │ ├── dummy_tmcl_interface.py │ ├── serial_tmcl_interface.py │ ├── socket_tmcl_interface.py │ ├── tmcl_interface.py │ ├── uart_ic_interface.py │ └── usb_tmcl_interface.py ├── datalogger.py ├── evalboards │ ├── MAX22215_eval.py │ ├── MAX22216_eval.py │ ├── TMC2100_eval.py │ ├── TMC2130_eval.py │ ├── TMC2160_eval.py │ ├── TMC2208_eval.py │ ├── TMC2209_eval.py │ ├── TMC2224_eval.py │ ├── TMC2225_eval.py │ ├── TMC2240_eval.py │ ├── TMC2300_eval.py │ ├── TMC2590_eval.py │ ├── TMC2660_eval.py │ ├── TMC4361_eval.py │ ├── TMC4671_eval.py │ ├── TMC5031_eval.py │ ├── TMC5041_eval.py │ ├── TMC5062_eval.py │ ├── TMC5072_eval.py │ ├── TMC5130_eval.py │ ├── TMC5160_eval.py │ ├── TMC5160_shield.py │ ├── TMC5240_eval.py │ ├── TMC5271_eval.py │ ├── TMC5272_eval.py │ ├── TMC6100_eval.py │ ├── TMC6140_eval.py │ ├── TMC6200_eval.py │ ├── TMC6300_eval.py │ ├── TMC7300_eval.py │ ├── TMC9660_eval.py │ ├── __init__.py │ └── tmcl_eval.py ├── features │ ├── __init__.py │ ├── abn_encoder.py │ ├── abn_encoder_module.py │ ├── absolute_encoder.py │ ├── absolute_encoder_module.py │ ├── brakechopper.py │ ├── brakechopper_module.py │ ├── coolstep.py │ ├── coolstep_module.py │ ├── current.py │ ├── current_module.py │ ├── digital_hall.py │ ├── digital_hall_module.py │ ├── drive_setting.py │ ├── drive_setting_module.py │ ├── linear_ramp.py │ ├── linear_ramp_module.py │ ├── motor_control.py │ ├── motor_control_ic.py │ ├── motor_control_module.py │ ├── pid.py │ ├── pid_module.py │ ├── ramp_settings.py │ ├── ramp_settings_module.py │ ├── referenceswitches.py │ ├── referenceswitches_module.py │ ├── s_ramp.py │ ├── s_ramp_module.py │ ├── six_point_ramp.py │ ├── six_point_ramp_module.py │ ├── solenoid.py │ ├── solenoid_control.py │ ├── solenoid_control_ic.py │ ├── solenoid_ic.py │ ├── stallguard2.py │ └── stallguard2_module.py ├── helpers.py ├── ic │ ├── MAX22215 │ │ ├── MAX22215.py │ │ └── MAX22215map.py │ ├── MAX22216.py │ ├── TMC2100.py │ ├── TMC2130.py │ ├── TMC2160.py │ ├── TMC2208.py │ ├── TMC2209.py │ ├── TMC2224.py │ ├── TMC2225.py │ ├── TMC2240.py │ ├── TMC2300.py │ ├── TMC2590.py │ ├── TMC2660.py │ ├── TMC4361.py │ ├── TMC4671.py │ ├── TMC5031.py │ ├── TMC5041.py │ ├── TMC5062.py │ ├── TMC5072.py │ ├── TMC5130.py │ ├── TMC5160.py │ ├── TMC5240.py │ ├── TMC5271.py │ ├── TMC5272.py │ ├── TMC6100.py │ ├── TMC6140.py │ ├── TMC6200.py │ ├── TMC6300.py │ ├── TMC7300.py │ ├── TMC9660 │ │ ├── ADCmap.py │ │ ├── MCCmap.py │ │ ├── SYS_CTRLmap.py │ │ ├── TMC9660.py │ │ ├── TMC9660_ap.py │ │ ├── TMC9660_gpbank0.py │ │ ├── TMC9660_gpbank2.py │ │ ├── TMC9660_gpbank3.py │ │ └── __init__.py │ ├── __init__.py │ └── tmc_ic.py ├── modules │ ├── Landungsbruecke.py │ ├── TMCC160.py │ ├── TMCM1021.py │ ├── TMCM1110.py │ ├── TMCM1111.py │ ├── TMCM1140.py │ ├── TMCM1141.py │ ├── TMCM1160.py │ ├── TMCM1161.py │ ├── TMCM1210.py │ ├── TMCM1211.py │ ├── TMCM123x_0_1.py │ ├── TMCM1240.py │ ├── TMCM1241.py │ ├── TMCM1260.py │ ├── TMCM1270.py │ ├── TMCM1276.py │ ├── TMCM1278.py │ ├── TMCM1290.py │ ├── TMCM1311.py │ ├── TMCM1316.py │ ├── TMCM1321.py │ ├── TMCM1370.py │ ├── TMCM1378.py │ ├── TMCM1617.py │ ├── TMCM1630.py │ ├── TMCM1633.py │ ├── TMCM1636.py │ ├── TMCM1637.py │ ├── TMCM1638.py │ ├── TMCM1640.py │ ├── TMCM1670.py │ ├── TMCM1690.py │ ├── TMCM2611.py │ ├── TMCM3110.py │ ├── TMCM3216.py │ ├── TMCM3312.py │ ├── TMCM3351.py │ ├── TMCM6110.py │ ├── TMCM6212.py │ ├── TMCM6214.py │ ├── TMCM_Python.py │ ├── __init__.py │ ├── canopen_node.py │ ├── tmc_eval_shield.py │ └── tmcl_module.py ├── rd.py ├── referencedesigns │ ├── TMC4671_LEV_REF.py │ └── __init__.py ├── tmcl.py ├── tools │ ├── __init__.py │ ├── tests │ │ └── test_ramp_runner.py │ └── velocity_ramp_runner.py └── version.py ├── tests ├── check_lb_fw_upload.py ├── test_can_adapters.py ├── test_datalogger_tmc4671_eval.py ├── test_datalogger_tmcm_1617.py ├── test_firmware_update.py ├── test_interface_timeouts.py ├── test_project_sanity.py └── test_socket_tmcl_interface.py └── tox.ini /.github/workflows/push-test.yml: -------------------------------------------------------------------------------- 1 | name: Push Triggered Testrun 2 | 3 | on: push 4 | 5 | jobs: 6 | test: 7 | 8 | runs-on: ubuntu-latest 9 | 10 | steps: 11 | - name: Check out the repository 12 | uses: actions/checkout@v4 13 | 14 | - name: Set up Python 15 | uses: actions/setup-python@v5 16 | with: 17 | python-version: '3.x' 18 | 19 | - name: Install dependencies 20 | run: | 21 | python -m pip install --upgrade pip 22 | pip install pytest pytest-html 23 | 24 | - name: Install pytrinamic from the checked out repository 25 | run: pip install . 26 | 27 | - name: Run the tests inside the project's root `tests` directory 28 | working-directory: tests 29 | run: pytest test_project_sanity.py -v --html=pytest_report.html --self-contained-html 30 | 31 | - name: Run the tests inside the `examples` directory 32 | working-directory: examples 33 | run: pytest -v --html=pytest_examples_report.html --self-contained-html 34 | 35 | - name: Upload the test reports even if tests fail 36 | if: always() 37 | uses: actions/upload-artifact@v4 38 | with: 39 | name: test-report 40 | path: | 41 | tests/pytest_report.html 42 | examples/pytest_examples_report.html 43 | 44 | -------------------------------------------------------------------------------- /.github/workflows/python-publish.yml: -------------------------------------------------------------------------------- 1 | name: Upload Python Package 2 | 3 | on: 4 | release: 5 | types: [published] 6 | 7 | jobs: 8 | deploy: 9 | 10 | runs-on: ubuntu-latest 11 | environment: 12 | name: pypi 13 | url: https://pypi.org/p/pytrinamic 14 | permissions: 15 | id-token: write # IMPORTANT: this permission is mandatory for trusted publishing 16 | 17 | steps: 18 | - uses: actions/checkout@v2 19 | - name: Set up Python 20 | uses: actions/setup-python@v2 21 | with: 22 | python-version: '3.x' 23 | - name: Install dependencies 24 | run: | 25 | python -m pip install --upgrade pip 26 | pip install build 27 | - name: Build package 28 | run: python -m build 29 | - name: Publish package 30 | uses: pypa/gh-action-pypi-publish@release/v1 -------------------------------------------------------------------------------- /.github/workflows/update_pages.yml: -------------------------------------------------------------------------------- 1 | # This workflow is based on the "Static HTML" workflow provided by GitHub Actions. 2 | name: Update the Documentation Pages 3 | 4 | on: workflow_dispatch 5 | 6 | # Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages 7 | permissions: 8 | contents: read 9 | pages: write 10 | id-token: write 11 | 12 | # Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued. 13 | # However, do NOT cancel in-progress runs as we want to allow these production deployments to complete. 14 | concurrency: 15 | group: "pages" 16 | cancel-in-progress: false 17 | 18 | jobs: 19 | # Single deploy job since we're just deploying 20 | deploy: 21 | environment: 22 | name: github-pages 23 | url: ${{ steps.deployment.outputs.page_url }} 24 | runs-on: ubuntu-latest 25 | steps: 26 | - name: Checkout 27 | uses: actions/checkout@v4 28 | - name: Set up Python 29 | uses: actions/setup-python@v2 30 | with: 31 | python-version: '3.x' 32 | - name: Install dependencies 33 | run: | 34 | python -m pip install --upgrade pip 35 | pip install -r ./docs/pages/requirements.txt 36 | - name: Build the docs 37 | run: | 38 | cd docs/pages 39 | make html 40 | - name: Setup Pages 41 | uses: actions/configure-pages@v5 42 | - name: Upload the generated website files 43 | uses: actions/upload-pages-artifact@v3 44 | with: 45 | path: './docs/pages/build/html' 46 | - name: Deploy to GitHub Pages 47 | id: deployment 48 | uses: actions/deploy-pages@v4 49 | -------------------------------------------------------------------------------- /.prospector.yaml: -------------------------------------------------------------------------------- 1 | strictness: verylow 2 | 3 | inherits: 4 | - no_pep8 # No PEP 8 check for now, we have more serious bugs to take care of. 5 | ignore-paths: 6 | - examples\tools\FirmwareUpdate.py # I have a new version ready somewhere else to replace this after "the merge". 7 | 8 | pylint: 9 | disable: 10 | - useless-object-inheritance # Disabled because we want the code Python 2 compatible, and in Python 2 the "object-inheritance" might be necessary. 11 | - consider-using-f-string # Disabled because we want the code Python 2 compatible, in Python 2 f-strings are not available. 12 | -------------------------------------------------------------------------------- /CCBL.txt: -------------------------------------------------------------------------------- 1 | __init__ 2 | version.py 3 | setup.py 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License 2 | =============== 3 | 4 | Copyright (c) 2023 Analog Devices, Inc. 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of 7 | this software and associated documentation files (the "Software"), to deal in the 8 | Software without restriction, including without limitation the rights to use, 9 | copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the 10 | Software, and to permit persons to whom the Software is furnished to do so, 11 | subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 20 | AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 21 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | 23 | This software is subject to the above license but may also include 24 | additional software components that are identified in the NOTICE file, 25 | together with their associated licenses. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PyTrinamic 2 | 3 | PyTrinamic is a Python package to set up and control TRINAMIC modules, evaluation boards and ICs via serial, USB or CAN interfaces. 4 | 5 | The package is intended to automate tasks that are typically done manually with TRINAMICs [TMCL-IDE](https://www.analog.com/en/resources/evaluation-hardware-and-software/motor-motion-control-software/tmcl-ide.html). 6 | 7 | ## Install 8 | 9 | Use pip to install PyTrinamic. 10 | 11 | ``` 12 | pip install pytrinamic 13 | ``` 14 | 15 | ## Getting Started 16 | 17 | Please have a look at the [code examples on GitHub](https://github.com/analogdevicesinc/PyTrinamic/tree/master/examples). 18 | 19 | ## Migration Guide 20 | 21 | Version 0.2.0 of PyTrinamic introduces several changes to the API. For those who want to convert code that uses an older version of PyTrinamic, we wrote a short [migration guide](https://github.com/analogdevicesinc/PyTrinamic/blob/master/docs/migration_guide.md). 22 | 23 | All previous versions of PyTrinamic will still be available on PyPI and can be installed via: `pip install pytrinamic==0.1.27`. 24 | 25 | ## Contributing 26 | 27 | We welcome pull requests! If you have major changes or questions about implementation, please open an issue first to discuss your ideas. 28 | 29 | Please ensure contributed Python code adheres to the [PEP 8](https://peps.python.org/pep-0008/) Python code style guide and the [PEP 257](https://peps.python.org/pep-0257/) style guide for docstrings. 30 | If you want to express details in docstrings using a markup language, please use [reStructuredText](reStructuredText) like proposed in [PEP 287](https://peps.python.org/pep-0287/) and when documenting parameters, variables, attributes, exceptions use the [Sphinx style](https://www.sphinx-doc.org/en/master/usage/domains/python.html#info-field-lists). 31 | 32 | Additionally, please use double quotes (") for string constants. 33 | 34 | 35 | ## License 36 | 37 | PyTrinamic is licensed under the MIT License. -------------------------------------------------------------------------------- /docs/migration_guide.md: -------------------------------------------------------------------------------- 1 | # Migration Guide 2 | 3 | This guide outlines how to convert existing code based on legacy PyTrinamic (<0.2.0) to newer versions. 4 | 5 | Also check out the new [examples](https://github.com/trinamic/PyTrinamic/tree/master/examples). 6 | For almost all examples that were published for legacy PyTrinamic, new examples are provided. 7 | 8 | ## Imports 9 | 10 | All imports now use PyTrinamic in lowercase letters. 11 | 12 | PyTrinamic < 0.2.0: 13 | 14 | ```py 15 | import PyTrinamic 16 | from PyTrinamic.version import __version__ 17 | ``` 18 | 19 | Now: 20 | 21 | ```py 22 | import pytrinamic 23 | from pytrinamic.version import __version__ 24 | ``` 25 | 26 | 27 | ## Shorter Import Paths 28 | 29 | We introduced shorter imports. 30 | 31 | PyTrinamic < 0.2.0: 32 | 33 | ```py 34 | from PyTrinamic.connections.ConnectionManager import ConnectionManager 35 | from PyTrinamic.modules.TMCM1160.TMCM_1160 import TMCM_1160 36 | ``` 37 | 38 | Now: 39 | 40 | ```py 41 | from pytrinamic.connections import ConnectionManager 42 | from pytrinamic.modules import TMCM1160 43 | ``` 44 | 45 | ## Module Naming 46 | 47 | All modules now use snake_case naming convention. 48 | 49 | PyTrinamic < 0.2.0: 50 | 51 | ```py 52 | from PyTrinamic.TMCL import ... 53 | ``` 54 | 55 | Now 56 | ```py 57 | from pytrinamic.tmcl import ... 58 | ``` 59 | 60 | ## Class Naming 61 | 62 | All classes now use the PascalCase naming convention. 63 | We also removed any underscore in class names. 64 | 65 | PyTrinamic < 0.2.0: 66 | 67 | ```py 68 | module = TMCM_1160(..) 69 | .. = TMCL.TMCL_Command 70 | ``` 71 | 72 | Now: 73 | 74 | ```py 75 | module = TMCM1160(..) 76 | .. = tmcl.TMCLCommand 77 | ``` 78 | 79 | ## Function Naming 80 | 81 | All functions now use the snake_case naming convention. 82 | 83 | PyTrinamic < 0.2.0: 84 | 85 | ```py 86 | module.getAxisParameter(TMCM_1160.APs.ActualPosition) 87 | ``` 88 | 89 | Now: 90 | 91 | ```py 92 | module.get_axis_parameter(TMCM1160._MotorTypeA.AP.ActualPosition) 93 | ``` 94 | -------------------------------------------------------------------------------- /docs/pages/Makefile: -------------------------------------------------------------------------------- 1 | # Minimal makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line, and also 5 | # from the environment for the first two. 6 | SPHINXOPTS ?= 7 | SPHINXBUILD ?= sphinx-build 8 | SOURCEDIR = source 9 | BUILDDIR = build 10 | 11 | # Put it first so that "make" without argument is like "make help". 12 | help: 13 | @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 14 | 15 | .PHONY: help Makefile 16 | 17 | # Catch-all target: route all unknown targets to Sphinx using the new 18 | # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). 19 | %: Makefile 20 | @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 21 | -------------------------------------------------------------------------------- /docs/pages/make.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | pushd %~dp0 4 | 5 | REM Command file for Sphinx documentation 6 | 7 | if "%SPHINXBUILD%" == "" ( 8 | set SPHINXBUILD=sphinx-build 9 | ) 10 | set SOURCEDIR=source 11 | set BUILDDIR=build 12 | 13 | %SPHINXBUILD% >NUL 2>NUL 14 | if errorlevel 9009 ( 15 | echo. 16 | echo.The 'sphinx-build' command was not found. Make sure you have Sphinx 17 | echo.installed, then set the SPHINXBUILD environment variable to point 18 | echo.to the full path of the 'sphinx-build' executable. Alternatively you 19 | echo.may add the Sphinx directory to PATH. 20 | echo. 21 | echo.If you don't have Sphinx installed, grab it from 22 | echo.https://www.sphinx-doc.org/ 23 | exit /b 1 24 | ) 25 | 26 | if "%1" == "" goto help 27 | 28 | %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% 29 | goto end 30 | 31 | :help 32 | %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% 33 | 34 | :end 35 | popd 36 | -------------------------------------------------------------------------------- /docs/pages/requirements.txt: -------------------------------------------------------------------------------- 1 | sphinx>=5.0 2 | myst-parser 3 | https://github.com/analogdevicesinc/doctools/releases/download/latest/adi-doctools.tar.gz -------------------------------------------------------------------------------- /docs/pages/source/conf.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2025 Analog Devices Inc. All Rights Reserved. 3 | # This software is proprietary to Analog Devices, Inc. and its licensors. 4 | ################################################################################ 5 | # Configuration file for the Sphinx documentation builder. 6 | # 7 | # For the full list of built-in configuration values, see the documentation: 8 | # https://www.sphinx-doc.org/en/master/usage/configuration.html 9 | 10 | # -- Project information ----------------------------------------------------- 11 | # https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information 12 | 13 | project = "PyTrinamic" 14 | copyright = "2025, Analog Devices, Inc." 15 | author = "ADI Trinamic Software Team" 16 | release = "0.0.0" 17 | 18 | # -- General configuration --------------------------------------------------- 19 | # https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration 20 | 21 | extensions = [ 22 | "myst_parser", 23 | "adi_doctools", 24 | ] 25 | 26 | templates_path = ["_templates"] 27 | exclude_patterns = [] 28 | 29 | # -- Options for HTML output ------------------------------------------------- 30 | # https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output 31 | 32 | html_theme = "cosmic" 33 | html_static_path = ["_static"] 34 | -------------------------------------------------------------------------------- /docs/pages/source/index.md: -------------------------------------------------------------------------------- 1 | # PyTrinamic Documentation 2 | 3 | PyTrinamic is a Python package to set up and control ADI Trinamic modules, evaluation boards and ICs via serial, USB or CAN interfaces. 4 | 5 | The package is intended to automate tasks that are typically done manually with the [TMCL-IDE](https://www.analog.com/en/resources/evaluation-hardware-and-software/motor-motion-control-software/tmcl-ide.html). 6 | 7 | ## Contents 8 | 9 | ```{toctree} 10 | 11 | user_guide.md 12 | ``` -------------------------------------------------------------------------------- /docs/pages/source/user_guide.md: -------------------------------------------------------------------------------- 1 | # User Guide 2 | 3 | Work in progress ... -------------------------------------------------------------------------------- /examples/evalboards/MAX22215/basic_usage.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2025 Analog Devices Inc. All Rights Reserved. 3 | # This software is proprietary to Analog Devices, Inc. and its licensors. 4 | ################################################################################ 5 | """Example on how to read all MAX22215 registers of MAX22215-EVAL.""" 6 | 7 | from pytrinamic.connections import ConnectionManager 8 | 9 | from pytrinamic.ic import MAX22215 10 | from pytrinamic.evalboards import MAX22215_eval 11 | 12 | 13 | with ConnectionManager().connect() as my_interface: 14 | 15 | max22215_eval = MAX22215_eval(my_interface) 16 | 17 | print(f"Chip revision {max22215_eval.read(MAX22215.REGMAP.CHIP_REV.CHIP_REV)}") 18 | 19 | max22215_eval.write(MAX22215.REGMAP.ACTION_ENABLE.ENABLE1, 1) 20 | max22215_eval.write(MAX22215.REGMAP.CFG_1.SR.choice["25 V/µs"]) 21 | max22215_eval.write(MAX22215.REGMAP.CFG_1.GAIN.choice["100"]) -------------------------------------------------------------------------------- /examples/evalboards/MAX22215/brake_release_example.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2025 Analog Devices Inc. All Rights Reserved. 3 | # This software is proprietary to Analog Devices, Inc. and its licensors. 4 | ################################################################################ 5 | """Example on how to control the Brake(ON/OFF).""" 6 | 7 | from pytrinamic.connections import ConnectionManager 8 | import time 9 | 10 | from pytrinamic.ic import MAX22215 11 | from pytrinamic.evalboards import MAX22215_eval 12 | 13 | with ConnectionManager().connect() as my_interface: 14 | max22215_eval = MAX22215_eval(my_interface) 15 | 16 | # Clear faults 17 | max22215_eval.write(MAX22215.REGMAP.CFG_2.RESET, 1) 18 | # Set software control mode 19 | max22215_eval.write(MAX22215.REGMAP.CFG_1.SW_HW, 1) 20 | # Set active mode 21 | max22215_eval.write(MAX22215.REGMAP.CFG_2.NSLEEP, 1) 22 | 23 | # Control the brake 24 | max22215_eval.write(MAX22215.REGMAP.CFG_2.RLS_BRK, 1) 25 | time.sleep(1.0) 26 | max22215_eval.write(MAX22215.REGMAP.CFG_2.RLS_BRK, 0) 27 | -------------------------------------------------------------------------------- /examples/evalboards/MAX22215/read_all_register_and_fields.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2025 Analog Devices Inc. All Rights Reserved. 3 | # This software is proprietary to Analog Devices, Inc. and its licensors. 4 | ################################################################################ 5 | """Example on how to read all MAX22215 registers of MAX22215-EVAL.""" 6 | 7 | from pytrinamic.connections import ConnectionManager 8 | 9 | from pytrinamic.ic import MAX22215 10 | from pytrinamic.evalboards import MAX22215_eval 11 | 12 | 13 | with ConnectionManager().connect() as my_interface: 14 | 15 | max22215_eval = MAX22215_eval(my_interface) 16 | 17 | for register in MAX22215.REGMAP.registers(): 18 | register_value = max22215_eval.read(register) 19 | print(f"{register.name:17}: 0x{register_value:08X}") 20 | for field in register.fields(): 21 | field_value = field.get(register_value) 22 | if field.choice: 23 | option_text = next((text for text, option in field.choice.items() if option.value == field_value), None) 24 | print(f" {field.name:22}: {option_text}") 25 | else: 26 | print(f" {field.name:22}: {field_value}") -------------------------------------------------------------------------------- /examples/evalboards/MAX22216/datalogger_check.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2025 Analog Devices Inc. All Rights Reserved. 3 | # This software is proprietary to Analog Devices, Inc. and its licensors. 4 | ################################################################################ 5 | 6 | from pytrinamic.connections import ConnectionManager 7 | from pytrinamic.ic import MAX22216 8 | from pytrinamic.evalboards import MAX22216_eval 9 | from pytrinamic.datalogger import DataLogger 10 | 11 | 12 | with ConnectionManager().connect() as my_interface: 13 | 14 | eval = MAX22216_eval(my_interface) 15 | 16 | dl = DataLogger(my_interface) 17 | 18 | eval.write_register_field(MAX22216.FIELD.ACTIVE, 1) 19 | 20 | dl.config.samples_per_channel = 10 21 | dl.config.log_data = { 22 | "ADC_VM_MEASUREMENT": dl.DataTypeRegister(block=0, channel=1, address=MAX22216.REG.ADC_VM_MEASUREMENT), 23 | } 24 | 25 | dl.start_capture() 26 | 27 | dl.wait_for_capture_completion() 28 | 29 | dl.download_log() 30 | 31 | print(dl.log.data["ADC_VM_MEASUREMENT"].samples) 32 | -------------------------------------------------------------------------------- /examples/evalboards/MAX22216/plunger_move.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG 3 | # (now owned by Analog Devices Inc.), 4 | # 5 | # Copyright © 2023 Analog Devices Inc. All Rights Reserved. 6 | # This software is proprietary to Analog Devices, Inc. and its licensors. 7 | ################################################################################ 8 | 9 | import logging 10 | import time 11 | 12 | import pytrinamic 13 | from pytrinamic.connections import ConnectionManager 14 | from pytrinamic.ic import MAX22216 15 | from pytrinamic.evalboards import MAX22216_eval 16 | 17 | 18 | logging.basicConfig(level=logging.DEBUG) 19 | 20 | pytrinamic.show_info() 21 | 22 | with ConnectionManager().connect() as my_interface: 23 | print(my_interface) 24 | 25 | eval = MAX22216_eval(my_interface) 26 | ic = eval.ics[0] 27 | solenoid = ic.motors[0] 28 | 29 | solenoid.u_supply = 24.0 # V 30 | 31 | solenoid.u_dc_h = 10.0 # V 32 | solenoid.u_dc_l = 0.0 # V 33 | solenoid.u_dc_l2h = 10.0 # V 34 | solenoid.u_dc_h2l = 0.0 # V 35 | solenoid.u_ac = 1.0 # V ampl 36 | solenoid.f_ac = 50.0 # Hz 37 | 38 | solenoid.set_high() 39 | time.sleep(1.0) 40 | solenoid.set_low() 41 | time.sleep(1.0) 42 | 43 | 44 | print("\nDone.") -------------------------------------------------------------------------------- /examples/evalboards/MAX22216/ramdebug.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG 3 | # (now owned by Analog Devices Inc.), 4 | # 5 | # Copyright © 2023 Analog Devices Inc. All Rights Reserved. 6 | # This software is proprietary to Analog Devices, Inc. and its licensors. 7 | ################################################################################ 8 | 9 | import logging 10 | 11 | import pytrinamic 12 | from pytrinamic.connections import ConnectionManager 13 | from pytrinamic.ic import MAX22216 14 | from pytrinamic.RAMDebug import Channel, RAMDebug, RAMDebug_Trigger 15 | 16 | logging.basicConfig(level=logging.DEBUG) 17 | pytrinamic.show_info() 18 | 19 | with ConnectionManager().connect() as my_interface: 20 | print(my_interface) 21 | 22 | ch = Channel.field(0, MAX22216.FIELD.ADC_VM_RAW, signed=True, eval_channel=1) 23 | trigger = Channel.field(0, MAX22216.FIELD.ADC_VM_RAW, signed=True, eval_channel=1) 24 | 25 | debug = RAMDebug(my_interface) 26 | debug.set_channel(ch) 27 | debug.set_trigger_type(RAMDebug_Trigger.TRIGGER_UNCONDITIONAL) 28 | debug.set_trigger_threshold(50) 29 | debug.start_measurement() 30 | 31 | while not debug.is_measurement_done(): 32 | pass 33 | 34 | samples = debug.get_samples() 35 | 36 | print("\nDone.") 37 | -------------------------------------------------------------------------------- /examples/evalboards/TMC2100/register_dump.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG 3 | # (now owned by Analog Devices Inc.), 4 | # 5 | # Copyright © 2023 Analog Devices Inc. All Rights Reserved. 6 | # This software is proprietary to Analog Devices, Inc. and its licensors. 7 | ################################################################################ 8 | 9 | """ 10 | Dump all register values of the TMC2100 IC. 11 | 12 | The connection to a Landungsbrücke is established over USB. TMCL commands are used for communicating with the IC. 13 | """ 14 | import pytrinamic 15 | from pytrinamic.connections import ConnectionManager 16 | from pytrinamic.evalboards import TMC2100_eval 17 | 18 | pytrinamic.show_info() 19 | 20 | my_interface = ConnectionManager().connect() 21 | print(my_interface) 22 | 23 | eval_board = TMC2100_eval(my_interface) 24 | drv = eval_board.ics[0] 25 | print("Driver info: " + str(drv.get_info())) 26 | print("Register dump for " + str(drv.get_name()) + ":") 27 | 28 | print("GCONF: 0x{0:08X}".format(eval_board.read_register(drv.REG.GCONF))) 29 | 30 | my_interface.close() 31 | 32 | print("\nReady.") 33 | -------------------------------------------------------------------------------- /examples/evalboards/TMC2100/rotate_demo.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG 3 | # (now owned by Analog Devices Inc.), 4 | # 5 | # Copyright © 2023 Analog Devices Inc. All Rights Reserved. 6 | # This software is proprietary to Analog Devices, Inc. and its licensors. 7 | ################################################################################ 8 | 9 | """ 10 | Move a motor back and forth using velocity and position mode of the TMC2100. 11 | """ 12 | import time 13 | import pytrinamic 14 | from pytrinamic.connections import ConnectionManager 15 | from pytrinamic.evalboards import TMC2100_eval 16 | 17 | pytrinamic.show_info() 18 | 19 | with ConnectionManager().connect() as my_interface: 20 | print(my_interface) 21 | 22 | # Create TMC2100-EVAL class which communicates over the Landungsbrücke via TMCL 23 | eval_board = TMC2100_eval(my_interface) 24 | motor = eval_board.motors[0] 25 | 26 | print("Rotating...") 27 | motor.rotate(1*25600) 28 | time.sleep(2) 29 | 30 | print("Stopping...") 31 | motor.stop() 32 | time.sleep(1) 33 | 34 | print("Moving back to 0...") 35 | motor.move_to(0, 10000) 36 | 37 | # Wait until position 0 is reached 38 | while motor.actual_position != 0: 39 | print("Actual position: " + str(motor.actual_position)) 40 | time.sleep(0.2) 41 | 42 | print("Reached position 0") 43 | 44 | print("\nReady.") 45 | -------------------------------------------------------------------------------- /examples/evalboards/TMC2130/rotate_demo.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG 3 | # (now owned by Analog Devices Inc.), 4 | # 5 | # Copyright © 2023 Analog Devices Inc. All Rights Reserved. 6 | # This software is proprietary to Analog Devices, Inc. and its licensors. 7 | ################################################################################ 8 | 9 | """ 10 | Move a motor back and forth using velocity and position mode of the TMC2130. 11 | """ 12 | import time 13 | import pytrinamic 14 | from pytrinamic.connections import ConnectionManager 15 | from pytrinamic.evalboards import TMC2130_eval 16 | 17 | pytrinamic.show_info() 18 | 19 | with ConnectionManager().connect() as my_interface: 20 | print(my_interface) 21 | 22 | # Create TMC2209-EVAL class which communicates over the Landungsbrücke via TMCL 23 | eval_board = TMC2130_eval(my_interface) 24 | motor = eval_board.motors[0] 25 | 26 | print("Rotating...") 27 | motor.rotate(10*25600) 28 | time.sleep(5) 29 | 30 | print("Stopping...") 31 | motor.stop() 32 | time.sleep(1) 33 | 34 | print("Moving back to 0...") 35 | motor.move_to(0, 200000) 36 | 37 | # Wait until position 0 is reached 38 | while motor.actual_position != 0: 39 | print("Actual position: " + str(motor.actual_position)) 40 | time.sleep(0.2) 41 | 42 | print("Reached position 0") 43 | 44 | print("\nReady.") 45 | -------------------------------------------------------------------------------- /examples/evalboards/TMC2160/rotate_demo.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG 3 | # (now owned by Analog Devices Inc.), 4 | # 5 | # Copyright © 2023 Analog Devices Inc. All Rights Reserved. 6 | # This software is proprietary to Analog Devices, Inc. and its licensors. 7 | ################################################################################ 8 | 9 | """ 10 | Move a motor back and forth using velocity and position mode of the TMC2160 11 | """ 12 | import time 13 | import pytrinamic 14 | from pytrinamic.connections import ConnectionManager 15 | from pytrinamic.evalboards import TMC2160_eval 16 | 17 | pytrinamic.show_info() 18 | 19 | with ConnectionManager().connect() as my_interface: 20 | print(my_interface) 21 | 22 | # Create TMC2160-EVAL class which communicates over the Landungsbrücke via TMCL 23 | eval_board = TMC2160_eval(my_interface) 24 | motor = eval_board.motors[0] 25 | 26 | print("Rotating...") 27 | motor.rotate(10*25600) 28 | time.sleep(5) 29 | 30 | print("Stopping...") 31 | motor.stop() 32 | time.sleep(1) 33 | 34 | print("Moving back to 0...") 35 | motor.move_to(0, 200000) 36 | 37 | # Wait until position 0 is reached 38 | while motor.actual_position != 0: 39 | print("Actual position: " + str(motor.actual_position)) 40 | time.sleep(0.2) 41 | 42 | print("Reached position 0") 43 | 44 | print("\nReady.") 45 | -------------------------------------------------------------------------------- /examples/evalboards/TMC2208/register_dump.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG 3 | # (now owned by Analog Devices Inc.), 4 | # 5 | # Copyright © 2023 Analog Devices Inc. All Rights Reserved. 6 | # This software is proprietary to Analog Devices, Inc. and its licensors. 7 | ################################################################################ 8 | 9 | """ 10 | Dump all register values of the drv IC. 11 | 12 | The connection to a Landungsbrücke is established over USB. TMCL commands are used for communicating with the IC. 13 | """ 14 | 15 | import pytrinamic 16 | from pytrinamic.connections import ConnectionManager 17 | from pytrinamic.evalboards import TMC2208_eval 18 | 19 | pytrinamic.show_info() 20 | 21 | my_interface = ConnectionManager().connect() 22 | print(my_interface) 23 | eval_board = TMC2208_eval(my_interface) 24 | drv = eval_board.ics[0] 25 | 26 | print("Driver info: " + str(drv.get_info())) 27 | print("Register dump for " + str(drv.get_name()) + ":") 28 | 29 | print("GCONF: 0x{0:08X}".format(eval_board.read_register(drv.REG.GCONF))) 30 | print("GSTAT: 0x{0:08X}".format(eval_board.read_register(drv.REG.GSTAT))) 31 | print("IFCNT: 0x{0:08X}".format(eval_board.read_register(drv.REG.IFCNT))) 32 | print("SLAVECONF: 0x{0:08X}".format(eval_board.read_register(drv.REG.SLAVECONF))) 33 | print("IHOLD_IRUN: 0x{0:08X}".format(eval_board.read_register(drv.REG.IHOLD_IRUN))) 34 | print("TPOWERDOWN: 0x{0:08X}".format(eval_board.read_register(drv.REG.TPOWERDOWN))) 35 | print("TSTEP: 0x{0:08X}".format(eval_board.read_register(drv.REG.TSTEP))) 36 | print("TPWMTHRS: 0x{0:08X}".format(eval_board.read_register(drv.REG.TPWMTHRS))) 37 | print("MSCNT: 0x{0:08X}".format(eval_board.read_register(drv.REG.MSCNT))) 38 | print("MSCURACT: 0x{0:08X}".format(eval_board.read_register(drv.REG.MSCURACT))) 39 | print("CHOPCONF: 0x{0:08X}".format(eval_board.read_register(drv.REG.CHOPCONF))) 40 | print("DRVSTATUS: 0x{0:08X}".format(eval_board.read_register(drv.REG.DRV_STATUS))) 41 | print("PWMCONF: 0x{0:08X}".format(eval_board.read_register(drv.REG.PWMCONF))) 42 | print("PWM_SCALE: 0x{0:08X}".format(eval_board.read_register(drv.REG.PWM_SCALE))) 43 | print("PWM_AUTO: 0x{0:08X}".format(eval_board.read_register(drv.REG.PWM_AUTO))) 44 | 45 | my_interface.close() 46 | -------------------------------------------------------------------------------- /examples/evalboards/TMC2208/rotate_demo.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG 3 | # (now owned by Analog Devices Inc.), 4 | # 5 | # Copyright © 2023 Analog Devices Inc. All Rights Reserved. 6 | # This software is proprietary to Analog Devices, Inc. and its licensors. 7 | ################################################################################ 8 | 9 | import time 10 | import pytrinamic 11 | from pytrinamic.connections import ConnectionManager 12 | from pytrinamic.evalboards import TMC2208_eval 13 | 14 | pytrinamic.show_info() 15 | 16 | with ConnectionManager().connect() as my_interface: 17 | print(my_interface) 18 | 19 | # Create TMC2209-EVAL class which communicates over the Landungsbrücke via TMCL 20 | eval_board = TMC2208_eval(my_interface) 21 | motor = eval_board.motors[0] 22 | 23 | print("Rotating...") 24 | motor.rotate(1*4000) 25 | time.sleep(2) 26 | 27 | print("Stopping...") 28 | motor.stop() 29 | time.sleep(1) 30 | 31 | print("Moving back to 0") 32 | motor.move_to(0, 2000) 33 | 34 | # Wait until position 0 is reached 35 | while motor.actual_position != 0: 36 | print("Actual position: " + str(motor.actual_position)) 37 | time.sleep(0.2) 38 | 39 | print("Reached position 0") 40 | 41 | print("\nReady.") 42 | -------------------------------------------------------------------------------- /examples/evalboards/TMC2209/rotate_demo.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG 3 | # (now owned by Analog Devices Inc.), 4 | # 5 | # Copyright © 2023 Analog Devices Inc. All Rights Reserved. 6 | # This software is proprietary to Analog Devices, Inc. and its licensors. 7 | ################################################################################ 8 | 9 | import time 10 | import pytrinamic 11 | from pytrinamic.connections import ConnectionManager 12 | from pytrinamic.evalboards import TMC2209_eval 13 | 14 | pytrinamic.show_info() 15 | 16 | with ConnectionManager().connect() as my_interface: 17 | print(my_interface) 18 | 19 | # Create TMC2209-EVAL class which communicates over the Landungsbrücke via TMCL 20 | eval_board = TMC2209_eval(my_interface) 21 | motor = eval_board.motors[0] 22 | mc = eval_board.ics[0] 23 | 24 | # Setting acceleration in ramp parameters 25 | motor.set_axis_parameter(motor.AP.MaxAcceleration, 100000) 26 | 27 | print("Rotating...") 28 | motor.rotate(1*4000) 29 | time.sleep(2) 30 | 31 | print("Stopping...") 32 | motor.stop() 33 | time.sleep(1) 34 | 35 | print("Moving back to 0") 36 | motor.move_to(0, 4000) 37 | 38 | # Wait until position 0 is reached 39 | while motor.actual_position != 0: 40 | print("Actual position: " + str(motor.actual_position)) 41 | time.sleep(0.2) 42 | 43 | print("Reached position 0") 44 | 45 | print("\nReady.") 46 | -------------------------------------------------------------------------------- /examples/evalboards/TMC2224/register_dump.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG 3 | # (now owned by Analog Devices Inc.), 4 | # 5 | # Copyright © 2023 Analog Devices Inc. All Rights Reserved. 6 | # This software is proprietary to Analog Devices, Inc. and its licensors. 7 | ################################################################################ 8 | 9 | """ 10 | Dump all register values of the TMC2224 IC. 11 | 12 | The connection to a Landungsbrücke is established over USB. TMCL commands are used for communicating with the IC. 13 | """ 14 | import pytrinamic 15 | from pytrinamic.connections import ConnectionManager 16 | from pytrinamic.evalboards import TMC2224_eval 17 | 18 | pytrinamic.show_info() 19 | 20 | my_interface = ConnectionManager().connect() 21 | print(my_interface) 22 | 23 | eval_board = TMC2224_eval(my_interface) 24 | drv = eval_board.ics[0] 25 | print("Driver info: " + str(drv.get_info())) 26 | print("Register dump for " + str(drv.get_name()) + ":") 27 | 28 | print("GCONF: 0x{0:08X}".format(eval_board.read_register(drv.REG.GCONF))) 29 | print("GSTAT: 0x{0:08X}".format(eval_board.read_register(drv.REG.GSTAT))) 30 | print("IFCNT: 0x{0:08X}".format(eval_board.read_register(drv.REG.IFCNT))) 31 | print("SLAVECONF: 0x{0:08X}".format(eval_board.read_register(drv.REG.SLAVECONF))) 32 | print("IHOLD_IRUN: 0x{0:08X}".format(eval_board.read_register(drv.REG.IHOLD_IRUN))) 33 | print("TPOWERDOWN: 0x{0:08X}".format(eval_board.read_register(drv.REG.TPOWERDOWN))) 34 | print("TSTEP: 0x{0:08X}".format(eval_board.read_register(drv.REG.TSTEP))) 35 | print("TPWMTHRS: 0x{0:08X}".format(eval_board.read_register(drv.REG.TPWMTHRS))) 36 | print("MSCNT: 0x{0:08X}".format(eval_board.read_register(drv.REG.MSCNT))) 37 | print("MSCURACT: 0x{0:08X}".format(eval_board.read_register(drv.REG.MSCURACT))) 38 | print("CHOPCONF: 0x{0:08X}".format(eval_board.read_register(drv.REG.CHOPCONF))) 39 | print("DRV_STATUS: 0x{0:08X}".format(eval_board.read_register(drv.REG.DRV_STATUS))) 40 | print("PWM_CONF: 0x{0:08X}".format(eval_board.read_register(drv.REG.PWM_CONF))) 41 | print("PWM_SCALE: 0x{0:08X}".format(eval_board.read_register(drv.REG.PWM_SCALE))) 42 | print("PWM_AUTO: 0x{0:08X}".format(eval_board.read_register(drv.REG.PWM_AUTO))) 43 | 44 | my_interface.close() 45 | 46 | print("\nReady.") 47 | -------------------------------------------------------------------------------- /examples/evalboards/TMC2224/rotate_demo.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG 3 | # (now owned by Analog Devices Inc.), 4 | # 5 | # Copyright © 2023 Analog Devices Inc. All Rights Reserved. 6 | # This software is proprietary to Analog Devices, Inc. and its licensors. 7 | ################################################################################ 8 | 9 | """ 10 | Move a motor back and forth using velocity and position mode of the TMC2224. 11 | """ 12 | import time 13 | import pytrinamic 14 | from pytrinamic.connections import ConnectionManager 15 | from pytrinamic.evalboards import TMC2224_eval 16 | 17 | pytrinamic.show_info() 18 | 19 | with ConnectionManager().connect() as my_interface: 20 | print(my_interface) 21 | 22 | # Create TMC2224-EVAL class which communicates over the Landungsbrücke via TMCL 23 | eval_board = TMC2224_eval(my_interface) 24 | motor = eval_board.motors[0] 25 | 26 | print("Rotating...") 27 | motor.rotate(1*11000) 28 | time.sleep(2) 29 | 30 | print("Stopping...") 31 | motor.stop() 32 | time.sleep(3) 33 | 34 | print("Moving back to 0...") 35 | motor.move_to(0, 10000) 36 | 37 | # Wait until position 0 is reached 38 | while motor.actual_position != 0: 39 | print("Actual position: " + str(motor.actual_position)) 40 | time.sleep(0.2) 41 | 42 | print("Reached position 0") 43 | 44 | print("\nReady.") 45 | -------------------------------------------------------------------------------- /examples/evalboards/TMC2225/register_dump.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG 3 | # (now owned by Analog Devices Inc.), 4 | # 5 | # Copyright © 2023 Analog Devices Inc. All Rights Reserved. 6 | # This software is proprietary to Analog Devices, Inc. and its licensors. 7 | ################################################################################ 8 | 9 | """ 10 | Dump all register values of the TMC2225 IC. 11 | 12 | The connection to a Landungsbrücke is established over USB. TMCL commands are used for communicating with the IC. 13 | """ 14 | import pytrinamic 15 | from pytrinamic.connections import ConnectionManager 16 | from pytrinamic.evalboards import TMC2225_eval 17 | 18 | pytrinamic.show_info() 19 | 20 | my_interface = ConnectionManager().connect() 21 | print(my_interface) 22 | 23 | eval_board = TMC2225_eval(my_interface) 24 | drv = eval_board.ics[0] 25 | print("Driver info: " + str(drv.get_info())) 26 | print("Register dump for " + str(drv.get_name()) + ":") 27 | 28 | print("GCONF: 0x{0:08X}".format(eval_board.read_register(drv.REG.GCONF))) 29 | print("GSTAT: 0x{0:08X}".format(eval_board.read_register(drv.REG.GSTAT))) 30 | print("IFCNT: 0x{0:08X}".format(eval_board.read_register(drv.REG.IFCNT))) 31 | print("SLAVECONF: 0x{0:08X}".format(eval_board.read_register(drv.REG.SLAVECONF))) 32 | print("IHOLD_IRUN: 0x{0:08X}".format(eval_board.read_register(drv.REG.IHOLD_IRUN))) 33 | print("TPOWERDOWN: 0x{0:08X}".format(eval_board.read_register(drv.REG.TPOWERDOWN))) 34 | print("TSTEP: 0x{0:08X}".format(eval_board.read_register(drv.REG.TSTEP))) 35 | print("TPWMTHRS: 0x{0:08X}".format(eval_board.read_register(drv.REG.TPWMTHRS))) 36 | print("MSCNT: 0x{0:08X}".format(eval_board.read_register(drv.REG.MSCNT))) 37 | print("MSCURACT: 0x{0:08X}".format(eval_board.read_register(drv.REG.MSCURACT))) 38 | print("CHOPCONF: 0x{0:08X}".format(eval_board.read_register(drv.REG.CHOPCONF))) 39 | print("DRV_STATUS: 0x{0:08X}".format(eval_board.read_register(drv.REG.DRV_STATUS))) 40 | print("PWM_CONF: 0x{0:08X}".format(eval_board.read_register(drv.REG.PWM_CONF))) 41 | print("PWM_SCALE: 0x{0:08X}".format(eval_board.read_register(drv.REG.PWM_SCALE))) 42 | print("PWM_AUTO: 0x{0:08X}".format(eval_board.read_register(drv.REG.PWM_AUTO))) 43 | 44 | my_interface.close() 45 | 46 | print("\nReady.") 47 | -------------------------------------------------------------------------------- /examples/evalboards/TMC2225/rotate_demo.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG 3 | # (now owned by Analog Devices Inc.), 4 | # 5 | # Copyright © 2023 Analog Devices Inc. All Rights Reserved. 6 | # This software is proprietary to Analog Devices, Inc. and its licensors. 7 | ################################################################################ 8 | 9 | """ 10 | Move a motor back and forth using velocity and position mode of the TMC2225. 11 | """ 12 | import time 13 | import pytrinamic 14 | from pytrinamic.connections import ConnectionManager 15 | from pytrinamic.evalboards import TMC2225_eval 16 | 17 | pytrinamic.show_info() 18 | 19 | with ConnectionManager().connect() as my_interface: 20 | print(my_interface) 21 | 22 | # Create TMC2225-EVAL class which communicates over the Landungsbrücke via TMCL 23 | eval_board = TMC2225_eval(my_interface) 24 | motor = eval_board.motors[0] 25 | 26 | print("Rotating...") 27 | motor.rotate(1*27000) 28 | time.sleep(2) 29 | 30 | print("Stopping...") 31 | motor.stop() 32 | time.sleep(1) 33 | 34 | print("Moving back to 0...") 35 | motor.move_to(0, 10000) 36 | 37 | # Wait until position 0 is reached 38 | while motor.actual_position != 0: 39 | print("Actual position: " + str(motor.actual_position)) 40 | time.sleep(0.2) 41 | 42 | print("Reached position 0") 43 | 44 | print("\nReady.") 45 | -------------------------------------------------------------------------------- /examples/evalboards/TMC2240/rotate_demo.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG 3 | # (now owned by Analog Devices Inc.), 4 | # 5 | # Copyright © 2023 Analog Devices Inc. All Rights Reserved. 6 | # This software is proprietary to Analog Devices, Inc. and its licensors. 7 | ################################################################################ 8 | 9 | """ 10 | Move a motor back and forth using velocity and position mode of the TMC2240 11 | """ 12 | import time 13 | import pytrinamic 14 | from pytrinamic.connections import ConnectionManager 15 | from pytrinamic.evalboards import TMC2240_eval 16 | 17 | pytrinamic.show_info() 18 | 19 | with ConnectionManager().connect() as my_interface: 20 | print(my_interface) 21 | 22 | # Create TMC2240-EVAL class which communicates over the Landungsbrücke via TMCL 23 | eval_board = TMC2240_eval(my_interface) 24 | mc = eval_board.ics[0] 25 | motor = eval_board.motors[0] 26 | 27 | print("Preparing parameter...") 28 | motor.set_axis_parameter(motor.AP.MaxAcceleration, 20000) 29 | motor.set_axis_parameter(motor.AP.MaxVelocity, 100000) 30 | motor.set_axis_parameter(motor.AP.MaxCurrent, 30) 31 | 32 | # Clear actual positions 33 | motor.actual_position = 0 34 | 35 | print("Rotating...") 36 | motor.rotate(7*25600) 37 | time.sleep(5) 38 | 39 | print("Stopping...") 40 | motor.stop() 41 | time.sleep(1) 42 | 43 | print("Moving back to 0...") 44 | motor.move_to(0, 100000) 45 | 46 | # Wait until position 0 is reached 47 | while motor.actual_position != 0: 48 | print("Actual position: " + str(motor.actual_position)) 49 | time.sleep(0.2) 50 | 51 | print("Reached position 0") 52 | 53 | print("\nReady.") 54 | -------------------------------------------------------------------------------- /examples/evalboards/TMC2300/register_dump.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG 3 | # (now owned by Analog Devices Inc.), 4 | # 5 | # Copyright © 2023 Analog Devices Inc. All Rights Reserved. 6 | # This software is proprietary to Analog Devices, Inc. and its licensors. 7 | ################################################################################ 8 | 9 | """ 10 | Dump all register values of the TMC2300 IC. 11 | 12 | The connection to a Landungsbrücke is established over USB. TMCL commands are used for communicating with the IC. 13 | """ 14 | import pytrinamic 15 | from pytrinamic.connections import ConnectionManager 16 | from pytrinamic.evalboards import TMC2300_eval 17 | 18 | pytrinamic.show_info() 19 | 20 | my_interface = ConnectionManager().connect() 21 | print(my_interface) 22 | 23 | eval_board = TMC2300_eval(my_interface) 24 | drv = eval_board.ics[0] 25 | print("Driver info: " + str(drv.get_info())) 26 | print("Register dump for " + str(drv.get_name()) + ":") 27 | 28 | print("GCONF: 0x{0:08X}".format(eval_board.read_register(drv.REG.GCONF))) 29 | print("GSTAT: 0x{0:08X}".format(eval_board.read_register(drv.REG.GSTAT))) 30 | print("IFCNT: 0x{0:08X}".format(eval_board.read_register(drv.REG.IFCNT))) 31 | print("SLAVECONF: 0x{0:08X}".format(eval_board.read_register(drv.REG.SLAVECONF))) 32 | print("IHOLD_IRUN: 0x{0:08X}".format(eval_board.read_register(drv.REG.IHOLD_IRUN))) 33 | print("TPOWERDOWN: 0x{0:08X}".format(eval_board.read_register(drv.REG.TPOWERDOWN))) 34 | print("TSTEP: 0x{0:08X}".format(eval_board.read_register(drv.REG.TSTEP))) 35 | print("TCOOLTHRS: 0x{0:08X}".format(eval_board.read_register(drv.REG.TCOOLTHRS))) 36 | print("MSCNT: 0x{0:08X}".format(eval_board.read_register(drv.REG.MSCNT))) 37 | print("MSCURACT: 0x{0:08X}".format(eval_board.read_register(drv.REG.MSCURACT))) 38 | print("CHOPCONF: 0x{0:08X}".format(eval_board.read_register(drv.REG.CHOPCONF))) 39 | print("DRV_STATUS: 0x{0:08X}".format(eval_board.read_register(drv.REG.DRV_STATUS))) 40 | print("PWM_CONF: 0x{0:08X}".format(eval_board.read_register(drv.REG.PWM_CONF))) 41 | print("PWM_SCALE: 0x{0:08X}".format(eval_board.read_register(drv.REG.PWM_SCALE))) 42 | print("PWM_AUTO: 0x{0:08X}".format(eval_board.read_register(drv.REG.PWM_AUTO))) 43 | 44 | my_interface.close() 45 | 46 | print("\nReady.") 47 | -------------------------------------------------------------------------------- /examples/evalboards/TMC2300/rotate_demo.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG 3 | # (now owned by Analog Devices Inc.), 4 | # 5 | # Copyright © 2023 Analog Devices Inc. All Rights Reserved. 6 | # This software is proprietary to Analog Devices, Inc. and its licensors. 7 | ################################################################################ 8 | 9 | """ 10 | Move a motor back and forth using velocity and position mode of the TMC2300. 11 | """ 12 | import time 13 | import pytrinamic 14 | from pytrinamic.connections import ConnectionManager 15 | from pytrinamic.evalboards import TMC2300_eval 16 | 17 | pytrinamic.show_info() 18 | 19 | with ConnectionManager().connect() as my_interface: 20 | print(my_interface) 21 | 22 | # Create TMC2300-EVAL class which communicates over the Landungsbrücke via TMCL 23 | eval_board = TMC2300_eval(my_interface) 24 | motor = eval_board.motors[0] 25 | 26 | motor.set_ic_standby(0) 27 | motor.set_microstep_resolution(256) 28 | 29 | print("Rotating...") 30 | motor.rotate(10*25600) 31 | time.sleep(2) 32 | 33 | print("Stopping...") 34 | motor.stop() 35 | time.sleep(1) 36 | 37 | print("Moving back to 0...") 38 | motor.move_to(0, 10*25600) 39 | 40 | # Wait until position 0 is reached 41 | while motor.actual_position != 0: 42 | print("Actual position: " + str(motor.actual_position)) 43 | time.sleep(0.2) 44 | 45 | print("Reached position 0") 46 | 47 | print("\nReady.") 48 | -------------------------------------------------------------------------------- /examples/evalboards/TMC2590/register_dump.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG 3 | # (now owned by Analog Devices Inc.), 4 | # 5 | # Copyright © 2023 Analog Devices Inc. All Rights Reserved. 6 | # This software is proprietary to Analog Devices, Inc. and its licensors. 7 | ################################################################################ 8 | 9 | """ 10 | Dump all register values of the TMC2590 IC. 11 | 12 | The connection to a Landungsbrücke is established over USB. TMCL commands are used for communicating with the IC. 13 | """ 14 | import pytrinamic 15 | from pytrinamic.connections import ConnectionManager 16 | from pytrinamic.evalboards import TMC2590_eval 17 | 18 | pytrinamic.show_info() 19 | 20 | with ConnectionManager().connect() as my_interface: 21 | print(my_interface) 22 | 23 | # Create TMC2590-EVAL class which communicates over the Landungsbrücke via TMCL 24 | eval_board = TMC2590_eval(my_interface) 25 | drv = eval_board.ics[0] 26 | print("Driver info: " + str(drv.get_info())) 27 | print("Register dump for " + str(drv.get_name()) + ":") 28 | 29 | print("DRVSTATUS___MSTEP: 0x{0:08X}".format(eval_board.read_register(drv.REG.DRVSTATUS___MSTEP))) 30 | print("DRVSTATUS___SG: 0x{0:08X}".format(eval_board.read_register(drv.REG.DRVSTATUS___SG))) 31 | print("DRVSTATUS___SG_SE: 0x{0:08X}".format(eval_board.read_register(drv.REG.DRVSTATUS___SG_SE))) 32 | print("DRVCTRL: 0x{0:08X}".format(eval_board.read_register(drv.REG.DRVCTRL))) 33 | print("CHOPCONF: 0x{0:08X}".format(eval_board.read_register(drv.REG.CHOPCONF))) 34 | print("SMARTEN: 0x{0:08X}".format(eval_board.read_register(drv.REG.SMARTEN))) 35 | print("SGCSCONF: 0x{0:08X}".format(eval_board.read_register(drv.REG.SGCSCONF))) 36 | print("DRVCONF: 0x{0:08X}".format(eval_board.read_register(drv.REG.DRVCONF))) 37 | 38 | print("\nReady.") 39 | -------------------------------------------------------------------------------- /examples/evalboards/TMC2590/rotate_demo.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG 3 | # (now owned by Analog Devices Inc.), 4 | # 5 | # Copyright © 2023 Analog Devices Inc. All Rights Reserved. 6 | # This software is proprietary to Analog Devices, Inc. and its licensors. 7 | ################################################################################ 8 | 9 | """ 10 | Move a motor back and forth using velocity and position mode of the TMC2590. 11 | """ 12 | import time 13 | import pytrinamic 14 | from pytrinamic.connections import ConnectionManager 15 | from pytrinamic.evalboards import TMC2590_eval 16 | 17 | pytrinamic.show_info() 18 | 19 | with ConnectionManager().connect() as my_interface: 20 | print(my_interface) 21 | 22 | # Create TMC2590-EVAL class which communicates over the Landungsbrücke via TMCL 23 | eval_board = TMC2590_eval(my_interface) 24 | motor = eval_board.motors[0] 25 | 26 | print("Rotating...") 27 | motor.rotate(10*25600) 28 | time.sleep(2) 29 | 30 | print("Stopping...") 31 | motor.stop() 32 | time.sleep(1) 33 | 34 | print("Moving back to 0...") 35 | motor.move_to(0, 10*25600) 36 | 37 | # Wait until position 0 is reached 38 | while motor.actual_position != 0: 39 | print("Actual position: " + str(motor.actual_position)) 40 | time.sleep(0.2) 41 | 42 | print("Reached position 0") 43 | 44 | print("\nReady.") 45 | -------------------------------------------------------------------------------- /examples/evalboards/TMC2660/register_dump.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG 3 | # (now owned by Analog Devices Inc.), 4 | # 5 | # Copyright © 2023 Analog Devices Inc. All Rights Reserved. 6 | # This software is proprietary to Analog Devices, Inc. and its licensors. 7 | ################################################################################ 8 | 9 | """ 10 | Dump all register values of the TMC2660 IC. 11 | 12 | The connection to a Landungsbrücke is established over USB. TMCL commands are used for communicating with the IC. 13 | """ 14 | import pytrinamic 15 | from pytrinamic.connections import ConnectionManager 16 | from pytrinamic.evalboards import TMC2660_eval 17 | 18 | pytrinamic.show_info() 19 | 20 | my_interface = ConnectionManager().connect() 21 | print(my_interface) 22 | 23 | eval_board = TMC2660_eval(my_interface) 24 | drv = eval_board.ics[0] 25 | print("Driver info: " + str(drv.get_info())) 26 | print("Register dump for " + str(drv.get_name()) + ":") 27 | 28 | print("DRVSTATUS_MSTEP: 0x{0:08X}".format(eval_board.read_register(drv.REG.DRVSTATUS_MSTEP))) 29 | print("DRVSTATUS_SG: 0x{0:08X}".format(eval_board.read_register(drv.REG.DRVSTATUS_SG))) 30 | print("DRVSTATUS_SG_SE: 0x{0:08X}".format(eval_board.read_register(drv.REG.DRVSTATUS_SG_SE))) 31 | print("DRVCTRL: 0x{0:08X}".format(eval_board.read_register(drv.REG.DRVCTRL))) 32 | print("CHOPCONF: 0x{0:08X}".format(eval_board.read_register(drv.REG.CHOPCONF))) 33 | print("SMARTEN: 0x{0:08X}".format(eval_board.read_register(drv.REG.SMARTEN))) 34 | print("SGCSCONF: 0x{0:08X}".format(eval_board.read_register(drv.REG.SGCSCONF))) 35 | print("DRVCONF: 0x{0:08X}".format(eval_board.read_register(drv.REG.DRVCONF))) 36 | 37 | my_interface.close() 38 | 39 | print("\nReady.") 40 | -------------------------------------------------------------------------------- /examples/evalboards/TMC2660/rotate_demo.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG 3 | # (now owned by Analog Devices Inc.), 4 | # 5 | # Copyright © 2023 Analog Devices Inc. All Rights Reserved. 6 | # This software is proprietary to Analog Devices, Inc. and its licensors. 7 | ################################################################################ 8 | 9 | """ 10 | Move a motor back and forth using velocity and position mode of the TMC2660. 11 | """ 12 | import time 13 | import pytrinamic 14 | from pytrinamic.connections import ConnectionManager 15 | from pytrinamic.evalboards import TMC2660_eval 16 | 17 | pytrinamic.show_info() 18 | 19 | with ConnectionManager().connect() as my_interface: 20 | print(my_interface) 21 | 22 | # Create TMC2660-EVAL class which communicates over the Landungsbrücke via TMCL 23 | eval_board = TMC2660_eval(my_interface) 24 | motor = eval_board.motors[0] 25 | 26 | print("Rotating...") 27 | motor.rotate(51200) 28 | time.sleep(2) 29 | 30 | print("Stopping...") 31 | motor.stop() 32 | time.sleep(1) 33 | 34 | print("Moving back to 0...") 35 | motor.move_to(0, 10*25600) 36 | 37 | # Wait until position 0 is reached 38 | while motor.actual_position != 0: 39 | print("Actual position: " + str(motor.actual_position)) 40 | time.sleep(0.2) 41 | 42 | print("Reached position 0") 43 | 44 | print("\nReady.") 45 | -------------------------------------------------------------------------------- /examples/evalboards/TMC4361/TMC4331_eval_TMC2130_eval_rotateDemo.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG 3 | # (now owned by Analog Devices Inc.), 4 | # 5 | # Copyright © 2023 Analog Devices Inc. All Rights Reserved. 6 | # This software is proprietary to Analog Devices, Inc. and its licensors. 7 | ################################################################################ 8 | 9 | import time 10 | 11 | import pytrinamic 12 | from pytrinamic.connections import ConnectionManager 13 | from pytrinamic.evalboards import TMC4361_eval, TMC2130_eval 14 | 15 | pytrinamic.show_info() 16 | 17 | with ConnectionManager().connect() as my_interface: 18 | print(my_interface) 19 | 20 | # Create an TMC4361-Eval class which communicates over the Landungsbruecke via TMCL 21 | eval_mc = TMC4361_eval(my_interface) 22 | motor = eval_mc.motors[0] 23 | mc = eval_mc.ics[0] 24 | print("Motion controller: " + str(mc.get_info())) 25 | 26 | # Create an TMC2130-Eval class which communicates over the Landungsbruecke via TMCL 27 | eval_drv = TMC2130_eval(my_interface) 28 | drv = eval_drv.ics[0] 29 | print("Driver: " + str(drv.get_info())) 30 | 31 | # configure TMC2130 pwm for use with TMC4361 (disable singleline)" 32 | # eval_drv.write_register(drv.REG.DRVCTRL, 0x00) 33 | # eval_drv.write_register(drv.REG.CHOPCONF, 0x0C) 34 | # eval_drv.write_register(drv.REG.SMARTEN, 0x0D) 35 | # eval_drv.write_register(drv.REG.SGCSCONF, 0x0E) 36 | # eval_drv.write_register(drv.REG.DRVCONF, 0x0F) 37 | 38 | motor.set_axis_parameter(motor.AP.MaxVelocity, 1000) 39 | motor.set_axis_parameter(motor.AP.MaxAcceleration, 10000) 40 | 41 | print("Rotating...") 42 | motor.rotate(30 * 25600) 43 | time.sleep(10) 44 | 45 | print("Stopping...") 46 | motor.stop() 47 | time.sleep(1) 48 | 49 | print("Moving back to 0...") 50 | motor.move_to(0, 30 * 25600) 51 | 52 | # Wait until position 0 is reached 53 | while motor.actual_position != 0: 54 | print("Actual position: " + str(motor.actual_position)) 55 | time.sleep(0.2) 56 | 57 | print("Reached position 0") 58 | 59 | 60 | print("\nReady.") 61 | -------------------------------------------------------------------------------- /examples/evalboards/TMC4671/TMC4671_eval_baud_rate_change.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2024 Analog Devices Inc. All Rights Reserved. 3 | # This software is proprietary to Analog Devices, Inc. and its licensors. 4 | ################################################################################ 5 | 6 | import struct 7 | import pytrinamic 8 | from pytrinamic.connections import UartIcInterface 9 | from pytrinamic.ic import TMC4671 10 | 11 | pytrinamic.show_info() 12 | 13 | default_data_rate = 9600 14 | default_baud_rate = 0x00009600 15 | 16 | new_data_rate = 115200 17 | new_baud_rate = 0x00115200 18 | 19 | # new_data_rate = 921600 # not working correctly with pyserial? 20 | # new_baud_rate = 0x00921600 # not working correctly with pyserial? 21 | 22 | # new_data_rate = 3000000 23 | # new_baud_rate = 0x03000000 24 | 25 | # Open connection with standard baud rate 26 | my_interface = UartIcInterface('COM10', datarate=default_data_rate) 27 | 28 | # Read actual baud rate 29 | print("Actual baud rate: \t", hex(my_interface.send(TMC4671.REG.UART_BPS, 0x0).value)) 30 | 31 | # Update baud rate (do not read afterwards) 32 | print("Change baud rate:\t", hex(new_baud_rate)) 33 | my_interface.serial.write(struct.pack(">BI", TMC4671.REG.UART_BPS | 0x80, new_baud_rate)) 34 | 35 | my_interface.close() 36 | 37 | # Open connection with new baud rate 38 | my_interface = UartIcInterface('COM10', datarate=new_data_rate) 39 | mc = TMC4671(my_interface) 40 | 41 | # Read actual baud rate 42 | print("New baud rate: \t\t", hex(my_interface.send(TMC4671.REG.UART_BPS, 0x0).value)) 43 | 44 | # ======================================== 45 | 46 | # >>> put in your code here <<< 47 | 48 | # ======================================== 49 | 50 | # Set baud rate back to default (do not read afterwards) 51 | my_interface.serial.write(struct.pack(">BI", TMC4671.REG.UART_BPS | 0x80, default_baud_rate)) 52 | 53 | my_interface.close() 54 | 55 | print("\nReady.") 56 | -------------------------------------------------------------------------------- /examples/evalboards/TMC4671/TMC4671_eval_datalogger_check.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2024 Analog Devices Inc. All Rights Reserved. 3 | # This software is proprietary to Analog Devices, Inc. and its licensors. 4 | ################################################################################ 5 | 6 | import time 7 | from pytrinamic.connections import ConnectionManager 8 | from pytrinamic.evalboards import TMC4671_eval 9 | from pytrinamic.ic import TMC4671 10 | 11 | 12 | with ConnectionManager().connect() as my_interface: 13 | 14 | mc_eval = TMC4671_eval(my_interface) 15 | 16 | dl = mc_eval.datalogger 17 | 18 | dl.config.samples_per_channel = 10 19 | dl.config.log_data = { 20 | "CHIPINFO_DATA": dl.DataTypeRegister(block=0, channel=0, address=TMC4671.REG.CHIPINFO_DATA), 21 | "ADC_IV": dl.DataTypeField(block=0, channel=0, field=TMC4671.FIELD.ADC_IWY, signed=True), 22 | } 23 | 24 | dl.start_logging() 25 | 26 | while not dl.is_capture_complete(): 27 | time.sleep(0.1) 28 | 29 | dl.download_log() 30 | 31 | print([f"0x{sample:x}" for sample in dl.log.data["CHIPINFO_DATA"].samples]) 32 | print(dl.log.data["ADC_IV"].samples) 33 | -------------------------------------------------------------------------------- /examples/evalboards/TMC4671/TMC4671_eval_datalogger_demo.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2024 Analog Devices Inc. All Rights Reserved. 3 | # This software is proprietary to Analog Devices, Inc. and its licensors. 4 | ################################################################################ 5 | 6 | from pytrinamic.connections import ConnectionManager 7 | from pytrinamic.evalboards import TMC4671_eval 8 | from pytrinamic.ic import TMC4671 9 | 10 | 11 | with ConnectionManager().connect() as my_interface: 12 | 13 | mc_eval = TMC4671_eval(my_interface) 14 | 15 | ################################################################################################ 16 | # Logging begin 17 | 18 | # Get a reference to the eval's DataLogger instance 19 | dl = mc_eval.datalogger 20 | # Configure the data to be logged 21 | dl.config.log_data = { 22 | "actual_velocity": dl.DataTypeRegister(block=0, channel=0, address=TMC4671.REG.PID_VELOCITY_ACTUAL), 23 | "actual_position": dl.DataTypeRegister(block=0, channel=0, address=TMC4671.REG.PID_POSITION_ACTUAL), 24 | } 25 | # Update the logging settings 26 | dl.config.down_sampling_factor = 2 27 | dl.config.samples_per_channel = 128 28 | # Start the logging 29 | dl.start_capture() 30 | # Wait for the logging to finish 31 | dl.wait_for_capture_completion() 32 | print("Logging done.") 33 | # Pull the data from the eval 34 | dl.download_log() 35 | # Access the logged data 36 | actual_velocity_samples = dl.log.data["actual_velocity"].samples 37 | actual_position_samples = dl.log.data["actual_position"].samples 38 | print(f"Actual velocity data: {actual_velocity_samples}") 39 | print(f"Actual position data: {actual_position_samples}") 40 | 41 | # Logging end 42 | ################################################################################################ 43 | -------------------------------------------------------------------------------- /examples/evalboards/TMC5031/rotate_demo.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG 3 | # (now owned by Analog Devices Inc.), 4 | # 5 | # Copyright © 2023 Analog Devices Inc. All Rights Reserved. 6 | # This software is proprietary to Analog Devices, Inc. and its licensors. 7 | ################################################################################ 8 | 9 | """ 10 | Move a motor back and forth using velocity and position mode of the TMC5031 11 | """ 12 | import time 13 | import pytrinamic 14 | from pytrinamic.connections import ConnectionManager 15 | from pytrinamic.evalboards import TMC5031_eval 16 | 17 | pytrinamic.show_info() 18 | 19 | with ConnectionManager().connect() as my_interface: 20 | print(my_interface) 21 | 22 | # Create TMC5062-EVAL class which communicates over the Landungsbrücke via TMCL 23 | eval_board = TMC5031_eval(my_interface) 24 | mc = eval_board.ics[0] 25 | motor0 = eval_board.motors[0] 26 | print(motor0) 27 | motor1 = eval_board.motors[1] 28 | print(motor1) 29 | 30 | for i in range(2): 31 | print("Preparing parameter for motor" + str(i) + "...") 32 | eval_board.write_register(mc.REG.A1[i], 1000) 33 | eval_board.write_register(mc.REG.V1[i], 50000) 34 | eval_board.write_register(mc.REG.D1[i], 500) 35 | eval_board.write_register(mc.REG.DMAX[i], 500) 36 | eval_board.write_register(mc.REG.VSTART[i], 0) 37 | eval_board.write_register(mc.REG.VSTOP[i], 10) 38 | eval_board.write_register(mc.REG.AMAX[i], 1000) 39 | 40 | # Clear actual positions 41 | motor0.actual_position = 0 42 | motor1.actual_position = 0 43 | 44 | print("Rotating...") 45 | motor0.rotate(10 * 25600) 46 | motor1.rotate(-15 * 25600) 47 | time.sleep(3) 48 | 49 | print("Stopping...") 50 | motor0.stop() 51 | motor1.stop() 52 | time.sleep(1) 53 | 54 | print("Moving back to 0...") 55 | motor0.move_to(0, 30000) 56 | motor1.move_to(0, 100000) 57 | 58 | # Wait until position 0 is reached by both motors 59 | while (motor0.actual_position != 0) or (motor1.actual_position != 0): 60 | print("Actual position motor0: " + str(motor0.actual_position) + " " 61 | + "actual position motor1: " + str(motor1.actual_position)) 62 | time.sleep(0.2) 63 | 64 | print("Reached position 0") 65 | 66 | print("\nReady.") 67 | -------------------------------------------------------------------------------- /examples/evalboards/TMC5041/rotate_demo.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG 3 | # (now owned by Analog Devices Inc.), 4 | # 5 | # Copyright © 2023 Analog Devices Inc. All Rights Reserved. 6 | # This software is proprietary to Analog Devices, Inc. and its licensors. 7 | ################################################################################ 8 | 9 | """ 10 | Move a motor back and forth using velocity and position mode of the TMC5041 11 | """ 12 | import time 13 | import pytrinamic 14 | from pytrinamic.connections import ConnectionManager 15 | from pytrinamic.evalboards import TMC5041_eval 16 | 17 | pytrinamic.show_info() 18 | 19 | with ConnectionManager().connect() as my_interface: 20 | print(my_interface) 21 | 22 | # Create TMC5041-EVAL class which communicates over the Landungsbrücke via TMCL 23 | eval_board = TMC5041_eval(my_interface) 24 | mc = eval_board.ics[0] 25 | motor0 = eval_board.motors[0] 26 | print(motor0) 27 | motor1 = eval_board.motors[1] 28 | print(motor1) 29 | 30 | for i in range(2): 31 | print("Preparing parameter for motor" + str(i) + "...") 32 | eval_board.write_register(mc.REG.A1[i], 1000) 33 | eval_board.write_register(mc.REG.V1[i], 50000) 34 | eval_board.write_register(mc.REG.D1[i], 500) 35 | eval_board.write_register(mc.REG.DMAX[i], 500) 36 | eval_board.write_register(mc.REG.VSTART[i], 0) 37 | eval_board.write_register(mc.REG.VSTOP[i], 10) 38 | eval_board.write_register(mc.REG.AMAX[i], 1000) 39 | 40 | # Clear actual positions 41 | motor0.actual_position = 0 42 | motor1.actual_position = 0 43 | 44 | print("Rotating...") 45 | motor0.rotate(10 * 25600) 46 | motor1.rotate(-15 * 25600) 47 | time.sleep(3) 48 | 49 | print("Stopping...") 50 | motor0.stop() 51 | motor1.stop() 52 | time.sleep(1) 53 | 54 | print("Moving back to 0...") 55 | motor0.move_to(0, 30000) 56 | motor1.move_to(0, 100000) 57 | 58 | # Wait until position 0 is reached by both motors 59 | while (motor0.actual_position != 0) or (motor1.actual_position != 0): 60 | print("Actual position motor0: " + str(motor0.actual_position) + " " 61 | + "actual position motor1: " + str(motor1.actual_position)) 62 | time.sleep(0.2) 63 | 64 | print("Reached position 0") 65 | 66 | print("\nReady.") 67 | -------------------------------------------------------------------------------- /examples/evalboards/TMC5062/rotate_demo.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG 3 | # (now owned by Analog Devices Inc.), 4 | # 5 | # Copyright © 2023 Analog Devices Inc. All Rights Reserved. 6 | # This software is proprietary to Analog Devices, Inc. and its licensors. 7 | ################################################################################ 8 | 9 | """ 10 | Move a motor back and forth using velocity and position mode of the TMC5062 11 | """ 12 | import time 13 | import pytrinamic 14 | from pytrinamic.connections import ConnectionManager 15 | from pytrinamic.evalboards import TMC5062_eval 16 | 17 | pytrinamic.show_info() 18 | 19 | with ConnectionManager().connect() as my_interface: 20 | print(my_interface) 21 | 22 | # Create TMC5062-EVAL class which communicates over the Landungsbrücke via TMCL 23 | eval_board = TMC5062_eval(my_interface) 24 | mc = eval_board.ics[0] 25 | motor0 = eval_board.motors[0] 26 | print(motor0) 27 | motor1 = eval_board.motors[1] 28 | print(motor1) 29 | 30 | for i in range(2): 31 | print("Preparing parameter for motor" + str(i) + "...") 32 | eval_board.write_register(mc.REG.A1[i], 1000) 33 | eval_board.write_register(mc.REG.V1[i], 50000) 34 | eval_board.write_register(mc.REG.D1[i], 500) 35 | eval_board.write_register(mc.REG.DMAX[i], 500) 36 | eval_board.write_register(mc.REG.VSTART[i], 0) 37 | eval_board.write_register(mc.REG.VSTOP[i], 10) 38 | eval_board.write_register(mc.REG.AMAX[i], 1000) 39 | 40 | # Clear actual positions 41 | motor0.actual_position = 0 42 | motor1.actual_position = 0 43 | 44 | print("Rotating...") 45 | motor0.rotate(2 * 25600) 46 | motor1.rotate(-4 * 25600) 47 | time.sleep(5) 48 | 49 | print("Stopping...") 50 | motor0.stop() 51 | motor1.stop() 52 | time.sleep(1) 53 | 54 | print("Moving back to 0...") 55 | motor0.move_to(0, 100000) 56 | motor1.move_to(0, 100000) 57 | 58 | # Wait until position 0 is reached by both motors 59 | while (motor0.actual_position != 0) or (motor1.actual_position != 0): 60 | print("Actual position motor0: " + str(motor0.actual_position) + " " 61 | + "actual position motor1: " + str(motor1.actual_position)) 62 | time.sleep(0.2) 63 | 64 | print("Reached position 0") 65 | 66 | print("\nReady.") 67 | -------------------------------------------------------------------------------- /examples/evalboards/TMC5072/stop_switch_R1_AP.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG 3 | # (now owned by Analog Devices Inc.), 4 | # 5 | # Copyright © 2023 Analog Devices Inc. All Rights Reserved. 6 | # This software is proprietary to Analog Devices, Inc. and its licensors. 7 | ################################################################################ 8 | """ 9 | Automatically stops the motor during active (low active) right reference switch input using APs. 10 | """ 11 | 12 | import time 13 | import pytrinamic 14 | from pytrinamic.connections import ConnectionManager 15 | from pytrinamic.evalboards import TMC5072_eval 16 | 17 | pytrinamic.show_info() 18 | 19 | with ConnectionManager().connect() as my_interface: 20 | print(my_interface) 21 | 22 | # Create TMC5072-EVAL class which communicates over the Landungsbrücke via TMCL 23 | eval_board = TMC5072_eval(my_interface) 24 | mc = eval_board.ics[0] 25 | motor0 = eval_board.motors[0] 26 | print(motor0) 27 | 28 | # Preparing parameter for motor 0... 29 | motor0.set_axis_parameter(motor0.AP.MaxVelocity, 100000) 30 | motor0.set_axis_parameter(motor0.AP.MaxAcceleration, 1000) 31 | 32 | # Invert the active polarity of the right reference switch input (low active) and 33 | # Enable the automatic motor stop during active right reference switch input 34 | motor0.set_axis_parameter(motor0.AP.SW_MODE, 0xA) 35 | 36 | print("The motor rotates until left reference switch becomes active") 37 | motor0.rotate(10*25600) 38 | 39 | while motor0.get_axis_parameter(motor0.AP.RightEndstop) != 1: 40 | pass 41 | print("Switch is active!") 42 | while motor0.actual_velocity != 0: 43 | pass 44 | print("Motor stopped!") 45 | # Stop the motor to make sure that it doesn't start rotating again when the switch becomes inactive 46 | motor0.stop() 47 | 48 | print("\nReady.") 49 | -------------------------------------------------------------------------------- /examples/evalboards/TMC5072/stop_switch_R1_register_access.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG 3 | # (now owned by Analog Devices Inc.), 4 | # 5 | # Copyright © 2023 Analog Devices Inc. All Rights Reserved. 6 | # This software is proprietary to Analog Devices, Inc. and its licensors. 7 | ################################################################################ 8 | """ 9 | Automatically stops the motor during active (low active) right reference switch input using direct register access. 10 | """ 11 | 12 | import time 13 | import pytrinamic 14 | from pytrinamic.connections import ConnectionManager 15 | from pytrinamic.evalboards import TMC5072_eval 16 | 17 | pytrinamic.show_info() 18 | 19 | with ConnectionManager().connect() as my_interface: 20 | print(my_interface) 21 | 22 | # Create TMC5072-EVAL class which communicates over the Landungsbrücke via TMCL 23 | eval_board = TMC5072_eval(my_interface) 24 | mc = eval_board.ics[0] 25 | ic = eval_board.ics[0] 26 | motor0 = ic.motors[0] 27 | print(motor0) 28 | # Preparing parameter for motor 0... 29 | motor0.write_axis_field(ic.FIELD.AMAX, 1000) 30 | motor0.write_axis_field(ic.FIELD.VMAX, 100000) 31 | 32 | # Invert the active polarity of the right reference switch input (low active) and 33 | # Enable the automatic motor stop during active right reference switch input 34 | motor0.write_axis_field(ic.FIELD.STOP_R_ENABLE, 1) 35 | motor0.write_axis_field(ic.FIELD.POL_STOP_R, 1) 36 | 37 | print("The motor rotates until left reference switch becomes active") 38 | motor0.rotate(10 * 25600) 39 | 40 | while motor0.read_axis_field(ic.FIELD.STATUS_STOP_R) != 1: 41 | pass 42 | print("Switch is active!") 43 | while motor0.actual_velocity != 0: 44 | pass 45 | print("Motor stopped!") 46 | # Stop the motor to make sure that it doesn't start rotating again when the switch becomes inactive 47 | motor0.stop() 48 | 49 | print("\nReady.") 50 | 51 | 52 | -------------------------------------------------------------------------------- /examples/evalboards/TMC5160_shield/TMC5160_shield_register_dump.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG 3 | # (now owned by Analog Devices Inc.), 4 | # 5 | # Copyright © 2023 Analog Devices Inc. All Rights Reserved. 6 | # This software is proprietary to Analog Devices, Inc. and its licensors. 7 | ################################################################################ 8 | 9 | """ 10 | Dump all register values of the shield IC. 11 | 12 | The connection to a Landungsbrücke is established over USB. TMCL commands are 13 | used for communicating with the IC. 14 | """ 15 | 16 | import pytrinamic 17 | from pytrinamic.connections.connection_manager import ConnectionManager 18 | from pytrinamic.modules.tmc_eval_shield import TmcEvalShield 19 | from pytrinamic.evalboards.TMC5160_shield import TMC5160_shield 20 | 21 | pytrinamic.show_info() 22 | my_interface = ConnectionManager().connect() 23 | shields = TmcEvalShield(my_interface, TMC5160_shield).shields 24 | 25 | for shield in shields: 26 | print(shield) 27 | for name, register in shield.registers.__dict__.items(): 28 | if(not name.startswith("__")) and (not name.endswith("__")): 29 | print("{0}: 0x{1:08X}".format(name, shield.read_register(register))) 30 | 31 | my_interface.close() 32 | -------------------------------------------------------------------------------- /examples/evalboards/TMC5160_shield/TMC5160_stallGuard_demo_min.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG 3 | # (now owned by Analog Devices Inc.), 4 | # 5 | # Copyright © 2023 Analog Devices Inc. All Rights Reserved. 6 | # This software is proprietary to Analog Devices, Inc. and its licensors. 7 | ################################################################################ 8 | 9 | """ 10 | Minimalistic demonstration of the stallGuard feature of the TMC5160. 11 | To reset stall on all modules, restart then script. 12 | """ 13 | 14 | import time 15 | import pytrinamic 16 | from pytrinamic.connections.connection_manager import ConnectionManager 17 | from pytrinamic.modules.tmc_eval_shield import TmcEvalShield 18 | from pytrinamic.evalboards.TMC5160_shield import TMC5160_shield 19 | 20 | ################################################################################ 21 | # Configuration for all motors 22 | 23 | CURRENT_MAX = 10 24 | ACCELERATION = 1000 25 | VELOCITY = 50000 26 | THRESHOLD_SG = 3 27 | THRESHOLD_VELOCITY = 1 28 | 29 | ################################################################################ 30 | 31 | pytrinamic.show_info() 32 | 33 | my_interface = ConnectionManager().connect() 34 | 35 | shields = TmcEvalShield(my_interface, TMC5160_shield).shields 36 | 37 | # Initialize all attached shields 38 | for shield in shields: 39 | print("Rotating motor.") 40 | shield.set_axis_parameter(shield.AP.MaxCurrent, 0, CURRENT_MAX) 41 | shield.set_axis_parameter(shield.AP.MaxAcceleration, 0, ACCELERATION) 42 | shield.rotate(0, VELOCITY) 43 | 44 | shield.set_axis_parameter(shield.AP.SG2Threshold, 0, THRESHOLD_SG) 45 | shield.set_axis_parameter(shield.AP.smartEnergyStallVelocity, 0, 0) 46 | time.sleep(1) 47 | shield.set_axis_parameter(shield.AP.smartEnergyStallVelocity, 0, THRESHOLD_VELOCITY) 48 | 49 | # Loop over all attached shields 50 | while True: 51 | for shield in shields: 52 | print(f"Shield: {shield}, SGT: {shield.getAxisParameter(shield.AP.LoadValue, 0)}") 53 | time.sleep(0.1) 54 | 55 | # Demo exit, stop all motors 56 | logger.info("Stopping all motors.") 57 | for shield in shields: 58 | logger.info(f"Stopping motors for shield {shield}.") 59 | shield.stop(0) 60 | 61 | my_interface.close() 62 | -------------------------------------------------------------------------------- /examples/evalboards/TMC5240/rotate_demo.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2023 Analog Devices Inc. All Rights Reserved. 3 | # This software is proprietary to Analog Devices, Inc. and its licensors. 4 | ################################################################################ 5 | 6 | import time 7 | import pytrinamic 8 | from pytrinamic.connections import ConnectionManager 9 | from pytrinamic.evalboards import TMC5240_eval 10 | 11 | pytrinamic.show_info() 12 | 13 | with ConnectionManager().connect() as my_interface: 14 | print(my_interface) 15 | 16 | eval_board = TMC5240_eval(my_interface) 17 | motor = eval_board.motors[0] 18 | mc = eval_board.ics[0] 19 | eval_board.write_register(mc.REG.AMAX, 51200) 20 | 21 | print("Rotating...") 22 | motor.rotate(51200) 23 | time.sleep(2) 24 | 25 | print("Stopping...") 26 | motor.stop() 27 | time.sleep(1) 28 | 29 | print("\nReady.") 30 | 31 | -------------------------------------------------------------------------------- /examples/evalboards/TMC6140/hall_demo.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG 3 | # (now owned by Analog Devices Inc.), 4 | # 5 | # Copyright © 2023 Analog Devices Inc. All Rights Reserved. 6 | # This software is proprietary to Analog Devices, Inc. and its licensors. 7 | ################################################################################ 8 | """ 9 | Move a motor back and forth using pwm mode of the TMC6140-eval 10 | """ 11 | 12 | import time 13 | import pytrinamic 14 | from pytrinamic.connections import ConnectionManager 15 | from pytrinamic.evalboards import TMC6140_eval 16 | 17 | pytrinamic.show_info() 18 | 19 | with ConnectionManager().connect() as my_interface: 20 | print(my_interface) 21 | 22 | eval_board = TMC6140_eval(my_interface) 23 | motor = eval_board.motors[0] 24 | 25 | # configure 26 | motor.set_commutation_mode(1) 27 | motor.set_hall_order(0) 28 | 29 | print("Rotating...") 30 | motor.set_target_pwm(8000) 31 | time.sleep(3) 32 | 33 | print("Stopping...") 34 | motor.set_target_pwm(0) 35 | time.sleep(2) 36 | 37 | print("Rotating back...") 38 | motor.set_target_pwm(-8000) 39 | time.sleep(3) 40 | 41 | print("Stopping...") 42 | motor.set_target_pwm(0) 43 | 44 | print("\nReady.") 45 | -------------------------------------------------------------------------------- /examples/evalboards/TMC6140/openloop_demo.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG 3 | # (now owned by Analog Devices Inc.), 4 | # 5 | # Copyright © 2023 Analog Devices Inc. All Rights Reserved. 6 | # This software is proprietary to Analog Devices, Inc. and its licensors. 7 | ################################################################################ 8 | """ 9 | Move a motor back and forth using pwm mode of the TMC6140-eval. 10 | """ 11 | 12 | import time 13 | import pytrinamic 14 | from pytrinamic.connections import ConnectionManager 15 | from pytrinamic.evalboards import TMC6140_eval 16 | 17 | pytrinamic.show_info() 18 | 19 | with ConnectionManager().connect() as my_interface: 20 | print(my_interface) 21 | 22 | eval_board = TMC6140_eval(my_interface) 23 | motor = eval_board.motors[0] 24 | 25 | motor.set_axis_parameter(motor.AP.MotorPolePairs, 4) 26 | 27 | # configure 28 | motor.set_commutation_mode(0) 29 | 30 | print("Rotating...") 31 | motor.set_target_pwm(1000) 32 | time.sleep(3) 33 | 34 | print("Stopping...") 35 | motor.set_target_pwm(0) 36 | time.sleep(2) 37 | 38 | print("Rotating back...") 39 | motor.set_target_pwm(-1000) 40 | time.sleep(3) 41 | 42 | print("Stopping...") 43 | motor.set_target_pwm(0) 44 | time.sleep(1) 45 | 46 | print("\nReady.") -------------------------------------------------------------------------------- /examples/evalboards/TMC6300/hall_demo.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG 3 | # (now owned by Analog Devices Inc.), 4 | # 5 | # Copyright © 2023 Analog Devices Inc. All Rights Reserved. 6 | # This software is proprietary to Analog Devices, Inc. and its licensors. 7 | ################################################################################ 8 | 9 | """ 10 | Move a motor back and forth using velocity and position mode of the TMC6300 11 | """ 12 | import time 13 | import pytrinamic 14 | from pytrinamic.connections import ConnectionManager 15 | from pytrinamic.evalboards import TMC6300_eval 16 | 17 | pytrinamic.show_info() 18 | 19 | with ConnectionManager().connect() as my_interface: 20 | print(my_interface) 21 | 22 | eval_board = TMC6300_eval(my_interface) 23 | motor = eval_board.motors[0] 24 | 25 | # configure 26 | motor.set_standby_current(0) 27 | motor.set_commutation_mode(1) 28 | motor.set_hall_direction(1) 29 | motor.set_hall_order(0) 30 | 31 | print("Rotating...") 32 | motor.set_target_pwm(8000) 33 | time.sleep(3) 34 | 35 | print("Stopping...") 36 | motor.set_target_pwm(0) 37 | time.sleep(2) 38 | 39 | print("Rotating back...") 40 | motor.set_target_pwm(-8000) 41 | time.sleep(3) 42 | 43 | print("Stopping...") 44 | motor.set_target_pwm(0) 45 | 46 | print("\nReady.") 47 | -------------------------------------------------------------------------------- /examples/evalboards/TMC6300/openloop_demo.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG 3 | # (now owned by Analog Devices Inc.), 4 | # 5 | # Copyright © 2023 Analog Devices Inc. All Rights Reserved. 6 | # This software is proprietary to Analog Devices, Inc. and its licensors. 7 | ################################################################################ 8 | 9 | """ 10 | Move a motor back and forth using velocity mode of the TMC6300 11 | """ 12 | import time 13 | import pytrinamic 14 | from pytrinamic.connections import ConnectionManager 15 | from pytrinamic.evalboards import TMC6300_eval 16 | 17 | pytrinamic.show_info() 18 | 19 | with ConnectionManager().connect() as my_interface: 20 | print(my_interface) 21 | 22 | eval_board = TMC6300_eval(my_interface) 23 | motor = eval_board.motors[0] 24 | 25 | # configure 26 | motor.set_standby_current(0) 27 | motor.set_commutation_mode(0) 28 | 29 | print("Rotating...") 30 | motor.set_target_pwm(6000) 31 | time.sleep(3) 32 | 33 | print("Stopping...") 34 | motor.set_target_pwm(0) 35 | time.sleep(2) 36 | 37 | print("Rotating back...") 38 | motor.set_target_pwm(-6000) 39 | time.sleep(3) 40 | 41 | print("Stopping...") 42 | motor.set_target_pwm(0) 43 | time.sleep(1) 44 | 45 | print("\nReady.") 46 | -------------------------------------------------------------------------------- /examples/evalboards/TMC7300/register_dump.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG 3 | # (now owned by Analog Devices Inc.), 4 | # 5 | # Copyright © 2023 Analog Devices Inc. All Rights Reserved. 6 | # This software is proprietary to Analog Devices, Inc. and its licensors. 7 | ################################################################################ 8 | 9 | """ 10 | Dump all register values of the TMC7300 IC. 11 | 12 | The connection to a Landungsbrücke is established over USB. TMCL commands are used for communicating with the IC. 13 | """ 14 | import pytrinamic 15 | from pytrinamic.connections import ConnectionManager 16 | from pytrinamic.evalboards import TMC7300_eval 17 | 18 | pytrinamic.show_info() 19 | 20 | my_interface = ConnectionManager().connect() 21 | print(my_interface) 22 | 23 | eval_board = TMC7300_eval(my_interface) 24 | drv = eval_board.ics[0] 25 | print("Driver info: " + str(drv.get_info())) 26 | print("Register dump for " + str(drv.get_name()) + ":") 27 | 28 | print("GCONF: 0x{0:08X}".format(eval_board.read_register(drv.REG.GCONF))) 29 | print("GSTAT: 0x{0:08X}".format(eval_board.read_register(drv.REG.GSTAT))) 30 | print("IFCNT: 0x{0:08X}".format(eval_board.read_register(drv.REG.IFCNT))) 31 | print("SLAVECONF: 0x{0:08X}".format(eval_board.read_register(drv.REG.SLAVECONF))) 32 | print("IOIN: 0x{0:08X}".format(eval_board.read_register(drv.REG.IOIN))) 33 | print("CURRENT_LIMIT: 0x{0:08X}".format(eval_board.read_register(drv.REG.CURRENT_LIMIT))) 34 | print("PWM_AB: 0x{0:08X}".format(eval_board.read_register(drv.REG.PWM_AB))) 35 | print("CHOPCONF: 0x{0:08X}".format(eval_board.read_register(drv.REG.CHOPCONF))) 36 | print("DRV_STATUS: 0x{0:08X}".format(eval_board.read_register(drv.REG.DRV_STATUS))) 37 | print("PWMCONF: 0x{0:08X}".format(eval_board.read_register(drv.REG.PWMCONF))) 38 | 39 | my_interface.close() 40 | 41 | print("\nReady.") 42 | -------------------------------------------------------------------------------- /examples/evalboards/TMC7300/rotate_demo.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG 3 | # (now owned by Analog Devices Inc.), 4 | # 5 | # Copyright © 2023 Analog Devices Inc. All Rights Reserved. 6 | # This software is proprietary to Analog Devices, Inc. and its licensors. 7 | ################################################################################ 8 | 9 | """ 10 | Move a DC motor back and forth using the TMC7300 11 | """ 12 | import time 13 | import pytrinamic 14 | from pytrinamic.connections import ConnectionManager 15 | from pytrinamic.evalboards import TMC7300_eval 16 | 17 | pytrinamic.show_info() 18 | 19 | with ConnectionManager().connect() as my_interface: 20 | print(my_interface) 21 | 22 | # Create TMC7300-EVAL class which communicates over the Landungsbrücke via TMCL 23 | eval_board = TMC7300_eval(my_interface) 24 | motor = eval_board.motors[0] 25 | drv = eval_board.ics[0] 26 | 27 | # use two motors in this demo 28 | motor.set_axis_parameter(motor.AP.PWMTwoMotors, 1) 29 | 30 | # no standby current 31 | motor.set_standby_current(0) 32 | 33 | print("Rotating...") 34 | motor.set_axis_parameter(motor.AP.PWMDutyA, 20) 35 | motor.set_axis_parameter(motor.AP.PWMDutyB, 70) 36 | time.sleep(2) 37 | 38 | print("Stopping...") 39 | motor.set_axis_parameter(motor.AP.PWMDutyA, 0) 40 | motor.set_axis_parameter(motor.AP.PWMDutyB, 0) 41 | time.sleep(1) 42 | 43 | print("Rotating...") 44 | motor.set_axis_parameter(motor.AP.PWMDutyA, -20) 45 | motor.set_axis_parameter(motor.AP.PWMDutyB, -70) 46 | time.sleep(2) 47 | 48 | print("Stopping...") 49 | motor.set_axis_parameter(motor.AP.PWMDutyA, 0) 50 | motor.set_axis_parameter(motor.AP.PWMDutyB, 0) 51 | time.sleep(1) 52 | 53 | print("\nReady.") 54 | -------------------------------------------------------------------------------- /examples/evalboards/TMC9660/param/headless/tmc9660_any_eval_supply_voltage.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2024 Analog Devices Inc. All Rights Reserved. 3 | # This software is proprietary to Analog Devices, Inc. and its licensors. 4 | ################################################################################ 5 | """Minimal example on how to use PyTrinamic with TMC9660-3PH-EVAL/TMC9660-STEPPER-EVAL. 6 | 7 | The script will read the supply voltage ten times from the TMC9660 and print it to the console. 8 | 9 | The TMC9660-3PH-EVAL/TMC9660-STEPPER-EVAL is used in headless mode for this example. 10 | 11 | Note: To run this script the EVAL first needs an uploaded/burned configuration 12 | and the parameter app must have been started. 13 | On Windows this can be done with: 14 | ubltools_1.0.1/ublcli.exe --port write config ubltools_1.0.1/ioconfig_tmc9660-3ph-eval.toml 15 | ubltools_1.0.1/ublcli.exe --port start 16 | Where needs to be replaced by the COM port of the USB-UART cable. 17 | 18 | --------+ 19 | | USB-UART Cable - Connected to the machine running this script. 20 | +--|-----------------+ 21 | | | | 22 | | | 23 | |TMC9660-3PH-EVAL or | 24 | |TMC9660-STEPPER-EVAL| 25 | +--------------------+ 26 | """ 27 | 28 | import time 29 | 30 | from pytrinamic.connections import ConnectionManager 31 | from pytrinamic.ic import TMC9660 32 | 33 | 34 | com_port = "COM5" # Note: Change this to the com port of the USB-UART cable used. 35 | 36 | with ConnectionManager(f"--interface serial_tmcl --port {com_port}").connect() as my_interface: 37 | 38 | tmc9660 = TMC9660(my_interface) 39 | 40 | for _ in range(10): 41 | voltage_v = tmc9660.get_parameter(tmc9660.ap.SUPPLY_VOLTAGE) / 10 42 | print(f"Supply voltage: {voltage_v:.2f} V") 43 | time.sleep(0.2) 44 | -------------------------------------------------------------------------------- /examples/evalboards/TMC9660/param/with_landungsbruecke/demo_gpio.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2024 Analog Devices Inc. All Rights Reserved. 3 | # This software is proprietary to Analog Devices, Inc. and its licensors. 4 | ################################################################################ 5 | """Demo on how to read and write digital IOs. 6 | 7 | In order for the output to work, the following configuration has to be changed in the ioconfig_tmc9660-3ph-eval.toml file: 8 | ```toml 9 | [gpio18] 10 | type = "output" # "input", "output", "analog" (optional) (analog only supported on GPIO 2-5) 11 | output_value = true # false, true (optional) 12 | ``` 13 | 14 | On Windows the config upload and app start can be done with: 15 | python ubltools_1.0.1/ubl_evalsystem_wrapper.py write config ubltools_1.0.1/ioconfig_tmc9660-3ph-eval.toml 16 | python ubltools_1.0.1/ubl_evalsystem_wrapper.py start 17 | Where needs to be replaced by the COM port of the Landungsbruecke. 18 | 19 | Important: first connect USB and then power the TMC9660-3PH-EVAL. 20 | 21 | +-----+ +-------------------+ 22 | USB | |==| | 23 | -------| |==| | 24 | Connected to the machine | |==| | 25 | running this script. |LB |==|TMC9660-3PH-EVAL | 26 | +-----+ +-------------------+ 27 | 28 | """ 29 | 30 | from pytrinamic.connections import ConnectionManager 31 | from pytrinamic.ic import TMC9660 32 | from pytrinamic.evalboards import TMC9660_3PH_eval 33 | 34 | 35 | cm = ConnectionManager() 36 | 37 | with cm.connect() as my_interface: 38 | 39 | tmc9660_device = TMC9660_3PH_eval(my_interface) 40 | 41 | # Get the state of the digital input GPIO17 42 | print(f"GPIO17: {tmc9660_device.get_digital_input(17)}") 43 | print(f"GPIO17: {tmc9660_device.get_digital_input(TMC9660.IO.GPIO17)}") 44 | 45 | # Set the digital output GPIO18 to True and then to False 46 | tmc9660_device.set_digital_output(18, True) 47 | tmc9660_device.set_digital_output(TMC9660.IO.GPIO18, False) 48 | -------------------------------------------------------------------------------- /examples/evalboards/TMC9660/reg/create_reg_map.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2025 Analog Devices Inc. All Rights Reserved. 3 | # This software is proprietary to Analog Devices, Inc. and its licensors. 4 | ################################################################################ 5 | """Example script that showcases how to create a register map for the TMC9660.""" 6 | 7 | from pytrinamic.ic import TMC9660 8 | 9 | 10 | max_name_length = max([len(register.name) for register in TMC9660.MCC.registers()]) 11 | for register in TMC9660.MCC.registers(): 12 | print(f"#define {register.name:{max_name_length}} 0x{register.address:04x}") 13 | 14 | -------------------------------------------------------------------------------- /examples/evalboards/TMC9660/reg/headless/tmc9660_3ph_eval_min_demo.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2024 Analog Devices Inc. All Rights Reserved. 3 | # This software is proprietary to Analog Devices, Inc. and its licensors. 4 | ################################################################################ 5 | """Minimal example on how to use PyTrinamic with TMC9660-3PH-EVAL/TMC9660-STEPPER-EVAL. 6 | 7 | The TMC9660-3PH-EVAL/TMC9660-STEPPER-EVAL is used in headless mode for this example. 8 | 9 | Note: To run this script the EVAL first needs an uploaded/burned configuration 10 | and the register app must have been started. 11 | 12 | --------+ 13 | | USB-UART Cable - Connected to the machine running this script. 14 | +--|-----------------+ 15 | | | | 16 | | | 17 | |TMC9660-3PH-EVAL or | 18 | |TMC9660-STEPPER-EVAL| 19 | +--------------------+ 20 | """ 21 | 22 | import time 23 | 24 | from pytrinamic.connections import ConnectionManager 25 | 26 | from pytrinamic.ic import TMC9660 27 | 28 | 29 | 30 | com_port = "COM5" # Note: Change this to the com port of the USB-UART cable used. 31 | 32 | with ConnectionManager(f"--interface serial_tmcl --port {com_port}").connect() as my_interface: 33 | 34 | tmc9660 = TMC9660(my_interface) 35 | 36 | tmc9660.write(TMC9660.MCC.MOTOR_CONFIG.TYPE.choice.BLDC) 37 | tmc9660.write(TMC9660.MCC.MOTOR_CONFIG.N_POLE_PAIRS, 4) 38 | 39 | for _ in range(20): 40 | print(f"I0 = {tmc9660.read(TMC9660.MCC.ADC_I1_I0_SCALED.I0)}") 41 | print(f"I1 = {tmc9660.read(TMC9660.MCC.ADC_I1_I0_SCALED.I1)}") 42 | print(f"I2 = {tmc9660.read(TMC9660.MCC.ADC_I3_I2_SCALED.I2)}") 43 | time.sleep(0.2) 44 | -------------------------------------------------------------------------------- /examples/evalboards/TMC9660/reg/with_landungsbruecke/tmc9660_3ph_eval_datalogger_demo.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2025 Analog Devices Inc. All Rights Reserved. 3 | # This software is proprietary to Analog Devices, Inc. and its licensors. 4 | ################################################################################ 5 | """Demo on how to use the data-logging with TMC9660-3PH-EVKIT. 6 | 7 | Note: To run this script the TMC9660-3PH-EVAL first needs an uploaded/burned configuration 8 | and the register app must have been started. 9 | 10 | +-----+ +-------------------+ 11 | USB | |==| | 12 | -------| |==| | 13 | Connected to the machine | |==| | 14 | running this script. |LB |==|TMC9660-3PH-EVAL | 15 | +-----+ +-------------------+ 16 | 17 | Expected output: 18 | DataLogger.LogData(samples=[-8, -48], request_object=) 19 | DataLogger.LogData(samples=[-32, 24], request_object=) 20 | DataLogger.LogData(samples=[-8, 0], request_object=) 21 | """ 22 | 23 | from pytrinamic.connections import ConnectionManager 24 | 25 | from pytrinamic.ic import TMC9660 26 | from pytrinamic.evalboards import TMC9660_3PH_eval 27 | 28 | 29 | with ConnectionManager().connect() as my_interface: 30 | 31 | tmc9660_eval = TMC9660_3PH_eval(my_interface) 32 | 33 | dl = tmc9660_eval.datalogger 34 | 35 | dl.config.samples_per_channel = 2 36 | dl.config.set_sample_rate(1250.0) 37 | dl.config.log_data = [ 38 | TMC9660.MCC.ADC_I1_I0_SCALED.I0, 39 | TMC9660.MCC.ADC_I1_I0_SCALED.I1, 40 | TMC9660.MCC.ADC_I3_I2_SCALED.I2, 41 | ] 42 | 43 | dl.start_logging() 44 | 45 | dl.wait_for_capture_completion() 46 | 47 | dl.download_log() 48 | 49 | print(dl.log.data["ADC_I1_I0_SCALED.I0"]) 50 | print(dl.log.data["ADC_I1_I0_SCALED.I1"]) 51 | print(dl.log.data["ADC_I3_I2_SCALED.I2"]) 52 | -------------------------------------------------------------------------------- /examples/evalboards/TMC9660/reg/with_landungsbruecke/tmc9660_3ph_eval_min_demo.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2024 Analog Devices Inc. All Rights Reserved. 3 | # This software is proprietary to Analog Devices, Inc. and its licensors. 4 | ################################################################################ 5 | """Example on how to use TMC9660-3PH-EVKIT. 6 | 7 | Note: To run this script the TMC9660-3PH-EVAL first needs an uploaded/burned configuration 8 | and the register app must have been started. 9 | 10 | +-----+ +-------------------+ 11 | USB | |==| | 12 | -------| |==| | 13 | Connected to the machine | |==| | 14 | running this script. |LB |==|TMC9660-3PH-EVAL | 15 | +-----+ +-------------------+ 16 | 17 | """ 18 | 19 | import time 20 | 21 | from pytrinamic.connections import ConnectionManager 22 | 23 | from pytrinamic.ic import TMC9660 24 | from pytrinamic.evalboards import TMC9660_3PH_eval 25 | 26 | 27 | with ConnectionManager().connect() as my_interface: 28 | 29 | tmc9660_eval = TMC9660_3PH_eval(my_interface) 30 | 31 | tmc9660_eval.write(TMC9660.MCC.MOTOR_CONFIG.TYPE.choice.BLDC) 32 | tmc9660_eval.write(TMC9660.MCC.MOTOR_CONFIG.N_POLE_PAIRS, 4) 33 | 34 | for _ in range(20): 35 | print(f"I0 = {tmc9660_eval.read(TMC9660.MCC.ADC_I1_I0_SCALED.I0)}") 36 | print(f"I1 = {tmc9660_eval.read(TMC9660.MCC.ADC_I1_I0_SCALED.I1)}") 37 | print(f"I2 = {tmc9660_eval.read(TMC9660.MCC.ADC_I3_I2_SCALED.I2)}") 38 | time.sleep(0.2) 39 | -------------------------------------------------------------------------------- /examples/modules/Landungsbruecke/connected_eval_information.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2024 Analog Devices Inc. All Rights Reserved. 3 | # This software is proprietary to Analog Devices, Inc. and its licensors. 4 | ################################################################################ 5 | 6 | from pytrinamic.connections import ConnectionManager 7 | from pytrinamic.modules import Landungsbruecke 8 | 9 | 10 | cm = ConnectionManager() 11 | 12 | with cm.connect() as interface: 13 | lb = Landungsbruecke(interface) 14 | 15 | print("ID EEPROM content:") 16 | print("Mc: ", lb.id_eeprom_mc.read_id_info()) 17 | print("Drv:", lb.id_eeprom_drv.read_id_info()) 18 | 19 | print("Board IDs:") 20 | print(lb.get_board_ids()) 21 | 22 | print("Board Names:") 23 | print(lb.get_board_names()) -------------------------------------------------------------------------------- /examples/modules/Landungsbruecke/write_drv_id_eeprom.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2025 Analog Devices Inc. All Rights Reserved. 3 | # This software is proprietary to Analog Devices, Inc. and its licensors. 4 | ################################################################################ 5 | """Please do not use unless you know what you are doing!""" 6 | 7 | from pytrinamic.connections import ConnectionManager 8 | from pytrinamic.modules import Landungsbruecke 9 | 10 | 11 | cm = ConnectionManager() 12 | 13 | with cm.connect() as interface: 14 | lb = Landungsbruecke(interface) 15 | 16 | lb.id_eeprom_drv.write_id_info( 17 | description="TMC6200", 18 | board_id=10, # Check out Landungsbruecke.mc_id_names for a list of IDs 19 | hw_major_version=1, # Board has printed version 1.1 on it 20 | hw_minor_version=1, # Board has printed version 1.1 on it 21 | ) 22 | -------------------------------------------------------------------------------- /examples/modules/Landungsbruecke/write_mc_id_eeprom.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2024 Analog Devices Inc. All Rights Reserved. 3 | # This software is proprietary to Analog Devices, Inc. and its licensors. 4 | ################################################################################ 5 | """Please do not use unless you know what you are doing!""" 6 | 7 | from pytrinamic.connections import ConnectionManager 8 | from pytrinamic.modules import Landungsbruecke 9 | 10 | 11 | cm = ConnectionManager() 12 | 13 | with cm.connect() as interface: 14 | lb = Landungsbruecke(interface) 15 | 16 | lb.id_eeprom_mc.write_id_info( 17 | description="TMC4671", 18 | board_id=13, # Check out Landungsbruecke.mc_id_names for a list of IDs 19 | hw_major_version=1, # Board has printed version 1.2 on it 20 | hw_minor_version=2, # Board has printed version 1.2 on it 21 | ) 22 | -------------------------------------------------------------------------------- /examples/modules/TMCM1021/TMCL/StallGuard2_demo.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG 3 | # (now owned by Analog Devices Inc.), 4 | # 5 | # Copyright © 2023 Analog Devices Inc. All Rights Reserved. 6 | # This software is proprietary to Analog Devices, Inc. and its licensors. 7 | ################################################################################ 8 | 9 | import pytrinamic 10 | from pytrinamic.connections import ConnectionManager 11 | from pytrinamic.modules import TMCM1021 12 | import time 13 | 14 | pytrinamic.show_info() 15 | 16 | with ConnectionManager("--interface serial_tmcl --port COM8 --data-rate 9600").connect() as my_interface: 17 | print(my_interface) 18 | module = TMCM1021(my_interface) 19 | motor = module.motors[0] 20 | 21 | # The configuration is based on our PD28-x-1021-TMCL 22 | # If you use a different motor be sure you have the right configuration setup otherwise the script may not working. 23 | 24 | print("Preparing parameters...") 25 | 26 | # preparing drive settings 27 | motor.drive_settings.max_current = 128 28 | motor.drive_settings.standby_current = 0 29 | motor.drive_settings.boost_current = 0 30 | motor.drive_settings.microstep_resolution = motor.ENUM.MicrostepResolution256Microsteps 31 | print(motor.drive_settings) 32 | 33 | # preparing linear ramp settings 34 | motor.linear_ramp.max_acceleration = 51200 35 | motor.linear_ramp.max_velocity = 102400 36 | print(motor.linear_ramp) 37 | 38 | time.sleep(1.0) 39 | 40 | # clear position counter 41 | motor.actual_position = 0 42 | 43 | # start rotating motor for 1.5 sek 44 | print("Rotating...") 45 | motor.rotate(102400) 46 | 47 | # set up StahlGuard2 48 | print("Initial StallGuard2 values:") 49 | print(motor.stallguard2) 50 | 51 | motor.stallguard2.calibrate_zero() 52 | print("StallGuard2 after calibration:") 53 | print(motor.stallguard2) 54 | 55 | print("Try to stop motor...") 56 | 57 | while not(motor.actual_velocity == 0): 58 | print("Actual load value: " + str(motor.stallguard2.get_load_value())) 59 | time.sleep(0.2) 60 | 61 | print("Motor stopped by StallGuard2!") 62 | 63 | print("\nReady.") 64 | -------------------------------------------------------------------------------- /examples/modules/TMCM1110/TMCL/StallGuard2_demo.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG 3 | # (now owned by Analog Devices Inc.), 4 | # 5 | # Copyright © 2023 Analog Devices Inc. All Rights Reserved. 6 | # This software is proprietary to Analog Devices, Inc. and its licensors. 7 | ################################################################################ 8 | 9 | import pytrinamic 10 | from pytrinamic.connections import ConnectionManager 11 | from pytrinamic.modules import TMCM1110 12 | import time 13 | 14 | pytrinamic.show_info() 15 | 16 | # for serial interface 17 | #with ConnectionManager("--interface serial_tmcl --port COM6 --data-rate 115200").connect() as my_interface: 18 | # for usb interface 19 | with ConnectionManager().connect() as my_interface: 20 | print(my_interface) 21 | module = TMCM1110(my_interface) 22 | motor = module.motors[0] 23 | 24 | # The configuration is based on our TMCM-1110 25 | # If you use a different motor be sure you have the right configuration setup otherwise the script may not working. 26 | 27 | print("Preparing parameters...") 28 | 29 | # preparing drive settings 30 | motor.drive_settings.max_current = 16 31 | motor.drive_settings.standby_current = 0 32 | motor.drive_settings.boost_current = 0 33 | motor.drive_settings.microstep_resolution = motor.ENUM.MicrostepResolution256Microsteps 34 | print(motor.drive_settings) 35 | 36 | # preparing linear ramp settings 37 | motor.linear_ramp.max_acceleration = 2000 38 | motor.linear_ramp.max_velocity = 2000 39 | print(motor.linear_ramp) 40 | 41 | time.sleep(1.0) 42 | 43 | # clear position counter 44 | motor.actual_position = 0 45 | 46 | # start rotating motor for 1.5 sek 47 | print("Rotating...") 48 | motor.rotate(1500) 49 | 50 | # set up StahlGuard2 51 | print("Initial StallGuard2 values:") 52 | print(motor.stallguard2) 53 | 54 | motor.stallguard2.calibrate_zero() 55 | print("StallGuard2 after calibration:") 56 | print(motor.stallguard2) 57 | 58 | print("Try to stop motor...") 59 | 60 | while not(motor.actual_velocity == 0): 61 | print("Actual load value: " + str(motor.stallguard2.get_load_value())) 62 | time.sleep(0.2) 63 | 64 | print("Motor stopped by StallGuard2!") 65 | 66 | print("\nReady.") 67 | -------------------------------------------------------------------------------- /examples/modules/TMCM1111/TMCL/rotate_demo.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG 3 | # (now owned by Analog Devices Inc.), 4 | # 5 | # Copyright © 2023 Analog Devices Inc. All Rights Reserved. 6 | # This software is proprietary to Analog Devices, Inc. and its licensors. 7 | ################################################################################ 8 | """ 9 | Rotate the motor with the specified velocity to reach the target position. 10 | """ 11 | 12 | import pytrinamic 13 | from pytrinamic.connections import ConnectionManager 14 | from pytrinamic.modules import TMCM1111 15 | import time 16 | 17 | pytrinamic.show_info() 18 | 19 | connection_manager = ConnectionManager() # If no Interface is selected , the default interface is usb_tmcl 20 | with connection_manager.connect() as my_interface: 21 | module = TMCM1111(my_interface) 22 | motor = module.motors[0] 23 | 24 | # Please be sure not to use a too high current setting for your motor. 25 | 26 | print("Preparing parameters") 27 | # preparing drive settings 28 | motor.drive_settings.max_current = 128 29 | motor.drive_settings.standby_current = 0 30 | motor.drive_settings.boost_current = 0 31 | motor.drive_settings.microstep_resolution = motor.ENUM.microstep_resolution_256_microsteps 32 | print(motor.drive_settings) 33 | 34 | # preparing linear ramp settings 35 | motor.max_acceleration = 51200 36 | motor.max_velocity = 51200 37 | 38 | # reset actual position 39 | motor.actual_position = 0 40 | 41 | # start rotating motor in different directions 42 | print("Rotating...") 43 | motor.rotate(51200) 44 | time.sleep(5) 45 | 46 | # stop rotating motors 47 | print("Stopping...") 48 | motor.stop() 49 | 50 | # read actual position 51 | print("ActualPostion = {}".format(motor.actual_position)) 52 | time.sleep(2) 53 | 54 | # short delay and move back to start 55 | print("Moving back to 0") 56 | motor.move_to(0) 57 | 58 | # wait until position 0 is reached 59 | while not(motor.get_position_reached()): 60 | print("target position motor: " + str(motor.target_position) + " actual position motor: " + str(motor.actual_position)) 61 | time.sleep(0.2) 62 | 63 | print("Reached Position 0") 64 | 65 | print("\nReady.") 66 | -------------------------------------------------------------------------------- /examples/modules/TMCM1140/TMCL/StallGuard2_demo.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG 3 | # (now owned by Analog Devices Inc.), 4 | # 5 | # Copyright © 2023 Analog Devices Inc. All Rights Reserved. 6 | # This software is proprietary to Analog Devices, Inc. and its licensors. 7 | ################################################################################ 8 | 9 | import pytrinamic 10 | from pytrinamic.connections import ConnectionManager 11 | from pytrinamic.modules import TMCM1140 12 | import time 13 | 14 | pytrinamic.show_info() 15 | 16 | # for serial interface 17 | #with ConnectionManager("--interface serial_tmcl --port COM6 --data-rate 115200").connect() as my_interface: 18 | # for usb interface 19 | with ConnectionManager().connect() as my_interface: 20 | print(my_interface) 21 | module = TMCM1140(my_interface) 22 | motor = module.motors[0] 23 | 24 | # The configuration is based on our PD42-1-1140-TMCL 25 | # If you use a different motor be sure you have the right configuration setup otherwise the script may not working. 26 | 27 | print("Preparing parameters...") 28 | 29 | # preparing drive settings 30 | motor.drive_settings.max_current = 16 31 | motor.drive_settings.standby_current = 8 32 | motor.drive_settings.boost_current = 0 33 | motor.drive_settings.microstep_resolution = motor.ENUM.MicrostepResolution256Microsteps 34 | print(motor.drive_settings) 35 | 36 | # preparing linear ramp settings 37 | motor.linear_ramp.max_acceleration = 2000 38 | motor.linear_ramp.max_velocity = 2000 39 | print(motor.linear_ramp) 40 | 41 | time.sleep(1.0) 42 | 43 | # clear position counter 44 | motor.actual_position = 0 45 | 46 | # start rotating motor for 1.5 sek 47 | print("Rotating...") 48 | motor.rotate(1500) 49 | 50 | # set up StahlGuard2 51 | print("Initial StallGuard2 values:") 52 | print(motor.stallguard2) 53 | 54 | motor.stallguard2.calibrate_zero() 55 | print("StallGuard2 after calibration:") 56 | print(motor.stallguard2) 57 | 58 | print("Try to stop motor...") 59 | 60 | while not(motor.actual_velocity == 0): 61 | print("Actual load value: " + str(motor.stallguard2.get_load_value())) 62 | time.sleep(0.2) 63 | 64 | print("Motor stopped by StallGuard2!") 65 | 66 | print("\nReady.") 67 | -------------------------------------------------------------------------------- /examples/modules/TMCM1210/TMCL/rotate_demo.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG 3 | # (now owned by Analog Devices Inc.), 4 | # 5 | # Copyright © 2023 Analog Devices Inc. All Rights Reserved. 6 | # This software is proprietary to Analog Devices, Inc. and its licensors. 7 | ################################################################################ 8 | 9 | import pytrinamic 10 | from pytrinamic.connections import ConnectionManager 11 | from pytrinamic.modules import TMCM1210 12 | import time 13 | 14 | pytrinamic.show_info() 15 | 16 | connection_manager = ConnectionManager("--interface serial_tmcl --data-rate 9600 --port interactive") 17 | 18 | my_interface = connection_manager.connect() 19 | module = TMCM1210(my_interface) 20 | motor = module.motors[0] 21 | 22 | print("Preparing parameters") 23 | motor.max_acceleration = 20000 24 | 25 | print("Rotating") 26 | motor.rotate(50000) 27 | 28 | time.sleep(5) 29 | 30 | print("Stopping") 31 | motor.stop() 32 | 33 | print("ActualPostion = {}".format(motor.actual_position)) 34 | 35 | time.sleep(5) 36 | 37 | print("Doubling moved distance") 38 | motor.move_by(motor.actual_position, 50000) 39 | while not(motor.get_position_reached()): 40 | pass 41 | 42 | print("Furthest point reached") 43 | print("ActualPostion = {}".format(motor.actual_position)) 44 | 45 | time.sleep(5) 46 | 47 | print("Moving back to 0") 48 | motor.move_to(0, 100000) 49 | 50 | # Wait until position 0 is reached 51 | while not(motor.get_position_reached()): 52 | pass 53 | 54 | print("Reached Position 0") 55 | 56 | print() 57 | 58 | my_interface.close() 59 | -------------------------------------------------------------------------------- /examples/modules/TMCM123x_0_1/CANopen/rotate_demo_using_sdo.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG 3 | # (now owned by Analog Devices Inc.), 4 | # 5 | # Copyright © 2023 Analog Devices Inc. All Rights Reserved. 6 | # This software is proprietary to Analog Devices, Inc. and its licensors. 7 | ################################################################################ 8 | 9 | """ 10 | Uses SDO to rotate the motor for 5 seconds in profile velocity mode. 11 | """ 12 | import time 13 | import canopen 14 | from pytrinamic.modules.canopen_node import TmcmNode 15 | 16 | with canopen.Network() as network: 17 | network.connect(channel='0', bustype='kvaser', bitrate=1_000_000) 18 | 19 | tmcm_123x_0_1 = TmcmNode(1, 'TMCM-1230.eds') 20 | network.add_node(tmcm_123x_0_1) 21 | # Profile Velocity Mode 22 | tmcm_123x_0_1.sdo['Modes of Operation 1'].raw = tmcm_123x_0_1.ModeOfOperation.PROFILE_VELOCITY_MODE 23 | 24 | tmcm_123x_0_1.load_configuration() 25 | tmcm_123x_0_1.nmt.state = 'OPERATIONAL' 26 | 27 | tmcm_123x_0_1.go_to_operation_enabled() 28 | tmcm_123x_0_1.sdo['Absolute Max Current 1'].raw = 50 29 | tmcm_123x_0_1.sdo['Stop On Stall 1'].raw = 0 30 | 31 | 32 | target_velocity = 10000 33 | print("Rotating the motor...") 34 | tmcm_123x_0_1.sdo['Target Velocity 1'].raw = target_velocity 35 | time.sleep(5) 36 | tmcm_123x_0_1.sdo['Target Velocity 1'].raw = 0 37 | print("Motor stopped!") 38 | 39 | tmcm_123x_0_1.nmt.state = 'PRE-OPERATIONAL' 40 | tmcm_123x_0_1.shutdown() 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /examples/modules/TMCM123x_0_1/readme.txt: -------------------------------------------------------------------------------- 1 | "These examples are compatible with both TMCM1230 and TMCM1231 stepper motor drivers and 2 | can be used without any modification to the code except for CANopen examples, where the right eds file 3 | needs to be added to the script." 4 | However, it is important for the user to ensure that they provide the required voltage and 5 | current to the board based on its hardware specifications to prevent any damage to the module." -------------------------------------------------------------------------------- /examples/modules/TMCM1240/CANopen/tmcm_1240_profile_velocity_mode_demo.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2025 Analog Devices Inc. All Rights Reserved. 3 | # This software is proprietary to Analog Devices, Inc. and its licensors. 4 | ################################################################################ 5 | 6 | import time 7 | import canopen 8 | from pytrinamic.modules.canopen_node import TmcmNode 9 | 10 | with canopen.Network() as network: 11 | # PEAK CAN ADAPER SETTINGS FOR CAN CONNECTION 12 | network.connect(bustype='pcan', channel='PCAN_USBBUS1', bitrate=1_000_000) 13 | # TMCM-1240 EDS (ELECTRONIC DATASHEET IS CALLED,CANOPEN NODE .PY PYTRINAMIC IS CALLED ) 14 | tmcm_1240 = TmcmNode(1, 'TMCM-1240.eds') 15 | 16 | network.add_node(tmcm_1240) 17 | # LOADING CONFIGURATION FROM CANOPEN NODE FILE 18 | tmcm_1240.load_configuration() 19 | 20 | tmcm_1240.nmt.state = 'OPERATIONAL' 21 | tmcm_1240.go_to_operation_enabled() 22 | tmcm_1240.shutdown() 23 | 24 | tmcm_1240.sdo['Absolute Max Current 1'].raw = 80 #CURRENT SETTINGS 25 | tmcm_1240.sdo['Switch Parameters 1'].raw = 3 #DISSABLE LIMIT SWITCHES 26 | tmcm_1240.go_to_operation_enabled() 27 | # SETTING OPERATIONAL MODE 28 | tmcm_1240.sdo['Modes of Operation 1'].raw=3 #PROFILE VELOCITY MODE 29 | 30 | target_velocity = 50000 #SET TARGET VELOCITY 31 | print("Rotating the motor...") 32 | 33 | tmcm_1240.sdo['Target Velocity 1'].raw = target_velocity 34 | time.sleep(10) 35 | 36 | tmcm_1240.sdo['Target Velocity 1'].raw = 0 37 | print("Motor stopped!") 38 | # SHUTDOWN STATES 39 | tmcm_1240.nmt.state = 'PRE-OPERATIONAL' 40 | 41 | tmcm_1240.shutdown() -------------------------------------------------------------------------------- /examples/modules/TMCM1270/TMCL/rotate_demo.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG 3 | # (now owned by Analog Devices Inc.), 4 | # 5 | # Copyright © 2023 Analog Devices Inc. All Rights Reserved. 6 | # This software is proprietary to Analog Devices, Inc. and its licensors. 7 | ################################################################################ 8 | 9 | import pytrinamic 10 | from pytrinamic.connections import ConnectionManager 11 | from pytrinamic.modules import TMCM1270 12 | import time 13 | 14 | pytrinamic.show_info() 15 | 16 | # This example uses PCAN, if you want to use another connection please change this line. 17 | connection_manager = ConnectionManager("--interface pcan_tmcl") 18 | my_interface = connection_manager.connect() 19 | module = TMCM1270(my_interface) 20 | motor = module.motors[0] 21 | 22 | print("Preparing parameters") 23 | motor.max_acceleration = 20000 24 | 25 | print("Rotating") 26 | motor.rotate(50000) 27 | 28 | time.sleep(5) 29 | 30 | print("Stopping") 31 | motor.stop() 32 | 33 | print("ActualPostion = {}".format(motor.actual_position)) 34 | 35 | time.sleep(5) 36 | 37 | print("Doubling moved distance") 38 | motor.move_by(motor.actual_position, 50000) 39 | while not(motor.get_position_reached()): 40 | pass 41 | 42 | print("Furthest point reached") 43 | print("ActualPostion = {}".format(motor.actual_position)) 44 | 45 | time.sleep(5) 46 | 47 | print("Moving back to 0") 48 | motor.move_to(0, 100000) 49 | 50 | # Wait until position 0 is reached 51 | while not(motor.get_position_reached()): 52 | pass 53 | 54 | print("Reached Position 0") 55 | 56 | print() 57 | 58 | my_interface.close() 59 | -------------------------------------------------------------------------------- /examples/modules/TMCM1276/TMCL/rotate_demo.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG 3 | # (now owned by Analog Devices Inc.), 4 | # 5 | # Copyright © 2023 Analog Devices Inc. All Rights Reserved. 6 | # This software is proprietary to Analog Devices, Inc. and its licensors. 7 | ################################################################################ 8 | 9 | import pytrinamic 10 | from pytrinamic.connections import ConnectionManager 11 | from pytrinamic.modules import TMCM1276 12 | import time 13 | 14 | pytrinamic.show_info() 15 | 16 | # This example is using PCAN, if you want to use another connection please change the next line. 17 | connection_manager = ConnectionManager("--interface pcan_tmcl") 18 | 19 | my_interface = connection_manager.connect() 20 | module = TMCM1276(my_interface) 21 | motor = module.motors[0] 22 | 23 | print("Preparing parameters") 24 | motor.max_acceleration = 20000 25 | 26 | print("Rotating") 27 | motor.rotate(50000) 28 | 29 | time.sleep(5) 30 | 31 | print("Stopping") 32 | motor.stop() 33 | 34 | print("ActualPostion = {}".format(motor.actual_position)) 35 | 36 | time.sleep(5) 37 | 38 | print("Doubling moved distance") 39 | motor.move_by(motor.actual_position, 50000) 40 | while not(motor.get_position_reached()): 41 | pass 42 | 43 | print("Furthest point reached") 44 | print("ActualPostion = {}".format(motor.actual_position)) 45 | 46 | time.sleep(5) 47 | 48 | print("Moving back to 0") 49 | motor.move_to(0, 100000) 50 | 51 | # Wait until position 0 is reached 52 | while not(motor.get_position_reached()): 53 | pass 54 | 55 | print("Reached Position 0") 56 | 57 | print() 58 | 59 | my_interface.close() 60 | -------------------------------------------------------------------------------- /examples/modules/TMCM1276/TMCL/stop_switch_demo.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG 3 | # (now owned by Analog Devices Inc.), 4 | # 5 | # Copyright © 2023 Analog Devices Inc. All Rights Reserved. 6 | # This software is proprietary to Analog Devices, Inc. and its licensors. 7 | ################################################################################ 8 | 9 | import pytrinamic 10 | from pytrinamic.connections import ConnectionManager 11 | from pytrinamic.modules import TMCM1276 12 | import time 13 | 14 | pytrinamic.show_info() 15 | 16 | # This example is using PCAN, if you want to use another connection please change the next line. 17 | connection_manager = ConnectionManager("--interface pcan_tmcl") 18 | 19 | with connection_manager.connect() as my_interface: 20 | module = TMCM1276(my_interface) 21 | motor = module.motors[0] 22 | 23 | print("Preparing parameters") 24 | # preparing linear ramp settings 25 | motor.max_acceleration = 20000 26 | 27 | while 1: 28 | if motor.get_axis_parameter(motor.AP.RightEndstop): 29 | motor.stop() 30 | time.sleep(5) 31 | print("Rotating in opposite direction") 32 | motor.rotate(-50000) 33 | time.sleep(5) 34 | motor.stop() 35 | break 36 | else: 37 | print("Rotating") 38 | motor.rotate(50000) 39 | time.sleep(5) 40 | 41 | -------------------------------------------------------------------------------- /examples/modules/TMCM1278/TMCL/rotate_demo.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG 3 | # (now owned by Analog Devices Inc.), 4 | # 5 | # Copyright © 2023 Analog Devices Inc. All Rights Reserved. 6 | # This software is proprietary to Analog Devices, Inc. and its licensors. 7 | ################################################################################ 8 | 9 | import pytrinamic 10 | from pytrinamic.connections import ConnectionManager 11 | from pytrinamic.modules import TMCM1278 12 | import time 13 | 14 | pytrinamic.show_info() 15 | 16 | # This example is using PCAN, if you want to use another connection please change the next line. 17 | connection_manager = ConnectionManager("--interface pcan_tmcl") 18 | 19 | my_interface = connection_manager.connect() 20 | module = TMCM1278(my_interface) 21 | motor = module.motors[0] 22 | 23 | print("Preparing parameters") 24 | motor.max_acceleration = 20000 25 | 26 | print("Rotating") 27 | motor.rotate(50000) 28 | 29 | time.sleep(5) 30 | 31 | print("Stopping") 32 | motor.stop() 33 | 34 | print("ActualPostion = {}".format(motor.actual_position)) 35 | 36 | time.sleep(5) 37 | 38 | print("Doubling moved distance") 39 | motor.move_by(motor.actual_position, 50000) 40 | while not(motor.get_position_reached()): 41 | pass 42 | 43 | print("Furthest point reached") 44 | print("ActualPostion = {}".format(motor.actual_position)) 45 | 46 | time.sleep(5) 47 | 48 | print("Moving back to 0") 49 | motor.move_to(0, 100000) 50 | 51 | # Wait until position 0 is reached 52 | while not(motor.get_position_reached()): 53 | pass 54 | 55 | print("Reached Position 0") 56 | 57 | print() 58 | 59 | my_interface.close() 60 | -------------------------------------------------------------------------------- /examples/modules/TMCM1278/TMCL/stop_switch_demo.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG 3 | # (now owned by Analog Devices Inc.), 4 | # 5 | # Copyright © 2023 Analog Devices Inc. All Rights Reserved. 6 | # This software is proprietary to Analog Devices, Inc. and its licensors. 7 | ################################################################################ 8 | 9 | import pytrinamic 10 | from pytrinamic.connections import ConnectionManager 11 | from pytrinamic.modules import TMCM1278 12 | import time 13 | 14 | pytrinamic.show_info() 15 | 16 | # This example is using PCAN, if you want to use another connection please change the next line. 17 | connection_manager = ConnectionManager("--interface pcan_tmcl") 18 | 19 | with connection_manager.connect() as my_interface: 20 | module = TMCM1278(my_interface) 21 | motor = module.motors[0] 22 | 23 | print("Preparing parameters") 24 | # preparing linear ramp settings 25 | motor.max_acceleration = 20000 26 | 27 | while 1: 28 | if motor.get_axis_parameter(motor.AP.RightEndstop): 29 | motor.stop() 30 | time.sleep(5) 31 | print("Rotating in opposite direction") 32 | motor.rotate(-50000) 33 | time.sleep(5) 34 | motor.stop() 35 | break 36 | else: 37 | print("Rotating") 38 | motor.rotate(50000) 39 | time.sleep(5) 40 | 41 | -------------------------------------------------------------------------------- /examples/modules/TMCM1290/TMCL/rotate_demo.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG 3 | # (now owned by Analog Devices Inc.), 4 | # 5 | # Copyright © 2023 Analog Devices Inc. All Rights Reserved. 6 | # This software is proprietary to Analog Devices, Inc. and its licensors. 7 | ################################################################################ 8 | 9 | import pytrinamic 10 | from pytrinamic.connections import ConnectionManager 11 | from pytrinamic.modules import TMCM1290 12 | import time 13 | 14 | pytrinamic.show_info() 15 | 16 | # We are using RS485 17 | connection_manager = ConnectionManager("--interface serial_tmcl --data-rate 115200 --port interactive") 18 | 19 | my_interface = connection_manager.connect() 20 | module = TMCM1290(my_interface) 21 | motor = module.motors[0] 22 | 23 | print("Preparing parameters") 24 | motor.max_acceleration = 20000 25 | 26 | print("Rotating") 27 | motor.rotate(50000) 28 | 29 | time.sleep(5) 30 | 31 | print("Stopping") 32 | motor.stop() 33 | 34 | print("ActualPostion = {}".format(motor.actual_position)) 35 | 36 | time.sleep(5) 37 | 38 | print("Doubling moved distance") 39 | motor.move_by(motor.actual_position, 50000) 40 | while not(motor.get_position_reached()): 41 | pass 42 | 43 | print("Furthest point reached") 44 | print("ActualPostion = {}".format(motor.actual_position)) 45 | 46 | time.sleep(5) 47 | 48 | print("Moving back to 0") 49 | motor.move_to(0, 100000) 50 | 51 | # Wait until position 0 is reached 52 | while not(motor.get_position_reached()): 53 | pass 54 | 55 | print("Reached Position 0") 56 | 57 | print() 58 | 59 | my_interface.close() 60 | -------------------------------------------------------------------------------- /examples/modules/TMCM1290/TMCL/stop_switch_demo.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG 3 | # (now owned by Analog Devices Inc.), 4 | # 5 | # Copyright © 2023 Analog Devices Inc. All Rights Reserved. 6 | # This software is proprietary to Analog Devices, Inc. and its licensors. 7 | ################################################################################ 8 | 9 | import pytrinamic 10 | from pytrinamic.connections import ConnectionManager 11 | from pytrinamic.modules import TMCM1290 12 | import time 13 | 14 | pytrinamic.show_info() 15 | 16 | # We are using RS485 17 | connection_manager = ConnectionManager("--interface serial_tmcl --data-rate 115200 --port interactive") 18 | 19 | with connection_manager.connect() as my_interface: 20 | module = TMCM1290(my_interface) 21 | motor = module.motors[0] 22 | 23 | print("Preparing parameters") 24 | # preparing linear ramp settings 25 | motor.max_acceleration = 20000 26 | 27 | while 1: 28 | if motor.get_axis_parameter(motor.AP.RightEndstop): 29 | motor.stop() 30 | time.sleep(5) 31 | print("Rotating in opposite direction") 32 | motor.rotate(-50000) 33 | time.sleep(5) 34 | motor.stop() 35 | break 36 | else: 37 | print("Rotating") 38 | motor.rotate(50000) 39 | time.sleep(5) 40 | 41 | -------------------------------------------------------------------------------- /examples/modules/TMCM1316/TMCL/rotate_demo.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG 3 | # (now owned by Analog Devices Inc.), 4 | # 5 | # Copyright © 2023 Analog Devices Inc. All Rights Reserved. 6 | # This software is proprietary to Analog Devices, Inc. and its licensors. 7 | ################################################################################ 8 | """ 9 | Rotate the motor with the specified velocity to reach the target position. 10 | """ 11 | 12 | import pytrinamic 13 | from pytrinamic.connections import ConnectionManager 14 | from pytrinamic.modules import TMCM1316 15 | import time 16 | 17 | pytrinamic.show_info() 18 | 19 | connection_manager = ConnectionManager() # If no Interface is selected , the default interface is usb_tmcl 20 | with connection_manager.connect() as my_interface: 21 | module = TMCM1316(my_interface) 22 | motor = module.motors[0] 23 | 24 | # Please be sure not to use a too high current setting for your motor. 25 | 26 | print("Preparing parameters") 27 | # preparing drive settings 28 | motor.drive_settings.max_current = 128 29 | motor.drive_settings.standby_current = 0 30 | motor.drive_settings.boost_current = 0 31 | motor.drive_settings.microstep_resolution = motor.ENUM.microstep_resolution_256_microsteps 32 | print(motor.drive_settings) 33 | 34 | # preparing linear ramp settings 35 | motor.max_acceleration = 51200 36 | motor.max_velocity = 51200 37 | 38 | # reset actual position 39 | motor.actual_position = 0 40 | 41 | # start rotating motor in different directions 42 | print("Rotating...") 43 | motor.rotate(51200) 44 | time.sleep(5) 45 | 46 | # stop rotating motors 47 | print("Stopping...") 48 | motor.stop() 49 | 50 | # read actual position 51 | print("ActualPostion = {}".format(motor.actual_position)) 52 | time.sleep(2) 53 | 54 | # short delay and move back to start 55 | print("Moving back to 0") 56 | motor.move_to(0) 57 | 58 | # wait until position 0 is reached 59 | while not(motor.get_position_reached()): 60 | print("target position motor: " + str(motor.target_position) + " actual position motor: " + str(motor.actual_position)) 61 | time.sleep(0.2) 62 | 63 | print("Reached Position 0") 64 | 65 | print("\nReady.") 66 | -------------------------------------------------------------------------------- /examples/modules/TMCM1617/TMCL/register_access.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG 3 | # (now owned by Analog Devices Inc.), 4 | # 5 | # Copyright © 2023 Analog Devices Inc. All Rights Reserved. 6 | # This software is proprietary to Analog Devices, Inc. and its licensors. 7 | ################################################################################ 8 | 9 | import pytrinamic 10 | from pytrinamic.connections import ConnectionManager 11 | from pytrinamic.modules import TMCM1617 12 | 13 | pytrinamic.show_info() 14 | # connection_manager = ConnectionManager("--interface serial_tmcl --port COM4 --data-rate 115200") 15 | connection_manager = ConnectionManager("--interface kvaser_tmcl --module-id 1") 16 | 17 | with connection_manager.connect() as my_interface: 18 | 19 | # the module 20 | module = TMCM1617(my_interface) 21 | 22 | # axis parameter based feature access 23 | motor = module.motors[0] 24 | 25 | # direct register access to motion controller and driver 26 | mc_index = 0 27 | mc = module.ics[mc_index] 28 | 29 | drv_index = 1 30 | drv = module.ics[drv_index] 31 | 32 | print("\nMotionController: " + mc.get_name()) 33 | print(mc.get_info()) 34 | 35 | module.write_register(mc_index, mc.REG.CHIPINFO_ADDR, mc.VARIANT.CHIPINFO_ADDR_SI_TYPE) 36 | print("\tSI_TYPE: 0x{0:08X}".format(module.read_register(mc_index, mc.REG.CHIPINFO_DATA))) 37 | 38 | module.write_register(mc_index, mc.REG.CHIPINFO_ADDR, mc.VARIANT.CHIPINFO_ADDR_SI_VERSION) 39 | print("\tSI_VERSION: 0x{0:08X}".format(module.read_register(mc_index, mc.REG.CHIPINFO_DATA))) 40 | 41 | module.write_register(mc_index, mc.REG.CHIPINFO_ADDR, mc.VARIANT.CHIPINFO_ADDR_SI_DATE) 42 | print("\tSI_DATE: 0x{0:08X}".format(module.read_register(mc_index, mc.REG.CHIPINFO_DATA))) 43 | 44 | print("\nDriver: " + drv.get_name()) 45 | print(drv.get_info()) 46 | print("\tSI_VERSION: 0x{0:08X}".format(module.read_register_field(drv_index, drv.FIELD.VERSION))) 47 | print("\n") 48 | 49 | print("\nReady.") 50 | -------------------------------------------------------------------------------- /examples/modules/TMCM1636/TMCL/datalogger_demo.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2024 Analog Devices Inc. All Rights Reserved. 3 | # This software is proprietary to Analog Devices, Inc. and its licensors. 4 | ################################################################################ 5 | 6 | import math 7 | 8 | from pytrinamic.connections import ConnectionManager 9 | from pytrinamic.modules import TMCM1636 10 | 11 | 12 | connection_manager = ConnectionManager("--interface kvaser_tmcl") 13 | 14 | with connection_manager.connect() as my_interface: 15 | module = TMCM1636(my_interface) 16 | motor = module.motors[0] 17 | 18 | # Create a shorter reference to the modules DataLogger. 19 | dl = module.datalogger 20 | 21 | dl_info = dl.get_info() # This will read some information from the module. 22 | print(f"RAMdebug's base frequency is {dl_info.base_frequency_hz} Hz.") 23 | print(f"RAMdebug can sample up to {dl_info.number_of_channels} signals in parallel.") 24 | print(f"RAMdebug's total number of samples is {dl_info.sample_buffer_length}") 25 | for i in range(dl_info.number_of_channels): 26 | print(f" If you sample {i+1} signal, you can have up to {math.floor(dl_info.sample_buffer_length/(i+1))} samples.") 27 | 28 | # Configure 29 | dl.config.log_data = { 30 | "actual_velocity": dl.DataTypeAp(motor.AP.ActualVelocity), 31 | "actual_position": dl.DataTypeAp(motor.AP.ActualPosition), 32 | } 33 | dl.config.down_sampling_factor = 2 34 | dl.config.samples_per_channel = 1024 35 | 36 | # Do the logging 37 | dl.start_capture() 38 | 39 | # Wait for the logging to finish 40 | dl.wait_for_capture_completion() 41 | 42 | # Pull the data from the module 43 | while dl.download_log_step(): 44 | print(f"Download progress: {dl.download_progress:.2f}%") 45 | print(f"Download progress: {dl.download_progress:.2f}%") 46 | 47 | # Access the logged data 48 | actual_velocity = dl.log.data["actual_velocity"] 49 | actual_position = dl.log.data["actual_position"] 50 | -------------------------------------------------------------------------------- /examples/modules/TMCM1636/TMCL/datalogger_minimal.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2024 Analog Devices Inc. All Rights Reserved. 3 | # This software is proprietary to Analog Devices, Inc. and its licensors. 4 | ################################################################################ 5 | 6 | import logging 7 | 8 | from pytrinamic.connections import ConnectionManager 9 | from pytrinamic.modules import TMCM1636 10 | 11 | 12 | logging.basicConfig(level=logging.DEBUG) 13 | 14 | connection_manager = ConnectionManager("--interface kvaser_tmcl") 15 | 16 | with connection_manager.connect() as my_interface: 17 | module = TMCM1636(my_interface) 18 | motor = module.motors[0] 19 | 20 | # Add a shorter reference to the modules DataLogger. 21 | dl = module.datalogger 22 | 23 | # Configure 24 | dl.config.samples_per_channel = 10 25 | dl.config.log_data = { 26 | "ADC_I0": dl.DataTypeAp(index=motor.AP.AdcPhaseA), 27 | } 28 | 29 | # Do the logging logging immediately, without setting up any trigger condition. 30 | dl.start_capture() 31 | 32 | # Wait for the logging to finish 33 | dl.wait_for_capture_completion() 34 | 35 | # Pull the data from the module 36 | dl.download_log() 37 | 38 | # Access the logged data 39 | adc_i0 = dl.log.data["ADC_I0"] 40 | 41 | print(adc_i0.samples) 42 | print(dl.log.rate_hz) 43 | -------------------------------------------------------------------------------- /examples/modules/TMCM1636/TMCL/multi_module.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG 3 | # (now owned by Analog Devices Inc.), 4 | # 5 | # Copyright © 2023 Analog Devices Inc. All Rights Reserved. 6 | # This software is proprietary to Analog Devices, Inc. and its licensors. 7 | ################################################################################ 8 | 9 | """Example script for the TMCM-1636-TMCL that shows how to access two modules within one CAN network.""" 10 | 11 | from pytrinamic.connections import ConnectionManager 12 | from pytrinamic.modules import TMCM1636 13 | 14 | 15 | connection_manager = ConnectionManager("--interface kvaser_tmcl") 16 | 17 | with connection_manager.connect() as my_interface: 18 | 19 | modules = [ 20 | TMCM1636(my_interface, module_id=1), 21 | TMCM1636(my_interface, module_id=3), 22 | ] 23 | 24 | for module in modules: 25 | motor = module.motors[0] 26 | print(motor.get_axis_parameter(motor.AP.AdcOffsetPhaseA)) 27 | 28 | -------------------------------------------------------------------------------- /examples/modules/TMCM1670/TMCL/limit_switches.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG 3 | # (now owned by Analog Devices Inc.), 4 | # 5 | # Copyright © 2023 Analog Devices Inc. All Rights Reserved. 6 | # This software is proprietary to Analog Devices, Inc. and its licensors. 7 | ################################################################################ 8 | 9 | import pytrinamic 10 | from pytrinamic.connections import ConnectionManager 11 | from pytrinamic.modules import TMCM1670 12 | import time 13 | 14 | pytrinamic.show_info() 15 | 16 | # please select your CAN adapter 17 | # my_interface = ConnectionManager("--interface pcan_tmcl").connect() 18 | my_interface = ConnectionManager("--interface kvaser_tmcl").connect() 19 | 20 | with my_interface: 21 | module = TMCM1670(my_interface) 22 | motor = module.motors[0] 23 | 24 | # drive configuration 25 | motor.drive_settings.poles = 8 26 | motor.drive_settings.max_current = 2000 27 | motor.drive_settings.target_reached_velocity = 500 28 | motor.drive_settings.target_reached_distance = 10 29 | motor.drive_settings.motor_halted_velocity = 5 30 | motor.drive_settings.open_loop_current = 1000 31 | print(motor.drive_settings) 32 | 33 | # encoder configuration 34 | print(motor.absolute_encoder) 35 | 36 | # motion settings 37 | motor.linear_ramp.max_velocity = 4000 38 | motor.linear_ramp.max_acceleration = 4000 39 | motor.linear_ramp.enabled = 1 40 | print(motor.linear_ramp) 41 | 42 | # PI configuration 43 | motor.pid.torque_p = 1000 44 | motor.pid.torque_i = 1000 45 | motor.pid.velocity_p = 2000 46 | motor.pid.velocity_i = 1000 47 | motor.pid.position_p = 300 48 | print(motor.pid) 49 | 50 | time.sleep(1.0) 51 | 52 | # use out_0 output for enable input (directly shortened) 53 | module.set_digital_output(module.DO.OUT_0) 54 | 55 | # rotate motor in right direction 56 | motor.rotate(1000) 57 | while module.get_digital_input(module.DI.REF_R): 58 | print("waiting for right switch...") 59 | time.sleep(0.2) 60 | 61 | # rotate motor in left direction 62 | motor.rotate(-1000) 63 | while module.get_digital_input(module.DI.REF_L): 64 | print("waiting for left switch...") 65 | time.sleep(0.2) 66 | 67 | # stop motor 68 | motor.rotate(0) 69 | 70 | print("\nReady.") 71 | -------------------------------------------------------------------------------- /examples/modules/TMCM2611/encoder_velocity_mode.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2024 Analog Devices Inc. All Rights Reserved. 3 | # This software is proprietary to Analog Devices, Inc. and its licensors. 4 | ################################################################################ 5 | 6 | from pytrinamic.connections import ConnectionManager 7 | from pytrinamic.modules import TMCM2611 8 | import time 9 | 10 | 11 | connection_manager = ConnectionManager() 12 | 13 | with connection_manager.connect() as my_interface: 14 | module = TMCM2611(my_interface) 15 | motor = module.motors[0] 16 | 17 | # Define motor configuration for the TMCM-2611. 18 | # The configuration is based on the Trinamic standard BLDC motor (QBL4208-100-04-025-1024-AT). 19 | # If you use a different motor be sure you have the right configuration setup otherwise the script may not work. 20 | 21 | # motor configuration 22 | motor.drive_settings.pole_pairs = 4 23 | motor.drive_settings.max_current = 2000 24 | motor.drive_settings.target_reached_distance = 5 25 | motor.drive_settings.target_reached_velocity = 500 26 | motor.drive_settings.commutation_mode = motor.ENUM.COMM_MODE_ABN_ENCODER 27 | 28 | # encoder configuration 29 | motor.abn_encoder.direction = 1 30 | motor.abn_encoder.resolution = 4096 31 | 32 | # ramp settings 33 | motor.linear_ramp.max_velocity = 2000 34 | motor.linear_ramp.max_acceleration = 1000 35 | motor.linear_ramp.enabled = 1 36 | 37 | motor.set_axis_parameter(motor.AP.PositionScaler, 6 * motor.drive_settings.pole_pairs) 38 | 39 | # PI configuration 40 | motor.pid.torque_p = 2600 41 | motor.pid.torque_i = 128 42 | motor.pid.velocity_p = 2300 43 | motor.pid.velocity_i = 500 44 | 45 | motor.target_velocity = 500 # RPM 46 | time.sleep(3) 47 | motor.target_velocity = 0 48 | 49 | motor.drive_settings.commutation_mode = motor.ENUM.COMM_MODE_DISABLED 50 | -------------------------------------------------------------------------------- /examples/modules/TMCM2611/hall_velocity_mode.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2024 Analog Devices Inc. All Rights Reserved. 3 | # This software is proprietary to Analog Devices, Inc. and its licensors. 4 | ################################################################################ 5 | 6 | from pytrinamic.connections import ConnectionManager 7 | from pytrinamic.modules import TMCM2611 8 | import time 9 | 10 | 11 | connection_manager = ConnectionManager() 12 | 13 | with connection_manager.connect() as my_interface: 14 | module = TMCM2611(my_interface) 15 | motor = module.motors[0] 16 | 17 | # Define motor configuration for the TMCM-2611. 18 | # The configuration is based on the Trinamic standard BLDC motor (QBL4208-100-04-025-1024-AT). 19 | # If you use a different motor be sure you have the right configuration setup otherwise the script may not work. 20 | 21 | # motor configuration 22 | motor.drive_settings.pole_pairs = 4 23 | motor.drive_settings.max_current = 2000 24 | motor.drive_settings.target_reached_distance = 5 25 | motor.drive_settings.target_reached_velocity = 500 26 | motor.drive_settings.commutation_mode = motor.ENUM.COMM_MODE_DIGITAL_HALL 27 | 28 | # hall sensor configuration 29 | motor.digital_hall.direction = 0 30 | motor.digital_hall.polarity = 1 31 | motor.digital_hall.offset = 0 32 | 33 | # ramp settings 34 | motor.linear_ramp.max_velocity = 2000 35 | motor.linear_ramp.max_acceleration = 1000 36 | motor.linear_ramp.enabled = 1 37 | 38 | motor.set_axis_parameter(motor.AP.PositionScaler, 6 * motor.drive_settings.pole_pairs) 39 | 40 | # PI configuration 41 | motor.pid.torque_p = 2600 42 | motor.pid.torque_i = 128 43 | motor.pid.velocity_p = 2300 44 | motor.pid.velocity_i = 500 45 | 46 | motor.target_velocity = 500 # RPM 47 | time.sleep(3) 48 | motor.target_velocity = 0 49 | 50 | motor.drive_settings.commutation_mode = motor.ENUM.COMM_MODE_DISABLED 51 | -------------------------------------------------------------------------------- /examples/modules/TMCM3216/TMCL/rotate_demo.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG 3 | # (now owned by Analog Devices Inc.), 4 | # 5 | # Copyright © 2023 Analog Devices Inc. All Rights Reserved. 6 | # This software is proprietary to Analog Devices, Inc. and its licensors. 7 | ################################################################################ 8 | 9 | import pytrinamic 10 | from pytrinamic.connections import ConnectionManager 11 | from pytrinamic.modules import TMCM3216 12 | import time 13 | 14 | pytrinamic.show_info() 15 | 16 | # We are using RS485 17 | connection_manager = ConnectionManager() 18 | 19 | my_interface = connection_manager.connect() 20 | module = TMCM3216(my_interface) 21 | motor = module.motors[0] 22 | 23 | print("Preparing parameters") 24 | motor.max_acceleration = 20000 25 | 26 | print("Rotating") 27 | motor.rotate(50000) 28 | 29 | time.sleep(5) 30 | 31 | print("Stopping") 32 | motor.stop() 33 | 34 | print("ActualPostion = {}".format(motor.actual_position)) 35 | 36 | time.sleep(5) 37 | 38 | print("Doubling moved distance") 39 | motor.move_by(motor.actual_position, 50000) 40 | while not(motor.get_position_reached()): 41 | pass 42 | 43 | print("Furthest point reached") 44 | print("ActualPostion = {}".format(motor.actual_position)) 45 | 46 | time.sleep(5) 47 | 48 | print("Moving back to 0") 49 | motor.move_to(0, 100000) 50 | 51 | # Wait until position 0 is reached 52 | while not(motor.get_position_reached()): 53 | pass 54 | 55 | print("Reached Position 0") 56 | 57 | print() 58 | 59 | my_interface.close() 60 | -------------------------------------------------------------------------------- /examples/modules/TMCM3216/TMCL/stop_switch_demo.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG 3 | # (now owned by Analog Devices Inc.), 4 | # 5 | # Copyright © 2023 Analog Devices Inc. All Rights Reserved. 6 | # This software is proprietary to Analog Devices, Inc. and its licensors. 7 | ################################################################################ 8 | 9 | import pytrinamic 10 | from pytrinamic.connections import ConnectionManager 11 | from pytrinamic.modules import TMCM3216 12 | import time 13 | 14 | pytrinamic.show_info() 15 | 16 | # This example is using PCAN, if you want to use another connection please change the next line. 17 | connection_manager = ConnectionManager() 18 | 19 | with connection_manager.connect() as my_interface: 20 | module = TMCM3216(my_interface) 21 | motor = module.motors[0] 22 | 23 | print("Preparing parameters") 24 | # preparing linear ramp settings 25 | motor.max_acceleration = 20000 26 | 27 | while 1: 28 | if motor.get_axis_parameter(motor.AP.RightEndstop): 29 | motor.stop() 30 | time.sleep(5) 31 | print("Rotating in opposite direction") 32 | motor.rotate(-50000) 33 | time.sleep(5) 34 | motor.stop() 35 | break 36 | else: 37 | print("Rotating") 38 | motor.rotate(50000) 39 | time.sleep(5) 40 | 41 | -------------------------------------------------------------------------------- /examples/modules/TMCM6214/TMCL/rotate_demo.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG 3 | # (now owned by Analog Devices Inc.), 4 | # 5 | # Copyright © 2023 Analog Devices Inc. All Rights Reserved. 6 | # This software is proprietary to Analog Devices, Inc. and its licensors. 7 | ################################################################################ 8 | 9 | import pytrinamic 10 | from pytrinamic.connections import ConnectionManager 11 | from pytrinamic.modules import TMCM6214 12 | import time 13 | 14 | pytrinamic.show_info() 15 | connection_manager = ConnectionManager() 16 | 17 | with connection_manager.connect() as my_interface: 18 | module = TMCM6214(my_interface) 19 | motor_0 = module.motors[0] 20 | 21 | print("Preparing parameters") 22 | motor_0.max_acceleration = 20000 23 | 24 | print("Rotating") 25 | motor_0.rotate(50000) 26 | 27 | time.sleep(5) 28 | 29 | print("Stopping") 30 | motor_0.stop() 31 | 32 | print("ActualPostion = {}".format(motor_0.actual_position)) 33 | 34 | time.sleep(5) 35 | 36 | print("Doubling moved distance") 37 | motor_0.move_by(motor_0.actual_position, 50000) 38 | while not(motor_0.get_position_reached()): 39 | pass 40 | 41 | print("Furthest point reached") 42 | print("ActualPostion = {}".format(motor_0.actual_position)) 43 | 44 | time.sleep(5) 45 | 46 | print("Moving back to 0") 47 | motor_0.move_to(0, 100000) 48 | 49 | # Wait until position 0 is reached 50 | while not(motor_0.get_position_reached()): 51 | pass 52 | 53 | print("Reached Position 0") 54 | 55 | 56 | -------------------------------------------------------------------------------- /examples/modules/tests/README.md: -------------------------------------------------------------------------------- 1 | 2 | The test scripts located in this directory dry test the example scripts. 3 | The interface to the hardware is mocked away on the `tmcl_module_interface` level. 4 | Also the `time.sleep()` function is mocked away with an empty implementation so the tests run faster. 5 | 6 | To run the tests: 7 | 8 | * Install PyTrinamic via `python -m pip install -e ` 9 | * Install `pytest` 10 | * Call `pytest` from the terminal within this directory or from within the above directories. -------------------------------------------------------------------------------- /examples/modules/tests/test_tmcm6110_tmcl_examples.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG 3 | # (now owned by Analog Devices Inc.), 4 | # 5 | # Copyright © 2023 Analog Devices Inc. All Rights Reserved. 6 | # This software is proprietary to Analog Devices, Inc. and its licensors. 7 | ################################################################################ 8 | 9 | import time 10 | import pathlib 11 | import runpy 12 | 13 | import pytest 14 | 15 | from pytrinamic.connections.connection_manager import ConnectionManager 16 | from pytrinamic.modules import TMCM6110 17 | 18 | 19 | this_files_directory = pathlib.Path(__file__).parent 20 | 21 | 22 | class MockTmclInterface: 23 | def __init__(self): 24 | self._position_reached_toggle = [True for _ in range(6)] 25 | 26 | def __enter__(self): 27 | return self 28 | 29 | def __exit__(self, exitType, value, traceback): 30 | del exitType, value, traceback 31 | 32 | def set_axis_parameter(self, type, axis, value, module_id, ap_index_bit_width): 33 | pass 34 | 35 | def get_axis_parameter(self, type, axis, module_id, signed, ap_index_bit_width): 36 | if type == TMCM6110._MotorTypeA.AP.PositionReachedFlag: 37 | self._position_reached_toggle[axis] ^= True 38 | if self._position_reached_toggle[axis]: 39 | return 1 40 | else: 41 | return 0 42 | else: 43 | return 0 44 | 45 | def move_to(self, axis, position, module_id): 46 | pass 47 | 48 | def move_by(self, axis, delta, module_id): 49 | pass 50 | 51 | def rotate(self, axis, velocity, module_id): 52 | pass 53 | 54 | def stop(self, axis, module_id): 55 | pass 56 | 57 | 58 | @pytest.mark.parametrize("example_script_path", [ 59 | this_files_directory / "../TMCM6110/TMCL/rotate_demo.py", 60 | ]) 61 | def test(monkeypatch, example_script_path): 62 | 63 | def mock_init(self, _=None): 64 | pass 65 | 66 | def mock_connect(self): 67 | return MockTmclInterface() 68 | 69 | def mock_sleep(_): 70 | pass 71 | 72 | monkeypatch.setattr(ConnectionManager, "__init__", mock_init) 73 | monkeypatch.setattr(ConnectionManager, "connect", mock_connect) 74 | monkeypatch.setattr(time, "sleep", mock_sleep) 75 | 76 | runpy.run_path(example_script_path) 77 | -------------------------------------------------------------------------------- /examples/referencedesigns/TMC4671_LEV_REF/TMCL/rotate_openloop.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG 3 | # (now owned by Analog Devices Inc.), 4 | # 5 | # Copyright © 2023 Analog Devices Inc. All Rights Reserved. 6 | # This software is proprietary to Analog Devices, Inc. and its licensors. 7 | ################################################################################ 8 | 9 | """ 10 | Turn a motor without feedback in open loop mode 11 | """ 12 | 13 | import pytrinamic 14 | from pytrinamic.connections.connection_manager import ConnectionManager 15 | from pytrinamic.referencedesigns import TMC4671_LEV_REF 16 | import time 17 | 18 | pytrinamic.show_info() 19 | 20 | # please select your CAN adapter 21 | # my_interface = ConnectionManager("--interface pcan_tmcl").connect() 22 | my_interface = ConnectionManager("--interface kvaser_tmcl").connect() 23 | 24 | with my_interface: 25 | module = TMC4671_LEV_REF(my_interface) 26 | motor = module.motors[0] 27 | 28 | # Define motor configuration for the TMC4671-LEV-REF. 29 | # 30 | # The configuration is based on our standard BLDC motor (QBL4208-61-04-013-1024-AT). 31 | # If you use a different motor be sure you have the right configuration setup otherwise the script may not work. 32 | 33 | # drive configuration 34 | motor.drive_settings.motor_type = motor.ENUM.MOTOR_TYPE_THREE_PHASE_BLDC 35 | motor.drive_settings.pole_pairs = 4 36 | motor.drive_settings.max_current = 2000 37 | motor.drive_settings.commutation_mode = motor.ENUM.COMM_MODE_OPENLOOP 38 | motor.drive_settings.target_reached_distance = 5 39 | motor.drive_settings.target_reached_velocity = 500 40 | motor.drive_settings.open_loop_current = 1000 41 | print(motor.drive_settings) 42 | 43 | # motion settings 44 | motor.linear_ramp.max_velocity = 2000 45 | motor.linear_ramp.max_acceleration = 1000 46 | motor.linear_ramp.enabled = 1 47 | print(motor.linear_ramp) 48 | 49 | print("Starting motor...") 50 | motor.rotate(1000) 51 | time.sleep(3) 52 | 53 | print("Changing motor direction...") 54 | motor.rotate(-1000) 55 | time.sleep(6) 56 | 57 | print("Stopping motor...") 58 | motor.rotate(0) 59 | time.sleep(3) 60 | 61 | # power of 62 | motor.drive_settings.commutation_mode = motor.ENUM.COMM_MODE_DISABLED 63 | 64 | print("\nReady.") 65 | -------------------------------------------------------------------------------- /examples/tools/FirmwareUpdate.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG 3 | # (now owned by Analog Devices Inc.), 4 | # 5 | # Copyright © 2023 Analog Devices Inc. All Rights Reserved. 6 | # This software is proprietary to Analog Devices, Inc. and its licensors. 7 | ################################################################################ 8 | 9 | import pytrinamic.cli.tmclfwupload 10 | 11 | 12 | pytrinamic.cli.tmclfwupload.main() 13 | 14 | -------------------------------------------------------------------------------- /examples/tools/LoadTMCLBinary.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG 3 | # (now owned by Analog Devices Inc.), 4 | # 5 | # Copyright © 2023 Analog Devices Inc. All Rights Reserved. 6 | # This software is proprietary to Analog Devices, Inc. and its licensors. 7 | ################################################################################ 8 | 9 | # This program downloads a TMCL binary file to a module. 10 | # Such binary files can be generated using the TMCL Creator in the TMCL-IDE 11 | # (switch on the option "Generate binary file") or by the command line tool TMCLAsm. 12 | 13 | from functools import partial 14 | from pytrinamic.connections import ConnectionManager 15 | from pytrinamic.tmcl import TMCLCommand 16 | 17 | filename = "test.bin" # This can be any TMCL binary file generated by the TMCL-IDE or by TMCLAsm 18 | 19 | with open(filename, 'rb') as TMCLFile: 20 | connection_manager = ConnectionManager("--interface serial_tmcl --port COM4 --data-rate 9600") # This can also be any other interface 21 | with connection_manager.connect() as my_interface: 22 | my_interface.send(TMCLCommand.START_DOWNLOAD_MODE, 0, 0, 0) 23 | for cmd_array in iter(partial(TMCLFile.read, 8), b''): 24 | my_interface.send(cmd_array[0], cmd_array[1], cmd_array[2], (cmd_array[3]<<24)|(cmd_array[4]<<16)|(cmd_array[5]<<8)|(cmd_array[6])) 25 | 26 | my_interface.send(TMCLCommand.QUIT_DOWNLOAD_MODE, 0, 0, 0) 27 | my_interface.send(TMCLCommand.RESET_APPLICATION, 0, 0, 0) 28 | my_interface.send(TMCLCommand.RUN_APPLICATION, 0, 0, 0) # This can be omitted if the porgram does not need to be started right after downloading 29 | TMCLFile.close() 30 | -------------------------------------------------------------------------------- /examples/tools/test.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/analogdevicesinc/PyTrinamic/aeec0fdf0898b0dd7029f8ce4a3fd64304ed5a84/examples/tools/test.bin -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [build-system] 2 | requires = ["setuptools"] 3 | build-backend = "setuptools.build_meta" 4 | 5 | [project] 6 | name = "pytrinamic" 7 | authors = [ 8 | { name = "ADI Trinamic Software Team", email = "tmc_info@trinamic.com" }, 9 | ] 10 | description = "TRINAMIC's Python Technology Access Package." 11 | readme = "README.md" 12 | license = { text = "MIT" } 13 | classifiers = [ 14 | "Programming Language :: Python :: 3", 15 | "Intended Audience :: Developers", 16 | "Natural Language :: English", 17 | "License :: OSI Approved :: MIT License", 18 | "Operating System :: OS Independent", 19 | ] 20 | requires-python = ">=3.7" 21 | dependencies = [ 22 | "python-can>=3", 23 | "canopen", 24 | "pyserial>=3", 25 | "IntelHex>=2.3", 26 | ] 27 | dynamic = ["version"] 28 | 29 | [project.urls] 30 | Homepage = "https://github.com/analogdevicesinc/pytrinamic" 31 | Issues = "https://github.com/analogdevicesinc/pytrinamic/issues" 32 | 33 | [project.scripts] 34 | tmclfwupload = "pytrinamic.cli.tmclfwupload:main" 35 | 36 | [tool.setuptools.packages] 37 | find = {} 38 | 39 | [tool.setuptools.dynamic] 40 | version = { attr = "pytrinamic.version.__version__" } -------------------------------------------------------------------------------- /pytrinamic/__init__.py: -------------------------------------------------------------------------------- 1 | name = "pytrinamic" 2 | desc = "TRINAMIC's Python Technology Access Package" 3 | 4 | 5 | def show_info(): 6 | print(name + " - " + desc) 7 | -------------------------------------------------------------------------------- /pytrinamic/cli/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/analogdevicesinc/PyTrinamic/aeec0fdf0898b0dd7029f8ce4a3fd64304ed5a84/pytrinamic/cli/__init__.py -------------------------------------------------------------------------------- /pytrinamic/connections/__init__.py: -------------------------------------------------------------------------------- 1 | from .dummy_tmcl_interface import DummyTmclInterface 2 | from .can_tmcl.pcan_tmcl_interface import PcanTmclInterface 3 | from .can_tmcl.socketcan_tmcl_interface import SocketcanTmclInterface 4 | from .can_tmcl.kvaser_tmcl_interface import KvaserTmclInterface 5 | from .serial_tmcl_interface import SerialTmclInterface 6 | from .socket_tmcl_interface import SocketTmclInterface 7 | from .uart_ic_interface import UartIcInterface 8 | from .usb_tmcl_interface import UsbTmclInterface 9 | from .can_tmcl_interface import CanTmclInterface 10 | from .can_tmcl.slcan_tmcl_interface import SlcanTmclInterface 11 | from .can_tmcl.ixxat_tmcl_interface import IxxatTmclInterface 12 | from .connection_manager import ConnectionManager 13 | -------------------------------------------------------------------------------- /pytrinamic/connections/can_tmcl/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/analogdevicesinc/PyTrinamic/aeec0fdf0898b0dd7029f8ce4a3fd64304ed5a84/pytrinamic/connections/can_tmcl/__init__.py -------------------------------------------------------------------------------- /pytrinamic/connections/can_tmcl/kvaser_tmcl_interface.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG 3 | # (now owned by Analog Devices Inc.), 4 | # 5 | # Copyright © 2023 Analog Devices Inc. All Rights Reserved. 6 | # This software is proprietary to Analog Devices, Inc. and its licensors. 7 | ################################################################################ 8 | 9 | import can 10 | 11 | from ...connections.can_tmcl_interface import CanTmclInterface 12 | 13 | 14 | class KvaserTmclInterface(CanTmclInterface): 15 | """ 16 | This class implements a TMCL connection for Kvaser adapter using CANLIB. 17 | Try 0 as default channel. 18 | """ 19 | _CHANNELS = ["0", "1", "2"] 20 | 21 | def __init__(self, port="0", datarate=1000000, host_id=2, module_id=1, timeout_s=5): 22 | if not isinstance(port, str): 23 | raise TypeError 24 | 25 | if port not in self._CHANNELS: 26 | raise ValueError("Invalid port!") 27 | 28 | CanTmclInterface.__init__(self, port, datarate, host_id, module_id, timeout_s) 29 | 30 | self.logger.info("Connect to bus with bit-rate %s.", self._bitrate) 31 | try: 32 | self._connection = can.Bus(interface="kvaser", 33 | channel=self._channel, 34 | bitrate=self._bitrate, 35 | can_filters=[{"can_id": host_id, "can_mask": 0x7F}]) 36 | except can.CanError as e: 37 | self._connection = None 38 | raise ConnectionError("Failed to connect to Kvaser CAN bus") from e 39 | 40 | @classmethod 41 | def list(cls): 42 | """ 43 | Return a list of available connection ports as a list of strings. 44 | 45 | This function is required for using this interface with the 46 | connection manager. 47 | """ 48 | return cls._CHANNELS 49 | -------------------------------------------------------------------------------- /pytrinamic/connections/can_tmcl/slcan_tmcl_interface.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG 3 | # (now owned by Analog Devices Inc.), 4 | # 5 | # Copyright © 2023 Analog Devices Inc. All Rights Reserved. 6 | # This software is proprietary to Analog Devices, Inc. and its licensors. 7 | ################################################################################ 8 | 9 | import can 10 | from serial.tools.list_ports import comports 11 | 12 | from ...connections.can_tmcl_interface import CanTmclInterface 13 | 14 | 15 | class SlcanTmclInterface(CanTmclInterface): 16 | """ 17 | This class implements a TMCL connection for CAN over Serial / SLCAN. 18 | Compatible with CANable running slcan firmware and similar. 19 | Set underlying serial device as channel. (e.g. /dev/ttyUSB0, COM8, …) 20 | Maybe SerialBaudrate has to be changed based on adapter. 21 | """ 22 | 23 | def __init__(self, com_port, datarate=1000000, host_id=2, module_id=1, timeout_s=5, serial_baudrate=115200): 24 | if not isinstance(com_port, str): 25 | raise TypeError 26 | 27 | CanTmclInterface.__init__(self, com_port, datarate, host_id, module_id, timeout_s) 28 | self._serial_baudrate = serial_baudrate 29 | 30 | self.logger.info("Connect to bus. (Baudrate=%s)", self._serial_baudrate) 31 | try: 32 | self._connection = can.Bus(interface='slcan', 33 | channel=self._channel, 34 | bitrate=self._bitrate, 35 | ttyBaudrate=self._serial_baudrate) 36 | self._connection.set_filters([{"can_id": host_id, "can_mask": 0x7F}]) 37 | except can.CanError as e: 38 | self._connection = None 39 | raise ConnectionError("Failed to connect to CAN bus") from e 40 | 41 | @classmethod 42 | def list(cls): 43 | """ 44 | Return a list of available connection ports as a list of strings. 45 | 46 | This function is required for using this interface with the 47 | connection manager. 48 | """ 49 | connected = [] 50 | for element in sorted(comports()): 51 | connected.append(element.device) 52 | 53 | return connected 54 | -------------------------------------------------------------------------------- /pytrinamic/connections/can_tmcl/socketcan_tmcl_interface.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG 3 | # (now owned by Analog Devices Inc.), 4 | # 5 | # Copyright © 2023 Analog Devices Inc. All Rights Reserved. 6 | # This software is proprietary to Analog Devices, Inc. and its licensors. 7 | ################################################################################ 8 | 9 | import can 10 | 11 | from ...connections.can_tmcl_interface import CanTmclInterface 12 | 13 | 14 | class SocketcanTmclInterface(CanTmclInterface): 15 | """ 16 | This class implements a TMCL connection over a SocketCAN adapter. 17 | 18 | Use following command under linux to activate can socket 19 | sudo ip link set can0 down type can bitrate 1000000 20 | """ 21 | _CHANNELS = ["can0", "can1", "can2", "can3", "can4", "can5", "can6", "can7"] 22 | 23 | def __init__(self, port, datarate=1000000, host_id=2, module_id=1, timeout_s=5): 24 | if not isinstance(port, str): 25 | raise TypeError 26 | 27 | if port not in self._CHANNELS: 28 | raise ValueError("Invalid port") 29 | 30 | CanTmclInterface.__init__(self, port, datarate, host_id, module_id, timeout_s) 31 | 32 | self.logger.info("Connect to bus with bit-rate %s.", self._bitrate) 33 | try: 34 | self._connection = can.Bus(interface="socketcan", channel=self._channel, bitrate=self._bitrate) 35 | self._connection.set_filters([{"can_id": host_id, "can_mask": 0x7F}]) 36 | except can.CanError as e: 37 | self._connection = None 38 | raise ConnectionError("Failed to connect to SocketCAN bus") from e 39 | 40 | @classmethod 41 | def list(cls): 42 | """ 43 | Return a list of available connection ports as a list of strings. 44 | 45 | This function is required for using this interface with the 46 | connection manager. 47 | """ 48 | return cls._CHANNELS 49 | -------------------------------------------------------------------------------- /pytrinamic/connections/dummy_tmcl_interface.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG 3 | # (now owned by Analog Devices Inc.), 4 | # 5 | # Copyright © 2023 Analog Devices Inc. All Rights Reserved. 6 | # This software is proprietary to Analog Devices, Inc. and its licensors. 7 | ################################################################################ 8 | 9 | import logging 10 | 11 | from ..connections.tmcl_interface import TmclInterface 12 | 13 | 14 | class DummyTmclInterface(TmclInterface): 15 | 16 | def __init__(self, port, datarate=115200, host_id=2, module_id=1, timeout_s=5): 17 | """ 18 | Opens a dummy TMCL connection 19 | """ 20 | if not isinstance(port, str): 21 | raise TypeError 22 | 23 | TmclInterface.__init__(self, host_id, module_id) 24 | 25 | self.logger = logging.getLogger("{}.{}".format(self.__class__.__name__, port)) 26 | 27 | self.logger.debug("Opening port (baudrate=%s).", datarate) 28 | 29 | def _send(self, host_id, module_id, data): 30 | """ 31 | Send the bytearray parameter [data]. 32 | 33 | This is a required override function for using the tmcl_interface 34 | class. 35 | """ 36 | del host_id, module_id, data 37 | pass 38 | 39 | def _recv(self, host_id, module_id): 40 | """ 41 | Read 9 bytes and return them as a bytearray. 42 | 43 | This is a required override function for using the tmcl_interface 44 | class. 45 | """ 46 | del host_id, module_id 47 | 48 | return bytearray(9) 49 | 50 | @staticmethod 51 | def list(): 52 | """ 53 | Return a list of available connection ports as a list of strings. 54 | 55 | This function is required for using this interface with the 56 | connection manager. 57 | """ 58 | return ["dummy"] 59 | 60 | def __str__(self): 61 | return "Connection: type={}".format(type(self).__name__) 62 | -------------------------------------------------------------------------------- /pytrinamic/connections/usb_tmcl_interface.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG 3 | # (now owned by Analog Devices Inc.), 4 | # 5 | # Copyright © 2023 Analog Devices Inc. All Rights Reserved. 6 | # This software is proprietary to Analog Devices, Inc. and its licensors. 7 | ################################################################################ 8 | 9 | import serial.tools.list_ports 10 | from ..connections.serial_tmcl_interface import SerialTmclInterface 11 | 12 | 13 | class UsbTmclInterface(SerialTmclInterface): 14 | """ 15 | Opens a USB TMCL connection. 16 | 17 | This class is almost the same as the class for serial TMCL connections. 18 | The only difference are the functions for the connection manager, which 19 | filter the available serial connections to only include the serial over 20 | USB ones. 21 | """ 22 | 23 | # USB Vendor and Product IDs 24 | __USB_IDS = [ 25 | { # Landungsbrücke 26 | "VID": 0x2A3C, 27 | "PID": 0x0700 28 | }, 29 | { # TMCM1460 30 | "VID": 0x16D0, 31 | "PID": 0x0461 32 | }, 33 | { # Startrampe 34 | "VID": 0x16D0, 35 | "PID": 0x07E4 36 | }, 37 | { # TMC_CDC_DEV 38 | "VID": 0x2A3C, 39 | "PID": 0x0200 40 | }, 41 | { # TMCM1160, TMCM1161 42 | "VID": 0x2A3C, 43 | "PID": 0x0100 44 | }, 45 | { # TMCM1161 46 | "VID": 0x16D0, 47 | "PID": 0x05A1 48 | }, 49 | { # TMC_EvalShield 50 | "VID": 0x0483, 51 | "PID": 0x374B 52 | }, 53 | { # TMCM0960 54 | "VID": 0xF055, 55 | "PID": 0x9800 56 | } 57 | ] 58 | 59 | @staticmethod 60 | def list(): 61 | """ 62 | Return a list of available connection ports as a list of strings. 63 | 64 | This function is required for using this interface with the 65 | connection manager. 66 | """ 67 | connected = [] 68 | for element in sorted(serial.tools.list_ports.comports()): 69 | for entry in UsbTmclInterface.__USB_IDS: 70 | if entry["VID"] == element.vid and entry["PID"] == element.pid: 71 | connected.append(element.device) 72 | 73 | return connected 74 | -------------------------------------------------------------------------------- /pytrinamic/evalboards/MAX22215_eval.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2025 Analog Devices Inc. All Rights Reserved. 3 | # This software is proprietary to Analog Devices, Inc. and its licensors. 4 | ################################################################################ 5 | """Implementation of MAX22215-EVAL""" 6 | 7 | 8 | from pytrinamic.ic import MAX22215 9 | from pytrinamic.ic import RegisterApiDevice 10 | from pytrinamic.tmcl import TMCLCommand 11 | 12 | 13 | class MAX22215_eval(RegisterApiDevice): 14 | """Generic class for MAX22215 eval boards.""" 15 | 16 | def __init__(self, connection, module_id=1): 17 | self._connection = connection 18 | self._module_id = module_id 19 | self.ics = [MAX22215()] 20 | 21 | def write_register(self, register_address, block, value): 22 | """Implementation of the RegisterApiDevice::write_register() function.""" 23 | return self._connection.write_register( 24 | register_address, 25 | TMCLCommand.WRITE_DRV, 26 | block, 27 | value, 28 | module_id=self._module_id 29 | ) 30 | 31 | def read_register(self, register_address, block, signed=False): 32 | """Implementation of the RegisterApiDevice::read_register() function.""" 33 | return self._connection.read_register( 34 | register_address, 35 | TMCLCommand.READ_DRV, 36 | block, 37 | module_id=self._module_id, 38 | signed=signed, 39 | ) -------------------------------------------------------------------------------- /pytrinamic/evalboards/MAX22216_eval.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG 3 | # (now owned by Analog Devices Inc.), 4 | # 5 | # Copyright © 2023 Analog Devices Inc. All Rights Reserved. 6 | # This software is proprietary to Analog Devices, Inc. and its licensors. 7 | ################################################################################ 8 | 9 | from pytrinamic.evalboards import TMCLEval 10 | from pytrinamic.ic import MAX22216 11 | 12 | 13 | class MAX22216_eval(TMCLEval): 14 | """ 15 | This class represents a MAX22216 Evaluation board. 16 | """ 17 | def __init__(self, connection, module_id=1): 18 | """ 19 | Constructor for the MAX22216 evalboard instance. 20 | 21 | Parameters: 22 | connection: TMCL connection interface instance. 23 | module_id: Module ID to identify the evalboard module. This is used to differentiate 24 | between different modules on shared busses. Default is set to 1, different 25 | values have to be configured with the module first. 26 | """ 27 | TMCLEval.__init__(self, connection, module_id) 28 | self.motors = [ 29 | self._MotorTypeA(self, 0), 30 | self._MotorTypeA(self, 1), 31 | self._MotorTypeA(self, 2), 32 | self._MotorTypeA(self, 3) 33 | ] 34 | self.ics = [MAX22216(self)] 35 | 36 | # Use the driver controller functions for register access 37 | 38 | def write_register(self, register_address, value): 39 | return self._connection.write_drv(register_address, value, self._module_id) 40 | 41 | def read_register(self, register_address, signed=False): 42 | return self._connection.read_drv(register_address, self._module_id, signed) 43 | 44 | class _MotorTypeA(object): 45 | """ 46 | Motor class for the generic motor. 47 | """ 48 | def __init__(self, eval_board, axis): 49 | pass 50 | 51 | class AP: 52 | pass 53 | -------------------------------------------------------------------------------- /pytrinamic/evalboards/TMC6100_eval.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG 3 | # (now owned by Analog Devices Inc.), 4 | # 5 | # Copyright © 2023 Analog Devices Inc. All Rights Reserved. 6 | # This software is proprietary to Analog Devices, Inc. and its licensors. 7 | ################################################################################ 8 | 9 | from pytrinamic.evalboards import TMCLEval 10 | from pytrinamic.ic import TMC6100 11 | 12 | 13 | class TMC6100_eval(TMCLEval): 14 | """ 15 | Use TMC6100-EVAL with Landungsbrücke/Startrampe at DRV spi channel to access the TMC6100. 16 | """ 17 | def __init__(self, connection, module_id=1): 18 | TMCLEval.__init__(self, connection, module_id) 19 | self.ics = [TMC6100()] 20 | 21 | # use Landungsbrücke/Startrampe with DRV channel for register access 22 | 23 | def write_register(self, register_address, value): 24 | return self._connection.write_drv(register_address, value, self._module_id) 25 | 26 | def read_register(self, register_address, signed=False): 27 | return self._connection.read_drv(register_address, self._module_id, signed) 28 | -------------------------------------------------------------------------------- /pytrinamic/evalboards/TMC6140_eval.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG 3 | # (now owned by Analog Devices Inc.), 4 | # 5 | # Copyright © 2023 Analog Devices Inc. All Rights Reserved. 6 | # This software is proprietary to Analog Devices, Inc. and its licensors. 7 | ################################################################################ 8 | 9 | from pytrinamic.evalboards import TMCLEval 10 | from pytrinamic.ic import TMC6140 11 | from pytrinamic.features import MotorControlModule 12 | 13 | 14 | class TMC6140_eval(TMCLEval): 15 | def __init__(self, connection, module_id=1): 16 | TMCLEval.__init__(self, connection, module_id) 17 | self.motors = [self._MotorTypeA(self, 0)] 18 | self.ics = [TMC6140()] 19 | 20 | # Motion control functions 21 | 22 | def rotate(self, motor, value): 23 | self._connection.rotate(motor, value) 24 | 25 | def stop(self, motor): 26 | self._connection.stop(motor) 27 | 28 | class _MotorTypeA(MotorControlModule): 29 | def __init__(self, eval_board, axis): 30 | MotorControlModule.__init__(self, eval_board, axis, self.AP) 31 | 32 | def set_target_pwm(self, value): 33 | self.set_axis_parameter(self.AP.TargetPWM, value) 34 | 35 | def set_commutation_mode(self, value): 36 | self.set_axis_parameter(self.AP.CommutationMode, value) 37 | 38 | def set_hall_direction(self, value): 39 | self.set_axis_parameter(self.AP.InvertHallDirection, value) 40 | 41 | def set_hall_order(self, value): 42 | self.set_axis_parameter(self.AP.HallOrder, value) 43 | 44 | class AP: 45 | TargetAngle = 1 46 | HallAngle = 2 47 | TargetPWM = 3 48 | ActualPWM = 4 49 | CommutationMode = 5 50 | Current = 6 51 | InvertHallDirection = 7 52 | HallOrder = 8 53 | StandbyOnDriverDisable = 10 54 | ActualHallVelocity = 16 55 | MotorPolePairs = 19 56 | 57 | -------------------------------------------------------------------------------- /pytrinamic/evalboards/TMC6200_eval.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG 3 | # (now owned by Analog Devices Inc.), 4 | # 5 | # Copyright © 2023 Analog Devices Inc. All Rights Reserved. 6 | # This software is proprietary to Analog Devices, Inc. and its licensors. 7 | ################################################################################ 8 | 9 | from pytrinamic.evalboards import TMCLEval 10 | from pytrinamic.ic import TMC6200 11 | 12 | 13 | class TMC6200_eval(TMCLEval): 14 | """ 15 | Use TMC6100-EVAL with Landungsbrücke/Startrampe at DRV spi channel to access the TMC6100. 16 | """ 17 | def __init__(self, connection, module_id=1): 18 | TMCLEval.__init__(self, connection, module_id) 19 | self.ics = [TMC6200()] 20 | 21 | # use Landungsbrücke/Startrampe with DRV channel for register access 22 | 23 | def write_register(self, register_address, value): 24 | return self._connection.write_drv(register_address, value, self._module_id) 25 | 26 | def read_register(self, register_address, signed=False): 27 | return self._connection.read_drv(register_address, self._module_id, signed) 28 | -------------------------------------------------------------------------------- /pytrinamic/evalboards/TMC6300_eval.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG 3 | # (now owned by Analog Devices Inc.), 4 | # 5 | # Copyright © 2023 Analog Devices Inc. All Rights Reserved. 6 | # This software is proprietary to Analog Devices, Inc. and its licensors. 7 | ################################################################################ 8 | 9 | from pytrinamic.evalboards import TMCLEval 10 | from pytrinamic.ic import TMC6300 11 | from pytrinamic.features import MotorControlModule 12 | 13 | 14 | class TMC6300_eval(TMCLEval): 15 | def __init__(self, connection, module_id=1): 16 | TMCLEval.__init__(self, connection, module_id) 17 | self.motors = [self._MotorTypeA(self, 0)] 18 | self.ics = [TMC6300()] 19 | 20 | # Motion control functions 21 | 22 | def rotate(self, motor, value): 23 | self._connection.rotate(motor, value) 24 | 25 | def stop(self, motor): 26 | self._connection.stop(motor) 27 | 28 | class _MotorTypeA(MotorControlModule): 29 | def __init__(self, eval_board, axis): 30 | MotorControlModule.__init__(self, eval_board, axis, self.AP) 31 | 32 | def set_target_pwm(self, value): 33 | self.set_axis_parameter(self.AP.TargetPWM, value) 34 | 35 | def set_commutation_mode(self, value): 36 | self.set_axis_parameter(self.AP.CommutationMode, value) 37 | 38 | def set_standby_current(self, value): 39 | self.set_axis_parameter(self.AP.ICStandby, value) 40 | 41 | def set_hall_direction(self, value): 42 | self.set_axis_parameter(self.AP.HallDirection, value) 43 | 44 | def set_hall_order(self, value): 45 | self.set_axis_parameter(self.AP.HallOrder, value) 46 | 47 | class AP: 48 | ActualControlledAngle = 1 49 | ActualHallAngle = 2 50 | ActualPWM = 3 51 | TargetPWM = 4 52 | CommutationMode = 5 53 | OpenLoopStepTime = 6 54 | Current = 7 55 | HallDirection = 8 56 | HallOrder = 9 57 | ICStandby = 10 58 | VMMeasurement = 11 59 | -------------------------------------------------------------------------------- /pytrinamic/evalboards/__init__.py: -------------------------------------------------------------------------------- 1 | from .tmcl_eval import TMCLEval 2 | from .MAX22216_eval import MAX22216_eval 3 | from .TMC2100_eval import TMC2100_eval 4 | from .TMC2130_eval import TMC2130_eval 5 | from .TMC2160_eval import TMC2160_eval 6 | from .TMC2208_eval import TMC2208_eval 7 | from .TMC2209_eval import TMC2209_eval 8 | from .TMC2224_eval import TMC2224_eval 9 | from .TMC2225_eval import TMC2225_eval 10 | from .TMC2240_eval import TMC2240_eval 11 | from .TMC2300_eval import TMC2300_eval 12 | from .TMC2590_eval import TMC2590_eval 13 | from .TMC2660_eval import TMC2660_eval 14 | from .TMC4361_eval import TMC4361_eval 15 | from .TMC4671_eval import TMC4671_eval 16 | from .TMC5031_eval import TMC5031_eval 17 | from .TMC5041_eval import TMC5041_eval 18 | from .TMC5062_eval import TMC5062_eval 19 | from .TMC5072_eval import TMC5072_eval 20 | from .TMC5130_eval import TMC5130_eval 21 | from .TMC5160_eval import TMC5160_eval 22 | from .TMC5160_shield import TMC5160_shield 23 | from .TMC5240_eval import TMC5240_eval 24 | from .TMC6100_eval import TMC6100_eval 25 | from .TMC6140_eval import TMC6140_eval 26 | from .TMC6200_eval import TMC6200_eval 27 | from .TMC6300_eval import TMC6300_eval 28 | from .TMC7300_eval import TMC7300_eval 29 | from .TMC5272_eval import TMC5272_eval 30 | from .TMC5271_eval import TMC5271_eval 31 | from .TMC9660_eval import TMC9660_3PH_eval 32 | from .TMC9660_eval import TMC9660_STEPPER_eval 33 | from .MAX22215_eval import MAX22215_eval -------------------------------------------------------------------------------- /pytrinamic/features/__init__.py: -------------------------------------------------------------------------------- 1 | from .abn_encoder_module import ABNEncoderModule 2 | from .absolute_encoder_module import AbsoluteEncoderModule 3 | from .digital_hall_module import DigitalHallModule 4 | from .drive_setting import DriveSetting 5 | from .drive_setting_module import DriveSettingModule 6 | from .linear_ramp_module import LinearRampModule 7 | from .motor_control_module import MotorControlModule 8 | from .pid_module import PIDModule 9 | from .stallguard2_module import StallGuard2Module 10 | from .coolstep_module import CoolStepModule 11 | -------------------------------------------------------------------------------- /pytrinamic/features/abn_encoder.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG 3 | # (now owned by Analog Devices Inc.), 4 | # 5 | # Copyright © 2023 Analog Devices Inc. All Rights Reserved. 6 | # This software is proprietary to Analog Devices, Inc. and its licensors. 7 | ################################################################################ 8 | 9 | from abc import ABC, abstractmethod 10 | 11 | 12 | class ABNEncoder(ABC): 13 | 14 | def __init__(self, parent, axis): 15 | self._parent = parent 16 | self._axis = axis 17 | 18 | @abstractmethod 19 | def set_resolution(self, steps): 20 | raise NotImplementedError 21 | 22 | @abstractmethod 23 | def get_resolution(self): 24 | raise NotImplementedError 25 | 26 | @abstractmethod 27 | def set_direction(self, direction): 28 | raise NotImplementedError 29 | 30 | @abstractmethod 31 | def get_direction(self): 32 | raise NotImplementedError 33 | 34 | @abstractmethod 35 | def set_init_mode(self, mode): 36 | raise NotImplementedError 37 | 38 | @abstractmethod 39 | def get_init_mode(self): 40 | raise NotImplementedError 41 | 42 | @abstractmethod 43 | def clear_once_on_n_channel(self): 44 | raise NotImplementedError 45 | -------------------------------------------------------------------------------- /pytrinamic/features/abn_encoder_module.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG 3 | # (now owned by Analog Devices Inc.), 4 | # 5 | # Copyright © 2023 Analog Devices Inc. All Rights Reserved. 6 | # This software is proprietary to Analog Devices, Inc. and its licensors. 7 | ################################################################################ 8 | 9 | from ..features.abn_encoder import ABNEncoder 10 | 11 | 12 | class ABNEncoderModule(ABNEncoder): 13 | 14 | def __init__(self, module, axis, aps): 15 | super().__init__(module, axis) 16 | self._aps = aps 17 | 18 | def set_resolution(self, steps): 19 | self._parent.set_axis_parameter(self._aps.EncoderSteps, self._axis, steps) 20 | 21 | def get_resolution(self): 22 | return self._parent.get_axis_parameter(self._aps.EncoderSteps, self._axis) 23 | 24 | def set_direction(self, direction): 25 | self._parent.set_axis_parameter(self._aps.EncoderDirection, self._axis, direction) 26 | 27 | def get_direction(self): 28 | return self._parent.get_axis_parameter(self._aps.EncoderDirection, self._axis) 29 | 30 | def set_init_mode(self, mode): 31 | self._parent.set_axis_parameter(self._aps.EncoderInitMode, self._axis, mode) 32 | 33 | def get_init_mode(self): 34 | return self._parent.get_axis_parameter(self._aps.EncoderInitMode, self._axis) 35 | 36 | def clear_once_on_n_channel(self): 37 | self._parent.set_axis_parameter(self._aps.ClearOnce, self._axis, 1) 38 | self._parent.set_axis_parameter(self._aps.ClearOnNull, self._axis, 1) 39 | 40 | # Properties 41 | resolution = property(get_resolution, set_resolution) 42 | direction = property(get_direction, set_direction) 43 | init_mode = property(get_init_mode, set_init_mode) 44 | 45 | def __str__(self): 46 | return "{} {}".format( 47 | "ABNEncoder", 48 | { 49 | "resolution": self.resolution, 50 | "direction": self.direction, 51 | "init_mode": self.init_mode 52 | } 53 | ) 54 | -------------------------------------------------------------------------------- /pytrinamic/features/brakechopper.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2021 TRINAMIC Motion Control GmbH & Co. KG 3 | # (now owned by Analog Devices Inc.), 4 | # 5 | # Copyright © 2023 Analog Devices Inc. All Rights Reserved. 6 | # This software is proprietary to Analog Devices, Inc. and its licensors. 7 | ################################################################################ 8 | 9 | from abc import ABC, abstractmethod 10 | 11 | 12 | class BrakeChopper(ABC): 13 | 14 | def __init__(self, parent, axis): 15 | self._parent = parent 16 | self._axis = axis 17 | 18 | @abstractmethod 19 | def set_enable_parameter(self, enable): 20 | raise NotImplementedError 21 | 22 | @abstractmethod 23 | def get_enable_parameter(self): 24 | raise NotImplementedError 25 | 26 | @abstractmethod 27 | def set_type_parameter(self, type): 28 | raise NotImplementedError 29 | 30 | @abstractmethod 31 | def get_type_parameter(self): 32 | raise NotImplementedError 33 | 34 | @abstractmethod 35 | def set_voltage_limit_parameter(self, limit): 36 | raise NotImplementedError 37 | 38 | @abstractmethod 39 | def get_voltage_limit_parameter(self): 40 | raise NotImplementedError 41 | 42 | @abstractmethod 43 | def set_hysteresis_parameter(self, hysteresis): 44 | raise NotImplementedError 45 | 46 | @abstractmethod 47 | def get_hysteresis_parameter(self): 48 | raise NotImplementedError 49 | -------------------------------------------------------------------------------- /pytrinamic/features/current.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG 3 | # (now owned by Analog Devices Inc.), 4 | # 5 | # Copyright © 2023 Analog Devices Inc. All Rights Reserved. 6 | # This software is proprietary to Analog Devices, Inc. and its licensors. 7 | ################################################################################ 8 | 9 | from abc import ABC, abstractmethod 10 | 11 | 12 | class Current(ABC): 13 | """ 14 | Current feature implementation 15 | """ 16 | def __init__(self, parent, axis): 17 | self._parent = parent 18 | self._axis = axis 19 | 20 | @abstractmethod 21 | def set_run_current(self, current): 22 | """ 23 | Sets the run current of the given axis. 24 | 25 | Parameters: 26 | value: Value of the run current. This value is hardware specific, please refer 27 | to the documentation of the hardware. 28 | """ 29 | raise NotImplementedError 30 | 31 | @abstractmethod 32 | def get_run_current(self): 33 | """ 34 | Gets the run current of the given axis. 35 | 36 | Parameters: 37 | Returns: Run current for the given axis. 38 | """ 39 | raise NotImplementedError 40 | 41 | @abstractmethod 42 | def set_standby_current(self, current): 43 | """ 44 | Sets the standby current of the given axis. 45 | 46 | Parameters: 47 | value: Value of the standby current. This value is hardware specific, please refer 48 | to the documentation of the hardware. 49 | """ 50 | raise NotImplementedError 51 | 52 | @abstractmethod 53 | def get_standby_current(self): 54 | """ 55 | Gets the standby current of the given axis. 56 | 57 | Parameters: 58 | Returns: Standby current for the given axis. 59 | """ 60 | raise NotImplementedError 61 | -------------------------------------------------------------------------------- /pytrinamic/features/current_module.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG 3 | # (now owned by Analog Devices Inc.), 4 | # 5 | # Copyright © 2023 Analog Devices Inc. All Rights Reserved. 6 | # This software is proprietary to Analog Devices, Inc. and its licensors. 7 | ################################################################################ 8 | 9 | from pytrinamic.features.current import Current 10 | 11 | 12 | class CurrentModule(Current): 13 | """ 14 | Current feature implementation for modules 15 | """ 16 | def __init__(self, module, axis, aps): 17 | super().__init__(module, axis) 18 | self._aps = aps 19 | 20 | def set_run_current(self, current): 21 | """ 22 | Sets the run current of this axis. 23 | This value is stored as RunCurrent axis parameter. 24 | 25 | Parameters: 26 | value: Target run current. 27 | """ 28 | self._parent.set_axis_parameter(self._aps.RunCurrent, current) 29 | 30 | def get_run_current(self): 31 | """ 32 | Gets the run current of this axis. 33 | This value is stored as RunCurrent axis parameter. 34 | 35 | Returns: Run current for this axis. 36 | """ 37 | return self._parent.get_axis_parameter(self._aps.RunCurrent) 38 | 39 | def set_standby_current(self, current): 40 | """ 41 | Sets the standby current of this axis. 42 | This value is stored as StandbyCurrent axis parameter. 43 | 44 | Parameters: 45 | value: Target standby current. 46 | """ 47 | self._parent.set_axis_parameter(self._aps.StandbyCurrent, current) 48 | 49 | def get_standby_current(self): 50 | """ 51 | Gets the standby current of this axis. 52 | This value is stored as StandbyCurrent axis parameter. 53 | 54 | Returns: Standby current for this axis. 55 | """ 56 | return self._parent.get_axis_parameter(self._aps.StandbyCurrent) 57 | 58 | # Properties 59 | run = property(get_run_current, set_run_current) 60 | standby = property(get_standby_current, set_standby_current) 61 | 62 | def __str__(self): 63 | return "{} {}".format( 64 | "Current", 65 | { 66 | "run": self.run, 67 | "standby": self.standby 68 | } 69 | ) 70 | -------------------------------------------------------------------------------- /pytrinamic/features/digital_hall.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG 3 | # (now owned by Analog Devices Inc.), 4 | # 5 | # Copyright © 2023 Analog Devices Inc. All Rights Reserved. 6 | # This software is proprietary to Analog Devices, Inc. and its licensors. 7 | ################################################################################ 8 | 9 | from abc import ABC, abstractmethod 10 | 11 | 12 | class DigitalHall(ABC): 13 | 14 | def __init__(self, parent, axis): 15 | self._parent = parent 16 | self._axis = axis 17 | 18 | @abstractmethod 19 | def set_direction(self, direction): 20 | raise NotImplementedError 21 | 22 | @abstractmethod 23 | def get_direction(self): 24 | raise NotImplementedError 25 | 26 | @abstractmethod 27 | def set_polarity(self, polarity): 28 | raise NotImplementedError 29 | 30 | @abstractmethod 31 | def get_polarity(self): 32 | raise NotImplementedError 33 | 34 | @abstractmethod 35 | def set_sector_offset(self, sector_offset): 36 | raise NotImplementedError 37 | 38 | @abstractmethod 39 | def get_sector_offset(self): 40 | raise NotImplementedError 41 | 42 | @abstractmethod 43 | def set_offset(self, offset): 44 | raise NotImplementedError 45 | 46 | @abstractmethod 47 | def get_offset(self): 48 | raise NotImplementedError 49 | 50 | @abstractmethod 51 | def set_interpolation(self, enable_interpolation): 52 | raise NotImplementedError 53 | 54 | @abstractmethod 55 | def get_interpolation(self): 56 | raise NotImplementedError 57 | -------------------------------------------------------------------------------- /pytrinamic/features/linear_ramp.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG 3 | # (now owned by Analog Devices Inc.), 4 | # 5 | # Copyright © 2023 Analog Devices Inc. All Rights Reserved. 6 | # This software is proprietary to Analog Devices, Inc. and its licensors. 7 | ################################################################################ 8 | 9 | from abc import ABC, abstractmethod 10 | 11 | 12 | class LinearRamp(ABC): 13 | 14 | def __init__(self, parent, axis): 15 | self._parent = parent 16 | self._axis = axis 17 | 18 | @abstractmethod 19 | def set_max_velocity(self, velocity): 20 | """ 21 | Sets the maximum positioning velocity of this axis. 22 | 23 | Parameters: 24 | axis: Axis index. 25 | velocity: Maximum positioning velocity. 26 | """ 27 | raise NotImplementedError 28 | 29 | @abstractmethod 30 | def get_max_velocity(self): 31 | """ 32 | Gets the maximum positioning velocity of this axis. 33 | 34 | Parameters: 35 | axis: Axis index. 36 | 37 | Returns: Maximum positioning velocity for this axis. 38 | """ 39 | raise NotImplementedError 40 | 41 | @abstractmethod 42 | def set_max_acceleration(self, acceleration): 43 | """ 44 | Sets the maximum acceleration of this axis. 45 | 46 | Parameters: 47 | axis: Axis index. 48 | acceleration: Maximum acceleration. 49 | """ 50 | raise NotImplementedError 51 | 52 | @abstractmethod 53 | def get_max_acceleration(self): 54 | """ 55 | Gets the maximum acceleration of this axis. 56 | 57 | Parameters: 58 | axis: Axis index. 59 | 60 | Returns: Maximum acceleration for this axis. 61 | """ 62 | raise NotImplementedError 63 | -------------------------------------------------------------------------------- /pytrinamic/features/pid.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG 3 | # (now owned by Analog Devices Inc.), 4 | # 5 | # Copyright © 2023 Analog Devices Inc. All Rights Reserved. 6 | # This software is proprietary to Analog Devices, Inc. and its licensors. 7 | ################################################################################ 8 | 9 | from abc import ABC, abstractmethod 10 | 11 | 12 | class PID(ABC): 13 | 14 | def __init__(self, parent, axis): 15 | self._parent = parent 16 | self._axis = axis 17 | 18 | # torque/flux controller 19 | 20 | @abstractmethod 21 | def set_torque_p_parameter(self, p_value): 22 | raise NotImplementedError 23 | 24 | @abstractmethod 25 | def get_torque_p_parameter(self): 26 | raise NotImplementedError 27 | 28 | @abstractmethod 29 | def set_torque_i_parameter(self, i_value): 30 | raise NotImplementedError 31 | 32 | @abstractmethod 33 | def get_torque_i_parameter(self): 34 | raise NotImplementedError 35 | 36 | # velocity controller " 37 | 38 | @abstractmethod 39 | def set_velocity_p_parameter(self, p_value): 40 | raise NotImplementedError 41 | 42 | @abstractmethod 43 | def get_velocity_p_parameter(self): 44 | raise NotImplementedError 45 | 46 | @abstractmethod 47 | def set_velocity_i_parameter(self, i_value): 48 | raise NotImplementedError 49 | 50 | @abstractmethod 51 | def get_velocity_i_parameter(self): 52 | raise NotImplementedError 53 | 54 | # position controller 55 | 56 | @abstractmethod 57 | def set_position_p_parameter(self, p_value): 58 | raise NotImplementedError 59 | 60 | @abstractmethod 61 | def get_position_p_parameter(self): 62 | raise NotImplementedError 63 | -------------------------------------------------------------------------------- /pytrinamic/features/ramp_settings.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG 3 | # (now owned by Analog Devices Inc.), 4 | # 5 | # Copyright © 2023 Analog Devices Inc. All Rights Reserved. 6 | # This software is proprietary to Analog Devices, Inc. and its licensors. 7 | ################################################################################ 8 | 9 | from abc import ABC, abstractmethod 10 | 11 | 12 | class RampSettings(ABC): 13 | 14 | def __init__(self, parent, axis): 15 | self._parent = parent 16 | self._axis = axis 17 | 18 | @abstractmethod 19 | def set_max_velocity(self, velocity): 20 | """ 21 | Sets the maximum positioning velocity of this axis. 22 | 23 | Parameters: 24 | axis: Axis index. 25 | velocity: Maximum positioning velocity. 26 | """ 27 | raise NotImplementedError 28 | 29 | @abstractmethod 30 | def get_max_velocity(self): 31 | """ 32 | Gets the maximum positioning velocity of this axis. 33 | 34 | Parameters: 35 | axis: Axis index. 36 | 37 | Returns: Maximum positioning velocity for this axis. 38 | """ 39 | raise NotImplementedError 40 | 41 | @abstractmethod 42 | def set_max_acceleration(self, acceleration): 43 | """ 44 | Sets the maximum acceleration of this axis. 45 | 46 | Parameters: 47 | axis: Axis index. 48 | acceleration: Maximum acceleration. 49 | """ 50 | raise NotImplementedError 51 | 52 | @abstractmethod 53 | def get_max_acceleration(self): 54 | """ 55 | Gets the maximum acceleration of this axis. 56 | 57 | Parameters: 58 | axis: Axis index. 59 | 60 | Returns: Maximum acceleration for this axis. 61 | """ 62 | raise NotImplementedError 63 | -------------------------------------------------------------------------------- /pytrinamic/features/referenceswitches.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2021 TRINAMIC Motion Control GmbH & Co. KG 3 | # (now owned by Analog Devices Inc.), 4 | # 5 | # Copyright © 2023 Analog Devices Inc. All Rights Reserved. 6 | # This software is proprietary to Analog Devices, Inc. and its licensors. 7 | ################################################################################ 8 | 9 | from abc import ABC, abstractmethod 10 | 11 | 12 | class ReferenceSwitches(ABC): 13 | 14 | def __init__(self, parent, axis): 15 | self._parent = parent 16 | self._axis = axis 17 | 18 | @abstractmethod 19 | def set_enable_right_switch(self, enable): 20 | raise NotImplementedError 21 | 22 | @abstractmethod 23 | def get_enable_right_switch(self): 24 | raise NotImplementedError 25 | 26 | @abstractmethod 27 | def set_enable_left_switch(self, enable): 28 | raise NotImplementedError 29 | 30 | @abstractmethod 31 | def get_enable_left_switch(self): 32 | raise NotImplementedError 33 | 34 | @abstractmethod 35 | def set_polarity_right_switch(self, enable): 36 | raise NotImplementedError 37 | 38 | @abstractmethod 39 | def get_polarity_right_switch(self): 40 | raise NotImplementedError 41 | 42 | @abstractmethod 43 | def set_polarity_left_switch(self, enable): 44 | raise NotImplementedError 45 | 46 | @abstractmethod 47 | def get_polarity_left_switch(self): 48 | raise NotImplementedError 49 | 50 | @abstractmethod 51 | def get_right_switch_parameter(self): 52 | raise NotImplementedError 53 | 54 | @abstractmethod 55 | def get_left_switch_parameter(self): 56 | raise NotImplementedError 57 | -------------------------------------------------------------------------------- /pytrinamic/features/solenoid_control.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG 3 | # (now owned by Analog Devices Inc.), 4 | # 5 | # Copyright © 2023 Analog Devices Inc. All Rights Reserved. 6 | # This software is proprietary to Analog Devices, Inc. and its licensors. 7 | ################################################################################ 8 | 9 | from abc import ABC, abstractmethod 10 | 11 | class SolenoidControl(ABC): 12 | """ 13 | Solenoid control implementation 14 | """ 15 | def __init__(self, parent, axis): 16 | self._parent = parent 17 | self._axis = axis 18 | 19 | @abstractmethod 20 | def set_high(self): 21 | """ 22 | Apply high voltage. 23 | """ 24 | raise NotImplementedError 25 | 26 | @abstractmethod 27 | def set_low(self): 28 | """ 29 | Apply low voltage. 30 | """ 31 | raise NotImplementedError 32 | -------------------------------------------------------------------------------- /pytrinamic/features/solenoid_control_ic.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG 3 | # (now owned by Analog Devices Inc.), 4 | # 5 | # Copyright © 2023 Analog Devices Inc. All Rights Reserved. 6 | # This software is proprietary to Analog Devices, Inc. and its licensors. 7 | ################################################################################ 8 | 9 | from pytrinamic.features.solenoid_control import SolenoidControl 10 | 11 | class SolenoidControlIC(SolenoidControl): 12 | """ 13 | Solenoid control implementation for ICs 14 | """ 15 | 16 | def __init__(self, eval_board, ic, axis): 17 | super().__init__(eval_board, axis) 18 | self._ic = ic 19 | 20 | def set_high(self): 21 | """ 22 | Apply high voltage. 23 | This writes 1 to the corresponding CNTL channel field. 24 | """ 25 | self._parent.write_axis_field(self._axis, self._ic.FIELD.CNTL, 1) 26 | 27 | def set_low(self): 28 | """ 29 | Apply low voltage. 30 | This writes 0 to the corresponding CNTL channel field. 31 | """ 32 | self._parent.write_axis_field(self._axis, self._ic.FIELD.CNTL, 0) 33 | -------------------------------------------------------------------------------- /pytrinamic/helpers.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG 3 | # (now owned by Analog Devices Inc.), 4 | # 5 | # Copyright © 2023 Analog Devices Inc. All Rights Reserved. 6 | # This software is proprietary to Analog Devices, Inc. and its licensors. 7 | ################################################################################ 8 | 9 | class BitField: 10 | 11 | @staticmethod 12 | def field_get(data, mask, shift): 13 | return (data & mask) >> shift 14 | 15 | @staticmethod 16 | def field_set(data, mask, shift, value): 17 | return (data & (~mask)) | ((value << shift) & mask) 18 | 19 | 20 | def to_signed_32(x): 21 | """Convert any unsigned integer to a 32 bit signed integer.""" 22 | m = x & 0xffffffff 23 | return (m ^ 0x80000000) - 0x80000000 24 | 25 | 26 | def to_signed_16(x): 27 | """Convert any unsigned integer to a 16 bit signed integer.""" 28 | m = x & 0x0000ffff 29 | return (m ^ 0x00008000) - 0x00008000 30 | -------------------------------------------------------------------------------- /pytrinamic/ic/MAX22215/MAX22215.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2025 Analog Devices Inc. All Rights Reserved. 3 | # This software is proprietary to Analog Devices, Inc. and its licensors. 4 | ################################################################################ 5 | 6 | from ...ic import TMCIc 7 | from .MAX22215map import MAX22215Map 8 | 9 | 10 | class MAX22215(TMCIc): 11 | """ Motor Brake Driver with Current Sense Amplifier and Advanced Diagnostics""" 12 | 13 | REGMAP = MAX22215Map(channel=1, block=0).ALL_REGISTERS 14 | 15 | def __init__(self): 16 | super().__init__("MAX22215", self.__doc__) -------------------------------------------------------------------------------- /pytrinamic/ic/TMC2100.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG 3 | # (now owned by Analog Devices Inc.), 4 | # 5 | # Copyright © 2023 Analog Devices Inc. All Rights Reserved. 6 | # This software is proprietary to Analog Devices, Inc. and its licensors. 7 | ################################################################################ 8 | 9 | from ..ic.tmc_ic import TMCIc 10 | 11 | 12 | class TMC2100(TMCIc): 13 | """ 14 | The TMC2100 is a standalone driver IC for two-phase stepper motors. Supply voltage: 4.75 - 46V. 15 | """ 16 | def __init__(self): 17 | super().__init__("TMC2100", self.__doc__) 18 | 19 | class REG: 20 | """ 21 | Define all registers of the TMC2100. 22 | """ 23 | GCONF = 0x00 24 | 25 | class FIELD: 26 | """ 27 | Define all register bitfields of the TMC2100. 28 | 29 | Each field is defined as a tuple consisting of ( Address, Mask, Shift ). 30 | 31 | The name of the register is written as a comment behind each tuple. This is 32 | intended for IDE users viewing the definition of a field by hovering over 33 | it. This allows the user to see the corresponding register name of a field 34 | without opening this file and searching for the definition. 35 | """ 36 | # GCONF 37 | GCONF = (0x00, 0xFFFFFFFF, 0) 38 | -------------------------------------------------------------------------------- /pytrinamic/ic/TMC6140.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG 3 | # (now owned by Analog Devices Inc.), 4 | # 5 | # Copyright © 2023 Analog Devices Inc. All Rights Reserved. 6 | # This software is proprietary to Analog Devices, Inc. and its licensors. 7 | ################################################################################ 8 | 9 | from ..ic.tmc_ic import TMCIc 10 | 11 | 12 | class TMC6140(TMCIc): 13 | """ 14 | TMC6140 is a fully integrated universal 3-phase MOSFET gate driver for PMSM servo or BLDC motors. 15 | External MOSFETs for up to 100 A motor current are supported. Supply voltage: 5-30V 16 | """ 17 | def __init__(self): 18 | super().__init__("TMC6140", self.__doc__) 19 | -------------------------------------------------------------------------------- /pytrinamic/ic/TMC6300.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG 3 | # (now owned by Analog Devices Inc.), 4 | # 5 | # Copyright © 2023 Analog Devices Inc. All Rights Reserved. 6 | # This software is proprietary to Analog Devices, Inc. and its licensors. 7 | ################################################################################ 8 | 9 | from ..ic.tmc_ic import TMCIc 10 | 11 | 12 | class TMC6300(TMCIc): 13 | """ 14 | The TMC6300 is a highly efficient low voltage, zero standby current driver for 3-Phase BLDC/PMSM motors 15 | up to 2A. Supply voltage: 2-11V 16 | """ 17 | def __init__(self): 18 | super().__init__("TMC6300", self.__doc__) 19 | -------------------------------------------------------------------------------- /pytrinamic/ic/TMC9660/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/analogdevicesinc/PyTrinamic/aeec0fdf0898b0dd7029f8ce4a3fd64304ed5a84/pytrinamic/ic/TMC9660/__init__.py -------------------------------------------------------------------------------- /pytrinamic/ic/__init__.py: -------------------------------------------------------------------------------- 1 | from .tmc_ic import TMCIc 2 | from .tmc_ic import RegisterApiDevice 3 | from .tmc_ic import RegisterGroup 4 | from .tmc_ic import Register 5 | from .tmc_ic import Field 6 | from .tmc_ic import Access 7 | from .tmc_ic import Choice 8 | from .tmc_ic import Option 9 | from .MAX22216 import MAX22216 10 | from .TMC2100 import TMC2100 11 | from .TMC2130 import TMC2130 12 | from .TMC2160 import TMC2160 13 | from .TMC2208 import TMC2208 14 | from .TMC2209 import TMC2209 15 | from .TMC2224 import TMC2224 16 | from .TMC2225 import TMC2225 17 | from .TMC2240 import TMC2240 18 | from .TMC2300 import TMC2300 19 | from .TMC2590 import TMC2590 20 | from .TMC2660 import TMC2660 21 | from .TMC4361 import TMC4361 22 | from .TMC4671 import TMC4671 23 | from .TMC5031 import TMC5031 24 | from .TMC5041 import TMC5041 25 | from .TMC5062 import TMC5062 26 | from .TMC5072 import TMC5072 27 | from .TMC5130 import TMC5130 28 | from .TMC5160 import TMC5160 29 | from .TMC5240 import TMC5240 30 | from .TMC6100 import TMC6100 31 | from .TMC6140 import TMC6140 32 | from .TMC6200 import TMC6200 33 | from .TMC6300 import TMC6300 34 | from .TMC7300 import TMC7300 35 | from .TMC5272 import TMC5272 36 | from .TMC5271 import TMC5271 37 | from .TMC9660.TMC9660 import TMC9660 38 | from .MAX22215.MAX22215 import MAX22215 39 | 40 | 41 | -------------------------------------------------------------------------------- /pytrinamic/modules/TMCM_Python.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG 3 | # (now owned by Analog Devices Inc.), 4 | # 5 | # Copyright © 2023 Analog Devices Inc. All Rights Reserved. 6 | # This software is proprietary to Analog Devices, Inc. and its licensors. 7 | ################################################################################ 8 | 9 | class TMCM_Python(object): 10 | """ 11 | The TMCM-Python is the MicroPython TMCL Master/Slave interface. 12 | """ 13 | def __init__(self, connection, module_id=1): 14 | self.connection = connection 15 | self.MODULE_ID = module_id 16 | self.MOTORS = 0 17 | self.__default_motor = 0 18 | 19 | # Global parameter access 20 | def get_global_parameter(self, gp_type, bank): 21 | return self.connection.get_global_parameter(gp_type, bank) 22 | 23 | def set_global_parameter(self, gp_type, bank, value): 24 | self.connection.set_global_parameter(gp_type, bank, value) 25 | 26 | class AP: 27 | pass 28 | 29 | class ENUM: 30 | # Version formats 31 | VERSION_FORMAT_ASCII = 0 32 | VERSION_FORMAT_BINARY = 1 33 | VERSION_FORMAT_BUILD = 5 34 | # Python subscript methods 35 | SUBSCRIPT_METHOD_EXECUTE = 0 36 | SUBSCRIPT_METHOD_APPEND = 1 37 | SUBSCRIPT_METHOD_CLEAR = 2 38 | 39 | class GP: 40 | controlHost = 0 41 | controlModule = 1 42 | loggingEnabled = 2 43 | -------------------------------------------------------------------------------- /pytrinamic/modules/__init__.py: -------------------------------------------------------------------------------- 1 | from .tmcl_module import TMCLModule, ParameterGroup, Parameter, ParameterApiDevice 2 | from .TMCC160 import TMCC160 3 | from .TMCM1021 import TMCM1021 4 | from .TMCM1110 import TMCM1110 5 | from .TMCM1111 import TMCM1111 6 | from .TMCM1140 import TMCM1140 7 | from .TMCM1141 import TMCM1141 8 | from .TMCM1160 import TMCM1160 9 | from .TMCM1161 import TMCM1161 10 | from .TMCM1210 import TMCM1210 11 | from .TMCM1211 import TMCM1211 12 | from .TMCM1240 import TMCM1240 13 | from .TMCM1241 import TMCM1241 14 | from .TMCM1260 import TMCM1260 15 | from .TMCM1270 import TMCM1270 16 | from .TMCM1276 import TMCM1276 17 | from .TMCM1278 import TMCM1278 18 | from .TMCM1290 import TMCM1290 19 | from .TMCM1311 import TMCM1311 20 | from .TMCM1316 import TMCM1316 21 | from .TMCM1321 import TMCM1321 22 | from .TMCM1370 import TMCM1370 23 | from .TMCM1378 import TMCM1378 24 | from .TMCM1617 import TMCM1617 25 | from .TMCM1630 import TMCM1630 26 | from .TMCM1633 import TMCM1633 27 | from .TMCM1636 import TMCM1636 28 | from .TMCM1637 import TMCM1637 29 | from .TMCM1638 import TMCM1638 30 | from .TMCM1640 import TMCM1640 31 | from .TMCM1670 import TMCM1670 32 | from .TMCM1690 import TMCM1690 33 | from .TMCM3110 import TMCM3110 34 | from .TMCM3216 import TMCM3216 35 | from .TMCM3312 import TMCM3312 36 | from .TMCM3351 import TMCM3351 37 | from .TMCM6110 import TMCM6110 38 | from .TMCM6212 import TMCM6212 39 | from .TMCM6214 import TMCM6214 40 | from .TMCM123x_0_1 import TMCM123x_0_1 41 | from .TMCM2611 import TMCM2611 42 | from .Landungsbruecke import Landungsbruecke -------------------------------------------------------------------------------- /pytrinamic/modules/tmc_eval_shield.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG 3 | # (now owned by Analog Devices Inc.), 4 | # 5 | # Copyright © 2023 Analog Devices Inc. All Rights Reserved. 6 | # This software is proprietary to Analog Devices, Inc. and its licensors. 7 | ################################################################################ 8 | 9 | class TmcEvalShield: 10 | """ 11 | Arguments: 12 | connection: 13 | Type: connection interface 14 | The connection interface used for this module. 15 | shield: 16 | Type: class 17 | The EvalShield class used for every axis on this module. 18 | For every axis connected, an instance of this class will be created, 19 | which can be used later. 20 | """ 21 | def __init__(self, connection, shield, module_id=1): 22 | self.shields = [] 23 | 24 | while not(connection.get_global_parameter(self.GP.AttachedAxes, 0, module_id)): 25 | pass 26 | 27 | attached_axes = connection.get_global_parameter(self.GP.AttachedAxes, 0, module_id) 28 | for i in range(attached_axes): 29 | self.shields.append(shield(connection, i, module_id)) 30 | 31 | class GP: 32 | AttachedAxes = 6 33 | -------------------------------------------------------------------------------- /pytrinamic/referencedesigns/__init__.py: -------------------------------------------------------------------------------- 1 | from .TMC4671_LEV_REF import TMC4671_LEV_REF 2 | -------------------------------------------------------------------------------- /pytrinamic/tools/__init__.py: -------------------------------------------------------------------------------- 1 | from .velocity_ramp_runner import VelocityRampRunner 2 | -------------------------------------------------------------------------------- /pytrinamic/version.py: -------------------------------------------------------------------------------- 1 | __version__ = "0.2.18-dev" 2 | -------------------------------------------------------------------------------- /tests/check_lb_fw_upload.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright © 2024 Analog Devices Inc. All Rights Reserved. 3 | # This software is proprietary to Analog Devices, Inc. and its licensors. 4 | ################################################################################ 5 | """This script checks the firmware upload CLI tool tmclfwupload. 6 | 7 | A standard Landungsbruecke is used for this check, please connect one via USB. 8 | The hex files are downloaded from the internet, so you need internet connection to run this script. 9 | """ 10 | 11 | import time 12 | import urllib 13 | import struct 14 | import subprocess 15 | import urllib.request 16 | 17 | from pytrinamic.connections import ConnectionManager 18 | from pytrinamic.tmcl import TMCLCommand 19 | 20 | 21 | lb_fw_3_10_1_hex = urllib.request.urlretrieve("https://github.com/analogdevicesinc/TMC-EvalSystem/releases/download/3.10.1/Landungsbruecke_v3.10.1_BL.hex")[0] 22 | lb_fw_3_10_2_hex = urllib.request.urlretrieve("https://github.com/analogdevicesinc/TMC-EvalSystem/releases/download/3.10.2/Landungsbruecke_v3.10.2_BL.hex")[0] 23 | 24 | for hex, expected_build_version in [(lb_fw_3_10_1_hex, 3101), (lb_fw_3_10_2_hex, 3102)]: 25 | 26 | subprocess.run(["tmclfwupload", hex]) 27 | 28 | time.sleep(5) 29 | 30 | cm = ConnectionManager() 31 | 32 | with cm.connect() as interface: 33 | 34 | get_fw_result = interface.send(TMCLCommand.GET_FIRMWARE_VERSION, 1, 0, 0) 35 | fw_version_minor, fw_version_major, module_number = struct.unpack("