Go Down

Topic: Is the Due fast enough for BLDC commutation? (Read 1 time) previous topic - next topic

Hi, I'm planning on using the Arduino Due for 3-phase commutation for a Brushless DC motor. The motor is 8-pole, and I would like it to run up to 10000 rpm. With 6 commutations pr. electrical rotations, it equals 8000 state changes pr. second which equals 125 micro seconds between state changes. However in order not to loose too much torque, i would like to make the state change within 5% of that period, which means 6.25 micro seconds.
I would like to avoid direct port manipulation etc. and instead use digitalRead, analogWrite etc.

So I imagine a process like: React to an interrupt triggered by one of 3 hall sensors - set flag in interrupt routine - check for that flag in main loop before any other processor intensive tasks (like lcd display, PID calculations etc.) - If flag is set then read 3 hall sensor states and analogWrite to the 6 outputs to the half bridge drivers according to the hall sensors  (cross conduction and over current is taken care of in hardware).

My question is: Is the Arduino Due able to do the above process in 6.25 micro seconds?

Another question is: Is it possible to do digitalRead on pins that are setup for interrupts.

Regards, Peter

bobcousins

There is a sliding scale of difficulty here.

Quote
Is the Due fast enough for BLDC commutation?


In general, yes. If you can do 9000 RPM with an 8bit AVR, 10kRPM should be easily achievable, and you can probably afford to be a bit loose with your coding.
http://www.instructables.com/id/BLDC-Motor-Control-with-Arduino-salvaged-HD-motor/

Quote
My question is: Is the Arduino Due able to do the above process in 6.25 micro seconds?


This I think is starting to push the limits, depending on how much calculation is performed, you can quickly eat up 5us and have not much left over.

If motor control was the only function, then it should still be doable, but you may need to do some optimizations and use whatever hardware assist is available. Will need to be interrupt driven.

Quote
check for that flag in main loop before any other processor intensive tasks (like lcd display, PID calculations etc.)


This is where you will probably run into difficulties. if you have the CPU 80% dedicated to driving the motor, the rest of the tasks have to be low-priority background stuff. There is no low-overhead way to assign priority to real-time tasks other than with interrupts.

With the right architecture, and some careful coding, you might be able to squeeze everything in. I would consider having a chip dedicated to motor control, and another for UI type functions.

Even with a detailed spec, it's not possible to give a definitive answer. The only way to find out for sure is to prototype it. If you write some representative control code and measure how much CPU it takes, you can get an idea how much is spare.
Please don't PM me asking for help. Ask questions in the forum.

Collin80

Well, the Due is 84MHz and executes one instruction per clock so you get 84 instructions per uS and thus 525 instructions in the span of 6.25us. But, you really have 125uS if you can calculate and anticipate the next operation directly after doing the current one. That gives you upwards of 10,500 instructions. I'm fairly sure that the hardware pins can be toggled at least at 1MHz and maybe faster so that gives you plenty of leeway. But, if you plan to do this why wouldn't you use a chip with built-in three phase hardware outputs? This is much safer because they tend to support hardware based dead time and all sorts of other pleasantries. You might not need to do as much PWM with a BLDC but my understanding is that you still want trapezoidal waveforms so that means you are going to be doing PWM up the ramp and down.

BTW, you can always do digitalRead even if the pin has interrupts. Reading the pin state will still tell you whether it is high or low. But, if you hope to do fast I/O you really might want to use faster routines than digitalWrite/digitalRead. I seem to remember people commenting on ways to make those two functions faster but I'm not sure of the current state of either one. If you need speed it might be better to be sure you've got the fastest routines possible.

Thank you, both :) This gives me some ideas about how to make the code as efficient as possible i.e. interrupt driven and anticipating the next commutation. I guess I'll have to wait for the Due to arrive in the mail, and do some benchmark test. If it is too slow, I'll have to wrap my head around using direct port manipulation.

I'll be using 3 IR2183 for the half bridge drivers. The reason for this, is that i prefer through hole parts (related to poor soldering skills), and that I'll be using a total of 12 hefty mosfets, so i need some power for gate drive. Also the IR2183 have built in cross conduction protection and 500ns dead time. I haven't been able to find  a through hole 3-phase driver IC for this. I'm finishing of the schematic and will be making a post about this in the electronics part of forum.

I remembered reading something about analogWrite on the Due, having a lot of overhead, bit I can't find it again. Does anybody know how many cycles it takes to do an analogWrite (and maybe also cycles for digitalRead)?

MarkT

#4
Aug 23, 2014, 02:53 pm Last Edit: Aug 23, 2014, 03:02 pm by MarkT Reason: 1
This is how I'd do it.

Install the same interrupt handler on each of the hall pins, on CHANGE.

Drive a pin with PWM and install the same handler on it, on CHANGE

This interrupt handler reads all 3 hall signals and the PWM line and does
a quick table-lookup to determine the output values, which it outputs (use
direct port manipulation for input and output if you can).  It also writes a
variable indicating the current commutation state (and increments
or decrements a counter if you want to keep track of rotations like an
encoder).

