diff --git a/src/platforms/posix/drivers/df_bebop_bus_wrapper/df_bebop_bus_wrapper.cpp b/src/platforms/posix/drivers/df_bebop_bus_wrapper/df_bebop_bus_wrapper.cpp
index e4b1222dce907201f1ec5cc558708a5bc24eedbf..a0d8d0e4a84df6d2786da5fb4b4de5cecaf1d71f 100644
--- a/src/platforms/posix/drivers/df_bebop_bus_wrapper/df_bebop_bus_wrapper.cpp
+++ b/src/platforms/posix/drivers/df_bebop_bus_wrapper/df_bebop_bus_wrapper.cpp
@@ -50,10 +50,11 @@
 #include <uORB/topics/actuator_outputs.h>
 #include <uORB/topics/actuator_controls.h>
 #include <uORB/topics/actuator_armed.h>
+#include <uORB/topics/battery_status.h>
 
 #include <systemlib/mixer/mixer.h>
-#include <systemlib/mixer/mixer_multirotor.generated.h>
 #include <systemlib/pwm_limit/pwm_limit.h>
+#include <systemlib/battery.h>
 
 #include <bebop_bus/BebopBus.hpp>
 #include <DevMgr.hpp>
@@ -65,18 +66,34 @@ using namespace DriverFramework;
 class DfBebopBusWrapper : public BebopBus
 {
 public:
-  DfBebopBusWrapper();
-  ~DfBebopBusWrapper() = default;
+	DfBebopBusWrapper();
+	~DfBebopBusWrapper() = default;
 
-  int start();
-  int stop();
-  int print_info();
+	int start();
+	int stop();
+	int print_info();
+	int start_motors();
+	int stop_motors();
+	int clear_errors();
+	int set_esc_speeds(const float pwm[4]);
+
+	void set_last_throttle(float throttle) {_last_throttle = throttle;};
 
 private:
+	orb_advert_t _battery_topic;
+
+	Battery _battery;
+	bool _armed;
+	float _last_throttle;
+
+	int _battery_orb_class_instance;
+
+	int _publish(struct bebop_state_data &data);
 };
 
 DfBebopBusWrapper::DfBebopBusWrapper() :
-  BebopBus(BEBOP_BUS_DEVICE_PATH)
+	BebopBus(BEBOP_BUS_DEVICE_PATH), _battery_topic(nullptr), _battery(), _armed(false), _last_throttle(0.0f),
+	_battery_orb_class_instance(-1)
 {}
 
 int DfBebopBusWrapper::start()
@@ -96,10 +113,14 @@ int DfBebopBusWrapper::start()
 		return ret;
 	}
 
+	// Signal bus start on Bebop
+	BebopBus::_play_sound(BebopBus::BOOT);
+
 	return 0;
 }
 
