Trinamic TMCM-0960-MotionPy SBC + Stepper Motor - Review

Table of contents

RoadTest: Trinamic TMCM-0960-MotionPy SBC + Stepper Motor

Author: MARK2011

Creation date:

Evaluation Type: Development Boards & Tools

Did you receive all parts the manufacturer stated would be included in the package?: True

What other parts do you consider comparable to this product?: Concerning the TMCM board - most comparable seems to be popular PY-Boards. Also Infineons Stepper Motor Control Shield should be mentioned (e.g. FX9201 and XMC1300 as well as Ti products with their popular motor drivers. The smart motor module in my opinion has no competitors. Of course if we split it just the engine can be compared with many NEMA steppers but the idea of PANdrive is extraordinary.

What were the biggest problems encountered?: I must honestly confess I missed more detailed instructions of setup and initial preparation of the set. Documentation is still in development and some codes wers outdated when I started to lern it. There is also question of the reliable support. As finally I was instructed by top specialist in the topic, the beginning was truly worse.

Detailed Review:

Introduction

 

The roadtest I have the honour to conduct concerns the set of the TMCM-0960-MotionPy board  and PD42-1270 stepper motor.

Both came from Trinamic, now the part of Maxim Integrated.

I ‘m ashamed to start my report by complaining about the  TMCM-0960-MotionPy. But I want to tell about that misunderstanding at the beginning.

The board is defined as the open-source single board computer running MicroPython. I must honestly disagree

as my understanding of single board computers differs very much. TMCM-0960 is in truth the kind of development board

with the STM32F405RGT6 as the “heart” or “brain”.  It is very close to the idea of popular PYBoards.

That made some consternation as we can’t run any OS on that system. Only limited FV dedicated to that board.

Nevertheless, the Arm Cortex-M4 core is still an interesting option and the simple and easy to operate system

based on micropython lets us spread the scope of application for the TMCM-0960.

 

The Kit

Unboxing was very pleasant reward for relative long waiting for customs procedures completion.

TMCM-0960 board;  PD42-1270 stepper motor; adapter board with plugs; 32G SD Card and USB type C cable.

All fine and secure packed.

The “smell” of fresh electronic - as always - unforgotten.

 

Documentation

The kit is well documented and comes with clear description on TRINAMIC site there are also links to related github repositories

as well as some fine video on YT (I love watching presentations with TMCL-IDE graphs - especially live waveform is great)

TMCM-0960-MotionPy resources are simply available at

https://www.trinamic.com/products/modules/details/tmcm-0960-motionpy/

The most convenient document is  TMCM-0960-MotionPy_HW_Manual_V10 (6).pdf

MicroPython SBC for Test, Dev, and Lab Automation MICROPYTHON SBCimage

Document Revision V1.00 • 2020-10-23

image

There is no need to repeat details and features of that board.

Things worth to emphasize: big range of motor supply voltage (6..50V)

many interfaces:UART as well as USB, CAN, RS485, SPI

The board employes STM32F405RGT6 controller

https://www.st.com/en/microcontrollers-microprocessors/stm32f405rg.html

Arm Cortex-M4 core with DSP and FPU, 1 Mbyte of Flash memory, 168 MHz CPU, ART Accelerator

image

The STM32F405xx and STM32F407xx family is based on the high-performance Arm® Cortex®-M4 32-bit RISC core operating at a frequency of up to 168 MHz.

The Cortex-M4 core features a Floating point unit (FPU) single precision which supports all Arm single-precision data-processing instructions and data types.

It also implements a full set of DSP instructions and a memory protection unit (MPU) which enhances application security.

The STM32F405xx and STM32F407xx family incorporates high-speed embedded memories (Flash memory up to 1 Mbyte, up to 192 Kbytes of SRAM),

up to 4 Kbytes of backup SRAM, and an extensive range of enhanced I/Os and peripherals connected to two APB buses, three AHB buses and a 32-bit multi-AHB bus matrix.

All devices offer three 12-bit ADCs, two DACs, a low-power RTC, twelve general-purpose 16-bit timers including two PWM timers for motor control, two general-purpose 32-bit timers.

True random number generator (RNG). They also feature standard and advanced communication interfaces.

 

PD42-1270 PANdrive smart stepper motor

https://www.trinamic.com/products/drives/details/pd42-x-1270/

Regarding the motor, the main paper is  PD42-1270 Hardware Manual

PD-1270_hardware_manual_hw1.00_rev1.11_01 (1).pdf

https://www.element14.com/community/servlet/JiveServlet/previewBody/96384-102-1-397573/PD-1270_hardware_manual_hw1.00_rev1.11_01%20(1).pdf

I found very useful:  TMCL Reference and Programming Manual  (TMCL_reference_2015.pdf)

Trinamic Motion Control Language (TMCL)

 

PD42-1270 belongs to the family of PANdrive™ smart stepper motors. The control module is interfaced with the MCU board  via CAN bus

It is normal stepper motor

image

with CANbus interface board together with motion controller.

 

main parameters:

Supply Voltage +24V nom. (+6V to +28VDC) and 1.0A RMS phase current.

Interesting features of the unit are:

StealthChop for absolute silent motor control in PWM mode,

SpreadCycle smart mixed decay for high speed stepper motor commutation,

SixPoint motion ramps - fully integrated hardware motion controller,

StallGuard2 load detection

CoolStep for automatic current scaling

The smart motor employes TMCL or CANopen protocol - in my case the TMCL firmware was used.

 

PANdrive concept:

https://www.trinamic.com/products/pandrive-smart-motors/

PANdrive™ smart motors are compact drives complete with all the components you need. The module mounted on the back of the motor

offers an onboard TMCL mini-PLC for standalone operation, which can be easily programmed with the free TMCL-IDE software.

Various standard interfaces are supported and combined with Trinamic's industry-leading feature set. Together with the built-in SensOstep™ encoder,

PANdrive smart motors are the perfect solution for easily scalable systems.

Regarding multimedia, mentioned above very useful youtube films:

How to use graphs within the TMCL-IDE https://www.youtube.com/watch?v=DLRblB8DZ7k

Trinamic's Swiss Army Knife for Engineers Running MicroPython https://www.youtube.com/watch?v=UcnQzKeuleA

Software projects, examples and all necessary repositories are available on Github: https://github.com/trinamic/PyTrinamicMicro .

Trinamic Motion Control site on FB  https://www.facebook.com/Trinamic.MC/

I think I studied above materials quite thoroughly

with one remark -  I couldn’t find the explanation of the mysterious sentence from the papers:

“module offers a total of 13 functions in Python programming language”

The family of TMCM boards as well as PANdrive motors is fully supported with convenient software:

TMCL-IDE

https://www.trinamic.com/support/software/tmcl-ide/#c414

TMCL - IDE is the short for Trinamic Motion Control Language - Integrated Development Environment.

The TMCL-IDE is an integrated development environment made for developing applications using Trinamic modules and chips.

The graphical user interface provides tools for setting parameters, visualizing data in real-time, and for developing and debugging stand-alone applications.

The program is perfect solution to quickly set, check and tune motor parameters and features. Is perfect for evaluation purpose.

Moreover - Using the TMCL Creator it is possible to develop stand-alone TMCL programs. These programs can be downloaded to a module and then run on the module.

https://www.trinamic.com/fileadmin/assets/toolkit/TMCL-IDE_User_manual.pdf

https://www.247motioncontrol.com/media/1271/tmcl-ide_usermanual_v201.pdf

 

Apart from documentation, manuals, tutorials and examples, a very important part for developers are support resources and user foras.

In our case the official Trinamic  Support is now directing you to the common Maxim Integrated support.

https://www.trinamic.com/support/technical-support/

image

https://maximsupport.microsoftcrmportals.com/en-US/tech-support/

The driver

TMCM-0960  board driver installation sequence.

After inserting to the USB port it was quickly recognized as PYBFLASH.



The board is also available as the storage device (of very small capacity, less 100MB in fact), the possibility of extending the space using an SD card is very convenient.

But we need to remember that native storage will be inaccessible when using the SD.

image

Unfortunately I realized soon that my system recognized the drivers improperly.

It was inaccessible in the clients terminal shell.

First I tried to reinstall drivers

image

But then I discovered that the driver signing issue arose

image

 

the driver is not digitally signed

Since the driver is not digitally signed, Windows may prevent you completely from

proceeding with the installation.

I had to go to the test mode to install Unsigned Drivers in Windows 10

https://www.maketecheasier.com/install-unsigned-drivers-windows10/

 

 

Base contents of the board storage folder

image

 

README.txt

This is a MicroPython board

You can get started right away by writing your Python code in 'main.py'.

For a serial prompt:
 - Windows: you need to go to 'Device manager', right click on the unknown device,
   then update the driver software, using the 'pybcdc.inf' file found on this drive.
   Then use a terminal program like Hyperterminal or putty.
 - Mac OS X: use the command: screen /dev/tty.usbmodem*
 - Linux: use the command: screen /dev/ttyACM0

Please visit http://micropython.org/help/ for further help.

key = USB_VID val = f055
key = USB_PID_CDC_MSC val = 9800
key = USB_PID_CDC_HID val = 9801
key = USB_PID_CDC val = 9802
key = USB_PID_MSC val = 9803
key = USB_PID_CDC2_MSC val = 9804
key = USB_PID_CDC2 val = 9805
key = USB_PID_CDC3 val = 9806
key = USB_PID_CDC3_MSC val = 9807
key = USB_PID_CDC_MSC_HID val = 9808
key = USB_PID_CDC2_MSC_HID val = 9809
key = USB_PID_CDC3_MSC_HID val = 980a
; Windows USB CDC ACM Setup File
; Based on INF files which were:
;     Copyright (c) 2000 Microsoft Corporation
;     Copyright (C) 2007 Microchip Technology Inc.
; Likely to be covered by the MLPL as found at:
;    <http://msdn.microsoft.com/en-us/cc300389.aspx#MLPL>.

[Version]
Signature="$Windows NT$"
Class=Ports
ClassGuid={4D36E978-E325-11CE-BFC1-08002BE10318}
Provider=%MFGNAME%
LayoutFile=layout.inf
DriverVer=03/11/2010,5.1.2600.3

[Manufacturer]
%MFGNAME%=DeviceList, NTamd64

[DestinationDirs]
DefaultDestDir=12

;---------------------------------------------------------------------
; Windows 2000/XP/Server2003/Vista/Server2008/7 - 32bit Sections

[DriverInstall.nt]
include=mdmcpq.inf
CopyFiles=DriverCopyFiles.nt
AddReg=DriverInstall.nt.AddReg

[DriverCopyFiles.nt]
usbser.sys,,,0x20

[DriverInstall.nt.AddReg]
HKR,,DevLoader,,*ntkern
HKR,,NTMPDriver,,usbser.sys
HKR,,EnumPropPages32,,"MsPorts.dll,SerialPortPropPageProvider"

[DriverInstall.nt.Services]
AddService=usbser, 0x00000002, DriverService.nt

[DriverService.nt]
DisplayName=%SERVICE%
ServiceType=1
StartType=3
ErrorControl=1
ServiceBinary=%12%\usbser.sys

;---------------------------------------------------------------------
;  Windows XP/Server2003/Vista/Server2008/7 - 64bit Sections

[DriverInstall.NTamd64]
include=mdmcpq.inf
CopyFiles=DriverCopyFiles.NTamd64
AddReg=DriverInstall.NTamd64.AddReg

[DriverCopyFiles.NTamd64]
usbser.sys,,,0x20

[DriverInstall.NTamd64.AddReg]
HKR,,DevLoader,,*ntkern
HKR,,NTMPDriver,,usbser.sys
HKR,,EnumPropPages32,,"MsPorts.dll,SerialPortPropPageProvider"

[DriverInstall.NTamd64.Services]
AddService=usbser, 0x00000002, DriverService.NTamd64

[DriverService.NTamd64]
DisplayName=%SERVICE%
ServiceType=1
StartType=3
ErrorControl=1
ServiceBinary=%12%\usbser.sys

;---------------------------------------------------------------------
;  Vendor and Product ID Definitions

[SourceDisksFiles]
[SourceDisksNames]
[DeviceList]
%DESCRIPTION%=DriverInstall, USB\VID_f055&PID_9800&MI_00, USB\VID_f055&PID_9800&MI_01, USB\VID_f055&PID_9801&MI_00, USB\VID_f055&PID_9801&MI_01, USB\VID_f055&PID_9802

[DeviceList.NTamd64]
%DESCRIPTION%=DriverInstall, USB\VID_f055&PID_9800&MI_00, USB\VID_f055&PID_9800&MI_01, USB\VID_f055&PID_9801&MI_00, USB\VID_f055&PID_9801&MI_01, USB\VID_f055&PID_9802

;---------------------------------------------------------------------
;  String Definitions

[Strings]
MFGFILENAME="pybcdc"
MFGNAME="MicroPython"
DESCRIPTION="Pyboard USB Comm Port"
SERVICE="USB Serial Driver"

 

 

After fixing problem with the driver, the board is fully accessible. Any client can be used, I like puTTY

image

the board comes with following message:

image

MicroPython v1.13-96-g1dc64359d on 2020-10-07; PYBv1.1 with STM32F405RG

 

Micropython

@micropython MicroPython runs on a variety of systems and hardware platforms particularly is designed to be capable of running on microcontrollers.

It is fine described https://micropython.org    https://github.com/micropython

Let's begin playing with the board using  Micropython at the beginning.

look at help as suggested

>>> help()

Welcome to MicroPython!

For online help please visit http://micropython.org/help/.

Quick overview of commands for the board:
  pyb.info()    -- print some general information
  pyb.delay(n)  -- wait for n milliseconds
  pyb.millis()  -- get number of milliseconds since hard reset
  pyb.Switch()  -- create a switch object
                  Switch methods: (), callback(f)
  pyb.LED(n)    -- create an LED object for LED n (n=1,2,3,4)
                  LED methods: on(), off(), toggle(), intensity(<n>)
  pyb.Pin(pin)  -- get a pin, eg pyb.Pin('X1')
  pyb.Pin(pin, m, [p]) -- get a pin and configure it for IO mode m, pull mode p
                  Pin methods: init(..), value([v]), high(), low()
  pyb.ExtInt(pin, m, p, callback) -- create an external interrupt object
  pyb.ADC(pin)  -- make an analog object from a pin
                  ADC methods: read(), read_timed(buf, freq)
  pyb.DAC(port) -- make a DAC object
                  DAC methods: triangle(freq), write(n), write_timed(buf, freq)
  pyb.RTC()     -- make an RTC object; methods: datetime([val])
  pyb.rng()     -- get a 30-bit hardware random number
  pyb.Servo(n)  -- create Servo object for servo n (n=1,2,3,4)
                  Servo methods: calibration(..), angle([x, [t]]), speed([x, [t]])
  pyb.Accel()  -- create an Accelerometer object
                  Accelerometer methods: x(), y(), z(), tilt(), filtered_xyz()

Pins are numbered X1-X12, X17-X22, Y1-Y12, or by their MCU name
Pin IO modes are: pyb.Pin.IN, pyb.Pin.OUT_PP, pyb.Pin.OUT_OD
Pin pull modes are: pyb.Pin.PULL_NONE, pyb.Pin.PULL_UP, pyb.Pin.PULL_DOWN
Additional serial bus objects: pyb.I2C(n), pyb.SPI(n), pyb.UART(n)

Control commands:
  CTRL-A        -- on a blank line, enter raw REPL mode
  CTRL-B        -- on a blank line, enter normal REPL mode
  CTRL-C        -- interrupt a running program
  CTRL-D        -- on a blank line, do a soft reset of the board
  CTRL-E        -- on a blank line, enter paste mode

For further help on a specific object, type help(obj)
For a list of available modules, type help('modules')

 

review commands listed above

>>> pyb.info()

ID=xxxxxx
S=168000000
H=168000000
P1=42000000
P2=84000000
_etext=807401c
_sidata=8074024
_sdata=20000000
_edata=2000001c
_sbss=2000001c
_ebss=20002294
_sstack=2001bff8
_estack=2001fff8
_ram_start=20000000
_heap_start=20002294
_heap_end=2001bff8
_ram_end=20020000
qstr:
  n_pool=1
  n_qstr=3
  n_str_data_bytes=28
  n_total_bytes=124
GC:
  103360 total
  1536 : 101824
  1=23 2=5 m=40
LFS free: 88576 bytes

 

CTRL D

image

Time-related commands

rtc = pyb.RTC()
rtc.datetime((2021, 6, 19, 3, 12, 0, 0, 0))
print(rtc.datetime())

image

control of LEDs 1-4

“1”  means off!  “0” lits a LED

pyb.LED(1).off() #   LED1 lits 
print(pyb.LED(1).intensity()) #? doesn’t work?

toggle command

pyb.LED(1).toggle()

 

 

and others - we can see our board is fully compatible with micropython/ Pyboard standard.

pyb.repl_uart(pyb.UART(1, 9600)) # duplicate REPL on UART(1)
pyb.wfi() # pause CPU, waiting for interrupt
pyb.freq() # get CPU and bus frequencies
pyb.freq(60000000) # set CPU freq to 60MHz
pyb.stop() # stop CPU, waiting for external interrupt

 

image

 

Getting a MicroPython REPL prompt

- as desribed   https://docs.micropython.org/en/latest/esp8266/tutorial/repl.html

image

image

 

pyb — functions related to the board (PyBoard)

https://docs.micropython.org/en/latest/pyboard/tutorial/switch.html

sw = pyb.Switch()
sw.value()

image

image

The switch object have one useful feature: the sw.callback() function.

The callback function sets up something to run when the switch is pressed, and uses an interrupt.

sw.callback(lambda:print('press!'))

image

 

sw.callback(lambda:pyb.LED(1).toggle())

This will toggle the red LED each time the switch is pressed. And it will even work while other code is running.

image

To disable :

sw.callback(None)

 

class Pin – control I/O pins

https://docs.micropython.org/en/latest/library/machine.Pin.html

class Pin – control I/O pins

https://docs.micropython.org/en/latest/library/pyb.Pin.html

http://docs.micropython.org/en/latest/library/pyb.Pin.html#pyb-pin

 

Pins GPIO

http://docs.micropython.org/en/latest/pyboard/quickref.html#pins-an

 

Analog to Digital Conversion

http://docs.micropython.org/en/latest/pyboard/quickref.html#adc-analog-to-digital-conversion 

http://docs.micropython.org/en/latest/esp8266/tutorial/adc.html

 

from pyb import Pin, ADC
adc = ADC(Pin('X19'))
adc.read()    # read value, 0-4095

image

 

digital to analog conversion

from pyb import Pin, DAC
dac = DAC(Pin('X5'))
dac.write(120)

image

 

from pyb import SPI
spi = SPI(1, SPI.MASTER, baudrate=200000, polarity=1, phase=0)
spi.send('hello')
spi.recv(5) # receive 5 bytes on the bus
spi.send_recv('hello')

image

 

CAN bus (controller area network)

from pyb import CAN
can = CAN(1, CAN.LOOPBACK)
can.setfilter(0, CAN.LIST16, 0, (123, 124, 125, 126))
can.send('message!', 123)  # send a message with id 123
can.recv(0)                # receive message on FIFO 0

image

 

PIP

Use pip to install the library.

Pip is installed by default on many newer Python builds. To check and see if it is already installed on our system

pip help

image

or

pip -V

 

Upgrading Pip

python -m pip install --upgrade pip

image

image

In the PyTrinamic folder run "pip install -e."

image

PyTrinamic installation

PyTrinamic is a python library for communicating with TRINAMIC Modules and Evaluation boards.)

pip install PyTrinamic

image

 

PyTrinamicMicro installation

 

This repository provides connection interfaces and example scripts to use TRINAMIC modules aswell as TMCL slave functionality on MicroPython platforms.

It utilizes the PyTrinamic library.

To clone this repository along with all of its submodules from GIT on the PC, use the command:

git clone https://github.com/trinamic/PyTrinamicMicro.git --recurse-submodules

image

After successful import, I got following contents on the SD on the board

image

TMCL -IDE installation

installation went smooth:

image

image

image

The board seems to be recognized properly and ready to cooperate:

image

But...
image

Unfortunately My first joy was too early and all the system had to be adjusted and better prepared.

The only nice working function in the TMCL-IDE was training - virtual mode

 

TMCL-IDE  : Virtual mode

image

image

image

Truly, at that stage I encountered a serious problem with proper setting up the install filesystem and run the board.

I can't say now (after understanding the issues and finally successful run)  that instructions are unclear

but honestly it didn't save me from some mistakes and misunderstanding at the beginning.

First I tried to find the answer looking at Trinamic (MAXIM integrated) foras or its Github. Soon I realized I was not alone.

Very similar problem was reported before on MAXIM community portal : TMCL can't connect to TMC EVAL or TMCM

https://maximsupport.microsoftcrmportals.com/en-us/knowledgebase/article/KA-14692

