My daughter has been using her highly modified power wheels style car for quite a while now and I decided that a few issues needed to be fixed:
- Running the motors in parallel means that one motor could be damaged by using a majority of current in certain situations
- It is too easy to make the driven wheels spin out on wet surfaces or when trying to go over obstacles
- My wife thinks the car is much too fast at times and needs to be slowed down
New Control Board
I designed a new control board to independently control each motor. This allows me to finely control the speed and torque of each motor separately.
Walking through my neighborhood one day, I happened upon a pink Camaro Power Wheels style kids riding toy that someone was throwing away. It appeared to have been left outside for an extended period of time and was full of ants! I guessed that the car stopped working, probably due to being full of ants, and they decided to toss it rather than try to clean it up.
I have a young daughter at home that I knew would just love a pink convertible Camaro, so I grabbed it and decided to get it working for her.
The first thing I did was to rip out all of the wiring and switches. The entire setup was extremely simple. The car was powered by two small DC motors, one for each rear wheel. The motors look to be standard 550 size and were geared down quite a bit with plastic gearboxes. The shifting mechanism was two integrated switches that allowed for full speed forward, half speed forward, and reverse. The biggest surprise was that the foot pedal was simply a switch and did not allow for any sort of variable speed control! All of this was connected to a standard 12V lead acid battery.
A while back I was asked to work on a project that required a microcontroller to monitor a signal that determined the health of a system. The microcontroller had to fit in a tiny area and handle extreme temperature ranges. The signal to monitor was a series of pulses that had to stay within a certain time period. This is the sort of thing that any microcontroller should be able to handle very easily, assuming it could fit where I needed it and work at the temperatures required.
In order to configure the ATSAME54P20A, we have to talk about the clock system. The SAME5x/SAMD5x family has one of the more complicated clocking systems I have seen in a microcontroller (the following figure is taken from the SAM-D5XE5X Family Datasheet, page 144):
The dsPIC is one of the easier MCUs in this series to get running. Much like the PIC32MK, the default startup scripts are hidden in the compiler directory and included by default. Generally, they do not need to be touched. Almost all of the register definitions are included the standard device header file xc.h. This provides the register values both as a full register variable and as a bit fields. The compiler contains some built in functions that are required to switch clocks. These functions are documented in the compiler reference.
This example uses the internal 8MHz fast oscillator and PLL to run the system clock at 180MHz. I then set up Timer 1 and interrupts.
The steps are as follows:
The TI C2000 series of MCUs are not designed for people new to development. TI does not have any software that auto-configures the devices, the startup code does not automatically populate things like vectored interrupt tables, and register defaults require configuration. However, TI does provide an extensive set of generic hardware configuration files and peripheral example files for every peripheral that are clean and concise. I like this much better than any configuration utility. The best way to get started is to download C2000Ware.
I will be using some of the files from C2000Ware in this example:
Microchip MPLAB X hides some of the details of starting up the PIC32. The default startup code and linker scripts are hidden in the compiler directory and included by default. Generally, they do not need to be touched. Almost all of the register definitions are included the standard device header file xc.h. This provides the register values both as a full register variable and as a bit fields. The bit fields are a really nice touch that Microchip does with all their PIC MCUs. I also include cp0defs.h to access the defines used to configure CP0.
This example uses the built in 8MHz fast RC internal oscillator and PLL to run at 120MHz. I then set up Timer1 and enable interrupts.
The startup works as follows:
A default bit of basic startup code is created when you start a project in Atollic TrueSTUDIO. For my project, the code is called startup_stm32f446xx.s. This code sets up the initial vector table, the program counter, the stack pointer, and branches to the main function. I also include the standard device header files that ST provides and use the definitions in the files for register configuration. These are well documented in the headers and the names match the datasheet.
This configuration uses the 16MHz internal oscillator and PLL to run the system clock at 180MHz. I then set up the SysTick timer for a 1ms interrupt.
The rest of the startup code is pretty straightforward:
Almost all microcontroller manufacturers provide peripheral libraries that are intended to make development using their products faster and easier. In some instances, these libraries work well and really accelerate development. On the other hand, some libraries contain bugs, only cover a subset of the peripheral features, add huge amounts of overhead, or require so much research and exploration that you might as well just use the reference guides and program the registers yourself.
I generally only use the manufacturer provided peripheral libraries for items that are very complex such as USB and Ethernet. Instead, I read the references and program the registers myself. I have discovered that once you start doing more complex things with your chosen MCU, sooner or later you need to understand the peripherals on the register level. The best way for me to do this is to simply start out using the registers.
Whether you use your own peripheral code or the libraries, you need to be comfortable with what they are doing and verify that it matches the documentation as you understand it.
In my motor control microcontroller performance comparison post, I used a selection of different MCUs. This series of posts is intended to cover how I got them working using only the bare minimum of libraries.
I will cover the following processors. However, the basic code should work for all variations in the same family:
Almost every company that develops microcontrollers (MCU) has a part or series of parts that is designed for motor and real time control. When used correctly, the parts I have worked with all perform admirably. Although I generally choose an MCU based on the price, peripherals, package type, and familiarity, there are performance differences between them beyond just the added features. This post is my attempt to measure the performance of a selection of MCU cores when executing a standard Field Oriented Control (FOC) loop. These tests are very application specific and mainly stress each MCU’s math, flash, and caching speed.
I chose a selection of MCUs that I have experience using, have the tools to develop, and cover a range of core types. The price varies greatly between the most expensive and least expensive MCU I tested. The exact part chosen depended more on availability of development boards than any particular application requirement. However, the overall family of each MCU has a variety of parts that cover a large range of price points and feature-sets. That said, following are the MCUs: