This blog page is dedicated to the motors of the AR Drone.

You can download an on-drone c program (source+compiled) to control the motors and leds.

Pinout

Pin 1 Battery 11.4V
Pin 2 VCC 5V (ATMega8a VCC Pin4+5)
Pin 3 TX+RX (ATmega8a Pin30+31)
Pin 4 IRQ to main board (ATmega8a PC3 Pin26)
Pin 5 GND

Pin 1 Red
Pin 2 White
Pin 3 Motor1=Yellow,M2=Orange,M3=Blue,M4=Green
Pin 4 Motor1=Purple,M2=Gray,M3=Brown,M4=Pink
Pin 5 Black

IRQ

Whenever the motor controller detects a problem, it will stop running and toggles the IRQ pin. A rising edge to 5v on the IRQ pin sets GPIO 106 (i.e. `gpio 106 -r` returns 1). Pin 106 can be reset to 0 by toggling GPIO 107, i.e. `gpio 107 -d ho 0; gpio 107 -d ho 1`.

In other words this is a flipflop circuit, with Set=IRQ, Reset=GPIO107 and Data=GPIO106.

GPIO

gpio 68 -d i = select motor1
gpio 68 -d ho 0 = deselect motor1
gpio 69 -d i = select motor2
gpio 69 -d ho 0 = deselect motor2
gpio 70 -d i = select motor3
gpio 70 -d ho 0 = deselect motor3
gpio 71 -d i = select motor4
gpio 71 -d ho 0 = deselect motor4
gpio 106 -i = IRQ input, 1=IRQ requested
gpio 107 -d ho 0; gpio 107 -d ho 1 = reset GPIO 106 to 0

Serial Communication

Baud rate: 115200, 8n1

Unicast Commands

Configuiration sent to single motor. The motor is selected with GPIO 68 to 71.

write -> reply in hex, null means no reply
E0 -> status             : get status 00=ok, 50=need reflash
if(status==50){
 71 64bytes 70 -> null    : program flash, repeated 120 times (120 blocks of 64bytes = 7920bytes)
 91 -> 120 bytes          : get 120 checksums of 64 byte flash blocks
 A1 -> A0 FF              : set status OK (command send after command 91)
}
01 or 02,03,04 -> null    : assign as motor1,2,3,4
40 -> 11 bytes            : check versions (eg 01 0b 03 00 01 01 0a 0a 1a 0a 0a = soft version 1.11, hard version 3.0, supplier 1.1, lot number 10/10, FVT1 26/10/10)

Multicast commands

Sent to all motors.

A0 A0 A0 A0 A0 A0 -> null : start of multicast
2x xx xx xx xx -> null    : set speeds sent every 5ms
89 or 8A,8B,8X -> 28 2f   : check motor1,2,3,4 alive - sent one command every 25 frames (i.e. every 125ms one motor, same motor every 500ms)
6x xx,7x xx -> null       : set leds bit5=Red Rear Left, bit6=Green Rear Left, bit7=Red Rear Right, bit8=Green Rear Right, bit9=Red Front Right, bit10=Green Front Right, bit11=Red Front Left, bit12=Green Front Left  (011grgrg rgrxxxx)

Init Sequence

(as used by program.elf)

for x=1 to 4
    CSx_ Low
    TX E0, RX 2 bytes
    TX 91, RX 121 bytes
    TX A1, RX 3 bytes
    TX 00+x, RX 1 byte
    TX 40, RX 12 bytes
    CSx_ High
    wait 500ms
end for
for x=1 to 4
    CSx_ Low
    TX E0, RX 2 bytes
    TX 00+x, RX 1 byte
    TX 40, RX 12 bytes
    CSx_ High
end for
wait 500ms
CS1_,CS2_,CS3_,CS4_ Low (select all)
for x=1 to 6
    TX A0 -> RX 1 byte
end for

Set Speeds

001aaaaa aaaabbbb bbbbbccc ccccccdd ddddddd0
a,b,c,d = 9 bits for motor 1,2,3,4 (msb first)
transmitted every 5ms (200Hz)
every 80ms send 2x + one 8x code

References

http://fenrir.naruoka.org/archives/000805.html

http://www.ardrone-flyers.com/forum/viewtopic.php?f=13&t=1025&start=15

Test Script

The following script initializes the motor and starts the control loop. The control loop flashes all leds. The script has been tested as replacement for program.elf on a AR.Drone with firmware version 1.7.4 and 1.3.3, motor software version 1.20 and 1.11, motor hardware version 3.0, motor supplier 1.1 and 2.2.

#set baud rate
stty -F /dev/ttyPA1 115200

#reset IRQ flipflop - on error 106 read 1, this code resets 106 to 0
gpio 106 -d i
gpio 107 -d ho 0
gpio 107 -d ho 1

#all select lines inactive
gpio 68 -d ho 1
gpio 69 -d ho 1
gpio 70 -d ho 1
gpio 72 -d ho 1