-int DfBebopBusWrapper::stop() {
+int DfBebopBusWrapper::stop()
+{
 
 	int ret = BebopBus::stop();
 
@@ -113,13 +134,12 @@ int DfBebopBusWrapper::stop() {
 
 int DfBebopBusWrapper::print_info()
 {
-  bebop_bus_info info;
+	bebop_bus_info info;
 	int ret = _get_info(&info);
 
-	if (ret < 0)
-  {
-    return -1;
-  }
+	if (ret < 0) {
+		return -1;
+	}
 
 	PX4_INFO("Bebop Controller Info");
 	PX4_INFO("  Software Version: %d.%d", info.version_major, info.version_minor);
@@ -130,19 +150,67 @@ int DfBebopBusWrapper::print_info()
 	PX4_INFO("  Total flight time: %d", info.total_flight_time);
 	PX4_INFO("  Last Error: %d\n", info.last_error);
 
-  return 0;
+	return 0;
+}
+
+int DfBebopBusWrapper::start_motors()
+{
+	_armed = true;
+	return BebopBus::_start_motors();
+}
+
+int DfBebopBusWrapper::stop_motors()
+{
+	_armed = false;
+	return BebopBus::_stop_motors();
+}
+
+int DfBebopBusWrapper::clear_errors()
+{
+	return BebopBus::_clear_errors();
+}
+
+int DfBebopBusWrapper::set_esc_speeds(const float pwm[4])
+{
+	return BebopBus::_set_esc_speed(pwm);
+}
+
+int DfBebopBusWrapper::_publish(struct bebop_state_data &data)
+{
+
+	battery_status_s battery_report;
+	const hrt_abstime timestamp = hrt_absolute_time();
+
+	// TODO Check if this is the right way for the Bebop
+	_battery.updateBatteryStatus(timestamp, data.battery_voltage_v, 0.0, _last_throttle, _armed, &battery_report);
+
+	// TODO: when is this ever blocked?
+	if (!(m_pub_blocked)) {
+
+		if (_battery_topic == nullptr) {
+			_battery_topic = orb_advertise_multi(ORB_ID(battery_status), &battery_report,
+							     &_battery_orb_class_instance, ORB_PRIO_LOW);
+
+		} else {
+			orb_publish(ORB_ID(battery_status), _battery_topic, &battery_report);
+		}
+
+	}
+
+	return 0;
 }
 
 namespace df_bebop_bus_wrapper
 {
-  
-DfBebopBusWrapper *g_dev = nullptr;
-volatile bool _task_should_exit = false; // flag indicating if snapdragon_rc_pwm task should exit
-static bool _is_running = false;         // flag indicating if snapdragon_rc_pwm app is running
+
+DfBebopBusWrapper *g_dev = nullptr;      // interface to the Bebop's I2C device
+volatile bool _task_should_exit = false; // flag indicating if bebop esc control task should exit
+static bool _is_running = false;         // flag indicating if bebop esc  app is running
+static bool _motors_running = false;     // flag indicating if the motors are running
 static px4_task_t _task_handle = -1;     // handle to the task main thread
 
 static const int FREQUENCY_PWM = 400;
-static const char *MIXER_FILENAME = "";
+static const char *MIXER_FILENAME = "/home/root/quad_x.main.mix";
 
 // subscriptions
 int     _controls_sub;
@@ -153,34 +221,26 @@ orb_advert_t    _outputs_pub = nullptr;
 orb_advert_t    _rc_pub = nullptr;
 
 // topic structures
-actuator_controls_s _controls;
+actuator_controls_s _controls[1];
 actuator_outputs_s  _outputs;
 actuator_armed_s    _armed;
 
-pwm_limit_t     _pwm_limit;
-
-// esc parameters
-int32_t _pwm_disarmed;
-int32_t _pwm_min;
-int32_t _pwm_max;
-
-MultirotorMixer *_mixer = nullptr;
+MixerGroup *_mixers = nullptr;
 
 int start();
 int stop();
 int info();
 void usage();
-void send_outputs_pwm(const uint16_t *pwm);
 void task_main(int argc, char *argv[]);
 
-/* mixer initialization */
-int initialize_mixer(const char *mixer_filename);
-int mixer_control_callback(uintptr_t handle, uint8_t control_group, uint8_t control_index, float &input);
+/* mixers initialization */
+int initialize_mixers(const char *mixers_filename);
+int mixers_control_callback(uintptr_t handle, uint8_t control_group, uint8_t control_index, float &input);
 
-int mixer_control_callback(uintptr_t handle,
-			   uint8_t control_group,
-			   uint8_t control_index,
-			   float &input)
+int mixers_control_callback(uintptr_t handle,
+			    uint8_t control_group,
+			    uint8_t control_index,
+			    float &input)
 {
 	const actuator_controls_s *controls = (actuator_controls_s *)handle;
 
@@ -189,70 +249,44 @@ int mixer_control_callback(uintptr_t handle,
 	return 0;
 }
 
-int initialize_mixer(const char *mixer_filename)
+int initialize_mixers(const char *mixers_filename)
 {
-	char buf[2048];
+	char buf[2048] = {0};
 	size_t buflen = sizeof(buf);
 
-	PX4_INFO("Trying to initialize mixer from config file %s", mixer_filename);
-
-	int fd_load = ::open(mixer_filename, O_RDONLY);
-
-	if (fd_load != -1) {
-		int nRead = ::read(fd_load, buf, buflen);
-		close(fd_load);
-
-		if (nRead > 0) {
-			_mixer = MultirotorMixer::from_text(mixer_control_callback, (uintptr_t)&_controls, buf, buflen);
+	PX4_INFO("Trying to initialize mixers from config file %s", mixers_filename);
 
-			if (_mixer != nullptr) {
-				PX4_INFO("Successfully initialized mixer from config file");
-				return 0;
+	if (load_mixer_file(mixers_filename, &buf[0], sizeof(buf)) < 0) {
+		warnx("can't load mixer: %s", mixers_filename);
+		return -1;
+	}
 
-			} else {
-				PX4_ERR("Unable to parse from mixer config file");
-				return -1;
-			}
+	if (_mixers == nullptr) {
+		_mixers = new MixerGroup(mixers_control_callback, (uintptr_t)_controls);
+	}
 
-		} else {
-			PX4_WARN("Unable to read from mixer config file");
-			return -2;
-		}
+	if (_mixers == nullptr) {
+		PX4_ERR("No mixers available");
+		return -1;
 
 	} else {
-		PX4_WARN("No mixer config file found, using default mixer.");
+		int ret = _mixers->load_from_buf(buf, buflen);
 
-		/* Mixer file loading failed, fall back to default mixer configuration for
-		* QUAD_X airframe. */
-		float roll_scale = 1;
-		float pitch_scale = 1;
-		float yaw_scale = 1;
-		float deadband = 0;
-
-		_mixer = new MultirotorMixer(mixer_control_callback, (uintptr_t)&_controls,
-					     MultirotorGeometry::QUAD_X,
-					     roll_scale, pitch_scale, yaw_scale, deadband);
-
-		// TODO: temporary hack to make this compile
-		(void)_config_index[0];
-
-		if (_mixer == nullptr) {
-			PX4_ERR("Mixer initialization failed");
-			return -1;
+		if (ret != 0) {
+			PX4_ERR("Unable to parse mixers file");
+			delete _mixers;
+			_mixers = nullptr;
+			ret = -1;
 		}
 
 		return 0;
 	}
 }
 
-void send_outputs_pwm(const uint16_t *pwm)
-{
-  PX4_INFO("%d %d %d %d", pwm[0], pwm[1], pwm[2], pwm[3]);
-}
-
 void task_main(int argc, char *argv[])
 {
 	_is_running = true;
+	_motors_running = false;
 
 	// Subscribe for orb topics
 	_controls_sub = orb_subscribe(ORB_ID(actuator_controls_0));
@@ -269,13 +303,14 @@ void task_main(int argc, char *argv[])
 	/* Don't limit poll intervall for now, 250 Hz should be fine. */
 	//orb_set_interval(_controls_sub, 10);
 
-	// Set up mixer
-	if (initialize_mixer(MIXER_FILENAME) < 0) {
+	// Set up mixers
+	if (initialize_mixers(MIXER_FILENAME) < 0) {
 		PX4_ERR("Mixer initialization failed.");
 		return;
 	}
 
-	pwm_limit_init(&_pwm_limit);
+	// TODO check if we have to adjust the frequency
+	//orb_set_interval(_controls_sub, 1000);
 
 	// Main loop
 	while (!_task_should_exit) {
@@ -296,49 +331,54 @@ void task_main(int argc, char *argv[])
 		}
 
 		if (fds[0].revents & POLLIN) {
-			orb_copy(ORB_ID(actuator_controls_0), _controls_sub, &_controls);
+			orb_copy(ORB_ID(actuator_controls_0), _controls_sub, &_controls[0]);
 
-			_outputs.timestamp = _controls.timestamp;
+			_outputs.timestamp = _controls[0].timestamp;
 
-			/* do mixing */
-			_outputs.noutputs = _mixer->mix(_outputs.output,
-							0 /* not used */,
-							NULL);
 
+			if (_mixers != nullptr) {
+				/* do mixing */
+				_outputs.noutputs = _mixers->mix(_outputs.output,
+								 4,
+								 NULL);
+			}
+
+			// Set last throttle for battery calculations
+			g_dev->set_last_throttle(_controls[0].control[3]);
 
 			/* disable unused ports by setting their output to NaN */
-			for (size_t i = _outputs.noutputs;
-			     i < sizeof(_outputs.output) / sizeof(_outputs.output[0]);
+			for (size_t i = _outputs.noutputs; i < sizeof(_outputs.output) / sizeof(_outputs.output[0]);
 			     i++) {
 				_outputs.output[i] = NAN;
 			}
 
-			const uint16_t reverse_mask = 0;
-			uint16_t disarmed_pwm[4];
-			uint16_t min_pwm[4];
-			uint16_t max_pwm[4];
-
-			for (unsigned int i = 0; i < 4; i++) {
-				disarmed_pwm[i] = _pwm_disarmed;
-				min_pwm[i] = _pwm_min;
-				max_pwm[i] = _pwm_max;
+			float motor_out[4];
+
+			for (size_t i = 0; i < 4; ++i) {
+				if (i < _outputs.noutputs &&
+				    PX4_ISFINITE(_outputs.output[i]) &&
+				    _outputs.output[i] >= -1.0f &&
+				    _outputs.output[i] <= 1.0f) {
+					/* scale for Bebop output 0.0 - 1.0 */
+					_outputs.output[i] = (_outputs.output[i] + 1.0f) / 2.0f;
+
+				} else {
+					/*
+					 * Value is NaN, INF or out of band - set to the minimum value.
+					 * This will be clearly visible on the servo status and will limit the risk of accidentally
+					 * spinning motors. It would be deadly in flight.
+					 */
+					_outputs.output[i] = 0.0;
+				}
 			}
 
-			uint16_t pwm[4];
-
-			// TODO FIXME: pre-armed seems broken
-			pwm_limit_calc(_armed.armed,
-				       false/*_armed.prearmed*/,
-				       _outputs.noutputs,
-				       reverse_mask,
-				       disarmed_pwm,
-				       min_pwm,
-				       max_pwm,
-				       _outputs.output,
-				       pwm,
-				       &_pwm_limit);
+			// Adjust order of BLDCs from PX4 to Bebop
+			motor_out[0] = _outputs.output[2];
+			motor_out[1] = _outputs.output[0];
+			motor_out[2] = _outputs.output[3];
+			motor_out[3] = _outputs.output[1];
 
-			send_outputs_pwm(pwm);
+			g_dev->set_esc_speeds(motor_out);
 
 			if (_outputs_pub != nullptr) {
 				orb_publish(ORB_ID(actuator_outputs), _outputs_pub, &_outputs);
@@ -354,6 +394,17 @@ void task_main(int argc, char *argv[])
 		if (updated) {
 			orb_copy(ORB_ID(actuator_armed), _armed_sub, &_armed);
 		}
+
+		if (_armed.armed && !_motors_running) {
+			g_dev->start_motors();
+			_motors_running = true;
+		}
+
+		if (!_armed.armed && _motors_running) {
+			g_dev->stop_motors();
+			g_dev->clear_errors();
+			_motors_running = false;
+		}
 	}
 
 	orb_unsubscribe(_controls_sub);
@@ -379,7 +430,7 @@ int start()
 		return ret;
 	}
 
-	// Open the MAG sensor
+	// Open the Bebop dirver
 	DevHandle h;
 	DevMgr::getHandle(BEBOP_BUS_DEVICE_PATH, h);
 
@@ -391,7 +442,7 @@ int start()
 
 	DevMgr::releaseHandle(h);
 
-  // Start the task to forward the motor control commands
+	// Start the task to forward the motor control commands
 	ASSERT(_task_handle == -1);
 
 	/* start the task */
@@ -413,7 +464,7 @@ int start()
 
 int stop()
 {
-  // Stop bebop motor control task
+	// Stop bebop motor control task
 	_task_should_exit = true;
 
 	while (_is_running) {
@@ -428,7 +479,7 @@ int stop()
 		return 1;
 	}
 
-  // Stop DF device
+	// Stop DF device
 	int ret = g_dev->stop();
 
 	if (ret != 0) {
@@ -455,9 +506,10 @@ info()
 	PX4_DEBUG("state @ %p", g_dev);
 
 	int ret = g_dev->print_info();
+
 	if (ret != 0) {
-	  PX4_ERR("Unable to print info");
-	  return ret;
+		PX4_ERR("Unable to print info");
+		return ret;
 	}
 
 	return 0;
@@ -469,7 +521,7 @@ usage()
 	PX4_INFO("Usage: df_bebop_bus_wrapper 'start', 'info', 'stop'");
 }
 
-} /* df_bebop_bus_wrapper */ 
+} /* df_bebop_bus_wrapper */
 
 
 int