THIS ARTICLE IS MEND TO BE WRITTEN BACK IN 2017, WHEN I WAS 14 YEARS OLD.
A week ago, there’re some word popped up in my mind. “FOC”. Which stands for “Field Oriented Control”. You might wonder what is FOC?
FOC is a (very amazing) technique to control Brushless DC (BLDC) motor. By modulating the already modulated pulse signal (modulate the PWM) and carefully monitor the position of the motor. The Very precise position, Speed and Torque control can be achieved since the modulation is basically “mimicking” Sine wave. This allows user to freely control the “Vector” of the voltage. That’s why BLDC motor can pretty much act as generic RC servo motor or spins really fast like typical RC motor.
In order to control BLDC motor in FOC style. You can use a method called SVM or Space Vector Modulation. I won’t go deep in to this because the main focus of this post is not about the SVM (I might get into this later, with FPGA xD).
Our main focus today is SPWM or Sinusoidal PWM. This is the very first step before we have FOC. SPWM is used for “Synthesizing” the Sine wave by using Sine function to change the PWM duty cycle.
PWM_duty_cycle = sin(angle);
The result is something like this :
The square wave might not look like a sine wave. But It will average out in real world as (almost) a sine wave.
Now, you have some basic knowledge of FOC and SPWM. Now lets hop on story-telling time machine back to 2017
Grade 9 student, just started Arduino for ~1 year, have a fraction of knowledge of what I have today (😎), a 14 years old me. Saw really cool stuffs on Aliexpress for the very first time. And one of them is “SimpleBGC Gimbal”
“Motors, Electronics, Stuffs. These are cool!” 14 years old me said back then.
And then I saw the “Expansion board”. 14 years old me thinking.
“What if, I only buy that Expansion board. Write some magic code on it. And turn it into a I2C motor controller. I can build a DC Fan that speaks I2C, or I can build a cool POV display. That would be nice”
Easier said than done.
After I bought the “AlexMos SimpleBGC 3rd Axis Expansion board” from eBay (I got the cheapest one tho). First thing I did is reprogramming my one and only Arduino Uno with Arduino ISP example code. This will allow me to use Arduino as a ICSP programmer for the ATtiny261A. Brain of this long-named BLDC controller.
The I spend a day, trying to dump the firmware with AVRDude. Result ended in failure. Not sure if I did somethinf wrong or the Flash is protected.
“Screw it! I’m gonna write my own code”
I ended up using ATtiny Arduino core as a platform to work on (Which I sill use today to get this project done). I begin to search for the code online. And I found one that might work. Unknowing that there’re Bare-metally-ish coded. I ended up throwing this board away in my electronics box. And mostly forgot about it.
Until last week.
After I watched videos on YouTube “Teaching Old Motors New Tricks” by Dave from Texas Instrument. I suddenly recalled that I have BLDC controller board from the failed project “AlexMod”. I talked to my self, why don’t give it another shot as I did with many past project?
I literally walked from Uni to my dorm (just couple hundred meters away) to grab the board. Walked back to the Uni. And went to the Robot club (You can meet me there, KMITL Robot club, E12 building, Third floor). And I began to solder the ICSP pin header. Grab a random Arduino Uno and turn it into ISP programmer.
In day 1 of working. I was able to map (probably) all necessary pinout that I need to know. And I began to write down some blink code to make sure that It’s still alive.
At the end of the day. I got the BLDC to do some weird spinning. The motor is vibrating really violently. I call it a day.
Day 2, I started by using Dr LUT website <insert web> to generate three 32 bytes array for phase 0° 120° and 240° Sine function for PWM duty cycle. Now the motor also spinning and vibrating like crazy. But still, I can’t achieve the open loop FOC position control.
I almost called it a day. Went out to grab a Kebab for dinner, Apple Juice. And went back the the RB club. It’s 9PM.
With some more work. I ended with 256 Bytes Sin LUT. With the help of PROGMEM to make it fit in 2K Flash instead of 128 Bytes worth of SRAM. The reason that I went with 256 instead of 360 LUT samples is because I can use uint8_t counter and it will automagically overflow and roll over back to 0 without using “if” to check for out of bound.
Now, the resolution of Sine is high enough to make motor spin smoother. I carefully set the delay (but the code is slowed by the PROGMEM read). I was able to get the motor to spin slowly! Just like stepper motor. That is the power of FOC.
With a little tweak. Set timer clock to 64MHz from PLL to get 32kHz PWM (illiminates humming noise). Set CPU clock to 16MHz. Now I almost have a perfect BLDC Position controller!
Third day, not much happened. I tried to get the I2C to work but It just refused to work. I called it a day with no further progress.
On day 4, which is today. I able to get the I2C (on USI) working. With some FSM tweaking. I got what I wanted!
Sadly, It’s very close to Final exam. I would probably back to make full length video after the Final is over. Until then, See ya!