#configure motor1
gpio 68 -d i
echo -en "\xe0" > /dev/ttyPA1
usleep 100
echo -en "\x01" > /dev/ttyPA1
usleep 100
echo -en "\x40" > /dev/ttyPA1
usleep 100
gpio 68 -d ho 1

#configure motor2
gpio 69 -d i
echo -en "\xe0" > /dev/ttyPA1
usleep 100
echo -en "\x02" > /dev/ttyPA1
usleep 100
echo -en "\x40" > /dev/ttyPA1
usleep 100
gpio 69 -d ho 1

#configure motor3
gpio 70 -d i
echo -en "\xe0" > /dev/ttyPA1
usleep 100
echo -en "\x03" > /dev/ttyPA1
usleep 100
echo -en "\x40" > /dev/ttyPA1
usleep 100
gpio 70 -d ho 1

#configure motor4
gpio 71 -d i
echo -en "\xe0" > /dev/ttyPA1
usleep 100
echo -en "\x04" > /dev/ttyPA1
usleep 100
echo -en "\x40" > /dev/ttyPA1
usleep 100
gpio 71 -d ho 1

#all select lines active
gpio 68 -d i
gpio 69 -d i
gpio 70 -d i
gpio 71 -d i

#start multicast
echo -en "\xa0" > /dev/ttyPA1
usleep 100
echo -en "\xa0" > /dev/ttyPA1
usleep 100
echo -en "\xa0" > /dev/ttyPA1
usleep 100
echo -en "\xa0" > /dev/ttyPA1
usleep 100
echo -en "\xa0" > /dev/ttyPA1
usleep 100
echo -en "\xa0" > /dev/ttyPA1
usleep 100

#reset IRQ flipflop - on error 106 read 1, this code resets 106 to 0
gpio 106 -d i
gpio 107 -d ho 0
gpio 107 -d ho 1

#multicast loop
while true
do

echo -en "\x20\x00\x00\x00\x00" >/dev/ttyPA1
usleep 5000
echo -en "\x20\x00\x00\x00\x00" >/dev/ttyPA1
usleep 5000
echo -en "\x20\x00\x00\x00\x00" >/dev/ttyPA1
usleep 5000
echo -en "\x20\x00\x00\x00\x00" >/dev/ttyPA1
usleep 5000
echo -en "\x20\x00\x00\x00\x00" >/dev/ttyPA1
usleep 5000
echo -en "\x20\x00\x00\x00\x00" >/dev/ttyPA1
usleep 5000
echo -en "\x20\x00\x00\x00\x00" >/dev/ttyPA1
usleep 5000
echo -en "\x20\x00\x00\x00\x00" >/dev/ttyPA1
usleep 5000
echo -en "\x20\x00\x00\x00\x00" >/dev/ttyPA1
usleep 5000
echo -en "\x20\x00\x00\x00\x00" >/dev/ttyPA1
usleep 5000
echo -en "\x20\x00\x00\x00\x00" >/dev/ttyPA1
usleep 5000
echo -en "\x20\x00\x00\x00\x00" >/dev/ttyPA1
usleep 5000
echo -en "\x20\x00\x00\x00\x00" >/dev/ttyPA1
usleep 5000
echo -en "\x20\x00\x00\x00\x00" >/dev/ttyPA1
usleep 5000
echo -en "\x20\x00\x00\x00\x00" >/dev/ttyPA1
usleep 5000
echo -en "\x20\x00\x00\x00\x00" >/dev/ttyPA1
usleep 5000
echo -en "\x20\x00\x00\x00\x00" >/dev/ttyPA1
usleep 5000
echo -en "\x20\x00\x00\x00\x00" >/dev/ttyPA1
usleep 5000
echo -en "\x20\x00\x00\x00\x00" >/dev/ttyPA1
usleep 5000
echo -en "\x20\x00\x00\x00\x00" >/dev/ttyPA1
usleep 5000
echo -en "\x20\x00\x00\x00\x00" >/dev/ttyPA1
usleep 5000
echo -en "\x20\x00\x00\x00\x00" >/dev/ttyPA1
usleep 5000
echo -en "\x20\x00\x00\x00\x00" >/dev/ttyPA1
usleep 5000
echo -en "\x20\x00\x00\x00\x00" >/dev/ttyPA1
usleep 5000
echo -en "\x20\x00\x00\x00\x00" >/dev/ttyPA1
usleep 5000
#all leds orange
echo -en "\x7f\xf0" >/dev/ttyPA1

