I'm starting to scratch the surface by spending several hours going through parameters. I can see many opportunities for different projects. I believe this is most of them with some casual comments.
do you find they give the steppers the same holding power whilst stationery as your other driver boards?
There are settings to set the full current that your stepper can take and a second setting that it will go to when not moving. Is your window blind design come unraveled once up? If not, you could set the secondary current to zero and it'll not be drawing in power. If you need some, to hold it up, then you can fine tune it to minimize energy/heat and still keep it up.
On robot project, I see several unique opportunities.
- Has two ways of delivering energy. One is quieter, one is for better high-speed torque. It can also be configured to go from one (quietly puttering around the house) to barreling up hills at full tilt.
- There is a back feed way of getting data about how much load it is using. Say you want to make a hand and detect when it has gently (egg) or firmly (cast iron skillet) grasped an item of variable size.
- As mentioned above the ability to "idle down" the power when its not needed.
- Extreme high resolution of movement. It has up to 256 micro-steps ability. Thus with a standard stepper motor, you could do dead reconning movements. ie, even if I used my 200mm wheels, I can move in increments of 200 (mm) * Pi / 200 (step/rev) / 256 (micro-steps/step) = 0.012mm
for (u8_t i=0; i<2; i++)
{
// 1. Core Hardware Reset & Init
driver[i].begin();
// Enable driver chopper (0 = disabled, 1-15 = active off-time)
driver[i].toff(4);
// Set comparator blank time (options: 16, 24, 32, 54)
driver[i].blank_time(24);
// Forces the PDN/UART pin into UART communication mode
driver[i].pdn_disable(true);
// Tells the chip to use software/UART registers for microsteps,
// not MS1/MS2 pins
driver[i].mstep_reg_select(true);
// 2. Current & Power Management
// 1st run current in mA (adjust to your motor specs)
// 2nd hold current % of run current.
// Although we put in 2A, the driver will only allow
// 1.76A RMS = 2.00 A peak
// Probably not use on arms needing to hold once still.
driver[i].rms_current(2000, 0.5);
// Standby delay time after motor stops moving (0-255)
// u8 255 ~= 5.57 seconds
driver[i].TPOWERDOWN(20);
// Time while lowering to hold current (0-15) so the sudden
// change doesn't make a sound.
// Values 0 to 15
// equation not worth describing here, ask Google, but
// for our case of 50% hold current 4 ~= 1 second
driver[i].iholddelay(10);
// Initialize TMC2209 Driver Configurations
// Uses the internal voltage not pot on board.
driver[i].I_scale_analog(false);
// 3. Step & Direction Logic
// Step resolution (1, 2, 4, 8, 16, 32, 64, 128, 256)
driver[i].microsteps(16);
// Smooth lower step rates into internal 1/256 interpolation
// Need to evaluate more for the "gear changing" driver.
driver[i].intpol(true);
// Invert physical motor rotation direction (true / false)
driver[i].shaft(false);
// 4. Chopper & Quiet Modes (StealthChop / SpreadCycle)
// false = StealthChop (Quiet), true = SpreadCycle (Torque)
driver[i].en_spreadCycle(true);
// Automatically scale PWM voltage amplitude for quietness
driver[i].pwm_autoscale(true);
// PWM frequency selection (0=2/1024, 1=2/683, 2=2/512 fCLK)
// 0=cooler, but noisy 2=hotter, quieter
driver[i].pwm_freq(1);
// Hybrid Threshold: Automatically shift from quiet mode
// (Stealth Chop) to high-torque mode (SpreadCycle) at high speeds
// Formula depends on your clock, but lower values =
// triggers at higher physical speeds
// Threshold speed value (0 disables hybrid switching)
// en_spreadCycle must be false for this to be used.
driver[i].TPWMTHRS(0);
// 5. Sensorless Homing & Stall Guard (Only active in SpreadCycle mode)
// StallGuard4 threshold sensitivity (0 - 255). This allows us
// to "feel" resistance, blocking, etc via function SG_RESULT()
// SG_RESULT() = 510 moving freely, 0 maximum load, stalled.
// SGTHRS() sets threshold of "stalled" TODO more study.
driver[i].SGTHRS(100);
// Lower speed threshold required for CoolStep/StallGuard operation
driver[i].TCOOLTHRS(300);
// 6. CoolStep (Dynamic Adaptive Current Scaling)
// Save energy when not under load. TODO: Evaluate more.
// Lower StallGuard value threshold to ramp up current (1-15, 0=off)
driver[i].semin(5);
// Upper StallGuard value threshold to drop current down (0-15)
driver[i].semax(2);
// Current down-step speed scaling bits (00-11)
driver[i].sedn(0b01);
More to come!
Inq
@inq Thanks for the compressive review, I'm now keen to get a couple. And dear me, when checking to see if I could put an order in even though they are currently out of stock (cannot but I can register for an email when re-stocked) I see they (pimoroni) have some nema 17 steppers of various sizes on sale. I know I've got some steppers of various sizes that were purchased for testing some years back, but I don't think I have matching pairs so I might as well get a couple. Oh and mounting brackets.
And then I see they do stepper driver boards (though based on DRV8424P), also on sale, that fit my favourite robot controller board (the Yukon) - best get a couple just in case.
Your return to the forum is really quite wallet draining... But keep it up 😀
Your return to the forum is really quite wallet draining...
I do what I can. 🤣 🤣 🤣
I'll get you into a 3D printer before long and really spend your retirement savings. 😆
What was the reason, you're tied to a specific make. Amazon looks like there are many different clones using that TMC2209 chip with plenty of availability. I'm using the BIGTREETECH versions.
@ inq
No particular reason for the choice of board, but those were the only ones from my usual suppliers, and I'm comfortable with the Adafruit stuff.
I tend to avoid the Chinese suppliers from the like of Aliexpress or Amazon where a lot of their electronic stuff is just direct links to unknown Chinese traders. I do get items directly from the likes of Waveshare and Xiao etc.
I don't spend much on electronic items so the possible extra cost wont amount to much and I like to support my local suppliers in the main. Plus I'm not in any hurry to get these items as I know I wont get round to doing much for a few months. Apart from a few bursts of playing with this hobby in the daytime, like when its too hot to venture outside, I mainly just tinker for few hours in the evening when the mood takes me.
But thanks for the tip on the other boards with the TMC2209 chip 👍 and if the Adafruit one continue to be scarce I will check them out.
Hi @inq,
Great to see you back at the bench, and well done for getting some UART response!
The bad news, is that might tempt me into sermon mode ... I did try to warn you ... so I suggest you look out a hard hat and on-tap beverage!
-----------
I have some of the same BTT TMC2209s, still in their pristine BTT packaging, so your comments prompted me to briefly unseal one. (It is theoretically aimed at a 'pre-loved/past its sell-by date' 3D printer revival, but that is largely virtual at the moment.)
Github shows BTT has three versions of TMC2209 drivers (V1.1 ... V1.3), and provides some documentation.
https://github.com/bigtreetech/BIGTREETECH-Stepper-Motor-Driver/tree/master/TMC2209
The modules I have are V1.3. By chance, I note the V1.2 and V1.3 manuals are rather different. V1.2 aims at describing the driver itself, whilst V1.3 aims at how to use it with BTT SKR3 3D printer control board, as well as describing a variation regarding the UART pins. At first glance, the circuit of V1.2 and V1.3 only differs by a few small, but important ways, so it might be worth looking at the V1.2 version, bearing in mind the thing you are researching might be one of the differences!
------
When I mentioned the boards to plug these drivers into, from AliExpress, I was aware of the two 'extra pins'. My initial thought, though not tested or checked out, was that those two pins are supplied poking both up and down, plus they are Vref and Diag, which will not required to carry a substantial current. Thus, a workaround might be to cut the lower half pin off, preventing shorts, etc. and attach a lead to the upper half, if it is needed to be connected. Of course, this cunning plan has not been tested, so any reader must make their own checks and decisions!!
------
Returning to the UART pins, which are labelled variations on 4-PDN-UART-RX and 5-UART-TX, depending on where you look, it is necessary to look to the TMC2209 chip data sheet to get some visibility.
see https://www.analog.com/media/en/technical-documentation/data-sheets/tmc2209_datasheet_rev1.09.pdf
A microcontroller will usually have a TX UART pin, to transmit data, and an RX UART pin, to receive data. This arrangement allows the pair of pins to be connected to RX and TX data pins of another microcontroller or similar, so that each TX can set the level high or low at any moment in time, independent of what the other TX is sending.
The driver module pin matches the 'aspiration', with its 0.1" spaced pins 5 (TX) and 4 (RX).
But, the TMC2209 chip has only one combined pin for data to transmit and receive, leaving the driver module designer (and subsequently its user) with a conundrum of how to connect two board pins with one chip pin.
Two further problems for the user are:
(1) the same chip pin must be pulled low to enable a power down (power reduction?) function
(2) One of the variations between BTT's V1.2 and V1.3 board concerns the PCB track print design between these pins.
(I recall a similar situation of combining TX and RX arising from a discussion about an RC circuit some years ago.)
-----------
If your microcontroller software only transmits to the TMC2209, then a direct connection on the driver board will suffice. Similarly, if the TM2209 only ever sends data, never needs to receive any. The tricky case is when bidirectional data flow is required.
Section 4.3 of the TC2209 data sheet I referenced before, starts to suggest how the RX/TX pins should be connected to allow bidirectional flow. The simplest being the left-hand option in Figure 4.1
This has a 1kOhm resistor between pins 4 and 5.
My interpretation of BTT's V1.3 manual is that there is provision for this resistor, labelled R10, shown on pages 6 and 7 of the BTT V1.3 manual, but that this resistor is not fitted. (This means surface mount soldering.)
My interpretation of the V1.3 schematic, is that the TMC2209 chip pin directly connects to the RX board pin, so that alternately, the 1kOhm resistor, possibly wire ended, could be physically connected closer to the microcontroller, as 'intimated' on the schematic above.
----------
I think I can visualise how a microcontroller might also be able to provide the power down (reduction), by changing the RX pin to an output, set to low, at times when UART data flow is not required, but I haven't even read enough on this subject yet.
-----------
As I haven't wired any of this, I might be missing something, but hopefully it is a useful contribution.
Best wishes, Dave
I noticed the Adafruit board for the TCM2209 only had one pinhole marked UART when provoked by @inq to think of getting one (which was out of stock) and I did wonder how that would work. A jolly useful sermon this is and I must check theres some MicroPython samples of using this board before I buy them incase I'm back in c land to get it to work properly.
After doing a trivial small task of making MP run a C function, I'm not sure I want to bother with c again 😀. A crawling paced MP may entice me but I like an easy life.
My interpretation of the V1.3 schematic, is that the TMC2209 chip pin directly connects to the RX board pin, so that alternately, the 1kOhm resistor, possibly wire ended, could be physically connected closer to the microcontroller, as 'intimated' on the schematic above.
Once my major fight with AI about using which pin on the BTT TMC2209 was resolved, the 1K ohm resistor mixing UART RX/TX worked fine. The pins that normally set the micro-stepping on A4988, DRV8825 boards also does the same for these boards IF you're not using UART. If you do use UART, then it uses these pins to assign the UART address so you can configure up to four drivers running on the single line UART. Here I have two running on the UART line and am able to set the configuration and get diagnostics back.
Hi @byron,
Good to hear from you ... I hope you are keeping fit and healthy.
TMC2xxx modules seem to be a variable commodity ... the actual chip, if you go for something like TMC2009 may be fairly constant, although I wouldn't be surprised to find someone has been reprinting the chip markings onto a fake ...
The variability is in the multitude of ways that 16 (sometimes +2) pin dil board PC can be assembled. I have a photo I found on the web a year or so ago, with 10 variants for TMC2009, and only one (V1.2) was from BTT, and Adafruit wasn't among them.
I bought mine to hopefully match with a replacement 3D printer motherboard, and noted BTT make an effort to provide 'some' documentation. Typically, Adafruit also provide documentation (It wasn't relevant, so I haven't looked), so it may be a better choice for someone aiming for a complete design, rather than my intention.
As for which language, I shall be aiming for Marlin firmware, so I am compiling C++, but not intending to do a significant amount of coding.
I confess, I still haven't quite understood why Python is so popular, since I find some of its simplest common constructs confusing, but that is probably just my ignorance.
Best wishes and take care, Dave
@byron, et al,
I have spent probably five or six hours working with the TMC2209 and these rather large 17HS19-2004S1 steppers. I thought I'd give you an update so I'm not leading you down a garden path.
The Good
- Depending on settings, they are dead quiet.
- They are highly configurable depending on you needs.
- I will definitely use them for their feedback like the torque sense feature in a hand I'd like to make.
- At low/medium speeds they seem to have a lot of torque, but these steppers are large and do anyway.
The Not So Good
For Inqster and my initial, primary motive force I was first testing to see how fast I could drive them. I was rather disappointed that they would just slam stop at around 400 rpm. It didn't matter whether I did the basic loop() function of write the pin high, pause, pin low, long pause between micro steps or use the AccelStepper library. They both halted around 400 rpm. Now for raising/lowering blinds, you certainly won't need even this speed unless you want to blink you house windows at the neighbors. 😆
I first asked what the top speed should be. Gemini said, "500 to 600 rpm." I was surprised since the small steppers I used in InqEgg would happily top 2000 rpm. This is where Gemini started educating me about back-EMF and that these larger steppers tend to be worse. As I understand it, the motor also acts like a generator and this energy is opposite the driving energy and at some point they cancel out each other and won't accelerate anymore. Because the TMC2209 has a lot of "smarts" it detects it as a fault and stops.
After going through all the settings, learning what they do and why with Gemini, I made many settings changes that did increase the speed to nearly 900 rpm, but at the expense of noise. Still feeling like I was leaving too much headroom on the table, I reconnected the DRV8825 driver and used my custom stepper driver that using the hardware timer with 25 nano-second accuracy on the step firing. This popped my top speed to 1700 rpm. Although this is totally beyond what I need, I also expect the back-EMF and a fully loaded bot to win-out long before this. Although noisy, it was about the same as the TMC2209 trying to get to 900rpm.
I asked Gemini, why did the DRV8825 did so much better - The DRV8825 outpaced the TMC2209 at extreme speeds because it lacks the internal back-EMF current protection and StealthChop voltage limitations inherent to TMC drivers. While the TMC2209 is a superior driver for noise reduction, efficiency, and smoothness, its advanced safety and silence algorithms active-brake the motor at high frequencies where the raw, unfiltered output of the DRV8825 can still spin it.
I'll be using the DRV8825 for the drive wheels. 1700 rpm with 200 mm wheels = 64 km/hr. 😆
thanks for the update. But I'll be able to see for myself as they were back in stock this morning and I ordered a couple and they should arrive tomorrow with the pair of smallish NEMA17 steppers. Quiet operation and slow/moderate speed is probably just what I want of them as I think I will put these into a small self balancing bot test rig to play with indoors.
I must be getting keen to have a bash at this as going to bed last night I was having a metal block on thinking how using a PID to balance the bot thus driving the wheels back and forth to maintain the balance, how would I be able to make the bot to go in a steady forward motion and still maintain its balance.
But a short research this morning and it's all clear, Well maybe 😎 , I shall see, but first up I will have to design and print a bot chassis. Which will have to come after I've finish my room renovation, and more urgently get my internet connection sorted. // a short rant - bloody skylink - Ah thats better 😀
I must be getting keen to have a bash at this as going to bed last night I was having a metal block on thinking how using a PID to balance the bot thus driving the wheels back and forth to maintain the balance, how would I be able to make the bot to go in a steady forward motion and still maintain its balance.
@robotbuilder dropped this link for me on one of the cross-breeding topics going on. I skimmed it and watched the video and it does have some interesting techniques with PID and something that will auto tune it that was news to me. I bookmarked it and haven't decided to embrace it or try the problem from first principles on my own, so it nagging me from my bookmarks. https://projecthub.arduino.cc/RolfK/two-wheeled-self-balancing-robot-with-stepper-motor-9ecd74
Inq
Here's the first test with all the drive hardware.
- (1) ESP32-S3 - Overkill for this stage of the project. An ESP8266 would work this just as easily.
- (2) DRV8825 - Stepper Motor Drivers
- (2) 17hs19-2004s1 Stepper Motors
- (2) 100 uF Capacitors
- (2) 3D Printed wheels, stepper motor mounts
- ... and some wood for making the awful violin noises.
Here driving to 1000 rpm => 23 mph, 37.7 km/h
As you mentioned somewhere about getting a self balancing robot to train itself to balance, you may find this video series of interest. (Shawn Hymel)
I suppose it may be of interest if the goal is to pursue an understanding of the utilisation of AI, but I'ii be sticking with homebrewed hacking to see if I can train myself to complete the task of making a 2 wheeled bot balance, and to move along a specified route with some sort of positioning system, rather that a random path with just collision avoidance. Probably some sort of Ultra Wide Band setup, or I've read that maybe bluetooth ranging will be up to the job in a small area. Something for me to read up on. But it may end up as a faceplanting bot.
... I'ii be sticking with homebrewed hacking...
If you mean to try of "discovering it for yourself" or at least working it out, I kind of agree. If it can be done with a lowly Arduino and toy motors, it's a pretty mature cookbook project. I haven't exactly decided how I'm going to approach the problem yet.
I'm pretty much hammer-down on the house project. Still cautiously optimistic on my deadline.
But, I may explore several ways of doing it once the hardware comes in. The contenders:
- Proportional, Integral, Derivative (PID)
- https://electricdiylab.com/diy-self-balancing-robot/
- https://www.diva-portal.org/smash/get/diva2:1462103/FULLTEXT01.pdf
- https://hackaday.com/2022/12/27/3d-printed-self-balancing-robot-brings-control-theory-to-life/
- The one @robotbuilder found: https://projecthub.arduino.cc/RolfK/two-wheeled-self-balancing-robot-with-stepper-motor-9ecd74
- Linear Quadratic Regulator (LQR)
- Sliding Mode Control (SMC)
- Artificial Neural Networks (ANN)
- https://www.instructables.com/Arduino-Neural-Network-Self-Balancing-Two-Wheel-Ro/
- I'll add yours, but I'd want to build my ANN engine instead of using libraries (if I can) -
I'd really like to try all four and see which one works best for my scenario. Some of my goals:
- Self balancing
- Offset load - Many of the cookbook designs assume the robot balance point is fixed (strait up). I'd like to be able to have an arm/hand to pick up things which will result in variable balanced angles from an offset load.
- I want it to be able to pick itself up when it does fall.
- Its got to run outside in the yard and tolerate all kinds of terrain.
- It'll have to handle going sideways on hills and not topple over the lateral directions.
- I'd like to explore various navigation:
- Odometry
- Inertial Navigation
- GPS
- I'd like to explore various environment detection methods:
- Camera Vision
- TOF
- Sonar
- Lidar
- Human interaction with voice and hearing
- Putting it all together with some more ANN (AI) which would drive me toward it in the self-balancing portion. I started to dabble with it with InqEgg using the TOF sensor to detect, avoid obstacles and find a wall and follow it around the room.