or: https://maximsupport.microsoftcrmportals.com/en-us/knowledgebase/article/KA-12170

image

Unfortunately it wasn't solved. I decided to use official Trinamic Technical Support.

I opened new case CAS-144538-W1K0F4 https://maximsupport.microsoftcrmportals.com/en-US/edit-loggedin/?id=2f8cbb10-a8b5-eb11-89ee-0004ffa52304

Among confirmation of some basic assumptions concerning supply of motor and the module, starting sequence etc…

"Start with power supply off "is a precaution before connecting the wiring connections from and to the board.

Also there are logic supply connections such as +3.3V and main motor supply +Vcc so for the proper working we need both the connections

(ie it cannot work only if you provide 3.3 to SPI connections externally). As we have the on-board DC-DC converter, power from +Vcc itself

is sufficient to provide the logic power supply (+3.3V)too. That s the meaning of they can be driven by same source.”

There was also “a little” confusing informations and suggestions…

“The communication of TMCM-0960 is possible with TMCL-IDE but default communication is via terminal

You can check out the  python code given in our official github link here: https://github.com/trinamic/PyTrinamic.”

and finally I was forced to reinstall the firmware:

"Yes it is necessary to build the micropython in STM32.

Yes it required to install the serial port drivers pybcdc.inf from the root of the attached storage. You need to install without the SD card installed.”

The last sentence worried me indeed:

“As TMCM-0960 is not intended for usage with TMCL-IDE, you can neglect the errors in it. You can use it from the terminal using micropython.”

 

I was sure an important part of my roadtest would be discovering the TMCL-IDE with all its features and benefits. That message was shocking.

That was a frustrating experience. Moreover, even the onboard micropython was unavailable or I couldn't run it.

The help came from and !

Thanks to the very friendly support of   soon I could continue the work.

 

I realized some mistakes as installation/ cloning of the repositories in the wrong directories

C:\Users\marek>git clone https://github.com/trinamic/PyTrinamicMicro.git --recurse-submodules

image

install.py - failed

image

 

The problem was fixed after changing co C:\

image

the right contents of the trinamic folder after clone on the disc:

image

comparison of right/ wrong folder sizes from successful/ failed installations

image

successful installation of the py on the board (SD card):

py install.py E:\

image

On the boards SD card I have now:

image

I moved the main.py and boot.py scripts out of PyTrinamicMicro/platforms/motionpy1
image

to the root

image

 

Run "blinky" example

The first, simple  test if trinamic library (PyTrinamicMicro) was  properly installed was blinky.py script

micropython scripts on trinamic board are executed using following syntax

 

exec(open("PyTrinamicMicro/platforms/motionpy1/examples/io/blinky.py").read())

 