echo -en "\x20\x00\x00\x00\x00" >/dev/ttyPA1
usleep 5000
echo -en "\x20\x00\x00\x00\x00" >/dev/ttyPA1
usleep 5000
echo -en "\x20\x00\x00\x00\x00" >/dev/ttyPA1
usleep 5000
echo -en "\x20\x00\x00\x00\x00" >/dev/ttyPA1
usleep 5000
echo -en "\x20\x00\x00\x00\x00" >/dev/ttyPA1
usleep 5000
echo -en "\x20\x00\x00\x00\x00" >/dev/ttyPA1
usleep 5000
echo -en "\x20\x00\x00\x00\x00" >/dev/ttyPA1
usleep 5000
echo -en "\x20\x00\x00\x00\x00" >/dev/ttyPA1
usleep 5000
echo -en "\x20\x00\x00\x00\x00" >/dev/ttyPA1
usleep 5000
echo -en "\x20\x00\x00\x00\x00" >/dev/ttyPA1
usleep 5000
echo -en "\x20\x00\x00\x00\x00" >/dev/ttyPA1
usleep 5000
echo -en "\x20\x00\x00\x00\x00" >/dev/ttyPA1
usleep 5000
echo -en "\x20\x00\x00\x00\x00" >/dev/ttyPA1
usleep 5000
echo -en "\x20\x00\x00\x00\x00" >/dev/ttyPA1
usleep 5000
echo -en "\x20\x00\x00\x00\x00" >/dev/ttyPA1
usleep 5000
echo -en "\x20\x00\x00\x00\x00" >/dev/ttyPA1
usleep 5000
echo -en "\x20\x00\x00\x00\x00" >/dev/ttyPA1
usleep 5000
echo -en "\x20\x00\x00\x00\x00" >/dev/ttyPA1
usleep 5000
echo -en "\x20\x00\x00\x00\x00" >/dev/ttyPA1
usleep 5000
echo -en "\x20\x00\x00\x00\x00" >/dev/ttyPA1
usleep 5000
echo -en "\x20\x00\x00\x00\x00" >/dev/ttyPA1
usleep 5000
echo -en "\x20\x00\x00\x00\x00" >/dev/ttyPA1
usleep 5000
echo -en "\x20\x00\x00\x00\x00" >/dev/ttyPA1
usleep 5000
echo -en "\x20\x00\x00\x00\x00" >/dev/ttyPA1
usleep 5000
echo -en "\x20\x00\x00\x00\x00" >/dev/ttyPA1
usleep 5000
#all leds off
echo -en "\x60\x00" >/dev/ttyPA1

done

7 Responses to “AR Drone Motor Controller”

  1. > Set Speeds
    > 001aaaaa aaaabbbb bbbbbccc ccccccdd ddddddd0
    > a,b,c,d = 9 bits for motor 1,2,3,4 (msb first)

    I found the 9th bit of each are always 0.
    Looking into the raw NavData dump, the motor PWM speed value is in range of 0~255.
    So I think it should be a 8 bits speed value ,and the 9th bit is just a fill-in bit.
    That is:
    001aaaaa aaa0bbbb bbbb0ccc ccccc0dd dddddd00

    • Apparently the mainboard control program always sets the lsb bit to zero. Digging into a re-assembly of the motor controller’s AVR flash dump I found that the controller does use this 9th bit.

  2. For safe test with AR.Drone motors, I removed the spin-blades. But I got motor CUTOUT after ~3 seconds of running. How to avoid it and make a continued long running? (So I’m able to test the speed changes with different PWM values)

    • You probably need to put the spin-blade back on. I suspect that the motor controller senses that it is running without a blade and cuts out. On my test setup with the drone securely fixed to the table it keeps on running. The motor needs at least 0×66 to startup, after startup the value can be reduced to 0×33.

  3. Hello Hugo,

    I am attempting to create an Arduino program that can be used as an adapter, taking the output from the stock AR Drone boards (stock firmware too) and ultimately outputting a set of PWM signals for use with conventional ESC’s, for bigger motors. It would compare the four motor values against each other to determine ultimately what the drone is asking for Roll, Pitch, Yaw, and Throttle outputs, and then would multiply each against an adjustable gain, and then mix them again and output to their respective motors. The adjustable gains would be used to make the new airframe and motors respond at the same rates, tuning them to match what the AR Drone board is doing.

    The toughest part is learning Arduino, I2C, all of this stuff, it’s all new to me. If there is any help you could give, please let me know, and if you want, feel free to check out my thread about what I’m doing:

    http://www.ardrone-flyers.com/forum/viewtopic.php?f=8&t=4529

    And yes, I really would give you $200 if you could provide me an Arduino program that can read the I2C stream, communicate back to the Drone whatever is needed for the Drone to be happy thinking it’s talking with regular Motor controllers, and then output to four PWM’s for regular ESC’s to plug into. This is all in tons of more detail in my thread. I look forward to hearing from you!

  4. Hi Hugo,

    Thank you very much for sharing your knowledge about the AR Drone motor controller. I’m trying to control de motor with an Arduino board, but I am not able to read and write serial data on the same line (Pin 3) to communicate with the controller. Can you give me any tip?

    • Hi Adrian, in order to use an Arduino you will have to connect the TX & RX pins of the Arduino together. Then you have to modify the Serial library (or write your own library) in such a way that the TX pin is released (i.e. set as input) when the Arduino is not sending data. If the TX pin is kept as output you will not be able to “hear” the controller, and you potentially blow up the Arduino + the motor controller. In your experiments I would add a 1k resistor in series to the TX pin as protection. Good luck, Hugo

Leave a Reply

(required)

(required)


five + 4 =

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

© 2014 Tech Toy Hacks Suffusion theme by Sayontan Sinha