What action is responsible for speed changes in a brushless DC motor?
Properly driving BLDC motors is a bit of fun with advanced mathematics. 

That said, most of the cheap controllers, do some of the work, but rarely all of it. So the real question is, which tradeoffs do you want to make.

Theoretical / Optimal version

From the theoretical standpoint, you are driving each of the three windings (arranged in a triangle, which means each lead connects to two windings), with an out-of-phase sine waveform (which can be generated via PWM and some power MOSFETs/IGBTs), perhaps coupled with a balancing/filtering cap. 

You are also supposed to be looking at the current draw of each winding (remember, it's inductive, so it's not just I=U/R), and using that to determine the actual (time-dependent, when the motor is rotating) impedance - this can be used to compute where exactly is the rotor, and what is it's current rotational speed.

Then, you compare this with control signal, and make necessary adjustments.

Take a look at OpenBLDC project, for more information on how to make a really nice BLDC controller. Yup, it's complicated, yup, it requires hardware FPU to work quickly enough for practical applications. 

Practical Version:

From the practical standpoint, controllers take either of the four options:


Dedicated BLDC chip
Not exactly the cheapest option out there, but often enough actually implements all the above goals in hardware (either analog or digital, but basically optimized for this particual application). If you want to go that way, you can get going pretty quickly, but don't expect too much in terms of mass savings compared to a commercial product based on the same chip, at least if you want to keep this stuff hand-solderable - the PCB mass will add up, even if you can potentially shave off some useless electronics. The exception - some commercial BLDC controllers will have additional digital chip that interprets that weird proportional delay control RC models use. You can probably talk directly to the  dedicated driver.
El-Cheapo solution.
If really in a pinch for space, you can actually drive a BLDC with a square wave of correct frequency. You still have to use back-EMF for speed estimation, since if you drive it too fast, it will actually stall and do nothing - basically driving frequency needs to be just a bit above current rotational frequency for maximum torque. You can PWM it too, but I doubt Arduino would have enough CPU to do sine calculations (or RAM to do lookups) 
Really El-Cheapo solution
If really, really in a pinch for space, you can also skip the back-EMF calculation. You can do it in quadrocopters because you will have a nice feedback loop from accelerometers and the propellers acting as a turbine if it starts falling (thereby decreasing the work needed from the engine). With a lot of finetuning the open loop control software, you can actually do that. 
Recommended solution
Get a real Cortex M3/M4/M4F CPU. It will make everything software-related seem like a breeze :)