exec(MP.script("blinky"))

image

 

The loop can be end with Ctrl C

  image

 

Definitions of leds in blinky script:

leds = [
    ("LEDG1", Pin(Pin.cpu.A13, Pin.OUT_PP), True),
    ("LEDR1", Pin(Pin.cpu.A14, Pin.OUT_PP), False),
    ("LEDG2", Pin(Pin.cpu.A15, Pin.OUT_PP), True),
    ("LEDR2", Pin(Pin.cpu.B4, Pin.OUT_PP), False)
]

 

I could run command lines directly in the console:

ON/Off LED:

 

led[1].value(not(led[1].value()))

 

led[1].value(1)
led[1].value(0)

 

with "leds" defined as in "blinky" example:

leds[1][1].value(0)

 

lets all LEDs lit

image

 

buttons_leds

Next example with use of both LEDs and buttons on the board

 

exec(open("PyTrinamicMicro/platforms/motionpy1/examples/io/buttons_leds.py").read())

that syntax can’t be used

exec(MP.script("buttons_leds"))

image


this is how we define variables for buttons value

val = button[1].value()
print(val)

image

 

image

LEDs are [0] to [3]    led[4] is reported as an error!

image

 

let’s review that script

first we have imports

 

from pyb import Pin
import logging

then definitions

# Define button list for all buttons on board
buttons = [
    ("S1", Pin(Pin.cpu.C3, Pin.IN, pull=Pin.PULL_UP)),
    ("S2", Pin(Pin.cpu.C2, Pin.IN, pull=Pin.PULL_UP))
]

# Define default button states
button_states = {
    buttons[0][0]: 1,
    buttons[1][0]: 1
}


# Define dict to map button to control LED
leds = {
    buttons[0][0]: ("LEDG2", Pin(Pin.cpu.A15, Pin.OUT_PP), False),
    buttons[1][0]: ("LEDR2", Pin(Pin.cpu.B4, Pin.OUT_PP), False)
}

 

now initiate

 

# Prepare Logger
logger = logging.getLogger(__name__)


# Set initial state
for led in leds.values():
    led[1].value(led[2])

and the main loop

while(True):
    for button in buttons:
        val = button[1].value()
        led = leds[button[0]]
        if((val == 0) and (button_states[button[0]] == 1)):
                led[1].value(not(led[1].value()))

        button_states[button[0]] = val


image

image

 

switching ON/ OFF

led[1].value(0) # ON
led[1].value(1) # OFF

led[1].value(led[1])  # OFF
led[1].value(led[2])  #ON

 

image

Logger

 

understanding and testing logger commands in micropython

https://docs.python.org/3/library/logging.html

logging.getLogger(__name__)

image

 

logger.info("Blinky for all LEDs on board")

image

 

logger.debug("New {} state: {}".format(led[0], led[1].value()))

image

 

logger.debug("New {} state: {}".format(led[0], led[1].value()))

image

 

logger = logging.getLogger(__name__)

 

logger.info("test")

image

logger.debug

image

 

PyTrinamicMicro/platforms/motionpy1/examples/tmcl_analyzer/can_logger.py

exec(open("PyTrinamicMicro/platforms/motionpy1/examples/tmcl_analyzer/can_logger.py").read())

>>> exec(open("PyTrinamicMicro/platforms/motionpy1/examples/tmcl_analyzer/can_logger.py").read())

[2015-1-1 1:1:28] [__main__] [INFO] CAN Logger

[2015-1-1 1:1:28] [__main__] [INFO] Initializing interface ...

[2015-1-1 1:1:28] [__main__] [INFO] Interface initialized.

[2015-1-1 1:1:28] [__main__] [INFO] Initializing tmcl_analyzer ...

[2015-1-1 1:1:28] [__main__] [INFO] tmcl_analyzer initialized.

[2015-1-1 1:1:28] [__main__] [INFO] Start logging.

 

correct board time using RTC to get propper logs date/time

>>> exec(open("PyTrinamicMicro/platforms/motionpy1/examples/tmcl_analyzer/can_logger.py").read())

[2021-6-19 12:1:24] [__main__] [INFO] CAN Logger

[2021-6-19 12:1:24] [__main__] [INFO] Initializing interface ...

[2021-6-19 12:1:24] [__main__] [INFO] Interface initialized.

[2021-6-19 12:1:24] [__main__] [INFO] Initializing tmcl_analyzer ...

[2021-6-19 12:1:24] [__main__] [INFO] tmcl_analyzer initialized.

[2021-6-19 12:1:24] [__main__] [INFO] Start logging.

 

 

 

and other useful commands from  PyTrinamicMicro/platforms/motionpy1/tests/interfaces/

version.py

image

 

 

can_version.py
image

Rotate

Let's finally run the whole set. After connecting motor

I ran TMCM1270_rotate.py example script

exec(open("PyTrinamicMicro/platforms/motionpy1/examples/modules/TMCM1270/TMCM1270_rotate.py").read())

After success I tried to explore and learn examples from the PyTrinamic library.

image

Unfortunately scripts dedicated to TMCM_1270 "TMCM_1270_TMCL_rotateDemo.py" can't be run in my case

 

exec(MP.script("TMCM_1270_TMCL_rotateDemo.py"))

Traceback (most recent call last):

  File "<stdin>", line 1, in <module>

  File "PyTrinamicMicro/platforms/motionpy1/MotionPy.py", line 30, in script

  File "PyTrinamicMicro/PyTrinamicMicro.py", line 37, in script

TypeError: can't convert 'NoneType' object to str implicitly

 

exec(open("PyTrinamic/examples/modules/TMCM_1270_TMCL_rotateDemo.py").read())

Traceback (most recent call last):

  File "<stdin>", line 1, in <module>

OSError: [Errno 2] ENOENT

 

PyTrinamic/examples/modules/TMCM_1270/TMCM_1270_TMCL_rotateDemo.py

exec(open("PyTrinamic/examples/modules/TMCM_1270/TMCM_1270_TMCL_rotateDemo.py").read())

image

>>> exec(open("PyTrinamic/examples/modules/TMCM_1270/TMCM_1270_TMCL_rotateDemo.py").read())

Traceback (most recent call last):

  File "<stdin>", line 1, in <module>

  File "<string>", line 11, in <module>

  File "PyTrinamic/connections/ConnectionManagerPC.py", line 9, in <module>

  File "PyTrinamic/connections/pcan_tmcl_interface.py", line 7, in <module>

ImportError: no module named 'can'

 

image

 

I decided to merge and modify above scripts to use : buttons, LEDs and  rotate motor

script: rotate_button.py

 

from pyb import Pin
import logging
import time    # gdy  uzyjemy polecenia time()

from PyTrinamic.modules.TMCM1270.TMCM_1270 import TMCM_1270
from PyTrinamicMicro.platforms.motionpy1.connections.can_tmcl_interface import can_tmcl_interface

from pyb import Pin
import time

# Define button list for all buttons on board
buttons = [
    ("S1", Pin(Pin.cpu.C3, Pin.IN, pull=Pin.PULL_UP)),
    ("S2", Pin(Pin.cpu.C2, Pin.IN, pull=Pin.PULL_UP))
]

