<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="https://community.element14.com/cfs-file/__key/system/syndication/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Embedded and Microcontrollers</title><link>https://community.element14.com/technologies/embedded/</link><description>Embedded systems programming, design and products; also microcontrollers, programmable logic, memory, DSP and controllers. </description><dc:language>en-US</dc:language><generator>Telligent Community 12</generator><item><title /><link>https://community.element14.com/technologies/embedded/b/blog/posts/mspm0-project-with-vs-code-cmake-and-gcc---part-7b-middleware-stepper-motor-control-with-a4988-stepper-driver?CommentId=ea856249-658a-47ad-aa77-3da290f12ffa</link><pubDate>Tue, 13 Oct 2026 21:01:00 GMT</pubDate><guid isPermaLink="false">93d5dcb4-84c2-446f-b2cb-99731719e767:ea856249-658a-47ad-aa77-3da290f12ffa</guid><dc:creator>Jan Cumps</dc:creator><description>I&amp;#39;m trying to write similar code for the TI DRV8711 driver. I&amp;#39;ve done it before for a Raspberry Pico. The main exercise should be to translate Pico SPI to MSPM0 SDK SPI. I&amp;#39;ll try to use this as the SPI example: https://dev.ti.com/tirex/explore/node?isTheia=false&amp;amp;node=A__AHKXGvLW5o8tGkje0zlw4A__MSPM0-SDK__a3PaaoK__LATEST&amp;amp;placeholder=true</description></item><item><title /><link>https://community.element14.com/technologies/embedded/b/blog/posts/mspm0-project-with-vs-code-cmake-and-gcc---part-7b-middleware-stepper-motor-control-with-a4988-stepper-driver?CommentId=925e903d-703b-4c72-8eb8-7732126d0957</link><pubDate>Tue, 13 Oct 2026 09:50:00 GMT</pubDate><guid isPermaLink="false">93d5dcb4-84c2-446f-b2cb-99731719e767:925e903d-703b-4c72-8eb8-7732126d0957</guid><dc:creator>Jan Cumps</dc:creator><description>I created a GitHub repo for the Allegro A4988 driver. To use in your project: include(FetchContent) FetchContent_Declare(stepper_driver GIT_REPOSITORY &amp;quot;https://github.com/jancumps/stepper_driver_lib.git&amp;quot; GIT_TAG &amp;quot;origin/main&amp;quot; ) FetchContent_MakeAvailable(stepper_driver) FetchContent_Declare(mspm0_a4988 GIT_REPOSITORY &amp;quot;https://github.com/jancumps/mspm0_a4988_lib.git&amp;quot; GIT_TAG &amp;quot;origin/main&amp;quot; # prevent makefile execution (if any) SOURCE_SUBDIR = ) FetchContent_MakeAvailable(mspm0_a4988) # ... # list C++ module files here set(SOURCES_MODULES ${stepper_driver_SOURCE_DIR}/source/stepper_driver.cpp ${mspm0_a4988_SOURCE_DIR}/source/a4988_mspm0.cpp # ....</description></item><item><title /><link>https://community.element14.com/technologies/embedded/b/blog/posts/esp32-bit-pirate-v1-8-turning-an-esp32-s3-into-an-sdr-and-multi-protocol-hardware-debugging-tool?CommentId=b1e55cd8-981b-4769-bed6-a943808f6910</link><pubDate>Mon, 12 Oct 2026 17:43:00 GMT</pubDate><guid isPermaLink="false">93d5dcb4-84c2-446f-b2cb-99731719e767:b1e55cd8-981b-4769-bed6-a943808f6910</guid><dc:creator>spinden</dc:creator><description>Well done! Exciting project</description></item><item><title>Blog Post: ESP32 Bit Pirate v1.8: Turning an ESP32-S3 into an SDR and Multi-Protocol Hardware Debugging Tool</title><link>https://community.element14.com/technologies/embedded/b/blog/posts/esp32-bit-pirate-v1-8-turning-an-esp32-s3-into-an-sdr-and-multi-protocol-hardware-debugging-tool</link><pubDate>Mon, 12 Oct 2026 13:53:00 GMT</pubDate><guid isPermaLink="false">93d5dcb4-84c2-446f-b2cb-99731719e767:e41dc8df-7b72-4b3d-a48f-7a7ed4c7e211</guid><dc:creator>geotp</dc:creator><description>ESP32 Bit Pirate is an open-source firmware inspired by the original Bus Pirate, designed to turn inexpensive ESP32-S3 development boards into versatile hardware debugging and experimentation tools. The project started as a way to interact with common hardware interfaces such as I2C, SPI and UART without having to write dedicated firmware for every experiment. Since then, it has evolved into a much broader ecosystem combining embedded protocol analysis, wireless communication, firmware extraction, USB adapters and browser-based debugging tools. With the recent releases of v1.7 and v1.8 , several new capabilities have been introduced, including LoRa and Meshtastic analysis, improved protocol sniffing, additional hardware support and, perhaps most interestingly, an experimental SDR implementation using the ESP32-S3&amp;#39;s built-in Wi-Fi radio. One Firmware, Many Hardware Interfaces At its core, ESP32 Bit Pirate provides a command-line interface for interacting with connected hardware. Instead of repeatedly writing and flashing custom Arduino sketches, users can connect a compatible ESP32-S3 board and immediately start exploring different communication protocols. The firmware supports I2C, SPI, UART, 1-Wire, CAN, JTAG/SWD, GPIO, infrared, Wi-Fi, Bluetooth, Sub-GHz, LoRa, RFID and several other interfaces. Depending on the hardware, it can be used to inspect communication buses, identify connected devices, dump EEPROM and flash memories, capture signals, interact with radio modules or automate experiments. The same firmware can be accessed through USB Serial, a Wi-Fi web interface or dedicated browser-based tools. All supported boards share the same firmware functionality, although some features require additional hardware modules. Project website: https://geo-tp.github.io/ESP32-Bit-Pirate/ New: Using the ESP32-S3 as a Software-Defined Radio One of the most interesting additions in version 1.8 is the experimental ESP SDR adapter . The ESP32-S3 contains a 2.4 GHz Wi-Fi radio, but its capabilities are usually exposed through the standard Wi-Fi and Bluetooth software stacks. By accessing the radio hardware at a lower level, it is possible to capture raw I/Q samples and use them for basic software-defined radio experiments. ESP32 Bit Pirate now provides a dedicated USB adapter that streams these samples to a browser-based SDR interface. The Web ESP SDR application includes live spectrum and waterfall visualization, wideband frequency scanning, peak detection, occupancy tracking, adjustable receiver settings and signal calibration. Two main operating modes are available: Live SDR provides a real-time spectrum and waterfall around a selected center frequency, allowing users to inspect nearby RF activity. Wideband Analyzer sweeps across a configurable frequency range, combining measurements to visualize activity over a much broader portion of the spectrum. The interface also includes frequency references for common Wi-Fi, BLE, Zigbee and nRF24 channels. The most reliable operating range remains the standard 2.4 GHz ISM band (2400–2483.5 MHz). Experimental tuning outside this range is possible, but reception quality, frequency accuracy and receiver behavior are not guaranteed. It is important to understand that the ESP32-S3 is not a dedicated wideband SDR receiver. Out-of-band signals may also produce harmonics, images or other artifacts. Nevertheless, it is an interesting demonstration of what can be achieved using the radio hardware already present in a low-cost microcontroller. Try the Web ESP SDR: https://geo-tp.github.io/ESP32-Bit-Pirate/web-tools/esp-sdr/ LoRa and Meshtastic Analysis Version 1.7 introduced support for SX1262 LoRa transceivers, expanding Bit Pirate&amp;#39;s capabilities beyond its existing Sub-GHz and 2.4 GHz interfaces. The dedicated LoRa mode allows users to transmit and receive packets, inspect signal strength, scan frequency activity, perform Channel Activity Detection and visualize radio activity. Radio parameters such as frequency, bandwidth, spreading factor, coding rate, preamble and transmit power can be configured directly from the interface. Received packets can also be recorded and replayed with their original radio configuration. A dedicated Meshtastic analysis shell was introduced alongside these capabilities, allowing users to inspect, send and receive Meshtastic packets. The objective is not to replace a conventional Meshtastic node, but to provide a convenient interface for debugging and experimenting with LoRa-based communications. Boards such as the Heltec WiFi LoRa 32 V4 and Heltec Vision Master T190 can take advantage of their integrated SX1262 transceivers without requiring additional radio modules. Improved I2C Sniffing and Protocol Analysis Version 1.8 also introduces several improvements to the existing wired protocol tools. The I2C sniffer has been reworked around the ESP32-S3&amp;#39;s RMT peripheral, providing improved passive signal capture and optional address filtering. A new frequency measurement command allows users to determine the actual I2C clock frequency directly from the SCL line without relying on the configured bus speed. The measurement reports the estimated frequency, clock period and HIGH/LOW timing. Other improvements include better handling of configured I2C frequencies, expanded SPI flash identification, configurable WP/HOLD pins and reliability improvements to JTAG/SWD scanning. These additions are particularly useful when working with unfamiliar embedded devices or troubleshooting communication problems. Firmware Extraction and Analysis Directly in the Browser The browser-based toolkit continues to grow alongside the firmware. In version 1.8, the ESP Tool gained support for extracting NVS partitions and LittleFS filesystems from ESP32 devices. NVS extraction allows users to inspect stored configuration data and recover readable keys and values. LittleFS extraction provides access to files stored inside compatible flash partitions. These features complement existing tools for SPI flash programming, logic analysis, ESP32 flashing, STM32 and AVR programming, and direct GPIO/I2C/SPI control. Another useful component is the Python Scripting Lab, which uses Pyodide to execute Python directly in the browser while communicating with Bit Pirate through Web Serial. This makes it possible to automate hardware experiments, bus scans and data collection without setting up a local Python environment. The idea behind these tools is to make common embedded debugging workflows accessible through a browser, from connecting to a device and extracting firmware to inspecting the resulting data. Explore the Web Tools: https://geo-tp.github.io/ESP32-Bit-Pirate/web-tools/ ESP32-C5/C6 Bus Expander and Zigbee ESP32 Bit Pirate also has a companion project called ESP32 Bus Expander , which extends the available wireless capabilities using additional ESP32 devices. The recently released Bus Expander v0.3 introduces a reworked Zigbee mode and several stability improvements. Using an ESP32-C5 or ESP32-C6, users can explore IEEE 802.15.4 communication, scan Zigbee channels, discover devices, monitor network traffic and experiment with coordinator functionality. Both boards are supported through the project&amp;#39;s Web Flasher. This companion approach allows Bit Pirate to extend its capabilities beyond the peripherals available on the ESP32-S3 itself. Bus Expander: https://github.com/geo-tp/ESP32-Bus-Expander More Boards and Hardware Accessories Hardware compatibility has also expanded significantly. ESP32 Bit Pirate now supports a wide variety of ESP32-S3 development boards, ranging from inexpensive ESP32-S3 Super Mini modules to portable devices such as the M5Stack Cardputer, Cardputer ADV, M5StickS3 and LILYGO T-Embed. Recent additions include the Unexpected Maker ProS3 and 4 MB ESP32-S3 Super Mini boards. The M5Stack Cardputer ADV also benefits from support for the official CC1101 radio accessory, allowing users to experiment with Sub-GHz communication using a compact, portable setup. Additional improvements include ILI9341 SPI display support and updated GPIO configurations across several supported boards. All supported boards provide access to the same Bit Pirate features, with hardware-dependent functionality enabled through appropriate modules or accessories. Getting Started Getting started with ESP32 Bit Pirate does not require compiling the firmware. The project provides a Web Flasher that allows users to select their board and install the appropriate firmware directly from a compatible browser. Once installed, the device can be controlled through a conventional serial terminal or the browser-based Web Serial interface. The project website also includes documentation, wiring guides, supported hardware information and practical recipes covering common debugging tasks. For developers who prefer automation, Python scripts can interact with the firmware directly through its command-line interface or dedicated USB adapters. Web Flasher: https://geo-tp.github.io/ESP32-Bit-Pirate/webflasher/ Documentation: https://github.com/geo-tp/ESP32-Bit-Pirate/wiki What&amp;#39;s Next? ESP32 Bit Pirate continues to evolve as an open-source project, with contributions from developers experimenting with different boards, protocols and hardware interfaces. The goal remains the same: make hardware exploration and debugging more accessible by combining inexpensive microcontrollers with flexible firmware and tools that are easy to use. The latest SDR implementation is a good example of this approach. Rather than requiring another specialized instrument, it explores what can be achieved with hardware that many makers already own. There is still plenty of room for improvement, particularly around RF analysis, protocol capture and browser-based workflows. Feedback, testing and contributions are always welcome! GitHub repository: https://github.com/geo-tp/ESP32-Bit-Pirate Latest release (v1.8): https://github.com/geo-tp/ESP32-Bit-Pirate/releases/tag/v1.8 Project website: https://geo-tp.github.io/ESP32-Bit-Pirate/</description></item><item><title /><link>https://community.element14.com/technologies/embedded/b/blog/posts/pid-controller-without-floating-point-for-mspm0?CommentId=03f3ffec-c022-4272-9162-4ec6d1ac7e6f</link><pubDate>Mon, 12 Oct 2026 09:01:00 GMT</pubDate><guid isPermaLink="false">93d5dcb4-84c2-446f-b2cb-99731719e767:03f3ffec-c022-4272-9162-4ec6d1ac7e6f</guid><dc:creator>Jan Cumps</dc:creator><description>TI&amp;#39;s CCS has functionality to show IQMath variables as floating point values. In VS Code, you can do this with watch expressions. To show a Q(24): ((float) ) * 0.000000059604644775390625f You can also use it for conditional breakpoints. E.g.: break when the measured value gets higher than the target (overshoot): (( float ) feedback ) * 0.000000059604644775390625f &amp;gt; (( float ) target_command ) * 0.000000059604644775390625f</description></item><item><title>Blog Post: PID controller without floating point for MSPM0</title><link>https://community.element14.com/technologies/embedded/b/blog/posts/pid-controller-without-floating-point-for-mspm0</link><pubDate>Mon, 12 Oct 2026 07:50:00 GMT</pubDate><guid isPermaLink="false">93d5dcb4-84c2-446f-b2cb-99731719e767:8c85e1c3-c4c8-4327-b1ac-d3c5b26670d4</guid><dc:creator>Jan Cumps</dc:creator><description>PID controller implementation without using integer arithmetic. Uses TI IQMath lib to replace floating point instructions. Some of the content is created with AI support. I&amp;#39;ve marked the parts where AI was used. All narrative is written by me. Math and PID Traditionally, the PID algorithm uses floating point math. For an MSPM0 controller, those are expensive runtime calculations. And they have to be done in each execution of the PID control loop. TI MSPM0 SDK comes with the IQMath library. A library that lets you represent floating point numbers in an integer variable. And lets you calculate with them. I implemented the PID algorithm using IQMath variables and algorithms. The lib is used to: declare floating point values to IQMath representation multiply IQMath variables It&amp;#39;s not used to add values. You can just the C traditional + operation on IQMath variables. I also didn&amp;#39;t use the lib to convert ADC (the PID feedback signal) and PWM (the PWM output signal) to IQMath. Because of their nature, there was an optimised way to convert those. The lib allows you to select the number of bits reserved for the fractional part. I used the default Q(24) format, where 24 bits of an int32_t are used for fractional. source: Google&amp;#39;s Gemini AI PID algorithm I created a C++ class that implements the PID algorithm, and can hold the controller state.. #include const _iq out_max = _IQ(1.0); // Maximum allowable output (e.g., _IQ(1.0) for 100% PWM) const _iq out_min = _IQ(0.0); // Minimum allowable output (e.g., _IQ(0.0) for 0% PWM) class pid { public: pid(_iq kp, _iq ki, _iq kd) : kp(kp), ki(ki), kd(kd) {} void init(_iq kp, _iq ki, _iq kd, bool reset = true) { kp = kp; ki = ki; kd = kd; if (reset) { reset_state(); } } _iq compute(_iq setpoint, _iq feedback) { _iq error; _iq p_term, i_term, d_term; _iq output; // 1. Calculate the current error (e = r - y) error = setpoint - feedback; // 2. Proportional Term: P = kp * error p_term = _IQmpy(kp, error); // 3. Integral Term with anti-windup: I = I_prev + (ki * error) integral = integral + _IQmpy(ki, error); // Anti-windup: Clamp the integral accumulator to prevent runway saturation if (integral &amp;gt; out_max) { integral = out_max; } else if (integral out_max) { output = out_max; } else if (output &amp;gt; 8; DL_TimerG_setCaptureCompareValue(PWM_0_INST, pwm_counts, DL_TIMER_CC_0_INDEX); // update ccr0 value } Again, a shift was used to translate the Q(24) to the desired duty cycle value for PWM register. I used Google Gemini AI to suggest the most performant way to translate the Q(24) to DL_TIMER_CC_0_INDEX Result This &amp;quot;measure - assess - correct&amp;quot; loop is driven by a common timer, that makes it run every 200 ms. You can influence speed and stability by tuning the 3 parameters. AI can support. You can ask it to suggest parameters to make it move faster to the set point, to react faster or slower on load changes, to improve stability, to avoid ringing or overshoot... This is how Google Gemini AI explains the role of the parameters: Resources used: ADC0, with input pin PA25. Its interrupt flags when conversion done PWM timer TIMG1, with output pin PA26 generic timer PWMG0, to make the control loop tick every 200 ms. It fires an Interrupt to signal the loop has to be executed. GPIO pin PA27 to make a LED light up when the loop runs. The loop is so fast that you can&amp;#39;t see it, but you can put an oscilloscope over it. The attached project targets the MSPM0L1306 Launchpad. But you can adapt it to EasyL1105 with SysConfig. references: TI IQMath library . It&amp;#39;s part of the MSPM0 SDK. MSPM0 IQMath example. PID controller on Wikipedia EasyL1105 development board. Expressif also uses that IQMath library . Thank you for reading. VS Code project: community.element14.com/.../mspm0_5F00_pid_5F00_20261012.zip (check this post for the expected VS Code workspace settings: MSPM0 project with VS Code, CMake and GCC - part 6: empty &amp;quot;template&amp;quot; project ) part of the EasyL1105 series. all posts</description><category domain="https://community.element14.com/technologies/embedded/tags/MSPM0L1105">MSPM0L1105</category><category domain="https://community.element14.com/technologies/embedded/tags/MSPM0">MSPM0</category><category domain="https://community.element14.com/technologies/embedded/tags/easyL1105">easyL1105</category><category domain="https://community.element14.com/technologies/embedded/tags/MSPM0L1306">MSPM0L1306</category><category domain="https://community.element14.com/technologies/embedded/tags/pid">pid</category><category domain="https://community.element14.com/technologies/embedded/tags/texas%2binstruments">texas instruments</category></item><item><title /><link>https://community.element14.com/technologies/embedded/b/blog/posts/mspm0-project-with-vs-code-cmake-and-gcc---part-7c-stepper-motor-control-with-s-shaped-ramps?CommentId=03ce6d35-9294-47e5-a21e-0f06d9249026</link><pubDate>Sat, 10 Oct 2026 08:46:00 GMT</pubDate><guid isPermaLink="false">93d5dcb4-84c2-446f-b2cb-99731719e767:03ce6d35-9294-47e5-a21e-0f06d9249026</guid><dc:creator>Jan Cumps</dc:creator><description>Let&amp;#39;s say that you decide to use 4 microsteps, and want to maintain the same curve and speeds: This is the original curve array (I removed const because I want to change values): inline static /*const*/ std::array s_curve_lut = { 150, 151, 152, 155, 160, 166, 174, 184, 196, 211, 228, 247, 269, 293, 321, 352, 386, 424, 465, 509, 557, 608, 662, 719, 779, 842, 908, 976, 1046, 1118, 1191, 1265, 1340, 1414, 1489, 1563, 1636, 1707, 1777, 1845, 1910, 1971, 2000 }; This transform multiplies each value by 4, in place. It takes exact same controller resources (ticks, code size) as doing this in a traditional for loop: std::transform(s_curve_lut.begin(), s_curve_lut.end(), s_curve_lut.begin(), [](uint32_t val) { return val * 4; // Adjust the divisor to scale the speed values as needed });</description></item><item><title /><link>https://community.element14.com/technologies/embedded/b/blog/posts/mspm0-project-with-vs-code-cmake-and-gcc---part-7c-stepper-motor-control-with-s-shaped-ramps?CommentId=87f9ee65-7309-4e65-a5af-e1db485d1e29</link><pubDate>Thu, 08 Oct 2026 22:56:00 GMT</pubDate><guid isPermaLink="false">93d5dcb4-84c2-446f-b2cb-99731719e767:87f9ee65-7309-4e65-a5af-e1db485d1e29</guid><dc:creator>shabaz</dc:creator><description>Great work! Beautiful &amp;#39;scope screenshots too by the way.. Also, there is something really relaxing hearing a motor turn with this level of smooth control!</description></item><item><title /><link>https://community.element14.com/technologies/embedded/b/blog/posts/mspm0-project-with-vs-code-cmake-and-gcc---part-7c-stepper-motor-control-with-s-shaped-ramps?CommentId=19f14d23-eafc-4f34-823f-43132f3b0142</link><pubDate>Thu, 08 Oct 2026 20:02:00 GMT</pubDate><guid isPermaLink="false">93d5dcb4-84c2-446f-b2cb-99731719e767:19f14d23-eafc-4f34-823f-43132f3b0142</guid><dc:creator>DAB</dc:creator><description>Great update Jan.</description></item><item><title>File: MSPM0 stepper motor with s-curve ramps</title><link>https://community.element14.com/technologies/embedded/m/managed-videos/151887</link><pubDate>Thu, 08 Oct 2026 16:56:00 GMT</pubDate><guid isPermaLink="false">93d5dcb4-84c2-446f-b2cb-99731719e767:00050726-11e0-463d-8afe-8dfdab574a87</guid><dc:creator>Jan Cumps</dc:creator><description>demo of MSPM0 project with VS Code, CMake and GCC - part 7c: stepper motor control with S-shaped ramps https://community.element14.com/technologies/embedded/b/blog/posts/mspm0-project-with-vs-code-cmake-and-gcc---part-7c-stepper-motor-control-with...</description><category domain="https://community.element14.com/technologies/embedded/tags/MSPM0">MSPM0</category><category domain="https://community.element14.com/technologies/embedded/tags/stepper">stepper</category><category domain="https://community.element14.com/technologies/embedded/tags/c_2B002B00_">c++</category><category domain="https://community.element14.com/technologies/embedded/tags/launchpad">launchpad</category></item><item><title /><link>https://community.element14.com/technologies/embedded/b/blog/posts/mspm0-project-with-vs-code-cmake-and-gcc---part-7c-stepper-motor-control-with-s-shaped-ramps?CommentId=3d62fd06-bcc9-4227-a852-351b9588f4d0</link><pubDate>Thu, 08 Oct 2026 16:12:00 GMT</pubDate><guid isPermaLink="false">93d5dcb4-84c2-446f-b2cb-99731719e767:3d62fd06-bcc9-4227-a852-351b9588f4d0</guid><dc:creator>Jan Cumps</dc:creator><description>I asked Google AI to come up with curves. I defined the number of steps and the desired plateau. Here&amp;#39;s an example for 43 steps, 200 PPS max: inline static const std::array s_curve_lut = { 150, 151, 152, 155, 160, 166, 174, 184, 196, 211, 228, 247, 269, 293, 321, 352, 386, 424, 465, 509, 557, 608, 662, 719, 779, 842, 908, 976, 1046, 1118, 1191, 1265, 1340, 1414, 1489, 1563, 1636, 1707, 1777, 1845, 1910, 1971, 2000 }; The code will use the table you give it, so you can play with shape, and how fast/slow you want to ramp.</description></item><item><title /><link>https://community.element14.com/technologies/embedded/b/blog/posts/mspm0-project-with-vs-code-cmake-and-gcc---part-7c-stepper-motor-control-with-s-shaped-ramps?CommentId=e5a93322-09d7-4ddf-aa47-cce1eaa22992</link><pubDate>Thu, 08 Oct 2026 14:54:00 GMT</pubDate><guid isPermaLink="false">93d5dcb4-84c2-446f-b2cb-99731719e767:e5a93322-09d7-4ddf-aa47-cce1eaa22992</guid><dc:creator>kk99</dc:creator><description>Good series of the blogs.</description></item><item><title>Blog Post: MSPM0 project with VS Code, CMake and GCC - part 7c: stepper motor control with S-shaped ramps</title><link>https://community.element14.com/technologies/embedded/b/blog/posts/mspm0-project-with-vs-code-cmake-and-gcc---part-7c-stepper-motor-control-with-s-shaped-ramps</link><pubDate>Thu, 08 Oct 2026 12:09:00 GMT</pubDate><guid isPermaLink="false">93d5dcb4-84c2-446f-b2cb-99731719e767:9108d948-c327-4dfd-b828-de2a48777fe4</guid><dc:creator>Jan Cumps</dc:creator><description>In this blog series, I build a Texas Instruments MSPM0 example with VS Code as IDE, and CMake as build infrastructure. In the next series of posts, I try to create a stepper motor project. It will be based on TI&amp;#39;s stepper motor middleware. In the previous post, I got constant step speed working , with an Allegro A4988 stepper motor IC. In this post, a nice s-shaped ramp-up and ramp-down curve this table contains AI generated content I asked AI: [...] [...] Object Oriented approach I created a class for the constant stepper (see previous post). This class can manage the motor while it&amp;#39;s performing the requested number of steps: (in this case constant) speed direction start step until done (count and stop) I based a new s-curve capable class based on that one. It adds this functionality: accept a ramp profile ( set of speeds) decide when to ramp up or down handle the ramp speeds additional controller resources needed The logic needs an additional timer. A traditional one this time, not a PWM one like the one that generates the pulses. The firmware will have to provide a handler for that timer, that calls the classes check_ramp () method: void TIMER_RAMP_INST_IRQHandler(void) { if (DL_Timer_getPendingInterrupt(TIMER_RAMP_INST) == DL_TIMER_IIDX_ZERO) { pwm_stepper_driver1.check_ramp(); } } I&amp;#39;ve set up the timer to tick each 10 ms. The ISR then asks the class to &amp;quot;manage the ramp&amp;quot;. Based on the state (ramping up / ramping down / cruise), it either ramps up, ramps down, or does nothing. void check_ramp() { switch (profile_state) { case motor_profile::motor_accel: // Move forward through the S-curve array for smooth acceleration if (current_lut_index 0) { current_lut_index--; set_speed(s_curve_lut[current_lut_index]); } break; default: break; } } A override version of the base classes check_step() (that just counts steps and stops when done) , validates if we need to ramp up, stay steady (cruise) or ramp down. It doesn&amp;#39;t do anything else based on that info. It just computes it, so that the ramp handling method check_ramp() (see above) can act upon it. void check_step() { if(control_mode_ == control_mode::step) { uint32_t steps_remaining = set_step_ - (step_count +1); // +1 because step_count is incremented in base class check_step(); mspm0_pwm_stepper_driver::check_step(); // Call base class check_step() to handle step counting switch (profile_state) { case motor_profile::motor_accel: accel_steps_taken++; // Handle Short Moves: If half the steps are spent, start braking immediately if (steps_remaining s_curve_lut = { 150, 150, 151, 154, 160, 169, 181, 197, 217, 242, 272, 308, 349, 397, 451, 512, 581, 656, 739, 830, 928, 1033, 1146, 1266, 1393, 1526, 1666, 1812, 1963, 2119, 2279, 2443, 2610, 2779, 2949, 3120, 3290, 3459, 3625, 3788, 3946, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000 }; int main() { // ... pwm_stepper_driver1.init(); pwm_stepper_driver1.stop_motor(); // pwm_stepper_driver1.set_speed(1); // CURVE determines speed for ramp style motion, so set_speed() is not used in this example pwm_stepper_driver1.set_control_mode(mspm0_pwm_stepper_driver::control_mode::step); pwm_stepper_driver1.set_ramp(s_curve_lut); // the vector has to stay alive for the duration of the motor run, so it is stored in a static variable in this example /* Set the priority for interrupts */ NVIC_SetPriority(GENERIC_PWM_CHANNEL_0_INST_INT_IRQN, 1); NVIC_SetPriority(TIMER_RAMP_INST_INT_IRQN, 2); while (1) { driver1.enable(true); pwm_stepper_driver1.set_dir(true); pwm_stepper_driver1.set_step(5000); pwm_stepper_driver1.start_motor(); while (pwm_stepper_driver1.is_motor_running()) { __WFI(); // Enter low-power sleep mode; wake on timer interrupts } pwm_stepper_driver1.set_dir(false); pwm_stepper_driver1.set_step(5000); pwm_stepper_driver1.start_motor(); while (pwm_stepper_driver1.is_motor_running()) { __WFI(); // Enter low-power sleep mode; wake on timer interrupts } driver1.enable(false); } } The image below shows a scope trace of a 5000 steps command, with ramps. The more intense the yellow, the more steps per second. Thank you for reading. VS Code project: community.element14.com/.../mspm0_5F00_stepper_5F00_ramp_5F00_20261010.zip (check this post for the expected VS Code workspace settings: MSPM0 project with VS Code, CMake and GCC - part 6: empty &amp;quot;template&amp;quot; project ) previous post: MSPM0 project with VS Code, CMake and GCC - part 7b: middleware stepper motor control with A4988 stepper driver part of the EasyL1105 series. all posts</description><category domain="https://community.element14.com/technologies/embedded/tags/MSPM0L1105">MSPM0L1105</category><category domain="https://community.element14.com/technologies/embedded/tags/MSPM0">MSPM0</category><category domain="https://community.element14.com/technologies/embedded/tags/easyL1105">easyL1105</category><category domain="https://community.element14.com/technologies/embedded/tags/VS%2bCode">VS Code</category><category domain="https://community.element14.com/technologies/embedded/tags/MSPM0L1306">MSPM0L1306</category><category domain="https://community.element14.com/technologies/embedded/tags/vscode">vscode</category></item><item><title /><link>https://community.element14.com/technologies/embedded/b/blog/posts/ez-mcxn-simple-dev-board-for-nxp-mcx-n-series-microcontrollers?CommentId=43f2a6ec-43ef-487c-b761-57a0da1ddc32</link><pubDate>Sat, 03 Oct 2026 13:51:00 GMT</pubDate><guid isPermaLink="false">93d5dcb4-84c2-446f-b2cb-99731719e767:43f2a6ec-43ef-487c-b761-57a0da1ddc32</guid><dc:creator>michaelkellett</dc:creator><description>That looks more like I expected. Good luck with it. MK</description></item><item><title /><link>https://community.element14.com/technologies/embedded/b/blog/posts/ez-mcxn-simple-dev-board-for-nxp-mcx-n-series-microcontrollers?CommentId=727d0663-6e5c-4432-926c-c5b5c4a0aff2</link><pubDate>Sat, 03 Oct 2026 13:18:00 GMT</pubDate><guid isPermaLink="false">93d5dcb4-84c2-446f-b2cb-99731719e767:727d0663-6e5c-4432-926c-c5b5c4a0aff2</guid><dc:creator>shabaz</dc:creator><description>Unfortunately that&amp;#39;s an older screenshot (it&amp;#39;s the usual problem, the more recent updates get hidden by the site : ( I&amp;#39;d made it a solid pad, but didn&amp;#39;t enlarge the holes further (I have made them larger now; from 0.3 to 0.4mm dia), the pad is 6x6mm so hopefully that should be sufficient to get heat in (there happens to be no ground plane on the top side pad, and thermal relief on all other planes as you mentioned): Pad underside: The actual ground plane is the layer underneath top layer: This smaller board is quite niche admittedly, it is for mic experimenting. I hope to 3D-print an enclosure (at least some of the frame of it; the rest with milling machine). I&amp;#39;m not sure 3D printing alone would be satisfactory. The larger board is intended to be the more all-round useful one for sure.</description></item><item><title /><link>https://community.element14.com/technologies/embedded/b/blog/posts/ez-mcxn-simple-dev-board-for-nxp-mcx-n-series-microcontrollers?CommentId=0d1a6528-e20a-4733-a496-64d64b555511</link><pubDate>Sat, 03 Oct 2026 08:28:00 GMT</pubDate><guid isPermaLink="false">93d5dcb4-84c2-446f-b2cb-99731719e767:0d1a6528-e20a-4733-a496-64d64b555511</guid><dc:creator>michaelkellett</dc:creator><description>I would go for more or bigger vias on that centre pad and a full pad on the bottom with no thermal reliefs to the vias on either side (but thermal relief to the ground planes if there are any). This is so you can get a decent coupling from a soldering iron to the bottom pad if you should need to. (And you do not want solder resist on the bottom side of this pad. I don&amp;#39;t put solder resist on vias of any kind on prototypes to facilitate bodging later !). I would also take any unused pins out to connector footprints because I have often found this useful later when I end up using a board for some purpose I had no expected. Do you have a plan in mind for this board ? MK</description></item><item><title /><link>https://community.element14.com/technologies/embedded/b/blog/posts/ez-mcxn-simple-dev-board-for-nxp-mcx-n-series-microcontrollers?CommentId=16cc16ef-871d-47aa-a23e-f16ce4d81e13</link><pubDate>Fri, 02 Oct 2026 18:19:00 GMT</pubDate><guid isPermaLink="false">93d5dcb4-84c2-446f-b2cb-99731719e767:16cc16ef-871d-47aa-a23e-f16ce4d81e13</guid><dc:creator>shabaz</dc:creator><description>Very cut-down mini dev board; this is 26x48mm and exposes GPIO port 4 pins 0-7 (which can also be used as ADC inputs) on a flat flex connector, and has solderable pads for wiring up PDM mics (or use that as a couple more GPIO). The underside has three buttons and an LED (or patch wires to those and use as four more GPIO). The CAD/PCB/circuit diagram/BoM are in the same GitHub repo as the larger board.</description></item><item><title /><link>https://community.element14.com/technologies/embedded/b/blog/posts/ez-mcxn-simple-dev-board-for-nxp-mcx-n-series-microcontrollers?CommentId=4a684c36-801c-4403-9697-554dcf55d4f7</link><pubDate>Fri, 02 Oct 2026 07:46:00 GMT</pubDate><guid isPermaLink="false">93d5dcb4-84c2-446f-b2cb-99731719e767:4a684c36-801c-4403-9697-554dcf55d4f7</guid><dc:creator>shabaz</dc:creator><description>Mini version is a work-in-progress, but it&amp;#39;s quite small, 26x48mm (only slightly wider than a Pi Pico). There are 8 GPIO connections via flat flex, all ADC capable. PDM mic connections are solder pads for flat flex if desired, or wires could be tacked on. For the SWD connector I used JST SH since space was limited. The underside has three buttons and just one LED, I removed the other one. I still need to fix the QFP center pad soldering issue on this board.</description></item><item><title /><link>https://community.element14.com/technologies/embedded/b/blog/posts/ez-mcxn-simple-dev-board-for-nxp-mcx-n-series-microcontrollers?CommentId=ddea407e-2bb5-4b68-9af3-1bc90b50f2d4</link><pubDate>Fri, 02 Oct 2026 04:42:00 GMT</pubDate><guid isPermaLink="false">93d5dcb4-84c2-446f-b2cb-99731719e767:ddea407e-2bb5-4b68-9af3-1bc90b50f2d4</guid><dc:creator>manojroy123</dc:creator><description>I have downloaded both the book. I will definitely read both of them</description></item><item><title /><link>https://community.element14.com/technologies/embedded/b/blog/posts/ez-mcxn-simple-dev-board-for-nxp-mcx-n-series-microcontrollers?CommentId=3ea4ec36-d278-4b12-bdc8-9ba7d8a0c66f</link><pubDate>Thu, 01 Oct 2026 17:44:00 GMT</pubDate><guid isPermaLink="false">93d5dcb4-84c2-446f-b2cb-99731719e767:3ea4ec36-d278-4b12-bdc8-9ba7d8a0c66f</guid><dc:creator>shabaz</dc:creator><description>It&amp;#39;s definitely in there, guaranteed. They will just call it &amp;quot;pointers&amp;quot;, it&amp;#39;s always pointers to memory. By the way there&amp;#39;s another good book called &amp;quot;Problem Solving and Program Design in C&amp;quot; by Hanly &amp;amp; Koffman (expensive book but older editions are very low cost and just as good). Together, that&amp;#39;s a complete comprehensive C course, including some algorithms.</description></item></channel></rss>