The method described here is purely an example of combining individual technologies.
Do not fly this in areas with people or buildings nearby.
The Wii Remote's sensors were not designed for RC use. The craft can become uncontrollable and fly off in unexpected directions or crash.
Careless flying is extremely dangerous. Please exercise extreme caution.
In the previous post, I covered how to send input from Arduino to MultiWii.
This time, I'll use the Wii Remote as a transmitter and Arduino as a receiver, then connect it all to MultiWii.
…or rather, I'd like to — but jumping straight to that without safety measures would be a disaster. So first, let's add safety features.
Wii Remote + Arduino connection
Check on Amazon This is exactly the same as the earlier "RC car with Wii Remote + Arduino + LEGO" series.
See the relevant past posts:
- (3) Enabling the Bluetooth Dongle with USB Host Shield
- (4) Controlling DC Motors with the Wii Remote
Safety feature #1: Overview
The Wii Remote's Bluetooth range is at most about 10 meters.
That means if the quadcopter flies more than 10 meters away, you lose control.
Actually "lose control" is an understatement — it'll go off in whatever direction it pleases.
So before feeding Wii Remote input to the flight controller, we need a safety mechanism in place.
The safety mechanism is simple: trigger MultiWii's FAILSAFE mode.
In FAILSAFE mode, MultiWii cuts motor power just enough to attempt a controlled landing without outright crashing.
To enable FAILSAFE mode in MultiWii, uncomment the
#define FAILSAFE line in config.h.To trigger FAILSAFE while MultiWii is running, simply drive all PPM signals LOW (as described in the previous post).
Safety feature #1: Implementation
"Easy — just set PPM to LOW when the Wii Remote signal drops, right?"
That seems obvious, but implementing it that way and test-flying will cause a serious accident.
The reason: when Bluetooth between Arduino and the Wii Remote disconnects, the Wii Remote library keeps outputting the last received values.
So there's no way to distinguish "connection lost" from "still receiving the same signal".
After thinking about this, I came up with the following approach:
"The Wii Remote's accelerometer values (roll, pitch) are always fluctuating slightly.
If those values stay identical for a certain amount of time, the connection has probably been lost."
Here's the implementation:
Compare the current roll and pitch values against the previous values continuously. If the values remain identical for more than
WII_TIMEOUT milliseconds, set the activate flag to false and drive PPM LOW.
#include <Wii.h>
#include <usbhub.h>
USB Usb;
USBHub Hub1(&Usb);
BTD Btd(&Usb);
WII Wii(&Btd,PAIR);
float pp = 0.0;
float pr = 0.0;
unsigned int cc = 0;
#define WII_TIMEOUT 500
void loop() {
Usb.Task();
if(! Wii.wiimoteConnected || Wii.getButtonPress(HOME)){ activate = 0; return; }
if( millis() > uptime ){
// check connection
if( pp == Wii.getPitch() && pr == Wii.getRoll() ){ cc ++ ; }else{ cc = 0; }
pp = Wii.getPitch();
pr = Wii.getRoll();
uptime = millis() + SPAN;
}
if ( cc > WII_TIMEOUT / SPAN ){ activate = 0; return; }
activate = 1;
: (omitted)
}
void isr_sendPulses() {
digitalWrite(PIN_PPM, LOW);
if( ! activate ){ return; }
: (omitted)
}
Safety feature #2: Overview
Sometimes you need an emergency landing regardless of whether the connection is still active.
For example, when you've lost control of the craft and just need it on the ground — now.
We need a way to trigger FAILSAFE manually, even with the connection intact.
Safety feature #2: Implementation
This one is simple.
Assign a button on the Wii Remote to trigger FAILSAFE as an emergency landing button.
In the example below, pressing the HOME button immediately activates FAILSAFE.
void loop() {
Usb.Task();
if(! Wii.wiimoteConnected || Wii.getButtonPress(HOME)){ activate = 0; return; }
Safety feature #3: Overview
Check on Amazon
FAILSAFE cuts power gradually and the craft drifts down slowly — which means it can drift far in the wind.
When the craft is about to hit someone or something, there's no time for a gentle descent.
In those situations, you may need to abort the flight even at the cost of destroying the quadcopter — so we also add a "shoot-down mode" that cuts all motor power immediately.
If there's any altitude at all, the craft will almost certainly break. But if you hesitate, the damage to others will be far worse.
Practicing the decision to shoot it down is also part of responsible flying.
On the other hand, cutting power at altitude means a chunk of metal falls to the ground — and that's one of the inherent dangers of drones that can't easily be solved.
Safety feature #3: Implementation
For shoot-down mode, assign a motor-stop button combination on the Wii Remote.
Here, it's assigned to holding B and − simultaneously.
A single button is too risky — accidental bumps could trigger it.
Triggering shoot-down mode mid-flight by accident would be extremely dangerous, so I chose B (on the back of the remote) + − (a small button on the front) pressed together — a combination that can't happen by accident.
To stop the motors, set Throttle and Yaw to 1000 via PPM.
This is a special command built into MultiWii that means Disarm.
(For reference: Throttle=1000, Yaw=2000 is the Arm command.)
void loop() {
: (omitted)
if(Wii.getButtonPress(B)){
: (omitted)
if(Wii.getButtonPress(PLUS)){
// arm
currentTh = 1000;
y = 2000;
}else if(Wii.getButtonPress(MINUS)){
// disarm
currentTh = y = 1000;
}
}
setPulse(r,p,currentTh,y,a1,a2);
}
We now have three layers of safety, but even this isn't enough.
I'll also cover debugging procedures before outdoor flight in a future post.
No comments:
Post a Comment