# Define default button states
button_states = {
    buttons[0][0]: 1,
    buttons[1][0]: 1
}


# Define dict to map button to control LED
leds = {
    buttons[0][0]: ("LEDG2", Pin(Pin.cpu.A15, Pin.OUT_PP), False),
    buttons[1][0]: ("LEDR2", Pin(Pin.cpu.B4, Pin.OUT_PP), False)
}

rotation = {
    buttons[0][0]:  5000,
    buttons[1][0]: 1000
}

# Prepare Logger
logger = logging.getLogger(__name__)

# Set initial state
for led in leds.values():
    led[1].value(led[2])

con = can_tmcl_interface()
module = TMCM_1270(con)
en = Pin(Pin.cpu.A4, Pin.OUT_PP)

en.low()
while(True):
    for button in buttons:
        val = button[1].value()
        led = leds[button[0]]
    engine = rotation[button[0]]
        if((val == 0) and (button_states[button[0]] == 1)):
            led[1].value(not(led[1].value()))
            module.rotate(0, engine)
            time.sleep(5)
            module.stop(0)
            led[1].value(1)
    button_states[button[0]] = val

en.high()
con.close()

working as follow:

 

TMCL commands.

after fixing imports

from PyTrinamic.modules.TMCM1270.TMCM_1270 import TMCM_1270
from PyTrinamicMicro.platforms.motionpy1.connections.can_tmcl_interface import can_tmcl_interface
from pyb import Pin
import time

and definitions

myInterface= can_tmcl_interface()
Module_1270 = TMCM_1270(con)

 

Many trinamic micropython commands can be run directly in shell.

I used it to test TMCL commands defined and  described in  “TMCLReference and ProgrammingManual”

(TMCL_reference_2015.pdf)

e.g.  these lines calls ROR and resulting the same action - rotate motor:

Module_1270.setAxisParameter(Module_1270.APs.TargetVelocity,0,40000)
Module_1270.setAxisParameter(2,0,40000)
Module_1270.rotate(0,40000)
myInterface.send(5, 2, 0, 40000)

 

the example of possibility of different calling TMCL commands is shown below

scripts from METHOD1 and METHOD 2 do the same job:

method 1

from PyTrinamicMicro.platforms.motionpy1.connections.can_tmcl_interface import can_tmcl_interface
from PyTrinamic.TMCL import TMCL_Command, TMCL_Request, TMCL_Reply
con = can_tmcl_interface()
con.send(TMCL_Command.SAP, 5, 0, 10000, 1)
con.send(TMCL_Command.ROR, 0, 0, 50000, 1)
con.send(TMCL_Command.MST, 0, 0, 0, 1)
con.send(TMCL_Command.SAP, 4, 0, 50000, 1)
con.send(TMCL_Command.MVP, 1, 0, 50000, 1)

 

method 2 with defining "module"

from PyTrinamicMicro.platforms.motionpy1.connections.can_tmcl_interface import can_tmcl_interface
from PyTrinamic.modules.TMCM1270.TMCM_1270 import TMCM_1270
con = can_tmcl_interface() 
module = TMCM_1270(con)
module.setMaxAcceleration(0, 10000)
module.rotate(0, 50000)
module.stop(0)
module.setMaxVelocity(0, 50000)
module.moveBy(0, 50000)

 

unfortunately in my case module.moveBy(0, 50000) is faulty

 

image

I tried to change syntax but unsuccessfully

image

 

Nevertheless, as we can see all above commands are simple and useful

 

con.send(1, 2, 0, 40000)  #rotate the motor right
con.send(2, 2, 0, 40000)  #rotate the motor left
con.send(3, 2, 0, 40000)  #stop motor
con.send(5, 2, 0, 40000)  # move by...

image

 

Everything went fine until  I encountered some troubles trying to run scripts tested before.

details and problem analysis below:

from PyTrinamicMicro.platforms.motionpy1.connections.can_tmcl_interface import can_tmcl_interface

from PyTrinamic.TMCL import TMCL_Command, TMCL_Request, TMCL_Reply

 

image

ImportError: can't import name TMCL_Command

 

TMCL_Command can't be imported!!!!

instead TMCL_Command now, should be TMCL !!!!!!!!!!!!!!!

changes in GIT trinamic as we can see TMCL_Command isn't there anymore:

image

image

image

the correct line:

from PyTrinamic.TMCL import TMCL, TMCL_Request, TMCL_Reply

or:

from PyTrinamic.TMCL import TMCL, TMCL_Request, TMCL_Reply, TMCL_Status

 

con = can_tmcl_interface()

still some errors as we should forget about TMCL_Command

con.send(TMCL_Command.SAP, 5, 0, 10000, 1)

con.send(TMCL_Command.ROR, 0, 0, 50000, 1)

con.send(TMCL_Command.MST, 0, 0, 0, 1)

con.send(TMCL_Command.SAP, 4, 0, 50000, 1)

con.send(TMCL_Command.MVP, 1, 0, 50000, 1)

NameError: name 'TMCL_Command' isn't defined

 

replacing it with TMCL.COMMANDS

con.send(TMCL.COMMANDS[“SAP”], 5, 0, 10000, 1)

