This is an amazing forum that has such a wealth of information and so many helpful people!
I will be coaching a few kids for a robotic project, and I am researching what uProcessor to use. Since kids have used Lego NXT and arduino hybrid system last time, I want them to learn a more advanced and capable system this time. I came across STM32 and found all you guys. STM32 seems such a powerful system and faster than regular Arduino.
So I bought a STM32F103C8 board to play with, and was able to upload code to it via Arduino ide from reading the post here and Roger’s blog. Also got bootloader installed, basic things (GPIO) seem working well. However, when I tried encoder library (https://www.pjrc.com/teensy/td_libs_Encoder.html), it won’t compile if I select STM32 board (but the same code works fine for Arduino nano). The timer1 library refuse to cooperate either.
My question is : is it a good idea to get the kids to try STM32? I would like your opinion if this system is mature enough for kids with solid Arduino experience. Currently, I am thinking to use one STM32 board as the controller, it will use build-in hardware quadrature decoders and PWM to control the motors. It also needs read a couple other sensors, via ADC, I2C and maybe SPI interface.
Thanks!
is it a good idea to get the kids to try STM32? … kids with solid Arduino experience.
mhm…good question. As your problem above, there aren’t much ready made libraries for the STM32duino platform. On most of them you have to rewrite some code. The “core system” itself is good working for most applications. There a few pitfalls left (crash while pinMode, digitalWrite/read in the constructor of libraries) but Roger and the rest of the people here are working hard to eliminate those bugs. On the other side, if you put together a set with well known and working hardware (for example: maple mini clone, ILI9341 TFT, SSD1306 Oled’s (I2c or SPI) see the “libraries” section of the forum) there is nothing against using it for the kids, but you must be really fit with it.
Matthias
The hardware timers do work, but no one has had the time to write the Timer1 wrapper.
It’s probably not that hard to write, but would take some time.
if you goal is just to get your kids starting with computing, then the STM32 may be a bit too much on the “bleeding edge”
The main benefits of the STM32 are the speed (72MHz) and the size of RAM and Flash memory.
So if you have a project that needs either of these, the STM32 is a good fit.
if however 16MHz is fast enough for your application, then the safe and easy route is to definitely just use a Uno.
<…>
My question is : is it a good idea to get the kids to try STM32? I would like your opinion if this system is mature enough for kids with solid Arduino experience. Currently, I am thinking to use one STM32 board as the controller, it will use build-in hardware quadrature decoders and PWM to control the motors. It also needs read a couple other sensors, via ADC, I2C and maybe SPI interface.
Thanks!
This is an amazing forum that has such a wealth of information and so many helpful people!
I guess I was not very clear when I posted my initial question. These kids were hand picked from a robotic club and they are really really good. They will be participating in a robotic competition, and they are just starting out to design their system. Now, they have all kinds of ideas from plain old Arduino to Android. However, I do not want to see them pick a system that requires a huge effort just to get started. They will have to build a physical robot with all sorts of sensors, and develop AI software for autonomous mission. Plus time is very limited as well.
The reason why STM32 is so attractive is that, as Roger pointed out, they indeed can use many of its features, such as build-in flash memory, faster speed, more memory, and hardware quadrature decoders, plus a lot of GPIO pins for over a dozen sensors that they need. And most importantly, they will be able to learn a lot more in uProcessor programming than using Arduino. However, this can be a double-edge sword, since a huge amount of time could be sucked into this. Another choice is Arduino Due, it might not be able to run all standard libraries out of the box either, as I understand. So this will be a really tough decision, and this was the reason why I posted my question.
Will appreciated your insight on this…
Its a tough call.
If you were building a robot to solve a maze, the extra speed would be a benefit.
I’m not sure what board you had in mind, but the STM32F103VET and STM32F103ZET boards have loads of GPIO (I think the ZET has over 100 GPIO !)
Re: Due
I’m not sure if its going to be any easier than using an STM32, unless someone has already ported the libs you need onto the Due.
I have 2 Due boards, but never use them now that I have the STM32 boards.
Your other option would be a Teensy (which you mentioned before), but I guess price could be an issue e.g. Teensy is around $20 and Maple mini’s are around $6, so it would depend on how many you need to buy, and also the chances of the students destroying the boards.
I suspect there is a high lightlyhood that you will destroy multiple boards – plenty of experienced people on this forum have fried their boards, simply by plugging things onto the wrong pins, its very easily done, and even easier on 3.3V devices I suspect than on the 5V AVR boards.
Ultimately it depends on how much time you have to put into the project, and whether the students will benefit from using the newer architecture
If its an inter school challenge, I guess there is also the cool factor of having non-standard stuff, e.g. if everyone else has 16MHz AVR and your students have 72Mhz STM32’s
But this would all count for nothing if things don’t work ![]()
[b]And most importantly, they will be able to learn a lot more in uProcessor programming than using Arduino. [/b]However, this can an double-edge sword, since a huge amount of time could be sucked into this. Another choice is Arduino Due, it might not be able to run all standard libraries out of the box either, as I understand. So this will be a really tough decision, and this was the reason why I posted my question.I would buy a maple mini or two, check if the things that you strictly need work as you need them to work (encoders or anything else). If that works fine, then anything after that is a nice extra but not essential, so you know you could complete the course even if the extra things do not work as expected or problems can not be solved timely.
If you find that your essentials do not work with the maple mini, and you can not get them to work by yourseld, then I would not use it, and would rather try to get those things working perhaps for the next class.
That’s how I got sucked in this STM stuff. I saw the potential, bought a maple mini to test for my hobby projects, and as things worked I decided to try more things with them, but if things had not worked I would just have written off the $4 and moved on to something else.
As Ray cleverly pointed, people here will definitely try to help, but no one can give you a guarantee that this or that peripheral will have a working library doing what you need by a certain time frame.
So just go order one of those maple mini for $4 on ebay or aliexpress, test it out and see if it does what you need to do right now.
If they work, you can order boards with VET or RET chips for around $10, which have extra flash, ram, timers, DAC and GPIO to do all the extra cool stuff that may not be essential, but can be pretty cool, like playing cool sounds thru the DAC, but if you dont get those to work, the robot will still work as intended.
I looked at the quadrature encoder stuff, and the existing code e.g. on PRJC.com would need to be ported, as its got big swathes of code in #ifdef blocks, some of which is AVR compiler code.
In fact, directly porting the code is not the only approach, because some of the timers are designed to operate as quadrature decoders.
But, if those timers are co opted to decode quadrature, they can’t do other things like PWM that the OP would need.
So also having a class that uses interrupts on the quadrature inputs may also be required.
I don’t have any quadrature encoders, so i will order some small ones from eBay just as a matter of interest ( but they wont be here for weeks)
The other thing the OP mentioned was TimerOne.
This has been mentioned by a few other people, but I’m not sure its worth attempting to make an STM32 version of this lib, because the things it achieves are already available without using the lib, e.g. duty cycle on PWM and timer interrupts.
I suspect the better approach would be to port the libs, which themselves use TimerOne rather than to have a hacky wrapper around the HardwareTimers and PWM functions.
This is my code for multiple encoders with acceleration using HW timer 1, I wrote some months ago. Drawback: You need a 2 pins for each encoder (no multiplexing possible).
Edit: I see there is much space for polish the code: the acceleration time measurement with millis() isn’t needed, until the timer is exactly 1ms each duration, so a simple counter for each encoder within the ISR routine would do the trick also.
Edit2: Shame on my, I totally forgot the author of the genius “logical routine”, please let me know if somebody guess it!
Edit3: Ok, I grab the code years ago from here: http://www.electronicaestudio.com/docs/SHT-153.txt
// multi encoder code with speed up values adapted for STM32-arduino by Matthias Diro
// no caps for encoder pins needed: gives back wrong acc values
// using gpio_read_bit instead of digitalRead gives about 4x more speed http://forums.leaflabs.com/topic.php?id=1107
#define MAXENCODERS 2
volatile int encstate[MAXENCODERS];
volatile int encflag[MAXENCODERS];
boolean A_set[MAXENCODERS];
boolean B_set[MAXENCODERS];
volatile int16_t encoderpos[MAXENCODERS];
volatile int encodertimer = millis(); // acceleration measurement
int encoderpinA[MAXENCODERS] = {4, 6}; // pin array of all encoder A inputs
int encoderpinB[MAXENCODERS] = {5, 7}; // pin array of all encoder B inputs
unsigned int lastEncoderPos[MAXENCODERS];
// timer
#define ENCODER_RATE 1000 // in microseconds;
HardwareTimer timer(1);
void setup()
{
Serial.begin(9600);
initEncoders();
}
void loop()
{
for (byte counter = 0; counter < MAXENCODERS; counter++)
{
if ((lastEncoderPos[counter] != encoderpos[counter])) {
Serial.print("Encoder #");
Serial.print(counter);
Serial.print(" Value ");
Serial.println(encoderpos[counter]);
encflag[counter] = LOW;
lastEncoderPos[counter] = encoderpos[counter];
}
}
}
// ********encoder function
void readEncoders() {
for (byte counter = 0; counter < MAXENCODERS; counter++)
{
if ( (gpio_read_bit(PIN_MAP[encoderpinA[counter]].gpio_device, PIN_MAP[encoderpinA[counter]].gpio_bit) ? HIGH : LOW) != A_set[counter] )
{
A_set[counter] = !A_set[counter];
if ( A_set[counter] && !B_set[counter] )
{
if (millis() - encodertimer > 3)
encoderpos[counter] += 1;
else
encoderpos[counter] += 5;
}
encodertimer = millis();
}
if ( (gpio_read_bit(PIN_MAP[encoderpinB[counter]].gpio_device, PIN_MAP[encoderpinB[counter]].gpio_bit) ? HIGH : LOW) != B_set[counter] )
{
B_set[counter] = !B_set[counter];
if ( B_set[counter] && !A_set[counter] )
if (millis() - encodertimer > 3)
encoderpos[counter] -= 1;
else
encoderpos[counter] -= 5;
encodertimer = millis();
}
}
}
void initEncoders()
{
encodertimer = millis(); // acceleration measurement
for (byte counter = 0; counter < MAXENCODERS; counter++)
{
encstate[counter] = HIGH;
encflag[counter] = HIGH;
A_set[counter] = false;
B_set[counter] = false;
encoderpos[counter] = 0;
pinMode(encoderpinA[counter], INPUT_PULLUP);
pinMode(encoderpinB[counter], INPUT_PULLUP);
lastEncoderPos[counter] = 1;
}
// timer setup for encoder
timer.pause();
timer.setPeriod(ENCODER_RATE); // in microseconds
timer.setChannel1Mode(TIMER_OUTPUT_COMPARE);
timer.setCompare(TIMER_CH1, 1); // Interrupt 1 count after each update
timer.attachCompare1Interrupt(readEncoders);
timer.refresh();
timer.resume();
}
I will try a few more things then decide if STM32 is suitable for this project. My understanding is that most things can be done, but some might require quite a bit effort.
@Roger, as you said each timer can only do one thing, either PWM or quadrature decoder, although they do have 4 independent channels for IC/OC/PWM. So that means we will need something like STM32F103ZE.
I will try a few more things then decide if STM32 is suitable for this project. My understanding is that most things can be done, but some might require quite a bit effort.
@Roger, as you said each timer can only do one thing, either PWM or quadrature decoder, although they do have 4 independent channels for IC/OC/PWM. So that means we will need something like STM32F103ZE.
BTW. Im afraid i was a bit lazy with the V and Z series PIN MAP porting, and i have not done the Timer assignments to the extra GPIO pins that are in those boards, so I suspect PWM will not work on all GPIO pins on those boards.
I think its just a question of going through the manual and working out which pins each of the timers apply to, but I’ve not looked in detail.
On the whole the core code seems to have ifdefs for devices that are not available on the Maple mini etc, but again, I’ve not thoroughly reviewed the code to see if the Z series timers are setup etc in the core.
STM32 has hardware quadrature decoders, all we have to do is to setup a few registries then just read the decoder output, almost no overhead at all. This can be very useful for a fast running robot while AI code is running – the hardware decoders will not skip a beat.
I know it will be a lot more work for kids if we go with STM32, but they will learn some lower level programming skills this way. However, I can’t decide which part they should spend more time, on low level hardware control or high level AI algorithm. It is a very small team, otherwise, they can be split to three teams, one builds hardware, one programs motor control / sensors (low level), and another one does AI part.
Once again, thank you all for your suggestions and comments.
However, it might not have enough pins
That depends which kind pins you need. Any MCU can be expanded with GPIO expander such MC23017.
If your needs are for a lot of pins timer’s oriented, maybe you’re right but maybe MapleMini is not enough too !
Will you create your own PCB ? Is your project is cost sensitive ? Maybe STM32F4xx is even better ?
I know the F4 is a great chip, but I think its probably a bridge too far in this case. I think they will have their work cut out even with the F103 ![]()
maybe you can use more than one microcontroller. Another option can be a RaspberryPI and one or more microcontrollers.
I looked at the quadrature encoder stuff, and the existing code e.g. on PRJC.com would need to be ported, as its got big swathes of code in #ifdef blocks, some of which is AVR compiler code.
In fact, directly porting the code is not the only approach, because some of the timers are designed to operate as quadrature decoders.
But, if those timers are co opted to decode quadrature, they can’t do other things like PWM that the OP would need.
So also having a class that uses interrupts on the quadrature inputs may also be required.
I don’t have any quadrature encoders, so i will order some small ones from eBay just as a matter of interest ( but they wont be here for weeks)
The other thing the OP mentioned was TimerOne.
This has been mentioned by a few other people, but I’m not sure its worth attempting to make an STM32 version of this lib, because the things it achieves are already available without using the lib, e.g. duty cycle on PWM and timer interrupts.
I suspect the better approach would be to port the libs, which themselves use TimerOne rather than to have a hacky wrapper around the HardwareTimers and PWM functions.
victor_pv wrote:i have been reading all about the timer lately, and seems like we whould be able to read several enconders with a single timer, and we got 4 of them at the very least in a maple mini.
We can easily have 2 timers doing PWM, with another 2 reading a few encoders, and all using DMA and interrupts.