The main code can change the PWM duty cycle to control drive and
overwrite the lookup table to select reverse or emergency stop.

Have the outputs to the 3-phase bridge arranged as contiguous
bits in the same PIO port, makes the lookup table easier to manage.

You'll have to find a suitable PWM frequency by trial and error, but
due to the fast commutation perhaps 20kHz?

analogWrite for PWM ends up just writing one control register, once
all the hardware is setup by the first call to analogWrite for that pin.
Look at the code for analogWrite perhaps?  Its fast enough though
I think.

If you're using 2 MOSFETs per leg what sort of current are you driving?
These days devices down to 1 milliohm are readily obtained which can
handle 50A+ without hassle on a heatsink.

Remember when driving multiple MOSFETs from one driver you need
gate resistors per device.
[ I won't respond to messages, use the forum please ]

MarkT

I should mention I've driven 2 and 4 pole BLDCs from an ATmega328 at upto 4000rpm
and 8kHz PWM.  Direct port manipulation was important to get that throughput, but
the Due is 5 times faster and 4 times wider (32 bit, not 8).

My favorite high-performance MOSFET at the moment is the IPB017N06N3,
60V, 1.3 milliohm, 180A (bond wire limit), 250W. 
Its surface mount but large enough to be hand solderable, and can be directly
hot-air soldered onto copper strips if you bend up the gate lead and wire that
separately.  Having 5 source leads instead of 1 really allows significant current
handling

http://www.infineon.com/dgdl/IPB017N06N3_Rev2.0.pdf?folderId=db3a30431441fb5d01148ca9f1be0e77&fileId=db3a30431ddc9372011e264a7ab746ea
[ I won't respond to messages, use the forum please ]

Hi MarkT, Thank you for your reply.
Quote
Drive a pin with PWM and install the same handler on it, on CHANGE

Could you explain more about this? I thought that reacting to the hall state change was enough.
Quote
If you're using 2 MOSFETs per leg what sort of current are you driving?

I want to drive a car alternator as a BLDC motor, I already have it running ok on a sensorless RC ESC, but it loses sync under heavy load or slow rpm. I'm planning to experiment with it at 24V-48V and up to about 100A.

I'm looking forward to writing this code, best kind of brain exercise  XD

bobcousins

To see how slow digitalWrite is, have a look at this thread http://forum.arduino.cc/index.php?topic=129868.msg1007525#msg1007525. It takes about 2.5us, or about 200 instructions.

OTOH, writing to an output port can be one instruction, but it takes 2 cycles for the output pin to be set.
Please don't PM me asking for help. Ask questions in the forum.

MarkT


Hi MarkT, Thank you for your reply.
Quote
Drive a pin with PWM and install the same handler on it, on CHANGE

Could you explain more about this? I thought that reacting to the hall state change was enough.

The output pattern to the bridge depends on commutator phase and on the PWM
signal.  So use both to do a table lookup is quick and foolproof way to update the
bridge - after any relevant change.
Quote

Quote
If you're using 2 MOSFETs per leg what sort of current are you driving?

I want to drive a car alternator as a BLDC motor, I already have it running ok on a sensorless RC ESC, but it loses sync under heavy load or slow rpm. I'm planning to experiment with it at 24V-48V and up to about 100A.

I'm looking forward to writing this code, best kind of brain exercise  XD


Ooh, which alternator?  Specs?  With that many poles your commutation position
can be used to implement a servo position loop of sorts.
[ I won't respond to messages, use the forum please ]

MarkT


To see how slow digitalWrite is, have a look at this thread http://forum.arduino.cc/index.php?topic=129868.msg1007525#msg1007525. It takes about 2.5us, or about 200 instructions.

OTOH, writing to an output port can be one instruction, but it takes 2 cycles for the output pin to be set.

I get 1.07us for digitalRead, 1.25us for digitalWrite, both on version 1.5.6

Note that benchmarking the Due is rather hit and miss due to the cache.
[ I won't respond to messages, use the forum please ]

bobcousins


I get 1.07us for digitalRead, 1.25us for digitalWrite, both on version 1.5.6

Note that benchmarking the Due is rather hit and miss due to the cache.


Ok, I get 2.44 us from a scope trace on 1.5.6-r2. How are you measuring it?

I believe the Due does not have a cache.
Please don't PM me asking for help. Ask questions in the forum.

MarkT

timing a tenfold unrolled loop, like I usually do to benchmark.  Not ideal.
[ I won't respond to messages, use the forum please ]

Quote
Ooh, which alternator?  Specs?  With that many poles your commutation position
can be used to implement a servo position loop of sorts.


I think it is an 80A Bosch, but i can't remember for sure. I bought it new about 4 years ago for about 20$ from an online Alfa Romeo parts dealer.

I just pulled it apart to look for possible sensor placement, and i remembered wrong it's only got 6 pole pairs, not 8.

Go Up