con.send(TMCL.COMMANDS[‘SAP’], 5, 0, 10000, 1)

con.send(TMCL.COMMANDS[‘ROR’], 5, 0, 10000, 1)

con.send(TMCL.COMMANDS[‘MST’], 0, 0, 0, 1)

con.send(TMCL.COMMANDS[‘SAP’], 4, 0, 50000, 1)

con.send(TMCL.COMMANDS[‘MVP’],  1, 0, 50000, 1)

image

Changing argument for "move by":

image

 

Running motor using TMCL- IDE

tmcl_slave -  only board without the motor

If we want to use TMCL- IDE the board must be in the  slave mode

E:\PyTrinamicMicro\platforms\motionpy1\examples\tmcl_slave

image

tmcl_slave_usb.py

exec(open("PyTrinamicMicro/platforms/motionpy1/examples/tmcl_slave/tmcl_slave_usb.py").read())

 

image

 

no motor - no errors in slave mode:

image

image

image

[1] 23:30:32.590> Get version 0 ‹01 88 00 00 00 00 00 00 89 | 02 30 39 36 30 56 31 30 30› 0960V100

[1] 23:30:32.611> Get version 1 ‹01 88 01 00 00 00 00 00 8A | 02 01 64 88 09 3C 01 00 35› : V 1.00

[1] 23:30:32.621> Get version 0 ‹01 88 00 00 00 00 00 00 89 | 02 30 39 36 30 56 31 30 30› 0960V100

 

tmcl_bridge -with motor - CAN interface

If we want to run motor using TMCL- IDE, the board must be in the  bridge mode

 

tmcl_bridge_usb_can example

E:\PyTrinamicMicro\platforms\motionpy1\examples\tmcl_bridge

image

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!the script below let us run the motor using TMCL-IDE !!!!!!!!!!!!!!!!!!!!

exec(open("PyTrinamicMicro/platforms/motionpy1/examples/tmcl_bridge/tmcl_bridge_usb_can.py").read())

according to the instruction:

  1. Wire up TMCM-1270 and connect it to MotionPy.
  2. Turn on power supply. I did it with 20V.
  3. Attach the MotionPy via USB to the PC.
  4. Connect to the MotionPy via PuTTY
  5. Run the tmcl_bridge_usb_can example.
  6. Close PuTTY without any extra chars sent.
  7. Open TMCL-IDE and scan for ID 1 (default) for just the TMCM-1270 or scan for ID range 1 to 3 to additionally have the MotionPy control instance.

image

image

image

image

Logging:

[1] 23:26:22.879> Get version 0 ‹01 88 00 00 00 00 00 00 89 | 02 31 32 37 30 56 31 30 30› 1270V100

[1] 23:26:23.043> Get version 1 ‹01 88 01 00 00 00 00 00 8A | 02 01 64 88 04 F6 01 00 00› : V 1.00

[1] 23:26:23.163> Get version 0 ‹01 88 00 00 00 00 00 00 89 | 02 31 32 37 30 56 31 30 30› 1270V100

[1] 23:26:23.747> Get version 0 ‹03 88 00 00 00 00 00 00 8B | 02 30 39 36 30 56 31 30 30› 0960V100

[1] 23:26:23.831> Get version 1 ‹03 88 01 00 00 00 00 00 8C | 02 03 64 88 09 3C 01 00 37› : V 1.00

[1] 23:26:23.843> Get version 0 ‹03 88 00 00 00 00 00 00 8B | 02 30 39 36 30 56 31 30 30› 0960V100

 

supply 24V

image

Testing additional features for motor control offered by TMCL-IDE

 

I revieved also availability of direct TMCL commands in the IDE

image

 

GAP get axis parameter

image

image

image

image

image

image

 

 

image

visualization of breaking the motor with support of StallGuard:

image

 

StealtChop function enabling

image

Time to end it at last and summarize

I'm impressed with easinnes of control motor using micropython. Availability of TMCL commands made me confused, I managed to use and examine only small section.

Appreciating simple scripts or single-line commands in shell I can't neglect more powerful tool as TMCL- IDE. Among user friendly interface and many ergonomic add-ons

I want to emphasize all visualization and reporting outfit of that program. It is perfect in prototyping stage, for debugging and testing motor applications.

I wish I  use more TMCL-IDE features and learn how to control motor more efficient, smoother and quiet.

Another highlight is PANdrive motor with control module based on CAN interface.

PD42-1270 stepper is smart indeed. I just started to get familiar with most famous and most advertised functions as  StealthChop or StallGuard. But still a few more remained to be learned deeply.

On the other hand TMCM-0960 board impesses with diversity of interfaces. I hope to extend my project soon and try to employ the RS485 and its SPI as well.

BTW I hope to fulfill my last task and decipher "TMCM-0960-MotionPy offers a total of 13 functions via Python" I sincerely hope to get info which are these 13 functions...

Thank you Trinamic/ Maxim Integrated thank you Element14 for given chance to have very informative and educative adventure.

I must apologize for delay and most of all for excess of material in that report.

I feel it should be selected more radically but on the other hand I hope some information would be helpful for somebody entered the realm of MotionPy boards and PANdrives

Anonymous
Parents Comment Children