My goal is to build a low cost stand alone public domain reference design of a stepper motor analyzer that can be used by makers to measure performance and diagnose issues with stepper motors in 3D printers and such.
The hardware is very simple, a STM32F401CE blackpill connected to the analog output of two ACS70331 current sensors that measure the current of the stepper coils and a 3.5" 480x320 touch screen for the user interface. Most fo the difficult part already works and now I make final touches before designing the PCB.
LVGL related points:
- I started with a STM32F103 CPU but pretty much realized that is doesn’t have sufficient resourced to use LVGL with my display so upgraded to STM32F401CE (faster and more ROM/RAM).
- I started driving the ILI9488 480x320 display with SPI because of it’s simplify but got a terrible screen refresh time, especially when adding a new point to a large shifting chart, so switched to 16 bit parallel data path to the TFT.
- I am running LVGL in 8 bits color depth which works well, but the ILI9488 doesn’t support 8 bit colors in parallel mode so I am using a lookup table uint8_t -> uint16_t which maps the 8 bit colors from the LVGL to 16 bit color to send to the TFT.
- Because of pins restrictions on the MCU I couldn’t allocate a whole 16 bit port to the TFT parallel output and had to spread the bits across 2 ports, A and B. To be able to update just those bits fast, I am using two lookup tables uint8_t -> uint32_t that takes a 8 bit target value and return the 32bit value to write to the BSSR register to set this value without affecting other bits. These two tables and the color table mentioned above are using in my LVGL TFT driver in an optimized loop.
- Because my 16 bits to the TFT are spread across ports, I couldn’t find a reasonable way to update the TFT with DMA. Therefore I am using a single LVGL buffer.
- The fonts that came with LVGL are not monospaced and as a results, numeric fields that update frequently didn’t look good, jumping with each value change. I ended up editing the fonts to have just 0-9 having fixed size and it looks much better now.
- So far I didn’t need to do any special LVGL RAM optimizations, such as creating screens and widgets dynamically only when I need them. It makes things simpler.
- I am using platformio and let it manage the LVGL library and this works very well. I specified a specific LVGL version to avoid surprises.
- I am using the LVGL simulator to experiments with new widgets but once I move it to the actual hardware I drop the simulator and tweak the real thing.
- Still need to figure out how to capture screen shots for publication. Got some ideas from a thread here. Builtin support from LVGL would be useful, especially for projects that can’t buffer an entire screen.
- Having access to the LVGL source code is very useful and replaces missing details in the documentation For example the documentation doesn’t mention if styles that are passed to macros are copied or the user’s point is retained so I can check the source code.
This osciloscope like screen captures current signals from the stepper motor coils. It uses a trigger detection that position the signals at a consistent position on the chart. Stepper signals look healthy here.
This screen shows an histogram of coil current as a function of stepper speed. In this example, the current drops at about 1K steps/sec because of high inductance and insufficient supply voltage.
This screen shows the stepper coils currents at higher speed. Looks non healthy. Another indication of high inductance and low supply voltage.
This one is a live gauge that shows the momentary stepper speed. The LVGL works very well and I can easily update > 10fps.
This the home screen with various information about the data collected. Stepper coil current, quadrature errors detected, accumulated steps, and so on.