diff --git a/org.fortiss.af3.platform.raspberry/trunk/code-gen-hal/inc/af3pihal/rumblepad.h b/org.fortiss.af3.platform.raspberry/trunk/code-gen-hal/inc/af3pihal/rumblepad.h
new file mode 100644
index 0000000000000000000000000000000000000000..5c42112503f2325b10cba12a2b145cd40ef2b09d
--- /dev/null
+++ b/org.fortiss.af3.platform.raspberry/trunk/code-gen-hal/inc/af3pihal/rumblepad.h
@@ -0,0 +1,66 @@
+/*******************************************************************************
+ * Copyright (c) 2017 fortiss GmbH.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v20.html
+ *
+ * Contributors:
+ *    Thomas Boehm, Florian Hoelzl - initial API and implementation
+ *******************************************************************************/
+#ifndef INC_RUMBLEPAD_H_
+#define INC_RUMBLEPAD_H_
+
+#include <stdint.h>
+
+#define RUMBLEPAD_AXIS_LEFT_STICK_HORIZONTAL	 0
+#define RUMBLEPAD_AXIS_LEFT_STICK_VERTICAL	 1
+#define RUMBLEPAD_AXIS_L2	 2
+#define RUMBLEPAD_AXIS_RIGHT_STICK_HORIZONTAL	 3
+#define RUMBLEPAD_AXIS_RIGHT_STICK_VERTICAL	 4
+#define RUMBLEPAD_AXIS_R2	 5
+//#define RUMBLEPAD_AXIS_CROSS_PAD_HORIZONTAL	 4
+//#define RUMBLEPAD_AXIS_CROSS_PAD_VERTICAL		 5
+
+#define RUMBLEPAD_BUTTON_A					 6
+#define RUMBLEPAD_BUTTON_B					 7
+#define RUMBLEPAD_BUTTON_Y					 8
+#define RUMBLEPAD_BUTTON_X					 9
+#define RUMBLEPAD_BUTTON_L1					10
+#define RUMBLEPAD_BUTTON_R1					11
+#define RUMBLEPAD_BUTTON_SELECT				12
+#define RUMBLEPAD_BUTTON_START				13
+#define RUMBLEPAD_BUTTON_L3					14
+#define RUMBLEPAD_BUTTON_R3					15
+#define RUMBLEPAD_BUTTON_HOME				16
+#define RUMBLEPAD_DPAD_UP					17
+#define RUMBLEPAD_DPAD_DOWN					18
+#define RUMBLEPAD_DPAD_LEFT					19
+#define RUMBLEPAD_DPAD_RIGHT				20
+//#define RUMBLEPAD_BUTTON_LEFT_STICK			16
+//#define RUMBLEPAD_BUTTON_RIGHT_STICK			17
+
+#define RUMBLEPAD_BUTTON_STATE_PRESSED		1
+#define RUMBLEPAD_BUTTON_STATE_NPRESSED		0
+
+struct rumblepad_configuration {
+	const char* device_id;
+	uint64_t waiting_sleep_in_micros;
+	void (*axis_callback)(uint8_t axis, int16_t value);
+	void (*button_callback)(uint8_t button, uint16_t old_value, uint16_t new_value);
+};
+typedef struct rumblepad_configuration rumblepad_configuration_t;
+
+/** Initializes the rumblepad and starts its thread. */
+void rumblepad_initialize(rumblepad_configuration_t* configuration);
+
+/** Get the axis position for the given axis. */
+int16_t rumblepad_get_axis_position(uint8_t axisID);
+
+/** Get the button state for the given button. */
+int16_t rumblepad_get_button_state(uint8_t buttonID);
+
+/** Terminates the rumblepad thread and frees its resources. */
+void rumblepad_terminate();
+
+#endif /* INC_RUMBLEPAD_H_ */
diff --git a/org.fortiss.af3.platform.raspberry/trunk/code-gen-hal/inc/af3pihal/temp_actuator.h b/org.fortiss.af3.platform.raspberry/trunk/code-gen-hal/inc/af3pihal/temp_actuator.h
index 7edc9167247ed40ef4f191a493ff32bc052460ba..332ccaf446d4efaac838aea1f77bb7604313a35b 100644
--- a/org.fortiss.af3.platform.raspberry/trunk/code-gen-hal/inc/af3pihal/temp_actuator.h
+++ b/org.fortiss.af3.platform.raspberry/trunk/code-gen-hal/inc/af3pihal/temp_actuator.h
@@ -3,12 +3,14 @@
 
 #include <stdint.h>
 
-void temp_actuator_initialize(const char * device);
+int temp_actuator_initialize(const char * device);
 
 int temp_actuator_get_position(uint8_t channel);
 
 int temp_actuator_set_target(uint8_t channel, uint16_t target);
 
+int temp_actuator_device_set_target(int device, uint8_t channel, uint16_t target);
+
 void temp_actuator_terminate();
 
 #endif /* INC_TEMP_ACTUATOR_H_ */
diff --git a/org.fortiss.af3.platform.raspberry/trunk/code-gen-hal/inc/brick/brick_imu_v2.h b/org.fortiss.af3.platform.raspberry/trunk/code-gen-hal/inc/brick/brick_imu_v2.h
new file mode 100644
index 0000000000000000000000000000000000000000..ebf49f3aa410d7565b1d104955dc170cf0431ca4
--- /dev/null
+++ b/org.fortiss.af3.platform.raspberry/trunk/code-gen-hal/inc/brick/brick_imu_v2.h
@@ -0,0 +1,1259 @@
+/* ***********************************************************
+ * This file was automatically generated on 2017-07-27.      *
+ *                                                           *
+ * C/C++ Bindings Version 2.1.17                             *
+ *                                                           *
+ * If you have a bugfix for this file and want to commit it, *
+ * please fix the bug in the generator. You can find a link  *
+ * to the generators git repository on tinkerforge.com       *
+ *************************************************************/
+
+#ifndef BRICK_IMU_V2_H
+#define BRICK_IMU_V2_H
+
+#include "ip_connection.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \defgroup BrickIMUV2 IMU Brick 2.0
+ */
+
+/**
+ * \ingroup BrickIMUV2
+ *
+ * Full fledged AHRS with 9 degrees of freedom
+ */
+typedef Device IMUV2;
+
+/**
+ * \ingroup BrickIMUV2
+ */
+#define IMU_V2_FUNCTION_GET_ACCELERATION 1
+
+/**
+ * \ingroup BrickIMUV2
+ */
+#define IMU_V2_FUNCTION_GET_MAGNETIC_FIELD 2
+
+/**
+ * \ingroup BrickIMUV2
+ */
+#define IMU_V2_FUNCTION_GET_ANGULAR_VELOCITY 3
+
+/**
+ * \ingroup BrickIMUV2
+ */
+#define IMU_V2_FUNCTION_GET_TEMPERATURE 4
+
+/**
+ * \ingroup BrickIMUV2
+ */
+#define IMU_V2_FUNCTION_GET_ORIENTATION 5
+
+/**
+ * \ingroup BrickIMUV2
+ */
+#define IMU_V2_FUNCTION_GET_LINEAR_ACCELERATION 6
+
+/**
+ * \ingroup BrickIMUV2
+ */
+#define IMU_V2_FUNCTION_GET_GRAVITY_VECTOR 7
+
+/**
+ * \ingroup BrickIMUV2
+ */
+#define IMU_V2_FUNCTION_GET_QUATERNION 8
+
+/**
+ * \ingroup BrickIMUV2
+ */
+#define IMU_V2_FUNCTION_GET_ALL_DATA 9
+
+/**
+ * \ingroup BrickIMUV2
+ */
+#define IMU_V2_FUNCTION_LEDS_ON 10
+
+/**
+ * \ingroup BrickIMUV2
+ */
+#define IMU_V2_FUNCTION_LEDS_OFF 11
+
+/**
+ * \ingroup BrickIMUV2
+ */
+#define IMU_V2_FUNCTION_ARE_LEDS_ON 12
+
+/**
+ * \ingroup BrickIMUV2
+ */
+#define IMU_V2_FUNCTION_SAVE_CALIBRATION 13
+
+/**
+ * \ingroup BrickIMUV2
+ */
+#define IMU_V2_FUNCTION_SET_ACCELERATION_PERIOD 14
+
+/**
+ * \ingroup BrickIMUV2
+ */
+#define IMU_V2_FUNCTION_GET_ACCELERATION_PERIOD 15
+
+/**
+ * \ingroup BrickIMUV2
+ */
+#define IMU_V2_FUNCTION_SET_MAGNETIC_FIELD_PERIOD 16
+
+/**
+ * \ingroup BrickIMUV2
+ */
+#define IMU_V2_FUNCTION_GET_MAGNETIC_FIELD_PERIOD 17
+
+/**
+ * \ingroup BrickIMUV2
+ */
+#define IMU_V2_FUNCTION_SET_ANGULAR_VELOCITY_PERIOD 18
+
+/**
+ * \ingroup BrickIMUV2
+ */
+#define IMU_V2_FUNCTION_GET_ANGULAR_VELOCITY_PERIOD 19
+
+/**
+ * \ingroup BrickIMUV2
+ */
+#define IMU_V2_FUNCTION_SET_TEMPERATURE_PERIOD 20
+
+/**
+ * \ingroup BrickIMUV2
+ */
+#define IMU_V2_FUNCTION_GET_TEMPERATURE_PERIOD 21
+
+/**
+ * \ingroup BrickIMUV2
+ */
+#define IMU_V2_FUNCTION_SET_ORIENTATION_PERIOD 22
+
+/**
+ * \ingroup BrickIMUV2
+ */
+#define IMU_V2_FUNCTION_GET_ORIENTATION_PERIOD 23
+
+/**
+ * \ingroup BrickIMUV2
+ */
+#define IMU_V2_FUNCTION_SET_LINEAR_ACCELERATION_PERIOD 24
+
+/**
+ * \ingroup BrickIMUV2
+ */
+#define IMU_V2_FUNCTION_GET_LINEAR_ACCELERATION_PERIOD 25
+
+/**
+ * \ingroup BrickIMUV2
+ */
+#define IMU_V2_FUNCTION_SET_GRAVITY_VECTOR_PERIOD 26
+
+/**
+ * \ingroup BrickIMUV2
+ */
+#define IMU_V2_FUNCTION_GET_GRAVITY_VECTOR_PERIOD 27
+
+/**
+ * \ingroup BrickIMUV2
+ */
+#define IMU_V2_FUNCTION_SET_QUATERNION_PERIOD 28
+
+/**
+ * \ingroup BrickIMUV2
+ */
+#define IMU_V2_FUNCTION_GET_QUATERNION_PERIOD 29
+
+/**
+ * \ingroup BrickIMUV2
+ */
+#define IMU_V2_FUNCTION_SET_ALL_DATA_PERIOD 30
+
+/**
+ * \ingroup BrickIMUV2
+ */
+#define IMU_V2_FUNCTION_GET_ALL_DATA_PERIOD 31
+
+/**
+ * \ingroup BrickIMUV2
+ */
+#define IMU_V2_FUNCTION_SET_SENSOR_CONFIGURATION 41
+
+/**
+ * \ingroup BrickIMUV2
+ */
+#define IMU_V2_FUNCTION_GET_SENSOR_CONFIGURATION 42
+
+/**
+ * \ingroup BrickIMUV2
+ */
+#define IMU_V2_FUNCTION_SET_SENSOR_FUSION_MODE 43
+
+/**
+ * \ingroup BrickIMUV2
+ */
+#define IMU_V2_FUNCTION_GET_SENSOR_FUSION_MODE 44
+
+/**
+ * \ingroup BrickIMUV2
+ */
+#define IMU_V2_FUNCTION_SET_SPITFP_BAUDRATE_CONFIG 231
+
+/**
+ * \ingroup BrickIMUV2
+ */
+#define IMU_V2_FUNCTION_GET_SPITFP_BAUDRATE_CONFIG 232
+
+/**
+ * \ingroup BrickIMUV2
+ */
+#define IMU_V2_FUNCTION_GET_SEND_TIMEOUT_COUNT 233
+
+/**
+ * \ingroup BrickIMUV2
+ */
+#define IMU_V2_FUNCTION_SET_SPITFP_BAUDRATE 234
+
+/**
+ * \ingroup BrickIMUV2
+ */
+#define IMU_V2_FUNCTION_GET_SPITFP_BAUDRATE 235
+
+/**
+ * \ingroup BrickIMUV2
+ */
+#define IMU_V2_FUNCTION_GET_SPITFP_ERROR_COUNT 237
+
+/**
+ * \ingroup BrickIMUV2
+ */
+#define IMU_V2_FUNCTION_ENABLE_STATUS_LED 238
+
+/**
+ * \ingroup BrickIMUV2
+ */
+#define IMU_V2_FUNCTION_DISABLE_STATUS_LED 239
+
+/**
+ * \ingroup BrickIMUV2
+ */
+#define IMU_V2_FUNCTION_IS_STATUS_LED_ENABLED 240
+
+/**
+ * \ingroup BrickIMUV2
+ */
+#define IMU_V2_FUNCTION_GET_PROTOCOL1_BRICKLET_NAME 241
+
+/**
+ * \ingroup BrickIMUV2
+ */
+#define IMU_V2_FUNCTION_GET_CHIP_TEMPERATURE 242
+
+/**
+ * \ingroup BrickIMUV2
+ */
+#define IMU_V2_FUNCTION_RESET 243
+
+/**
+ * \ingroup BrickIMUV2
+ */
+#define IMU_V2_FUNCTION_GET_IDENTITY 255
+
+/**
+ * \ingroup BrickIMUV2
+ *
+ * Signature: \code void callback(int16_t x, int16_t y, int16_t z, void *user_data) \endcode
+ * 
+ * This callback is triggered periodically with the period that is set by
+ * {@link imu_v2_set_acceleration_period}. The parameters are the acceleration
+ * for the x, y and z axis.
+ */
+#define IMU_V2_CALLBACK_ACCELERATION 32
+
+/**
+ * \ingroup BrickIMUV2
+ *
+ * Signature: \code void callback(int16_t x, int16_t y, int16_t z, void *user_data) \endcode
+ * 
+ * This callback is triggered periodically with the period that is set by
+ * {@link imu_v2_set_magnetic_field_period}. The parameters are the magnetic
+ * field for the x, y and z axis.
+ */
+#define IMU_V2_CALLBACK_MAGNETIC_FIELD 33
+
+/**
+ * \ingroup BrickIMUV2
+ *
+ * Signature: \code void callback(int16_t x, int16_t y, int16_t z, void *user_data) \endcode
+ * 
+ * This callback is triggered periodically with the period that is set by
+ * {@link imu_v2_set_angular_velocity_period}. The parameters are the angular
+ * velocity for the x, y and z axis.
+ */
+#define IMU_V2_CALLBACK_ANGULAR_VELOCITY 34
+
+/**
+ * \ingroup BrickIMUV2
+ *
+ * Signature: \code void callback(int8_t temperature, void *user_data) \endcode
+ * 
+ * This callback is triggered periodically with the period that is set by
+ * {@link imu_v2_set_temperature_period}. The parameter is the temperature.
+ */
+#define IMU_V2_CALLBACK_TEMPERATURE 35
+
+/**
+ * \ingroup BrickIMUV2
+ *
+ * Signature: \code void callback(int16_t x, int16_t y, int16_t z, void *user_data) \endcode
+ * 
+ * This callback is triggered periodically with the period that is set by
+ * {@link imu_v2_set_linear_acceleration_period}. The parameters are the
+ * linear acceleration for the x, y and z axis.
+ */
+#define IMU_V2_CALLBACK_LINEAR_ACCELERATION 36
+
+/**
+ * \ingroup BrickIMUV2
+ *
+ * Signature: \code void callback(int16_t x, int16_t y, int16_t z, void *user_data) \endcode
+ * 
+ * This callback is triggered periodically with the period that is set by
+ * {@link imu_v2_set_gravity_vector_period}. The parameters gravity vector
+ * for the x, y and z axis.
+ */
+#define IMU_V2_CALLBACK_GRAVITY_VECTOR 37
+
+/**
+ * \ingroup BrickIMUV2
+ *
+ * Signature: \code void callback(int16_t heading, int16_t roll, int16_t pitch, void *user_data) \endcode
+ * 
+ * This callback is triggered periodically with the period that is set by
+ * {@link imu_v2_set_orientation_period}. The parameters are the orientation
+ * (heading (yaw), roll, pitch) of the IMU Brick in Euler angles. See
+ * {@link imu_v2_get_orientation} for details.
+ */
+#define IMU_V2_CALLBACK_ORIENTATION 38
+
+/**
+ * \ingroup BrickIMUV2
+ *
+ * Signature: \code void callback(int16_t w, int16_t x, int16_t y, int16_t z, void *user_data) \endcode
+ * 
+ * This callback is triggered periodically with the period that is set by
+ * {@link imu_v2_set_quaternion_period}. The parameters are the orientation
+ * (x, y, z, w) of the IMU Brick in quaternions. See {@link imu_v2_get_quaternion}
+ * for details.
+ */
+#define IMU_V2_CALLBACK_QUATERNION 39
+
+/**
+ * \ingroup BrickIMUV2
+ *
+ * Signature: \code void callback(int16_t acceleration[3], int16_t magnetic_field[3], int16_t angular_velocity[3], int16_t euler_angle[3], int16_t quaternion[4], int16_t linear_acceleration[3], int16_t gravity_vector[3], int8_t temperature, uint8_t calibration_status, void *user_data) \endcode
+ * 
+ * This callback is triggered periodically with the period that is set by
+ * {@link imu_v2_set_all_data_period}. The parameters are as for
+ * {@link imu_v2_get_all_data}.
+ */
+#define IMU_V2_CALLBACK_ALL_DATA 40
+
+
+/**
+ * \ingroup BrickIMUV2
+ */
+#define IMU_V2_MAGNETOMETER_RATE_2HZ 0
+
+/**
+ * \ingroup BrickIMUV2
+ */
+#define IMU_V2_MAGNETOMETER_RATE_6HZ 1
+
+/**
+ * \ingroup BrickIMUV2
+ */
+#define IMU_V2_MAGNETOMETER_RATE_8HZ 2
+
+/**
+ * \ingroup BrickIMUV2
+ */
+#define IMU_V2_MAGNETOMETER_RATE_10HZ 3
+
+/**
+ * \ingroup BrickIMUV2
+ */
+#define IMU_V2_MAGNETOMETER_RATE_15HZ 4
+
+/**
+ * \ingroup BrickIMUV2
+ */
+#define IMU_V2_MAGNETOMETER_RATE_20HZ 5
+
+/**
+ * \ingroup BrickIMUV2
+ */
+#define IMU_V2_MAGNETOMETER_RATE_25HZ 6
+
+/**
+ * \ingroup BrickIMUV2
+ */
+#define IMU_V2_MAGNETOMETER_RATE_30HZ 7
+
+/**
+ * \ingroup BrickIMUV2
+ */
+#define IMU_V2_GYROSCOPE_RANGE_2000DPS 0
+
+/**
+ * \ingroup BrickIMUV2
+ */
+#define IMU_V2_GYROSCOPE_RANGE_1000DPS 1
+
+/**
+ * \ingroup BrickIMUV2
+ */
+#define IMU_V2_GYROSCOPE_RANGE_500DPS 2
+
+/**
+ * \ingroup BrickIMUV2
+ */
+#define IMU_V2_GYROSCOPE_RANGE_250DPS 3
+
+/**
+ * \ingroup BrickIMUV2
+ */
+#define IMU_V2_GYROSCOPE_RANGE_125DPS 4
+
+/**
+ * \ingroup BrickIMUV2
+ */
+#define IMU_V2_GYROSCOPE_BANDWIDTH_523HZ 0
+
+/**
+ * \ingroup BrickIMUV2
+ */
+#define IMU_V2_GYROSCOPE_BANDWIDTH_230HZ 1
+
+/**
+ * \ingroup BrickIMUV2
+ */
+#define IMU_V2_GYROSCOPE_BANDWIDTH_116HZ 2
+
+/**
+ * \ingroup BrickIMUV2
+ */
+#define IMU_V2_GYROSCOPE_BANDWIDTH_47HZ 3
+
+/**
+ * \ingroup BrickIMUV2
+ */
+#define IMU_V2_GYROSCOPE_BANDWIDTH_23HZ 4
+
+/**
+ * \ingroup BrickIMUV2
+ */
+#define IMU_V2_GYROSCOPE_BANDWIDTH_12HZ 5
+
+/**
+ * \ingroup BrickIMUV2
+ */
+#define IMU_V2_GYROSCOPE_BANDWIDTH_64HZ 6
+
+/**
+ * \ingroup BrickIMUV2
+ */
+#define IMU_V2_GYROSCOPE_BANDWIDTH_32HZ 7
+
+/**
+ * \ingroup BrickIMUV2
+ */
+#define IMU_V2_ACCELEROMETER_RANGE_2G 0
+
+/**
+ * \ingroup BrickIMUV2
+ */
+#define IMU_V2_ACCELEROMETER_RANGE_4G 1
+
+/**
+ * \ingroup BrickIMUV2
+ */
+#define IMU_V2_ACCELEROMETER_RANGE_8G 2
+
+/**
+ * \ingroup BrickIMUV2
+ */
+#define IMU_V2_ACCELEROMETER_RANGE_16G 3
+
+/**
+ * \ingroup BrickIMUV2
+ */
+#define IMU_V2_ACCELEROMETER_BANDWIDTH_7_81HZ 0
+
+/**
+ * \ingroup BrickIMUV2
+ */
+#define IMU_V2_ACCELEROMETER_BANDWIDTH_15_63HZ 1
+
+/**
+ * \ingroup BrickIMUV2
+ */
+#define IMU_V2_ACCELEROMETER_BANDWIDTH_31_25HZ 2
+
+/**
+ * \ingroup BrickIMUV2
+ */
+#define IMU_V2_ACCELEROMETER_BANDWIDTH_62_5HZ 3
+
+/**
+ * \ingroup BrickIMUV2
+ */
+#define IMU_V2_ACCELEROMETER_BANDWIDTH_125HZ 4
+
+/**
+ * \ingroup BrickIMUV2
+ */
+#define IMU_V2_ACCELEROMETER_BANDWIDTH_250HZ 5
+
+/**
+ * \ingroup BrickIMUV2
+ */
+#define IMU_V2_ACCELEROMETER_BANDWIDTH_500HZ 6
+
+/**
+ * \ingroup BrickIMUV2
+ */
+#define IMU_V2_ACCELEROMETER_BANDWIDTH_1000HZ 7
+
+/**
+ * \ingroup BrickIMUV2
+ */
+#define IMU_V2_SENSOR_FUSION_OFF 0
+
+/**
+ * \ingroup BrickIMUV2
+ */
+#define IMU_V2_SENSOR_FUSION_ON 1
+
+/**
+ * \ingroup BrickIMUV2
+ */
+#define IMU_V2_SENSOR_FUSION_ON_WITHOUT_MAGNETOMETER 2
+
+/**
+ * \ingroup BrickIMUV2
+ */
+#define IMU_V2_COMMUNICATION_METHOD_NONE 0
+
+/**
+ * \ingroup BrickIMUV2
+ */
+#define IMU_V2_COMMUNICATION_METHOD_USB 1
+
+/**
+ * \ingroup BrickIMUV2
+ */
+#define IMU_V2_COMMUNICATION_METHOD_SPI_STACK 2
+
+/**
+ * \ingroup BrickIMUV2
+ */
+#define IMU_V2_COMMUNICATION_METHOD_CHIBI 3
+
+/**
+ * \ingroup BrickIMUV2
+ */
+#define IMU_V2_COMMUNICATION_METHOD_RS485 4
+
+/**
+ * \ingroup BrickIMUV2
+ */
+#define IMU_V2_COMMUNICATION_METHOD_WIFI 5
+
+/**
+ * \ingroup BrickIMUV2
+ */
+#define IMU_V2_COMMUNICATION_METHOD_ETHERNET 6
+
+/**
+ * \ingroup BrickIMUV2
+ */
+#define IMU_V2_COMMUNICATION_METHOD_WIFI_V2 7
+
+/**
+ * \ingroup BrickIMUV2
+ *
+ * This constant is used to identify a IMU Brick 2.0.
+ *
+ * The {@link imu_v2_get_identity} function and the
+ * {@link IPCON_CALLBACK_ENUMERATE} callback of the IP Connection have a
+ * \c device_identifier parameter to specify the Brick's or Bricklet's type.
+ */
+#define IMU_V2_DEVICE_IDENTIFIER 18
+
+/**
+ * \ingroup BrickIMUV2
+ *
+ * This constant represents the display name of a IMU Brick 2.0.
+ */
+#define IMU_V2_DEVICE_DISPLAY_NAME "IMU Brick 2.0"
+
+/**
+ * \ingroup BrickIMUV2
+ *
+ * Creates the device object \c imu_v2 with the unique device ID \c uid and adds
+ * it to the IPConnection \c ipcon.
+ */
+void imu_v2_create(IMUV2 *imu_v2, const char *uid, IPConnection *ipcon);
+
+/**
+ * \ingroup BrickIMUV2
+ *
+ * Removes the device object \c imu_v2 from its IPConnection and destroys it.
+ * The device object cannot be used anymore afterwards.
+ */
+void imu_v2_destroy(IMUV2 *imu_v2);
+
+/**
+ * \ingroup BrickIMUV2
+ *
+ * Returns the response expected flag for the function specified by the
+ * \c function_id parameter. It is *true* if the function is expected to
+ * send a response, *false* otherwise.
+ *
+ * For getter functions this is enabled by default and cannot be disabled,
+ * because those functions will always send a response. For callback
+ * configuration functions it is enabled by default too, but can be disabled
+ * via the imu_v2_set_response_expected function. For setter functions it is
+ * disabled by default and can be enabled.
+ *
+ * Enabling the response expected flag for a setter function allows to
+ * detect timeouts and other error conditions calls of this setter as well.
+ * The device will then send a response for this purpose. If this flag is
+ * disabled for a setter function then no response is send and errors are
+ * silently ignored, because they cannot be detected.
+ */
+int imu_v2_get_response_expected(IMUV2 *imu_v2, uint8_t function_id, bool *ret_response_expected);
+
+/**
+ * \ingroup BrickIMUV2
+ *
+ * Changes the response expected flag of the function specified by the
+ * \c function_id parameter. This flag can only be changed for setter
+ * (default value: *false*) and callback configuration functions
+ * (default value: *true*). For getter functions it is always enabled.
+ *
+ * Enabling the response expected flag for a setter function allows to detect
+ * timeouts and other error conditions calls of this setter as well. The device
+ * will then send a response for this purpose. If this flag is disabled for a
+ * setter function then no response is send and errors are silently ignored,
+ * because they cannot be detected.
+ */
+int imu_v2_set_response_expected(IMUV2 *imu_v2, uint8_t function_id, bool response_expected);
+
+/**
+ * \ingroup BrickIMUV2
+ *
+ * Changes the response expected flag for all setter and callback configuration
+ * functions of this device at once.
+ */
+int imu_v2_set_response_expected_all(IMUV2 *imu_v2, bool response_expected);
+
+/**
+ * \ingroup BrickIMUV2
+ *
+ * Registers the given \c function with the given \c callback_id. The
+ * \c user_data will be passed as the last parameter to the \c function.
+ */
+void imu_v2_register_callback(IMUV2 *imu_v2, int16_t callback_id, void *function, void *user_data);
+
+/**
+ * \ingroup BrickIMUV2
+ *
+ * Returns the API version (major, minor, release) of the bindings for this
+ * device.
+ */
+int imu_v2_get_api_version(IMUV2 *imu_v2, uint8_t ret_api_version[3]);
+
+/**
+ * \ingroup BrickIMUV2
+ *
+ * Returns the calibrated acceleration from the accelerometer for the
+ * x, y and z axis in 1/100 m/s².
+ * 
+ * If you want to get the acceleration periodically, it is recommended
+ * to use the {@link IMU_V2_CALLBACK_ACCELERATION} callback and set the period with
+ * {@link imu_v2_set_acceleration_period}.
+ */
+int imu_v2_get_acceleration(IMUV2 *imu_v2, int16_t *ret_x, int16_t *ret_y, int16_t *ret_z);
+
+/**
+ * \ingroup BrickIMUV2
+ *
+ * Returns the calibrated magnetic field from the magnetometer for the
+ * x, y and z axis in 1/16 µT (Microtesla).
+ * 
+ * If you want to get the magnetic field periodically, it is recommended
+ * to use the {@link IMU_V2_CALLBACK_MAGNETIC_FIELD} callback and set the period with
+ * {@link imu_v2_set_magnetic_field_period}.
+ */
+int imu_v2_get_magnetic_field(IMUV2 *imu_v2, int16_t *ret_x, int16_t *ret_y, int16_t *ret_z);
+
+/**
+ * \ingroup BrickIMUV2
+ *
+ * Returns the calibrated angular velocity from the gyroscope for the
+ * x, y and z axis in 1/16 °/s.
+ * 
+ * If you want to get the angular velocity periodically, it is recommended
+ * to use the {@link IMU_V2_CALLBACK_ANGULAR_VELOCITY} acallback nd set the period with
+ * {@link imu_v2_set_angular_velocity_period}.
+ */
+int imu_v2_get_angular_velocity(IMUV2 *imu_v2, int16_t *ret_x, int16_t *ret_y, int16_t *ret_z);
+
+/**
+ * \ingroup BrickIMUV2
+ *
+ * Returns the temperature of the IMU Brick. The temperature is given in
+ * °C. The temperature is measured in the core of the BNO055 IC, it is not the
+ * ambient temperature
+ */
+int imu_v2_get_temperature(IMUV2 *imu_v2, int8_t *ret_temperature);
+
+/**
+ * \ingroup BrickIMUV2
+ *
+ * Returns the current orientation (heading, roll, pitch) of the IMU Brick as
+ * independent Euler angles in 1/16 degree. Note that Euler angles always
+ * experience a `gimbal lock <https://en.wikipedia.org/wiki/Gimbal_lock>`__.
+ * We recommend that you use quaternions instead, if you need the absolute
+ * orientation.
+ * 
+ * The rotation angle has the following ranges:
+ * 
+ * * heading: 0° to 360°
+ * * roll: -90° to +90°
+ * * pitch: -180° to +180°
+ * 
+ * If you want to get the orientation periodically, it is recommended
+ * to use the {@link IMU_V2_CALLBACK_ORIENTATION} callback and set the period with
+ * {@link imu_v2_set_orientation_period}.
+ */
+int imu_v2_get_orientation(IMUV2 *imu_v2, int16_t *ret_heading, int16_t *ret_roll, int16_t *ret_pitch);
+
+/**
+ * \ingroup BrickIMUV2
+ *
+ * Returns the linear acceleration of the IMU Brick for the
+ * x, y and z axis in 1/100 m/s².
+ * 
+ * The linear acceleration is the acceleration in each of the three
+ * axis of the IMU Brick with the influences of gravity removed.
+ * 
+ * It is also possible to get the gravity vector with the influence of linear
+ * acceleration removed, see {@link imu_v2_get_gravity_vector}.
+ * 
+ * If you want to get the linear acceleration periodically, it is recommended
+ * to use the {@link IMU_V2_CALLBACK_LINEAR_ACCELERATION} callback and set the period with
+ * {@link imu_v2_set_linear_acceleration_period}.
+ */
+int imu_v2_get_linear_acceleration(IMUV2 *imu_v2, int16_t *ret_x, int16_t *ret_y, int16_t *ret_z);
+
+/**
+ * \ingroup BrickIMUV2
+ *
+ * Returns the current gravity vector of the IMU Brick for the
+ * x, y and z axis in 1/100 m/s².
+ * 
+ * The gravity vector is the acceleration that occurs due to gravity.
+ * Influences of additional linear acceleration are removed.
+ * 
+ * It is also possible to get the linear acceleration with the influence
+ * of gravity removed, see {@link imu_v2_get_linear_acceleration}.
+ * 
+ * If you want to get the gravity vector periodically, it is recommended
+ * to use the {@link IMU_V2_CALLBACK_GRAVITY_VECTOR} callback and set the period with
+ * {@link imu_v2_set_gravity_vector_period}.
+ */
+int imu_v2_get_gravity_vector(IMUV2 *imu_v2, int16_t *ret_x, int16_t *ret_y, int16_t *ret_z);
+
+/**
+ * \ingroup BrickIMUV2
+ *
+ * Returns the current orientation (w, x, y, z) of the IMU Brick as
+ * `quaternions <https://en.wikipedia.org/wiki/Quaternions_and_spatial_rotation>`__.
+ * 
+ * You have to divide the returns values by 16383 (14 bit) to get
+ * the usual range of -1.0 to +1.0 for quaternions.
+ * 
+ * If you want to get the quaternions periodically, it is recommended
+ * to use the {@link IMU_V2_CALLBACK_QUATERNION} callback and set the period with
+ * {@link imu_v2_set_quaternion_period}.
+ */
+int imu_v2_get_quaternion(IMUV2 *imu_v2, int16_t *ret_w, int16_t *ret_x, int16_t *ret_y, int16_t *ret_z);
+
+/**
+ * \ingroup BrickIMUV2
+ *
+ * Return all of the available data of the IMU Brick.
+ * 
+ * * acceleration in 1/100 m/s² (see {@link imu_v2_get_acceleration})
+ * * magnetic field in 1/16 µT (see {@link imu_v2_get_magnetic_field})
+ * * angular velocity in 1/16 °/s (see {@link imu_v2_get_angular_velocity})
+ * * Euler angles in 1/16 ° (see {@link imu_v2_get_orientation})
+ * * quaternion 1/16383 (see {@link imu_v2_get_quaternion})
+ * * linear acceleration 1/100 m/s² (see {@link imu_v2_get_linear_acceleration})
+ * * gravity vector 1/100 m/s² (see {@link imu_v2_get_gravity_vector})
+ * * temperature in 1 °C (see {@link imu_v2_get_temperature})
+ * * calibration status (see below)
+ * 
+ * The calibration status consists of four pairs of two bits. Each pair
+ * of bits represents the status of the current calibration.
+ * 
+ * * bit 0-1: Magnetometer
+ * * bit 2-3: Accelerometer
+ * * bit 4-5: Gyroscope
+ * * bit 6-7: System
+ * 
+ * A value of 0 means for "not calibrated" and a value of 3 means
+ * "fully calibrated". In your program you should always be able to
+ * ignore the calibration status, it is used by the calibration
+ * window of the Brick Viewer and it can be ignored after the first
+ * calibration. See the documentation in the calibration window for
+ * more information regarding the calibration of the IMU Brick.
+ * 
+ * If you want to get the data periodically, it is recommended
+ * to use the {@link IMU_V2_CALLBACK_ALL_DATA} callback and set the period with
+ * {@link imu_v2_set_all_data_period}.
+ */
+int imu_v2_get_all_data(IMUV2 *imu_v2, int16_t ret_acceleration[3], int16_t ret_magnetic_field[3], int16_t ret_angular_velocity[3], int16_t ret_euler_angle[3], int16_t ret_quaternion[4], int16_t ret_linear_acceleration[3], int16_t ret_gravity_vector[3], int8_t *ret_temperature, uint8_t *ret_calibration_status);
+
+/**
+ * \ingroup BrickIMUV2
+ *
+ * Turns the orientation and direction LEDs of the IMU Brick on.
+ */
+int imu_v2_leds_on(IMUV2 *imu_v2);
+
+/**
+ * \ingroup BrickIMUV2
+ *
+ * Turns the orientation and direction LEDs of the IMU Brick off.
+ */
+int imu_v2_leds_off(IMUV2 *imu_v2);
+
+/**
+ * \ingroup BrickIMUV2
+ *
+ * Returns *true* if the orientation and direction LEDs of the IMU Brick
+ * are on, *false* otherwise.
+ */
+int imu_v2_are_leds_on(IMUV2 *imu_v2, bool *ret_leds);
+
+/**
+ * \ingroup BrickIMUV2
+ *
+ * A call of this function saves the current calibration to be used
+ * as a starting point for the next restart of continuous calibration
+ * of the IMU Brick.
+ * 
+ * A return value of *true* means that the calibration could be used and
+ * *false* means that it could not be used (this happens if the calibration
+ * status is not "fully calibrated").
+ * 
+ * This function is used by the calibration window of the Brick Viewer, you
+ * should not need to call it in your program.
+ */
+int imu_v2_save_calibration(IMUV2 *imu_v2, bool *ret_calibration_done);
+
+/**
+ * \ingroup BrickIMUV2
+ *
+ * Sets the period in ms with which the {@link IMU_V2_CALLBACK_ACCELERATION} callback is triggered
+ * periodically. A value of 0 turns the callback off.
+ * 
+ * The default value is 0.
+ */
+int imu_v2_set_acceleration_period(IMUV2 *imu_v2, uint32_t period);
+
+/**
+ * \ingroup BrickIMUV2
+ *
+ * Returns the period as set by {@link imu_v2_set_acceleration_period}.
+ */
+int imu_v2_get_acceleration_period(IMUV2 *imu_v2, uint32_t *ret_period);
+
+/**
+ * \ingroup BrickIMUV2
+ *
+ * Sets the period in ms with which the {@link IMU_V2_CALLBACK_MAGNETIC_FIELD} callback is triggered
+ * periodically. A value of 0 turns the callback off.
+ */
+int imu_v2_set_magnetic_field_period(IMUV2 *imu_v2, uint32_t period);
+
+/**
+ * \ingroup BrickIMUV2
+ *
+ * Returns the period as set by {@link imu_v2_set_magnetic_field_period}.
+ */
+int imu_v2_get_magnetic_field_period(IMUV2 *imu_v2, uint32_t *ret_period);
+
+/**
+ * \ingroup BrickIMUV2
+ *
+ * Sets the period in ms with which the {@link IMU_V2_CALLBACK_ANGULAR_VELOCITY} callback is
+ * triggered periodically. A value of 0 turns the callback off.
+ */
+int imu_v2_set_angular_velocity_period(IMUV2 *imu_v2, uint32_t period);
+
+/**
+ * \ingroup BrickIMUV2
+ *
+ * Returns the period as set by {@link imu_v2_set_angular_velocity_period}.
+ */
+int imu_v2_get_angular_velocity_period(IMUV2 *imu_v2, uint32_t *ret_period);
+
+/**
+ * \ingroup BrickIMUV2
+ *
+ * Sets the period in ms with which the {@link IMU_V2_CALLBACK_TEMPERATURE} callback is triggered
+ * periodically. A value of 0 turns the callback off.
+ */
+int imu_v2_set_temperature_period(IMUV2 *imu_v2, uint32_t period);
+
+/**
+ * \ingroup BrickIMUV2
+ *
+ * Returns the period as set by {@link imu_v2_set_temperature_period}.
+ */
+int imu_v2_get_temperature_period(IMUV2 *imu_v2, uint32_t *ret_period);
+
+/**
+ * \ingroup BrickIMUV2
+ *
+ * Sets the period in ms with which the {@link IMU_V2_CALLBACK_ORIENTATION} callback is triggered
+ * periodically. A value of 0 turns the callback off.
+ */
+int imu_v2_set_orientation_period(IMUV2 *imu_v2, uint32_t period);
+
+/**
+ * \ingroup BrickIMUV2
+ *
+ * Returns the period as set by {@link imu_v2_set_orientation_period}.
+ */
+int imu_v2_get_orientation_period(IMUV2 *imu_v2, uint32_t *ret_period);
+
+/**
+ * \ingroup BrickIMUV2
+ *
+ * Sets the period in ms with which the {@link IMU_V2_CALLBACK_LINEAR_ACCELERATION} callback is
+ * triggered periodically. A value of 0 turns the callback off.
+ */
+int imu_v2_set_linear_acceleration_period(IMUV2 *imu_v2, uint32_t period);
+
+/**
+ * \ingroup BrickIMUV2
+ *
+ * Returns the period as set by {@link imu_v2_set_linear_acceleration_period}.
+ */
+int imu_v2_get_linear_acceleration_period(IMUV2 *imu_v2, uint32_t *ret_period);
+
+/**
+ * \ingroup BrickIMUV2
+ *
+ * Sets the period in ms with which the {@link IMU_V2_CALLBACK_GRAVITY_VECTOR} callback is triggered
+ * periodically. A value of 0 turns the callback off.
+ */
+int imu_v2_set_gravity_vector_period(IMUV2 *imu_v2, uint32_t period);
+
+/**
+ * \ingroup BrickIMUV2
+ *
+ * Returns the period as set by {@link imu_v2_set_gravity_vector_period}.
+ */
+int imu_v2_get_gravity_vector_period(IMUV2 *imu_v2, uint32_t *ret_period);
+
+/**
+ * \ingroup BrickIMUV2
+ *
+ * Sets the period in ms with which the {@link IMU_V2_CALLBACK_QUATERNION} callback is triggered
+ * periodically. A value of 0 turns the callback off.
+ */
+int imu_v2_set_quaternion_period(IMUV2 *imu_v2, uint32_t period);
+
+/**
+ * \ingroup BrickIMUV2
+ *
+ * Returns the period as set by {@link imu_v2_set_quaternion_period}.
+ */
+int imu_v2_get_quaternion_period(IMUV2 *imu_v2, uint32_t *ret_period);
+
+/**
+ * \ingroup BrickIMUV2
+ *
+ * Sets the period in ms with which the {@link IMU_V2_CALLBACK_ALL_DATA} callback is triggered
+ * periodically. A value of 0 turns the callback off.
+ */
+int imu_v2_set_all_data_period(IMUV2 *imu_v2, uint32_t period);
+
+/**
+ * \ingroup BrickIMUV2
+ *
+ * Returns the period as set by {@link imu_v2_set_all_data_period}.
+ */
+int imu_v2_get_all_data_period(IMUV2 *imu_v2, uint32_t *ret_period);
+
+/**
+ * \ingroup BrickIMUV2
+ *
+ * Sets the available sensor configuration for the Magnetometer, Gyroscope and
+ * Accelerometer. The Accelerometer Range is user selectable in all fusion modes,
+ * all other configurations are auto-controlled in fusion mode.
+ * 
+ * The default values are:
+ * 
+ * * Magnetometer Rate 20Hz
+ * * Gyroscope Range 2000°/s
+ * * Gyroscope Bandwidth 32Hz
+ * * Accelerometer Range +/-4G
+ * * Accelerometer Bandwidth 62.5Hz
+ * 
+ * .. versionadded:: 2.0.5$nbsp;(Firmware)
+ */
+int imu_v2_set_sensor_configuration(IMUV2 *imu_v2, uint8_t magnetometer_rate, uint8_t gyroscope_range, uint8_t gyroscope_bandwidth, uint8_t accelerometer_range, uint8_t accelerometer_bandwidth);
+
+/**
+ * \ingroup BrickIMUV2
+ *
+ * Returns the sensor configuration as set by {@link imu_v2_set_sensor_configuration}.
+ * 
+ * .. versionadded:: 2.0.5$nbsp;(Firmware)
+ */
+int imu_v2_get_sensor_configuration(IMUV2 *imu_v2, uint8_t *ret_magnetometer_rate, uint8_t *ret_gyroscope_range, uint8_t *ret_gyroscope_bandwidth, uint8_t *ret_accelerometer_range, uint8_t *ret_accelerometer_bandwidth);
+
+/**
+ * \ingroup BrickIMUV2
+ *
+ * If the fusion mode is turned off, the functions {@link imu_v2_get_acceleration},
+ * {@link imu_v2_get_magnetic_field} and {@link imu_v2_get_angular_velocity} return uncalibrated
+ * and uncompensated sensor data. All other sensor data getters return no data.
+ * 
+ * Since firmware version 2.0.6 you can also use a fusion mode without magnetometer.
+ * In this mode the calculated orientation is relative (with magnetometer it is
+ * absolute with respect to the earth). However, the calculation can't be influenced
+ * by spurious magnetic fields.
+ * 
+ * By default sensor fusion is on.
+ * 
+ * .. versionadded:: 2.0.5$nbsp;(Firmware)
+ */
+int imu_v2_set_sensor_fusion_mode(IMUV2 *imu_v2, uint8_t mode);
+
+/**
+ * \ingroup BrickIMUV2
+ *
+ * Returns the sensor fusion mode as set by {@link imu_v2_set_sensor_fusion_mode}.
+ * 
+ * .. versionadded:: 2.0.5$nbsp;(Firmware)
+ */
+int imu_v2_get_sensor_fusion_mode(IMUV2 *imu_v2, uint8_t *ret_mode);
+
+/**
+ * \ingroup BrickIMUV2
+ *
+ * The SPITF protocol can be used with a dynamic baudrate. If the dynamic baudrate is
+ * enabled, the Brick will try to adapt the baudrate for the communication
+ * between Bricks and Bricklets according to the amount of data that is transferred.
+ * 
+ * The baudrate will be increased exponetially if lots of data is send/receieved and
+ * decreased linearly if little data is send/received.
+ * 
+ * This lowers the baudrate in applications where little data is transferred (e.g.
+ * a weather station) and increases the robustness. If there is lots of data to transfer
+ * (e.g. Thermal Imaging Bricklet) it automatically increases the baudrate as needed.
+ * 
+ * In cases where some data has to transferred as fast as possible every few seconds
+ * (e.g. RS485 Bricklet with a high baudrate but small payload) you may want to turn
+ * the dynamic baudrate off to get the highest possible performance.
+ * 
+ * The maximum value of the baudrate can be set per port with the function 
+ * {@link imu_v2_set_spitfp_baudrate}. If the dynamic baudrate is disabled, the baudrate
+ * as set by {@link imu_v2_set_spitfp_baudrate} will be used statically.
+ * 
+ * The minimum dynamic baudrate has a value range of 400000 to 2000000 baud.
+ * 
+ * By default dynamic baudrate is enabled and the minimum dynamic baudrate is 400000.
+ * 
+ * .. versionadded:: 2.0.10$nbsp;(Firmware)
+ */
+int imu_v2_set_spitfp_baudrate_config(IMUV2 *imu_v2, bool enable_dynamic_baudrate, uint32_t minimum_dynamic_baudrate);
+
+/**
+ * \ingroup BrickIMUV2
+ *
+ * Returns the baudrate config, see {@link imu_v2_set_spitfp_baudrate_config}.
+ * 
+ * .. versionadded:: 2.0.10$nbsp;(Firmware)
+ */
+int imu_v2_get_spitfp_baudrate_config(IMUV2 *imu_v2, bool *ret_enable_dynamic_baudrate, uint32_t *ret_minimum_dynamic_baudrate);
+
+/**
+ * \ingroup BrickIMUV2
+ *
+ * Returns the timeout count for the different communication methods.
+ * 
+ * The methods 0-2 are available for all Bricks, 3-7 only for Master Bricks.
+ * 
+ * This function is mostly used for debugging during development, in normal operation
+ * the counters should nearly always stay at 0.
+ * 
+ * .. versionadded:: 2.0.7$nbsp;(Firmware)
+ */
+int imu_v2_get_send_timeout_count(IMUV2 *imu_v2, uint8_t communication_method, uint32_t *ret_timeout_count);
+
+/**
+ * \ingroup BrickIMUV2
+ *
+ * Sets the baudrate for a specific Bricklet port ('a' - 'd'). The
+ * baudrate can be in the range 400000 to 2000000.
+ * 
+ * If you want to increase the throughput of Bricklets you can increase
+ * the baudrate. If you get a high error count because of high
+ * interference (see {@link imu_v2_get_spitfp_error_count}) you can decrease the
+ * baudrate.
+ * 
+ * If the dynamic baudrate feature is enabled, the baudrate set by this
+ * function corresponds to the maximum baudrate (see {@link imu_v2_set_spitfp_baudrate_config}).
+ * 
+ * Regulatory testing is done with the default baudrate. If CE compatability
+ * or similar is necessary in you applications we recommend to not change
+ * the baudrate.
+ * 
+ * The default baudrate for all ports is 1400000.
+ * 
+ * .. versionadded:: 2.0.5$nbsp;(Firmware)
+ */
+int imu_v2_set_spitfp_baudrate(IMUV2 *imu_v2, char bricklet_port, uint32_t baudrate);
+
+/**
+ * \ingroup BrickIMUV2
+ *
+ * Returns the baudrate for a given Bricklet port, see {@link imu_v2_set_spitfp_baudrate}.
+ * 
+ * .. versionadded:: 2.0.5$nbsp;(Firmware)
+ */
+int imu_v2_get_spitfp_baudrate(IMUV2 *imu_v2, char bricklet_port, uint32_t *ret_baudrate);
+
+/**
+ * \ingroup BrickIMUV2
+ *
+ * Returns the error count for the communication between Brick and Bricklet.
+ * 
+ * The errors are divided into
+ * 
+ * * ACK checksum errors,
+ * * message checksum errors,
+ * * frameing errors and
+ * * overflow errors.
+ * 
+ * The errors counts are for errors that occur on the Brick side. All
+ * Bricklets have a similar function that returns the errors on the Bricklet side.
+ * 
+ * .. versionadded:: 2.0.5$nbsp;(Firmware)
+ */
+int imu_v2_get_spitfp_error_count(IMUV2 *imu_v2, char bricklet_port, uint32_t *ret_error_count_ack_checksum, uint32_t *ret_error_count_message_checksum, uint32_t *ret_error_count_frame, uint32_t *ret_error_count_overflow);
+
+/**
+ * \ingroup BrickIMUV2
+ *
+ * Enables the status LED.
+ * 
+ * The status LED is the blue LED next to the USB connector. If enabled is is
+ * on and it flickers if data is transfered. If disabled it is always off.
+ * 
+ * The default state is enabled.
+ */
+int imu_v2_enable_status_led(IMUV2 *imu_v2);
+
+/**
+ * \ingroup BrickIMUV2
+ *
+ * Disables the status LED.
+ * 
+ * The status LED is the blue LED next to the USB connector. If enabled is is
+ * on and it flickers if data is transfered. If disabled it is always off.
+ * 
+ * The default state is enabled.
+ */
+int imu_v2_disable_status_led(IMUV2 *imu_v2);
+
+/**
+ * \ingroup BrickIMUV2
+ *
+ * Returns *true* if the status LED is enabled, *false* otherwise.
+ */
+int imu_v2_is_status_led_enabled(IMUV2 *imu_v2, bool *ret_enabled);
+
+/**
+ * \ingroup BrickIMUV2
+ *
+ * Returns the firmware and protocol version and the name of the Bricklet for a
+ * given port.
+ * 
+ * This functions sole purpose is to allow automatic flashing of v1.x.y Bricklet
+ * plugins.
+ */
+int imu_v2_get_protocol1_bricklet_name(IMUV2 *imu_v2, char port, uint8_t *ret_protocol_version, uint8_t ret_firmware_version[3], char ret_name[40]);
+
+/**
+ * \ingroup BrickIMUV2
+ *
+ * Returns the temperature in °C/10 as measured inside the microcontroller. The
+ * value returned is not the ambient temperature!
+ * 
+ * The temperature is only proportional to the real temperature and it has an
+ * accuracy of +-15%. Practically it is only useful as an indicator for
+ * temperature changes.
+ */
+int imu_v2_get_chip_temperature(IMUV2 *imu_v2, int16_t *ret_temperature);
+
+/**
+ * \ingroup BrickIMUV2
+ *
+ * Calling this function will reset the Brick. Calling this function
+ * on a Brick inside of a stack will reset the whole stack.
+ * 
+ * After a reset you have to create new device objects,
+ * calling functions on the existing ones will result in
+ * undefined behavior!
+ */
+int imu_v2_reset(IMUV2 *imu_v2);
+
+/**
+ * \ingroup BrickIMUV2
+ *
+ * Returns the UID, the UID where the Brick is connected to,
+ * the position, the hardware and firmware version as well as the
+ * device identifier.
+ * 
+ * The position can be '0'-'8' (stack position).
+ * 
+ * The device identifier numbers can be found :ref:`here <device_identifier>`.
+ * |device_identifier_constant|
+ */
+int imu_v2_get_identity(IMUV2 *imu_v2, char ret_uid[8], char ret_connected_uid[8], char *ret_position, uint8_t ret_hardware_version[3], uint8_t ret_firmware_version[3], uint16_t *ret_device_identifier);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/org.fortiss.af3.platform.raspberry/trunk/code-gen-hal/inc/brick/bricklet_laser_range_finder.h b/org.fortiss.af3.platform.raspberry/trunk/code-gen-hal/inc/brick/bricklet_laser_range_finder.h
new file mode 100644
index 0000000000000000000000000000000000000000..d54104f95e12cde99620c00f2f530324b0d09c3e
--- /dev/null
+++ b/org.fortiss.af3.platform.raspberry/trunk/code-gen-hal/inc/brick/bricklet_laser_range_finder.h
@@ -0,0 +1,671 @@
+/* ***********************************************************
+ * This file was automatically generated on 2017-07-27.      *
+ *                                                           *
+ * C/C++ Bindings Version 2.1.17                             *
+ *                                                           *
+ * If you have a bugfix for this file and want to commit it, *
+ * please fix the bug in the generator. You can find a link  *
+ * to the generators git repository on tinkerforge.com       *
+ *************************************************************/
+
+#ifndef BRICKLET_LASER_RANGE_FINDER_H
+#define BRICKLET_LASER_RANGE_FINDER_H
+
+#include "ip_connection.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \defgroup BrickletLaserRangeFinder Laser Range Finder Bricklet
+ */
+
+/**
+ * \ingroup BrickletLaserRangeFinder
+ *
+ * Measures distance up to 40m with laser light
+ */
+typedef Device LaserRangeFinder;
+
+/**
+ * \ingroup BrickletLaserRangeFinder
+ */
+#define LASER_RANGE_FINDER_FUNCTION_GET_DISTANCE 1
+
+/**
+ * \ingroup BrickletLaserRangeFinder
+ */
+#define LASER_RANGE_FINDER_FUNCTION_GET_VELOCITY 2
+
+/**
+ * \ingroup BrickletLaserRangeFinder
+ */
+#define LASER_RANGE_FINDER_FUNCTION_SET_DISTANCE_CALLBACK_PERIOD 3
+
+/**
+ * \ingroup BrickletLaserRangeFinder
+ */
+#define LASER_RANGE_FINDER_FUNCTION_GET_DISTANCE_CALLBACK_PERIOD 4
+
+/**
+ * \ingroup BrickletLaserRangeFinder
+ */
+#define LASER_RANGE_FINDER_FUNCTION_SET_VELOCITY_CALLBACK_PERIOD 5
+
+/**
+ * \ingroup BrickletLaserRangeFinder
+ */
+#define LASER_RANGE_FINDER_FUNCTION_GET_VELOCITY_CALLBACK_PERIOD 6
+
+/**
+ * \ingroup BrickletLaserRangeFinder
+ */
+#define LASER_RANGE_FINDER_FUNCTION_SET_DISTANCE_CALLBACK_THRESHOLD 7
+
+/**
+ * \ingroup BrickletLaserRangeFinder
+ */
+#define LASER_RANGE_FINDER_FUNCTION_GET_DISTANCE_CALLBACK_THRESHOLD 8
+
+/**
+ * \ingroup BrickletLaserRangeFinder
+ */
+#define LASER_RANGE_FINDER_FUNCTION_SET_VELOCITY_CALLBACK_THRESHOLD 9
+
+/**
+ * \ingroup BrickletLaserRangeFinder
+ */
+#define LASER_RANGE_FINDER_FUNCTION_GET_VELOCITY_CALLBACK_THRESHOLD 10
+
+/**
+ * \ingroup BrickletLaserRangeFinder
+ */
+#define LASER_RANGE_FINDER_FUNCTION_SET_DEBOUNCE_PERIOD 11
+
+/**
+ * \ingroup BrickletLaserRangeFinder
+ */
+#define LASER_RANGE_FINDER_FUNCTION_GET_DEBOUNCE_PERIOD 12
+
+/**
+ * \ingroup BrickletLaserRangeFinder
+ */
+#define LASER_RANGE_FINDER_FUNCTION_SET_MOVING_AVERAGE 13
+
+/**
+ * \ingroup BrickletLaserRangeFinder
+ */
+#define LASER_RANGE_FINDER_FUNCTION_GET_MOVING_AVERAGE 14
+
+/**
+ * \ingroup BrickletLaserRangeFinder
+ */
+#define LASER_RANGE_FINDER_FUNCTION_SET_MODE 15
+
+/**
+ * \ingroup BrickletLaserRangeFinder
+ */
+#define LASER_RANGE_FINDER_FUNCTION_GET_MODE 16
+
+/**
+ * \ingroup BrickletLaserRangeFinder
+ */
+#define LASER_RANGE_FINDER_FUNCTION_ENABLE_LASER 17
+
+/**
+ * \ingroup BrickletLaserRangeFinder
+ */
+#define LASER_RANGE_FINDER_FUNCTION_DISABLE_LASER 18
+
+/**
+ * \ingroup BrickletLaserRangeFinder
+ */
+#define LASER_RANGE_FINDER_FUNCTION_IS_LASER_ENABLED 19
+
+/**
+ * \ingroup BrickletLaserRangeFinder
+ */
+#define LASER_RANGE_FINDER_FUNCTION_GET_SENSOR_HARDWARE_VERSION 24
+
+/**
+ * \ingroup BrickletLaserRangeFinder
+ */
+#define LASER_RANGE_FINDER_FUNCTION_SET_CONFIGURATION 25
+
+/**
+ * \ingroup BrickletLaserRangeFinder
+ */
+#define LASER_RANGE_FINDER_FUNCTION_GET_CONFIGURATION 26
+
+/**
+ * \ingroup BrickletLaserRangeFinder
+ */
+#define LASER_RANGE_FINDER_FUNCTION_GET_IDENTITY 255
+
+/**
+ * \ingroup BrickletLaserRangeFinder
+ *
+ * Signature: \code void callback(uint16_t distance, void *user_data) \endcode
+ * 
+ * This callback is triggered periodically with the period that is set by
+ * {@link laser_range_finder_set_distance_callback_period}. The parameter is the distance
+ * value of the sensor.
+ * 
+ * The {@link LASER_RANGE_FINDER_CALLBACK_DISTANCE} callback is only triggered if the distance value has changed
+ * since the last triggering.
+ */
+#define LASER_RANGE_FINDER_CALLBACK_DISTANCE 20
+
+/**
+ * \ingroup BrickletLaserRangeFinder
+ *
+ * Signature: \code void callback(int16_t velocity, void *user_data) \endcode
+ * 
+ * This callback is triggered periodically with the period that is set by
+ * {@link laser_range_finder_set_velocity_callback_period}. The parameter is the velocity
+ * value of the sensor.
+ * 
+ * The {@link LASER_RANGE_FINDER_CALLBACK_VELOCITY} callback is only triggered if the velocity has changed since
+ * the last triggering.
+ */
+#define LASER_RANGE_FINDER_CALLBACK_VELOCITY 21
+
+/**
+ * \ingroup BrickletLaserRangeFinder
+ *
+ * Signature: \code void callback(uint16_t distance, void *user_data) \endcode
+ * 
+ * This callback is triggered when the threshold as set by
+ * {@link laser_range_finder_set_distance_callback_threshold} is reached.
+ * The parameter is the distance value of the sensor.
+ * 
+ * If the threshold keeps being reached, the callback is triggered periodically
+ * with the period as set by {@link laser_range_finder_set_debounce_period}.
+ */
+#define LASER_RANGE_FINDER_CALLBACK_DISTANCE_REACHED 22
+
+/**
+ * \ingroup BrickletLaserRangeFinder
+ *
+ * Signature: \code void callback(int16_t velocity, void *user_data) \endcode
+ * 
+ * This callback is triggered when the threshold as set by
+ * {@link laser_range_finder_set_velocity_callback_threshold} is reached.
+ * The parameter is the velocity value of the sensor.
+ * 
+ * If the threshold keeps being reached, the callback is triggered periodically
+ * with the period as set by {@link laser_range_finder_set_debounce_period}.
+ */
+#define LASER_RANGE_FINDER_CALLBACK_VELOCITY_REACHED 23
+
+
+/**
+ * \ingroup BrickletLaserRangeFinder
+ */
+#define LASER_RANGE_FINDER_THRESHOLD_OPTION_OFF 'x'
+
+/**
+ * \ingroup BrickletLaserRangeFinder
+ */
+#define LASER_RANGE_FINDER_THRESHOLD_OPTION_OUTSIDE 'o'
+
+/**
+ * \ingroup BrickletLaserRangeFinder
+ */
+#define LASER_RANGE_FINDER_THRESHOLD_OPTION_INSIDE 'i'
+
+/**
+ * \ingroup BrickletLaserRangeFinder
+ */
+#define LASER_RANGE_FINDER_THRESHOLD_OPTION_SMALLER '<'
+
+/**
+ * \ingroup BrickletLaserRangeFinder
+ */
+#define LASER_RANGE_FINDER_THRESHOLD_OPTION_GREATER '>'
+
+/**
+ * \ingroup BrickletLaserRangeFinder
+ */
+#define LASER_RANGE_FINDER_MODE_DISTANCE 0
+
+/**
+ * \ingroup BrickletLaserRangeFinder
+ */
+#define LASER_RANGE_FINDER_MODE_VELOCITY_MAX_13MS 1
+
+/**
+ * \ingroup BrickletLaserRangeFinder
+ */
+#define LASER_RANGE_FINDER_MODE_VELOCITY_MAX_32MS 2
+
+/**
+ * \ingroup BrickletLaserRangeFinder
+ */
+#define LASER_RANGE_FINDER_MODE_VELOCITY_MAX_64MS 3
+
+/**
+ * \ingroup BrickletLaserRangeFinder
+ */
+#define LASER_RANGE_FINDER_MODE_VELOCITY_MAX_127MS 4
+
+/**
+ * \ingroup BrickletLaserRangeFinder
+ */
+#define LASER_RANGE_FINDER_VERSION_1 1
+
+/**
+ * \ingroup BrickletLaserRangeFinder
+ */
+#define LASER_RANGE_FINDER_VERSION_3 3
+
+/**
+ * \ingroup BrickletLaserRangeFinder
+ *
+ * This constant is used to identify a Laser Range Finder Bricklet.
+ *
+ * The {@link laser_range_finder_get_identity} function and the
+ * {@link IPCON_CALLBACK_ENUMERATE} callback of the IP Connection have a
+ * \c device_identifier parameter to specify the Brick's or Bricklet's type.
+ */
+#define LASER_RANGE_FINDER_DEVICE_IDENTIFIER 255
+
+/**
+ * \ingroup BrickletLaserRangeFinder
+ *
+ * This constant represents the display name of a Laser Range Finder Bricklet.
+ */
+#define LASER_RANGE_FINDER_DEVICE_DISPLAY_NAME "Laser Range Finder Bricklet"
+
+/**
+ * \ingroup BrickletLaserRangeFinder
+ *
+ * Creates the device object \c laser_range_finder with the unique device ID \c uid and adds
+ * it to the IPConnection \c ipcon.
+ */
+void laser_range_finder_create(LaserRangeFinder *laser_range_finder, const char *uid, IPConnection *ipcon);
+
+/**
+ * \ingroup BrickletLaserRangeFinder
+ *
+ * Removes the device object \c laser_range_finder from its IPConnection and destroys it.
+ * The device object cannot be used anymore afterwards.
+ */
+void laser_range_finder_destroy(LaserRangeFinder *laser_range_finder);
+
+/**
+ * \ingroup BrickletLaserRangeFinder
+ *
+ * Returns the response expected flag for the function specified by the
+ * \c function_id parameter. It is *true* if the function is expected to
+ * send a response, *false* otherwise.
+ *
+ * For getter functions this is enabled by default and cannot be disabled,
+ * because those functions will always send a response. For callback
+ * configuration functions it is enabled by default too, but can be disabled
+ * via the laser_range_finder_set_response_expected function. For setter functions it is
+ * disabled by default and can be enabled.
+ *
+ * Enabling the response expected flag for a setter function allows to
+ * detect timeouts and other error conditions calls of this setter as well.
+ * The device will then send a response for this purpose. If this flag is
+ * disabled for a setter function then no response is send and errors are
+ * silently ignored, because they cannot be detected.
+ */
+int laser_range_finder_get_response_expected(LaserRangeFinder *laser_range_finder, uint8_t function_id, bool *ret_response_expected);
+
+/**
+ * \ingroup BrickletLaserRangeFinder
+ *
+ * Changes the response expected flag of the function specified by the
+ * \c function_id parameter. This flag can only be changed for setter
+ * (default value: *false*) and callback configuration functions
+ * (default value: *true*). For getter functions it is always enabled.
+ *
+ * Enabling the response expected flag for a setter function allows to detect
+ * timeouts and other error conditions calls of this setter as well. The device
+ * will then send a response for this purpose. If this flag is disabled for a
+ * setter function then no response is send and errors are silently ignored,
+ * because they cannot be detected.
+ */
+int laser_range_finder_set_response_expected(LaserRangeFinder *laser_range_finder, uint8_t function_id, bool response_expected);
+
+/**
+ * \ingroup BrickletLaserRangeFinder
+ *
+ * Changes the response expected flag for all setter and callback configuration
+ * functions of this device at once.
+ */
+int laser_range_finder_set_response_expected_all(LaserRangeFinder *laser_range_finder, bool response_expected);
+
+/**
+ * \ingroup BrickletLaserRangeFinder
+ *
+ * Registers the given \c function with the given \c callback_id. The
+ * \c user_data will be passed as the last parameter to the \c function.
+ */
+void laser_range_finder_register_callback(LaserRangeFinder *laser_range_finder, int16_t callback_id, void *function, void *user_data);
+
+/**
+ * \ingroup BrickletLaserRangeFinder
+ *
+ * Returns the API version (major, minor, release) of the bindings for this
+ * device.
+ */
+int laser_range_finder_get_api_version(LaserRangeFinder *laser_range_finder, uint8_t ret_api_version[3]);
+
+/**
+ * \ingroup BrickletLaserRangeFinder
+ *
+ * Returns the measured distance. The value has a range of 0 to 4000
+ * and is given in cm.
+ * 
+ * Sensor hardware version 1 (see {@link laser_range_finder_get_sensor_hardware_version}) cannot
+ * measure distance and velocity at the same time. Therefore, the distance mode
+ * has to be enabled using {@link laser_range_finder_set_mode}.
+ * Sensor hardware version 3 can measure distance and velocity at the same
+ * time. Also the laser has to be enabled, see {@link laser_range_finder_enable_laser}.
+ * 
+ * If you want to get the distance periodically, it is recommended to
+ * use the {@link LASER_RANGE_FINDER_CALLBACK_DISTANCE} callback and set the period with
+ * {@link laser_range_finder_set_distance_callback_period}.
+ */
+int laser_range_finder_get_distance(LaserRangeFinder *laser_range_finder, uint16_t *ret_distance);
+
+/**
+ * \ingroup BrickletLaserRangeFinder
+ *
+ * Returns the measured velocity. The value has a range of -12800 to 12700
+ * and is given in 1/100 m/s.
+ * 
+ * Sensor hardware version 1 (see {@link laser_range_finder_get_sensor_hardware_version}) cannot
+ * measure distance and velocity at the same time. Therefore, the velocity mode
+ * has to be enabled using {@link laser_range_finder_set_mode}.
+ * Sensor hardware version 3 can measure distance and velocity at the same
+ * time, but the velocity measurement only produces stables results if a fixed
+ * measurement rate (see {@link laser_range_finder_set_configuration}) is configured. Also the laser
+ * has to be enabled, see {@link laser_range_finder_enable_laser}.
+ * 
+ * If you want to get the velocity periodically, it is recommended to
+ * use the {@link LASER_RANGE_FINDER_CALLBACK_VELOCITY} callback and set the period with
+ * {@link laser_range_finder_set_velocity_callback_period}.
+ */
+int laser_range_finder_get_velocity(LaserRangeFinder *laser_range_finder, int16_t *ret_velocity);
+
+/**
+ * \ingroup BrickletLaserRangeFinder
+ *
+ * Sets the period in ms with which the {@link LASER_RANGE_FINDER_CALLBACK_DISTANCE} callback is triggered
+ * periodically. A value of 0 turns the callback off.
+ * 
+ * The {@link LASER_RANGE_FINDER_CALLBACK_DISTANCE} callback is only triggered if the distance value has
+ * changed since the last triggering.
+ * 
+ * The default value is 0.
+ */
+int laser_range_finder_set_distance_callback_period(LaserRangeFinder *laser_range_finder, uint32_t period);
+
+/**
+ * \ingroup BrickletLaserRangeFinder
+ *
+ * Returns the period as set by {@link laser_range_finder_set_distance_callback_period}.
+ */
+int laser_range_finder_get_distance_callback_period(LaserRangeFinder *laser_range_finder, uint32_t *ret_period);
+
+/**
+ * \ingroup BrickletLaserRangeFinder
+ *
+ * Sets the period in ms with which the {@link LASER_RANGE_FINDER_CALLBACK_VELOCITY} callback is triggered
+ * periodically. A value of 0 turns the callback off.
+ * 
+ * The {@link LASER_RANGE_FINDER_CALLBACK_VELOCITY} callback is only triggered if the velocity value has
+ * changed since the last triggering.
+ * 
+ * The default value is 0.
+ */
+int laser_range_finder_set_velocity_callback_period(LaserRangeFinder *laser_range_finder, uint32_t period);
+
+/**
+ * \ingroup BrickletLaserRangeFinder
+ *
+ * Returns the period as set by {@link laser_range_finder_set_velocity_callback_period}.
+ */
+int laser_range_finder_get_velocity_callback_period(LaserRangeFinder *laser_range_finder, uint32_t *ret_period);
+
+/**
+ * \ingroup BrickletLaserRangeFinder
+ *
+ * Sets the thresholds for the {@link LASER_RANGE_FINDER_CALLBACK_DISTANCE_REACHED} callback.
+ * 
+ * The following options are possible:
+ * 
+ * \verbatim
+ *  "Option", "Description"
+ * 
+ *  "'x'",    "Callback is turned off"
+ *  "'o'",    "Callback is triggered when the distance value is *outside* the min and max values"
+ *  "'i'",    "Callback is triggered when the distance value is *inside* the min and max values"
+ *  "'<'",    "Callback is triggered when the distance value is smaller than the min value (max is ignored)"
+ *  "'>'",    "Callback is triggered when the distance value is greater than the min value (max is ignored)"
+ * \endverbatim
+ * 
+ * The default value is ('x', 0, 0).
+ */
+int laser_range_finder_set_distance_callback_threshold(LaserRangeFinder *laser_range_finder, char option, uint16_t min, uint16_t max);
+
+/**
+ * \ingroup BrickletLaserRangeFinder
+ *
+ * Returns the threshold as set by {@link laser_range_finder_set_distance_callback_threshold}.
+ */
+int laser_range_finder_get_distance_callback_threshold(LaserRangeFinder *laser_range_finder, char *ret_option, uint16_t *ret_min, uint16_t *ret_max);
+
+/**
+ * \ingroup BrickletLaserRangeFinder
+ *
+ * Sets the thresholds for the {@link LASER_RANGE_FINDER_CALLBACK_VELOCITY_REACHED} callback.
+ * 
+ * The following options are possible:
+ * 
+ * \verbatim
+ *  "Option", "Description"
+ * 
+ *  "'x'",    "Callback is turned off"
+ *  "'o'",    "Callback is triggered when the velocity is *outside* the min and max values"
+ *  "'i'",    "Callback is triggered when the velocity is *inside* the min and max values"
+ *  "'<'",    "Callback is triggered when the velocity is smaller than the min value (max is ignored)"
+ *  "'>'",    "Callback is triggered when the velocity is greater than the min value (max is ignored)"
+ * \endverbatim
+ * 
+ * The default value is ('x', 0, 0).
+ */
+int laser_range_finder_set_velocity_callback_threshold(LaserRangeFinder *laser_range_finder, char option, int16_t min, int16_t max);
+
+/**
+ * \ingroup BrickletLaserRangeFinder
+ *
+ * Returns the threshold as set by {@link laser_range_finder_set_velocity_callback_threshold}.
+ */
+int laser_range_finder_get_velocity_callback_threshold(LaserRangeFinder *laser_range_finder, char *ret_option, int16_t *ret_min, int16_t *ret_max);
+
+/**
+ * \ingroup BrickletLaserRangeFinder
+ *
+ * Sets the period in ms with which the threshold callbacks
+ * 
+ * * {@link LASER_RANGE_FINDER_CALLBACK_DISTANCE_REACHED},
+ * * {@link LASER_RANGE_FINDER_CALLBACK_VELOCITY_REACHED},
+ * 
+ * are triggered, if the thresholds
+ * 
+ * * {@link laser_range_finder_set_distance_callback_threshold},
+ * * {@link laser_range_finder_set_velocity_callback_threshold},
+ * 
+ * keep being reached.
+ * 
+ * The default value is 100.
+ */
+int laser_range_finder_set_debounce_period(LaserRangeFinder *laser_range_finder, uint32_t debounce);
+
+/**
+ * \ingroup BrickletLaserRangeFinder
+ *
+ * Returns the debounce period as set by {@link laser_range_finder_set_debounce_period}.
+ */
+int laser_range_finder_get_debounce_period(LaserRangeFinder *laser_range_finder, uint32_t *ret_debounce);
+
+/**
+ * \ingroup BrickletLaserRangeFinder
+ *
+ * Sets the length of a `moving averaging <https://en.wikipedia.org/wiki/Moving_average>`__
+ * for the distance and velocity.
+ * 
+ * Setting the length to 0 will turn the averaging completely off. With less
+ * averaging, there is more noise on the data.
+ * 
+ * The range for the averaging is 0-30.
+ * 
+ * The default value is 10.
+ */
+int laser_range_finder_set_moving_average(LaserRangeFinder *laser_range_finder, uint8_t distance_average_length, uint8_t velocity_average_length);
+
+/**
+ * \ingroup BrickletLaserRangeFinder
+ *
+ * Returns the length moving average as set by {@link laser_range_finder_set_moving_average}.
+ */
+int laser_range_finder_get_moving_average(LaserRangeFinder *laser_range_finder, uint8_t *ret_distance_average_length, uint8_t *ret_velocity_average_length);
+
+/**
+ * \ingroup BrickletLaserRangeFinder
+ *
+ * \note
+ *  This function is only available if you have a LIDAR-Lite sensor with hardware
+ *  version 1. Use {@link laser_range_finder_set_configuration} for hardware version 3. You can check
+ *  the sensor hardware version using {@link laser_range_finder_get_sensor_hardware_version}.
+ * 
+ * The LIDAR-Lite sensor (hardware version 1) has five different modes. One mode is
+ * for distance measurements and four modes are for velocity measurements with
+ * different ranges.
+ * 
+ * The following modes are available:
+ * 
+ * * 0: Distance is measured with resolution 1.0 cm and range 0-400 cm
+ * * 1: Velocity is measured with resolution 0.1 m/s and range is 0-12.7 m/s
+ * * 2: Velocity is measured with resolution 0.25 m/s and range is 0-31.75 m/s
+ * * 3: Velocity is measured with resolution 0.5 m/s and range is 0-63.5 m/s
+ * * 4: Velocity is measured with resolution 1.0 m/s and range is 0-127 m/s
+ * 
+ * The default mode is 0 (distance is measured).
+ */
+int laser_range_finder_set_mode(LaserRangeFinder *laser_range_finder, uint8_t mode);
+
+/**
+ * \ingroup BrickletLaserRangeFinder
+ *
+ * Returns the mode as set by {@link laser_range_finder_set_mode}.
+ */
+int laser_range_finder_get_mode(LaserRangeFinder *laser_range_finder, uint8_t *ret_mode);
+
+/**
+ * \ingroup BrickletLaserRangeFinder
+ *
+ * Activates the laser of the LIDAR.
+ * 
+ * We recommend that you wait 250ms after enabling the laser before
+ * the first call of {@link laser_range_finder_get_distance} to ensure stable measurements.
+ */
+int laser_range_finder_enable_laser(LaserRangeFinder *laser_range_finder);
+
+/**
+ * \ingroup BrickletLaserRangeFinder
+ *
+ * Deactivates the laser of the LIDAR.
+ */
+int laser_range_finder_disable_laser(LaserRangeFinder *laser_range_finder);
+
+/**
+ * \ingroup BrickletLaserRangeFinder
+ *
+ * Returns *true* if the laser is enabled, *false* otherwise.
+ */
+int laser_range_finder_is_laser_enabled(LaserRangeFinder *laser_range_finder, bool *ret_laser_enabled);
+
+/**
+ * \ingroup BrickletLaserRangeFinder
+ *
+ * Returns the LIDAR-Lite hardware version.
+ * 
+ * .. versionadded:: 2.0.3$nbsp;(Plugin)
+ */
+int laser_range_finder_get_sensor_hardware_version(LaserRangeFinder *laser_range_finder, uint8_t *ret_version);
+
+/**
+ * \ingroup BrickletLaserRangeFinder
+ *
+ * \note
+ *  This function is only available if you have a LIDAR-Lite sensor with hardware
+ *  version 3. Use {@link laser_range_finder_set_mode} for hardware version 1. You can check
+ *  the sensor hardware version using {@link laser_range_finder_get_sensor_hardware_version}.
+ * 
+ * The **Aquisition Count** defines the number of times the Laser Range Finder Bricklet
+ * will integrate acquisitions to find a correlation record peak. With a higher count,
+ * the Bricklet can measure longer distances. With a lower count, the rate increases. The
+ * allowed values are 1-255.
+ * 
+ * If you set **Enable Quick Termination** to true, the distance measurement will be terminated
+ * early if a high peak was already detected. This means that a higher measurement rate can be achieved
+ * and long distances can be measured at the same time. However, the chance of false-positive
+ * distance measurements increases.
+ * 
+ * Normally the distance is calculated with a detection algorithm that uses peak value,
+ * signal strength and noise. You can however also define a fixed **Threshold Value**.
+ * Set this to a low value if you want to measure the distance to something that has
+ * very little reflection (e.g. glass) and set it to a high value if you want to measure
+ * the distance to something with a very high reflection (e.g. mirror). Set this to 0 to
+ * use the default algorithm. The other allowed values are 1-255.
+ * 
+ * Set the **Measurement Frequency** in Hz to force a fixed measurement rate. If set to 0,
+ * the Laser Range Finder Bricklet will use the optimal frequency according to the other
+ * configurations and the actual measured distance. Since the rate is not fixed in this case,
+ * the velocity measurement is not stable. For a stable velocity measurement you should
+ * set a fixed measurement frequency. The lower the frequency, the higher is the resolution
+ * of the calculated velocity. The allowed values are 10Hz-500Hz (and 0 to turn the fixed
+ * frequency off).
+ * 
+ * The default values for Acquisition Count, Enable Quick Termination, Threshold Value and
+ * Measurement Frequency are 128, false, 0 and 0.
+ * 
+ * .. versionadded:: 2.0.3$nbsp;(Plugin)
+ */
+int laser_range_finder_set_configuration(LaserRangeFinder *laser_range_finder, uint8_t acquisition_count, bool enable_quick_termination, uint8_t threshold_value, uint16_t measurement_frequency);
+
+/**
+ * \ingroup BrickletLaserRangeFinder
+ *
+ * Returns the configuration as set by {@link laser_range_finder_set_configuration}.
+ * 
+ * .. versionadded:: 2.0.3$nbsp;(Plugin)
+ */
+int laser_range_finder_get_configuration(LaserRangeFinder *laser_range_finder, uint8_t *ret_acquisition_count, bool *ret_enable_quick_termination, uint8_t *ret_threshold_value, uint16_t *ret_measurement_frequency);
+
+/**
+ * \ingroup BrickletLaserRangeFinder
+ *
+ * Returns the UID, the UID where the Bricklet is connected to,
+ * the position, the hardware and firmware version as well as the
+ * device identifier.
+ * 
+ * The position can be 'a', 'b', 'c' or 'd'.
+ * 
+ * The device identifier numbers can be found :ref:`here <device_identifier>`.
+ * |device_identifier_constant|
+ */
+int laser_range_finder_get_identity(LaserRangeFinder *laser_range_finder, char ret_uid[8], char ret_connected_uid[8], char *ret_position, uint8_t ret_hardware_version[3], uint8_t ret_firmware_version[3], uint16_t *ret_device_identifier);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/org.fortiss.af3.platform.raspberry/trunk/code-gen-hal/lib/libaf3pihal.a b/org.fortiss.af3.platform.raspberry/trunk/code-gen-hal/lib/libaf3pihal.a
index 4ade60d14cacc596134c09ac0aae68d3c07f27e6..112f85998f84585d9493877dc0d1cf1c740760f1 100644
Binary files a/org.fortiss.af3.platform.raspberry/trunk/code-gen-hal/lib/libaf3pihal.a and b/org.fortiss.af3.platform.raspberry/trunk/code-gen-hal/lib/libaf3pihal.a differ
diff --git a/org.fortiss.af3.platform.raspberry/trunk/model/raspberry.ecore b/org.fortiss.af3.platform.raspberry/trunk/model/raspberry.ecore
index 1d6e72397b2c061898ea17d0237cfc91d5df4831..1fe1845900eee27f1556c84d2e400293b7a54594 100644
--- a/org.fortiss.af3.platform.raspberry/trunk/model/raspberry.ecore
+++ b/org.fortiss.af3.platform.raspberry/trunk/model/raspberry.ecore
@@ -2,21 +2,21 @@
 <ecore:EPackage xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="model" nsURI="http://www.fortiss.org/af3/platform/raspberry"
     nsPrefix="org-fortiss-af3-platform-raspberry">
-  <eClassifiers xsi:type="ecore:EClass" name="RaspberryPi" eSuperTypes="../../org.fortiss.af3.platform/model/platform.ecore#//ExecutionUnit">
+  <eClassifiers xsi:type="ecore:EClass" name="RaspberryPi" eSuperTypes="platform:/resource/org.fortiss.af3.platform/model/platform.ecore#//ExecutionUnit">
     <eStructuralFeatures xsi:type="ecore:EAttribute" name="canCoordinationID" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EInt"/>
     <eStructuralFeatures xsi:type="ecore:EAttribute" name="ipAddress" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
     <eStructuralFeatures xsi:type="ecore:EAttribute" name="coordinatorUnit" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EBoolean"/>
     <eStructuralFeatures xsi:type="ecore:EAttribute" name="cycleTime" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EInt"/>
   </eClassifiers>
-  <eClassifiers xsi:type="ecore:EClass" name="CanBus" eSuperTypes="../../org.fortiss.af3.platform/model/platform.ecore#//TransmissionUnit"/>
-  <eClassifiers xsi:type="ecore:EClass" name="CanConnector" eSuperTypes="../../org.fortiss.af3.platform/model/platform.ecore#//Transceiver"/>
-  <eClassifiers xsi:type="ecore:EClass" name="ActuatorPWM" eSuperTypes="../../org.fortiss.af3.platform/model/platform.ecore#//Transmitter">
+  <eClassifiers xsi:type="ecore:EClass" name="CanBus" eSuperTypes="platform:/resource/org.fortiss.af3.platform/model/platform.ecore#//TransmissionUnit"/>
+  <eClassifiers xsi:type="ecore:EClass" name="CanConnector" eSuperTypes="platform:/resource/org.fortiss.af3.platform/model/platform.ecore#//Transceiver"/>
+  <eClassifiers xsi:type="ecore:EClass" name="ActuatorPWM" eSuperTypes="platform:/resource/org.fortiss.af3.platform/model/platform.ecore#//Transmitter">
     <eStructuralFeatures xsi:type="ecore:EAttribute" name="channelID" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EInt"/>
   </eClassifiers>
   <eSubpackages name="gamepad" nsURI="http://www.fortiss.org/af3/platform/raspberry/gamepad"
       nsPrefix="org-fortiss-af3-platform-raspberry-gamepad">
     <eClassifiers xsi:type="ecore:EClass" name="GamepadReceiverBase" abstract="true"
-        eSuperTypes="../../org.fortiss.af3.platform/model/platform.ecore#//Receiver"/>
+        eSuperTypes="platform:/resource/org.fortiss.af3.platform/model/platform.ecore#//Receiver"/>
     <eClassifiers xsi:type="ecore:EClass" name="Button1" eSuperTypes="#//gamepad/GamepadReceiverBase"/>
     <eClassifiers xsi:type="ecore:EClass" name="Button2" eSuperTypes="#//gamepad/GamepadReceiverBase"/>
     <eClassifiers xsi:type="ecore:EClass" name="Button3" eSuperTypes="#//gamepad/GamepadReceiverBase"/>
@@ -32,25 +32,25 @@
   </eSubpackages>
   <eSubpackages name="brick" nsURI="http://www.fortiss.org/af3/platform/raspberry/brick"
       nsPrefix="org-fortiss-af3-platform-raspberry">
-    <eClassifiers xsi:type="ecore:EClass" name="UIDUnit" abstract="true" eSuperTypes="../../org.fortiss.tooling.kernel/model/kernel.ecore#//INamedCommentedElement">
+    <eClassifiers xsi:type="ecore:EClass" name="UIDUnit" abstract="true" eSuperTypes="platform:/resource/org.fortiss.tooling.kernel/model/kernel.ecore#//INamedCommentedElement">
       <eStructuralFeatures xsi:type="ecore:EAttribute" name="uniqueBrickletID" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
     </eClassifiers>
-    <eClassifiers xsi:type="ecore:EClass" name="UltraSonicSensor" eSuperTypes="../../org.fortiss.af3.platform/model/platform.ecore#//Receiver #//brick/UIDUnit"/>
-    <eClassifiers xsi:type="ecore:EClass" name="LaserRangeSensor" eSuperTypes="../../org.fortiss.af3.platform/model/platform.ecore#//Receiver #//brick/UIDUnit"/>
-    <eClassifiers xsi:type="ecore:EClass" name="AccelerationXSensor" eSuperTypes="../../org.fortiss.af3.platform/model/platform.ecore#//Receiver #//brick/UIDUnit"/>
-    <eClassifiers xsi:type="ecore:EClass" name="AccelerationYSensor" eSuperTypes="../../org.fortiss.af3.platform/model/platform.ecore#//Receiver #//brick/UIDUnit"/>
-    <eClassifiers xsi:type="ecore:EClass" name="AccelerationZSensor" eSuperTypes="../../org.fortiss.af3.platform/model/platform.ecore#//Receiver #//brick/UIDUnit"/>
-    <eClassifiers xsi:type="ecore:EClass" name="AngularVelocityXSensor" eSuperTypes="../../org.fortiss.af3.platform/model/platform.ecore#//Receiver #//brick/UIDUnit"/>
-    <eClassifiers xsi:type="ecore:EClass" name="AngularVelocityYSensor" eSuperTypes="../../org.fortiss.af3.platform/model/platform.ecore#//Receiver #//brick/UIDUnit"/>
-    <eClassifiers xsi:type="ecore:EClass" name="AngularVelocityZSensor" eSuperTypes="../../org.fortiss.af3.platform/model/platform.ecore#//Receiver #//brick/UIDUnit"/>
-    <eClassifiers xsi:type="ecore:EClass" name="ActuatorDigits" eSuperTypes="../../org.fortiss.af3.platform/model/platform.ecore#//Transmitter #//brick/UIDUnit">
+    <eClassifiers xsi:type="ecore:EClass" name="UltraSonicSensor" eSuperTypes="platform:/resource/org.fortiss.af3.platform/model/platform.ecore#//Receiver #//brick/UIDUnit"/>
+    <eClassifiers xsi:type="ecore:EClass" name="LaserRangeSensor" eSuperTypes="platform:/resource/org.fortiss.af3.platform/model/platform.ecore#//Receiver #//brick/UIDUnit"/>
+    <eClassifiers xsi:type="ecore:EClass" name="AccelerationXSensor" eSuperTypes="platform:/resource/org.fortiss.af3.platform/model/platform.ecore#//Receiver #//brick/UIDUnit"/>
+    <eClassifiers xsi:type="ecore:EClass" name="AccelerationYSensor" eSuperTypes="platform:/resource/org.fortiss.af3.platform/model/platform.ecore#//Receiver #//brick/UIDUnit"/>
+    <eClassifiers xsi:type="ecore:EClass" name="AccelerationZSensor" eSuperTypes="platform:/resource/org.fortiss.af3.platform/model/platform.ecore#//Receiver #//brick/UIDUnit"/>
+    <eClassifiers xsi:type="ecore:EClass" name="AngularVelocityXSensor" eSuperTypes="platform:/resource/org.fortiss.af3.platform/model/platform.ecore#//Receiver #//brick/UIDUnit"/>
+    <eClassifiers xsi:type="ecore:EClass" name="AngularVelocityYSensor" eSuperTypes="platform:/resource/org.fortiss.af3.platform/model/platform.ecore#//Receiver #//brick/UIDUnit"/>
+    <eClassifiers xsi:type="ecore:EClass" name="AngularVelocityZSensor" eSuperTypes="platform:/resource/org.fortiss.af3.platform/model/platform.ecore#//Receiver #//brick/UIDUnit"/>
+    <eClassifiers xsi:type="ecore:EClass" name="ActuatorDigits" eSuperTypes="platform:/resource/org.fortiss.af3.platform/model/platform.ecore#//Transmitter #//brick/UIDUnit">
       <eStructuralFeatures xsi:type="ecore:EAttribute" name="showHexValue" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EBoolean"/>
     </eClassifiers>
   </eSubpackages>
   <eSubpackages name="rumblepad" nsURI="http://www.fortiss.org/af3/platform/raspberry/rumblepad"
       nsPrefix="org-fortiss-af3-platform-raspberry-rumblepad">
     <eClassifiers xsi:type="ecore:EClass" name="RumblepadReceiverBase" abstract="true"
-        eSuperTypes="../../org.fortiss.af3.platform/model/platform.ecore#//Receiver"/>
+        eSuperTypes="platform:/resource/org.fortiss.af3.platform/model/platform.ecore#//Receiver"/>
     <eClassifiers xsi:type="ecore:EClass" name="ButtonA" eSuperTypes="#//rumblepad/RumblepadReceiverBase"/>
     <eClassifiers xsi:type="ecore:EClass" name="ButtonB" eSuperTypes="#//rumblepad/RumblepadReceiverBase"/>
     <eClassifiers xsi:type="ecore:EClass" name="ButtonX" eSuperTypes="#//rumblepad/RumblepadReceiverBase"/>
diff --git a/org.fortiss.af3.platform.raspberry/trunk/model/raspberry.genmodel b/org.fortiss.af3.platform.raspberry/trunk/model/raspberry.genmodel
index 72acf71783029259a1b5a201a19b429f45b06f00..90acb6845358b3ee8ed69f427b6f4a41df4321f2 100644
--- a/org.fortiss.af3.platform.raspberry/trunk/model/raspberry.genmodel
+++ b/org.fortiss.af3.platform.raspberry/trunk/model/raspberry.genmodel
@@ -18,10 +18,6 @@
     <genClasses ecoreClass="raspberry.ecore#//ActuatorPWM">
       <genFeatures createChild="false" ecoreFeature="ecore:EAttribute raspberry.ecore#//ActuatorPWM/channelID"/>
     </genClasses>
-    <genClasses ecoreClass="raspberry.ecore#//ActuatorDigits">
-      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute raspberry.ecore#//ActuatorDigits/showHexValue"/>
-      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute raspberry.ecore#//ActuatorDigits/uniqueBrickletID"/>
-    </genClasses>
     <nestedGenPackages prefix="Gamepad" basePackage="org.fortiss.af3.platform.raspberry.model"
         disposableProviderFactory="true" ecorePackage="raspberry.ecore#//gamepad">
       <genClasses image="false" ecoreClass="raspberry.ecore#//gamepad/GamepadReceiverBase"/>
@@ -51,6 +47,34 @@
       <genClasses ecoreClass="raspberry.ecore#//brick/AngularVelocityXSensor"/>
       <genClasses ecoreClass="raspberry.ecore#//brick/AngularVelocityYSensor"/>
       <genClasses ecoreClass="raspberry.ecore#//brick/AngularVelocityZSensor"/>
+      <genClasses ecoreClass="raspberry.ecore#//brick/ActuatorDigits">
+        <genFeatures createChild="false" ecoreFeature="ecore:EAttribute raspberry.ecore#//brick/ActuatorDigits/showHexValue"/>
+      </genClasses>
+    </nestedGenPackages>
+    <nestedGenPackages prefix="Rumblepad" basePackage="org.fortiss.af3.platform.raspberry.model"
+        disposableProviderFactory="true" ecorePackage="raspberry.ecore#//rumblepad">
+      <genClasses image="false" ecoreClass="raspberry.ecore#//rumblepad/RumblepadReceiverBase"/>
+      <genClasses ecoreClass="raspberry.ecore#//rumblepad/ButtonA"/>
+      <genClasses ecoreClass="raspberry.ecore#//rumblepad/ButtonB"/>
+      <genClasses ecoreClass="raspberry.ecore#//rumblepad/ButtonX"/>
+      <genClasses ecoreClass="raspberry.ecore#//rumblepad/ButtonY"/>
+      <genClasses ecoreClass="raspberry.ecore#//rumblepad/ButtonL1"/>
+      <genClasses ecoreClass="raspberry.ecore#//rumblepad/ButtonR1"/>
+      <genClasses ecoreClass="raspberry.ecore#//rumblepad/ButtonL3"/>
+      <genClasses ecoreClass="raspberry.ecore#//rumblepad/ButtonR3"/>
+      <genClasses ecoreClass="raspberry.ecore#//rumblepad/Left_StickX_Position"/>
+      <genClasses ecoreClass="raspberry.ecore#//rumblepad/Left_StickY_Position"/>
+      <genClasses ecoreClass="raspberry.ecore#//rumblepad/Right_StickX_Position"/>
+      <genClasses ecoreClass="raspberry.ecore#//rumblepad/Right_StickY_Position"/>
+      <genClasses ecoreClass="raspberry.ecore#//rumblepad/L2_Position"/>
+      <genClasses ecoreClass="raspberry.ecore#//rumblepad/R2_Position"/>
+      <genClasses ecoreClass="raspberry.ecore#//rumblepad/DPadUp"/>
+      <genClasses ecoreClass="raspberry.ecore#//rumblepad/DPadDown"/>
+      <genClasses ecoreClass="raspberry.ecore#//rumblepad/DPadLeft"/>
+      <genClasses ecoreClass="raspberry.ecore#//rumblepad/DPadRight"/>
+      <genClasses ecoreClass="raspberry.ecore#//rumblepad/ButtonStart"/>
+      <genClasses ecoreClass="raspberry.ecore#//rumblepad/ButtonSelect"/>
+      <genClasses ecoreClass="raspberry.ecore#//rumblepad/ButtonHome"/>
     </nestedGenPackages>
   </genPackages>
 </genmodel:GenModel>
diff --git a/org.fortiss.af3.platform.raspberry/trunk/src/org/fortiss/af3/platform/raspberry/generator/executable/HeaderCopyGenerator.java b/org.fortiss.af3.platform.raspberry/trunk/src/org/fortiss/af3/platform/raspberry/generator/executable/HeaderCopyGenerator.java
index c3eda109d439b003f9de7f617cdfdd1a5a1caf0a..1770cd82bb58b7602febf04082f939ec29f20927 100644
--- a/org.fortiss.af3.platform.raspberry/trunk/src/org/fortiss/af3/platform/raspberry/generator/executable/HeaderCopyGenerator.java
+++ b/org.fortiss.af3.platform.raspberry/trunk/src/org/fortiss/af3/platform/raspberry/generator/executable/HeaderCopyGenerator.java
@@ -42,6 +42,7 @@ final class HeaderCopyGenerator {
 		incLibPack.addUnit(copyAF3Hal("canthread.h"));
 		incLibPack.addUnit(copyAF3Hal("debugprint.h"));
 		incLibPack.addUnit(copyAF3Hal("gamepad.h"));
+		incLibPack.addUnit(copyAF3Hal("rumblepad.h"));
 		incLibPack.addUnit(copyAF3Hal("protocol_can.h"));
 		incLibPack.addUnit(copyAF3Hal("protocol_control_center.h"));
 		incLibPack.addUnit(copyAF3Hal("protocol_coordinator.h"));
@@ -49,6 +50,11 @@ final class HeaderCopyGenerator {
 		incLibPack.addUnit(copyAF3Hal("protocol_worker.h"));
 		incLibPack.addUnit(copyAF3Hal("temp_actuator.h"));
 		incLibPack.addUnit(copyAF3Hal("timeutil.h"));
+		incLibPack.addUnit(copyBrick("ip_connection.h"));
+		incLibPack.addUnit(copyBrick("bricklet_distance_us.h"));
+		incLibPack.addUnit(copyBrick("bricklet_laser_range_finder.h"));
+		incLibPack.addUnit(copyBrick("brick_imu_v2.h"));
+		incLibPack.addUnit(copyBrick("bricklet_segment_display_4x7.h"));
 	}
 
 	/** Copies the AF3 HAL header file. */
diff --git a/org.fortiss.af3.platform.raspberry/trunk/src/org/fortiss/af3/platform/raspberry/generator/executable/MainGenerator.java b/org.fortiss.af3.platform.raspberry/trunk/src/org/fortiss/af3/platform/raspberry/generator/executable/MainGenerator.java
index dc85a9715c3615670e9f8a7db48683452e0745c7..10336121206c92c88ee60b44e72ffaebd3a127e0 100644
--- a/org.fortiss.af3.platform.raspberry/trunk/src/org/fortiss/af3/platform/raspberry/generator/executable/MainGenerator.java
+++ b/org.fortiss.af3.platform.raspberry/trunk/src/org/fortiss/af3/platform/raspberry/generator/executable/MainGenerator.java
@@ -34,19 +34,36 @@ import org.fortiss.af3.platform.model.Receiver;
 import org.fortiss.af3.platform.model.Transmitter;
 import org.fortiss.af3.platform.raspberry.model.ActuatorPWM;
 import org.fortiss.af3.platform.raspberry.model.RaspberryPi;
+import org.fortiss.af3.platform.raspberry.model.brick.AccelerationXSensor;
+import org.fortiss.af3.platform.raspberry.model.brick.AccelerationYSensor;
+import org.fortiss.af3.platform.raspberry.model.brick.AccelerationZSensor;
+import org.fortiss.af3.platform.raspberry.model.brick.ActuatorDigits;
+import org.fortiss.af3.platform.raspberry.model.brick.AngularVelocityXSensor;
+import org.fortiss.af3.platform.raspberry.model.brick.AngularVelocityYSensor;
+import org.fortiss.af3.platform.raspberry.model.brick.AngularVelocityZSensor;
+import org.fortiss.af3.platform.raspberry.model.brick.LaserRangeSensor;
+import org.fortiss.af3.platform.raspberry.model.brick.UltraSonicSensor;
 import org.fortiss.af3.platform.raspberry.model.gamepad.Button1;
 import org.fortiss.af3.platform.raspberry.model.gamepad.Button2;
 import org.fortiss.af3.platform.raspberry.model.gamepad.Button3;
 import org.fortiss.af3.platform.raspberry.model.gamepad.Button4;
-import org.fortiss.af3.platform.raspberry.model.gamepad.ButtonL1;
 import org.fortiss.af3.platform.raspberry.model.gamepad.ButtonL2;
-import org.fortiss.af3.platform.raspberry.model.gamepad.ButtonR1;
 import org.fortiss.af3.platform.raspberry.model.gamepad.ButtonR2;
 import org.fortiss.af3.platform.raspberry.model.gamepad.GamepadReceiverBase;
-import org.fortiss.af3.platform.raspberry.model.gamepad.Left_StickX_Position;
-import org.fortiss.af3.platform.raspberry.model.gamepad.Left_StickY_Position;
-import org.fortiss.af3.platform.raspberry.model.gamepad.Right_StickX_Position;
-import org.fortiss.af3.platform.raspberry.model.gamepad.Right_StickY_Position;
+import org.fortiss.af3.platform.raspberry.model.rumblepad.ButtonA;
+import org.fortiss.af3.platform.raspberry.model.rumblepad.ButtonB;
+import org.fortiss.af3.platform.raspberry.model.rumblepad.ButtonHome;
+import org.fortiss.af3.platform.raspberry.model.rumblepad.ButtonSelect;
+import org.fortiss.af3.platform.raspberry.model.rumblepad.ButtonStart;
+import org.fortiss.af3.platform.raspberry.model.rumblepad.ButtonX;
+import org.fortiss.af3.platform.raspberry.model.rumblepad.ButtonY;
+import org.fortiss.af3.platform.raspberry.model.rumblepad.DPadDown;
+import org.fortiss.af3.platform.raspberry.model.rumblepad.DPadLeft;
+import org.fortiss.af3.platform.raspberry.model.rumblepad.DPadRight;
+import org.fortiss.af3.platform.raspberry.model.rumblepad.DPadUp;
+import org.fortiss.af3.platform.raspberry.model.rumblepad.L2_Position;
+import org.fortiss.af3.platform.raspberry.model.rumblepad.R2_Position;
+import org.fortiss.af3.platform.raspberry.model.rumblepad.RumblepadReceiverBase;
 import org.fortiss.tooling.kernel.extension.data.ITransformationContext;
 
 /**
@@ -65,7 +82,12 @@ class MainGenerator {
 	private ITransformationContext context;
 
 	private boolean useGamepad;
+	private boolean useRumblepad;
+	private boolean useDigits;
 	private boolean usePWM;
+	private boolean useUS;
+	private boolean useLaser;
+	private boolean useACC;
 
 	/** Constructor. */
 	public MainGenerator(RaspberryPi executionUnit,
@@ -79,16 +101,36 @@ class MainGenerator {
 			if(!useGamepad && p.getFirst() instanceof GamepadReceiverBase) {
 				useGamepad = true;
 			}
+			if(!useRumblepad && p.getFirst() instanceof RumblepadReceiverBase) {
+				useRumblepad = true;
+			}
 			if(!usePWM && p.getFirst() instanceof ActuatorPWM) {
 				usePWM = true;
 			}
+			if(!useUS && p.getFirst() instanceof UltraSonicSensor) {
+				useUS = true;
+			}
+			if(!useLaser && p.getFirst() instanceof LaserRangeSensor) {
+				useLaser = true;
+			}
+			if(!useDigits && p.getFirst() instanceof ActuatorDigits) {
+				useDigits = true;
+			}
+			if(!useACC &&
+					(p.getFirst() instanceof AccelerationXSensor ||
+							p.getFirst() instanceof AccelerationYSensor ||
+							p.getFirst() instanceof AccelerationZSensor ||
+							p.getFirst() instanceof AngularVelocityXSensor ||
+							p.getFirst() instanceof AngularVelocityYSensor || p.getFirst() instanceof AngularVelocityZSensor)) {
+				useACC = true;
+			}
 		}
 	}
 
 	/** Creates the main.c file for deployments with distributed execution units. */
 	public AbstractUnit createMain() {
 		String includes = createIncludes(deployedComponents, deployedPorts);
-		// TODO: compute syncBox size
+		// TODO: compute syncBox sizef
 		int syncBoxSize = 0;
 		// TODO: syncbox code
 		String initCode = createInitCode(deployedComponents);
@@ -103,8 +145,9 @@ class MainGenerator {
 		String includes = createIncludes(deployedComponents, deployedPorts);
 		String initCode = createInitCode(deployedComponents);
 		String workerCode = createWorkerCode(deployedComponents, deployedPorts);
+		String sensorVariables = createSensorVariables(deployedComponents, deployedPorts);
 		return getSingleUnitMainCFile(executionUnit.getName(), executionUnit.getCycleTime(),
-				includes, initCode, workerCode);
+				includes, initCode, workerCode, sensorVariables);
 	}
 
 	/** Creates the includes of the system headers. */
@@ -118,9 +161,28 @@ class MainGenerator {
 		if(useGamepad) {
 			sb.append("#include <gamepad.h>\n");
 		}
+		if(useRumblepad) {
+			sb.append("#include <rumblepad.h>\n");
+		}
 		if(usePWM) {
 			sb.append("#include <temp_actuator.h>\n");
 		}
+		if(useUS || useLaser || useDigits || useACC) {
+			sb.append("#include <ip_connection.h>\n");
+		}
+		if(useUS) {
+			sb.append("#include <bricklet_distance_us.h>\n");
+		}
+		if(useLaser) {
+			sb.append("#include <bricklet_laser_range_finder.h>\n");
+		}
+		if(useACC) {
+			sb.append("#include <brick_imu_v2.h>\n");
+		}
+		if(useDigits) {
+			sb.append("#include <bricklet_segment_display_4x7.h>\n");
+		}
+		sb.append("#include <stdio.h>\n");
 		return sb.toString();
 	}
 
@@ -145,6 +207,94 @@ class MainGenerator {
 		return sb.toString();
 	}
 
+	/** Create the Sensor Variables and functions. */
+	private String createSensorVariables(List<Pair<ExecutionUnit, Component>> deployedComponents,
+			List<Pair<PlatformConnectorUnit, Port>> deployedPorts) {
+		StringBuilder sb = new StringBuilder();
+		sb.append("float Q = 0.022;\n");
+		sb.append("float R = 0.917;\n");
+		sb.append("float estimates[9] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};\n");
+		sb.append("float last_p[9] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};\n");
+		sb.append("float kalman_filter(float value, int sensor) {\n");
+		sb.append("if(sensor < 0 || sensor > 8) return -1;");
+		sb.append("float temp_est = estimates[sensor];\n");
+		sb.append("float p_temp = last_p[sensor] + Q;\n");
+		sb.append("float K = p_temp * (1.0*(p_temp + R));\n");
+		sb.append("float est = temp_est + K * (value - temp_est);\n");
+		sb.append("float P = (1-K)*p_temp;\n");
+		sb.append("last_p[sensor] = P;\n");
+		sb.append("estimates[sensor] = est;\n");
+		sb.append("return est;\n");
+		sb.append("}\n\n");
+		if(usePWM) {
+			sb.append("int pwm_engine_fd = -1;\n");
+			sb.append("int pwm_steering_fd = -1;\n");
+		}
+		if(useDigits) {
+			sb.append("SegmentDisplay4x7 segment_display;\n");
+			sb.append("static void set_led_display (SegmentDisplay4x7 *segment_display, uint16_t value, bool showHex) {\n");
+			sb.append("static const uint8_t digits[] = {0x3f,0x06,0x5b,0x4f,\n");
+			sb.append("                                 0x66,0x6d,0x7d,0x07,\n");
+			sb.append("                                 0x7f,0x6f,0x77,0x7c,\n");
+			sb.append("                                 0x39,0x5e,0x79,0x71};\n");
+			sb.append("if(showHex) {\n");
+			sb.append("uint8_t segments[4] = {digits[(value >> 12) & 0x0F], digits[(value >> 8) & 0x0F], digits[(value >> 4) & 0x0F], digits[value & 0x0F]};\n");
+			sb.append("segment_display_4x7_set_segments(segment_display, segments, 5, false);\n");
+			sb.append("} else {\n");
+			sb.append("uint8_t segments[4] = {digits[(value%10000)/1000], digits[(value%1000)/100], digits[(value%100)/10], digits[value%10]};\n");
+			sb.append("segment_display_4x7_set_segments(segment_display, segments, 5, false);\n");
+			sb.append("}\n");
+			sb.append("}\n\n");
+		}
+		if(useUS) {
+			sb.append("uint16_t ultra_sonic_A;\n");
+			sb.append("uint64_t us_A_last_cb_time = 0;\n");
+			sb.append("char* uid_us_A = \"zpW\";\n");
+			sb.append("void us_A_callback(uint16_t distance, void *data) {\n");
+			sb.append("ultra_sonic_A = kalman_filter(distance, 0);\n");
+			sb.append("us_A_last_cb_time = time_util_get_current_micros();\n");
+			sb.append("}\n");
+			sb.append("uint16_t ultra_sonic_B;\n");
+			sb.append("uint64_t us_B_last_cb_time = 0;\n");
+			sb.append("char* uid_us_B = \"zqN\";\n");
+			sb.append("void us_B_callback(uint16_t distance, void *data) {\n");
+			sb.append("us_B_last_cb_time = time_util_get_current_micros();\n");
+			sb.append("ultra_sonic_B = kalman_filter(distance, 1);\n");
+			sb.append("}\n\n");
+		}
+		if(useLaser) {
+			sb.append("int16_t laser_distance;\n");
+			sb.append("uint64_t laser_last_cb_time = 0;\n");
+			sb.append("void laser_callback(uint16_t distance, void *data) {\n");
+			sb.append("laser_distance = kalman_filter(distance, 2);\n");
+			sb.append("laser_last_cb_time = time_util_get_current_micros();\n");
+			sb.append("}\n\n");
+		}
+		if(useACC) {
+			sb.append("float acceleration_X, acceleration_Y, acceleration_Z;\n");
+			sb.append("uint64_t acc_last_cb_time = 0;\n");
+			sb.append("void acc_callback(int16_t x, int16_t y, int16_t z, void* data) {\n");
+			sb.append("if (abs(x - acceleration_X) > 2 * 10 * 100 ||\n");
+			sb.append("abs(y - acceleration_Y) > 2 * 10 * 100 ||\n");
+			sb.append("abs(z - acceleration_Z) > 2 * 10 * 100)\n");
+			sb.append("    return;\n");
+			sb.append("acceleration_X = kalman_filter(x, 3) / 100.0;\n");
+			sb.append("acceleration_Y = kalman_filter(y, 4) / 100.0;\n");
+			sb.append("acceleration_Z = kalman_filter(z, 5) / 100.0;\n");
+			sb.append("acc_last_cb_time = time_util_get_current_micros();\n");
+			sb.append("}\n\n");
+			sb.append("float angularVelocity_X, angularVelocity_Y, angularVelocity_Z;\n");
+			sb.append("uint64_t angV_last_cb_time = 0;\n");
+			sb.append("void angV_callback(int16_t x, int16_t y, int16_t z, void* data) {\n");
+			sb.append("angularVelocity_X = kalman_filter(x, 6) / 16;\n");
+			sb.append("angularVelocity_Y = kalman_filter(y, 7) / 16;\n");
+			sb.append("angularVelocity_Z = kalman_filter(z, 8) / 16;\n");
+			sb.append("angV_last_cb_time = time_util_get_current_micros();\n");
+			sb.append("}\n\n");
+		}
+		return sb.toString();
+	}
+
 	/** Returns the port and ID identifier. */
 	private String portName(Port port) {
 		return port.getName() + "_ID_" + port.getId();
@@ -155,9 +305,24 @@ class MainGenerator {
 		if(transmitter instanceof ActuatorPWM) {
 			ActuatorPWM act = (ActuatorPWM)transmitter;
 			String result = "if(!noval_" + portName(outport) + ") {\n";
+			if(act.getChannelID() == 0) {
+				result +=
+						"temp_actuator_device_set_target(pwm_engine_fd, 0, (uint16_t)" +
+								portName(outport) + ");\n";
+			} else {
+				result +=
+						"temp_actuator_device_set_target(pwm_steering_fd, 0, (uint16_t)" +
+								portName(outport) + ");\n";
+			}
+			result += "}\n";
+			return result;
+		}
+		if(transmitter instanceof ActuatorDigits) {
+			ActuatorDigits digits = (ActuatorDigits)transmitter;
+			String result = "if(!noval_" + portName(outport) + ") {\n";
 			result +=
-					"temp_actuator_set_target(" + act.getChannelID() + ", (uint16_t)" +
-							portName(outport) + ");\n";
+					"set_led_display(&segment_display, (uint16_t)" + portName(outport) + ", " +
+							digits.isShowHexValue() + ");\n";
 			result += "}\n";
 			return result;
 		}
@@ -166,6 +331,100 @@ class MainGenerator {
 
 	/** Creates the read code for the given receiver and port. */
 	private String createReadCode(Receiver receiver, InputPort inport) {
+		if(receiver instanceof UltraSonicSensor) {
+			StringBuilder sb = new StringBuilder();
+			UltraSonicSensor sensor = (UltraSonicSensor)receiver;
+			sb.append("float diff_A = (curr_time - us_A_last_cb_time) / (1.0 * SECONDS_IN_MICROS);\n");
+			sb.append("float diff_B = (curr_time - us_B_last_cb_time) / (1.0 * SECONDS_IN_MICROS);\n");
+			sb.append("noval_" + portName(inport) + " = false;\n");
+			sb.append("if (!strcmp(\"" + sensor.getUniqueBrickletID() +
+					"\", uid_us_A) && diff_A < 1.0) {\n");
+			sb.append(portName(inport) + " = ultra_sonic_A;\n");
+			sb.append("} else if (!strcmp(\"" + sensor.getUniqueBrickletID() +
+					"\", uid_us_B) && diff_B < 1.0) {\n");
+			sb.append(portName(inport) + " = ultra_sonic_B;\n");
+			sb.append("} else {\n");
+			sb.append("noval_" + portName(inport) + " = true;\n");
+			sb.append("}\n");
+			return sb.toString();
+		}
+		if(receiver instanceof LaserRangeSensor) {
+			StringBuilder sb = new StringBuilder();
+			sb.append("float diff_laser = (curr_time - laser_last_cb_time) / (1.0 * SECONDS_IN_MICROS);\n");
+			sb.append("if (diff_laser < 1.0) {\n");
+			sb.append("noval_" + portName(inport) + " = false;\n");
+			sb.append(portName(inport) + " = laser_distance;\n");
+			sb.append("} else {\n");
+			sb.append("noval_" + portName(inport) + " = true;\n");
+			sb.append("}\n");
+			return sb.toString();
+		}
+		if(receiver instanceof AccelerationXSensor) {
+			StringBuilder sb = new StringBuilder();
+			sb.append("float diff_accX = (curr_time - acc_last_cb_time) / (1.0 * SECONDS_IN_MICROS);\n");
+			sb.append("if (diff_accX < 1.0) {\n");
+			sb.append("noval_" + portName(inport) + " = false;\n");
+			sb.append(portName(inport) + " = acceleration_X;\n");
+			sb.append("} else {\n");
+			sb.append("noval_" + portName(inport) + " = true;\n");
+			sb.append("}\n");
+			return sb.toString();
+		}
+		if(receiver instanceof AccelerationYSensor) {
+			StringBuilder sb = new StringBuilder();
+			sb.append("float diff_accY = (curr_time - acc_last_cb_time) / (1.0 * SECONDS_IN_MICROS);\n");
+			sb.append("if (diff_accY < 1.0) {\n");
+			sb.append("noval_" + portName(inport) + " = false;\n");
+			sb.append(portName(inport) + " = acceleration_Y;\n");
+			sb.append("} else {\n");
+			sb.append("noval_" + portName(inport) + " = true;\n");
+			sb.append("}\n");
+			return sb.toString();
+		}
+		if(receiver instanceof AccelerationZSensor) {
+			StringBuilder sb = new StringBuilder();
+			sb.append("float diff_accZ = (curr_time - acc_last_cb_time) / (1.0 * SECONDS_IN_MICROS);\n");
+			sb.append("if (diff_accZ < 1.0) {\n");
+			sb.append("noval_" + portName(inport) + " = false;\n");
+			sb.append(portName(inport) + " = acceleration_Z;\n");
+			sb.append("} else {\n");
+			sb.append("noval_" + portName(inport) + " = true;\n");
+			sb.append("}\n");
+			return sb.toString();
+		}
+		if(receiver instanceof AngularVelocityXSensor) {
+			StringBuilder sb = new StringBuilder();
+			sb.append("float diff_angV_X = (curr_time - angV_last_cb_time) / (1.0 * SECONDS_IN_MICROS);\n");
+			sb.append("if (diff_angV_X < 1.0) {\n");
+			sb.append("noval_" + portName(inport) + " = false;\n");
+			sb.append(portName(inport) + " = angularVelocity_X;\n");
+			sb.append("} else {\n");
+			sb.append("noval_" + portName(inport) + " = true;\n");
+			sb.append("}\n");
+			return sb.toString();
+		}
+		if(receiver instanceof AngularVelocityYSensor) {
+			StringBuilder sb = new StringBuilder();
+			sb.append("float diff_angV_Y = (curr_time - angV_last_cb_time) / (1.0 * SECONDS_IN_MICROS);\n");
+			sb.append("if (diff_angV_Y < 1.0) {\n");
+			sb.append("noval_" + portName(inport) + " = false;\n");
+			sb.append(portName(inport) + " = angularVelocity_Y;\n");
+			sb.append("} else {\n");
+			sb.append("noval_" + portName(inport) + " = true;\n");
+			sb.append("}\n");
+			return sb.toString();
+		}
+		if(receiver instanceof AngularVelocityZSensor) {
+			StringBuilder sb = new StringBuilder();
+			sb.append("float diff_angV_Z = (curr_time - angV_last_cb_time) / (1.0 * SECONDS_IN_MICROS);\n");
+			sb.append("if (diff_angV_Z < 1.0) {\n");
+			sb.append("noval_" + portName(inport) + " = false;\n");
+			sb.append(portName(inport) + " = angularVelocity_Z;\n");
+			sb.append("} else {\n");
+			sb.append("noval_" + portName(inport) + " = true;\n");
+			sb.append("}\n");
+			return sb.toString();
+		}
 		if(receiver instanceof Button1) {
 			return gamepadReadCode("gamepad_get_button_state", "GAMEPAD_BUTTON_1", inport);
 		}
@@ -178,34 +437,101 @@ class MainGenerator {
 		if(receiver instanceof Button4) {
 			return gamepadReadCode("gamepad_get_button_state", "GAMEPAD_BUTTON_4", inport);
 		}
-		if(receiver instanceof ButtonL1) {
+		if(receiver instanceof org.fortiss.af3.platform.raspberry.model.gamepad.ButtonL1) {
 			return gamepadReadCode("gamepad_get_button_state", "GAMEPAD_BUTTON_L1", inport);
 		}
 		if(receiver instanceof ButtonL2) {
 			return gamepadReadCode("gamepad_get_button_state", "GAMEPAD_BUTTON_L2", inport);
 		}
-		if(receiver instanceof ButtonR1) {
+		if(receiver instanceof org.fortiss.af3.platform.raspberry.model.gamepad.ButtonR1) {
 			return gamepadReadCode("gamepad_get_button_state", "GAMEPAD_BUTTON_R1", inport);
 		}
 		if(receiver instanceof ButtonR2) {
 			return gamepadReadCode("gamepad_get_button_state", "GAMEPAD_BUTTON_R2", inport);
 		}
-		if(receiver instanceof Right_StickX_Position) {
+		if(receiver instanceof org.fortiss.af3.platform.raspberry.model.gamepad.Right_StickX_Position) {
 			return gamepadReadCode("gamepad_get_axis_position",
 					"GAMEPAD_AXIS_RIGHT_STICK_HORIZONTAL", inport);
 		}
-		if(receiver instanceof Right_StickY_Position) {
+		if(receiver instanceof org.fortiss.af3.platform.raspberry.model.gamepad.Right_StickY_Position) {
 			return gamepadReadCode("gamepad_get_axis_position",
 					"GAMEPAD_AXIS_RIGHT_STICK_VERTICAL", inport);
 		}
-		if(receiver instanceof Left_StickX_Position) {
+		if(receiver instanceof org.fortiss.af3.platform.raspberry.model.gamepad.Left_StickX_Position) {
 			return gamepadReadCode("gamepad_get_axis_position",
 					"GAMEPAD_AXIS_LEFT_STICK_HORIZONTAL", inport);
 		}
-		if(receiver instanceof Left_StickY_Position) {
+		if(receiver instanceof org.fortiss.af3.platform.raspberry.model.gamepad.Left_StickY_Position) {
 			return gamepadReadCode("gamepad_get_axis_position", "GAMEPAD_AXIS_LEFT_STICK_VERTICAL",
 					inport);
 		}
+		if(receiver instanceof ButtonA) {
+			return gamepadReadCode("rumblepad_get_button_state", "RUMBLEPAD_BUTTON_A", inport);
+		}
+		if(receiver instanceof ButtonB) {
+			return gamepadReadCode("rumblepad_get_button_state", "RUMBLEPAD_BUTTON_B", inport);
+		}
+		if(receiver instanceof ButtonX) {
+			return gamepadReadCode("rumblepad_get_button_state", "RUMBLEPAD_BUTTON_X", inport);
+		}
+		if(receiver instanceof ButtonY) {
+			return gamepadReadCode("rumblepad_get_button_state", "RUMBLEPAD_BUTTON_Y", inport);
+		}
+		if(receiver instanceof ButtonStart) {
+			return gamepadReadCode("rumblepad_get_button_state", "RUMBLEPAD_BUTTON_START", inport);
+		}
+		if(receiver instanceof ButtonSelect) {
+			return gamepadReadCode("rumblepad_get_button_state", "RUMBLEPAD_BUTTON_SELECT", inport);
+		}
+		if(receiver instanceof ButtonHome) {
+			return gamepadReadCode("rumblepad_get_button_state", "RUMBLEPAD_BUTTON_HOME", inport);
+		}
+		if(receiver instanceof DPadDown) {
+			return gamepadReadCode("rumblepad_get_button_state", "RUMBLEPAD_DPAD_DOWN", inport);
+		}
+		if(receiver instanceof DPadUp) {
+			return gamepadReadCode("rumblepad_get_button_state", "RUMBLEPAD_DPAD_UP", inport);
+		}
+		if(receiver instanceof DPadLeft) {
+			return gamepadReadCode("rumblepad_get_button_state", "RUMBLEPAD_DPAD_LEFT", inport);
+		}
+		if(receiver instanceof DPadRight) {
+			return gamepadReadCode("rumblepad_get_button_state", "RUMBLEPAD_DPAD_RIGHT", inport);
+		}
+		if(receiver instanceof org.fortiss.af3.platform.raspberry.model.rumblepad.ButtonL1) {
+			return gamepadReadCode("rumblepad_get_button_state", "RUMBLEPAD_BUTTON_L1", inport);
+		}
+		if(receiver instanceof org.fortiss.af3.platform.raspberry.model.rumblepad.ButtonR1) {
+			return gamepadReadCode("rumblepad_get_button_state", "RUMBLEPAD_BUTTON_R1", inport);
+		}
+		if(receiver instanceof org.fortiss.af3.platform.raspberry.model.rumblepad.ButtonL3) {
+			return gamepadReadCode("rumblepad_get_button_state", "RUMBLEPAD_BUTTON_L3", inport);
+		}
+		if(receiver instanceof org.fortiss.af3.platform.raspberry.model.rumblepad.ButtonR3) {
+			return gamepadReadCode("rumblepad_get_button_state", "RUMBLEPAD_BUTTON_R3", inport);
+		}
+		if(receiver instanceof L2_Position) {
+			return gamepadReadCode("rumblepad_get_axis_position", "RUMBLEPAD_AXIS_L2", inport);
+		}
+		if(receiver instanceof R2_Position) {
+			return gamepadReadCode("rumblepad_get_axis_position", "RUMBLEPAD_AXIS_R2", inport);
+		}
+		if(receiver instanceof org.fortiss.af3.platform.raspberry.model.rumblepad.Left_StickX_Position) {
+			return gamepadReadCode("rumblepad_get_axis_position",
+					"RUMBLEPAD_AXIS_LEFT_STICK_HORIZONTAL", inport);
+		}
+		if(receiver instanceof org.fortiss.af3.platform.raspberry.model.rumblepad.Left_StickY_Position) {
+			return gamepadReadCode("rumblepad_get_axis_position",
+					"RUMBLEPAD_AXIS_LEFT_STICK_VERTICAL", inport);
+		}
+		if(receiver instanceof org.fortiss.af3.platform.raspberry.model.rumblepad.Right_StickX_Position) {
+			return gamepadReadCode("rumblepad_get_axis_position",
+					"RUMBLEPAD_AXIS_RIGHT_STICK_HORIZONTAL", inport);
+		}
+		if(receiver instanceof org.fortiss.af3.platform.raspberry.model.rumblepad.Right_StickY_Position) {
+			return gamepadReadCode("rumblepad_get_axis_position",
+					"RUMBLEPAD_AXIS_RIGHT_STICK_VERTICAL", inport);
+		}
 		return "";
 	}
 
@@ -218,9 +544,61 @@ class MainGenerator {
 
 	/** Create the initialize code. */
 	private String createInitCode(List<Pair<ExecutionUnit, Component>> deployedComponents) {
+		int createdUsSensors = 0;
 		StringBuilder sb = new StringBuilder();
+		if(useUS || useLaser || useDigits || useACC) {
+			sb.append("IPConnection brick_connection;\n");
+			sb.append("ipcon_create(&brick_connection);\n");
+			sb.append("if(ipcon_connect(&brick_connection, BRICK_HOST, BRICK_PORT) < 0) {\n");
+			sb.append("perror(\"Failed to connect to brick sub-system.\");\n");
+			sb.append("return 1;\n");
+			sb.append("}\n\n");
+		}
+		if(useUS) {
+			for(Pair<PlatformConnectorUnit, Port> p : deployedPorts) {
+				if(createdUsSensors >= 2)
+					break;
+				if(p.getFirst() instanceof UltraSonicSensor) {
+					UltraSonicSensor sensor = (UltraSonicSensor)p.getFirst();
+					if(createdUsSensors == 0) {
+						sb.append("DistanceUS DistanceUS_A;\n");
+						sb.append("uid_us_A = \"" + sensor.getUniqueBrickletID() + "\";\n");
+						sb.append("distance_us_create(&DistanceUS_A, \"" +
+								sensor.getUniqueBrickletID() + "\", &brick_connection);\n");
+						sb.append("distance_us_register_callback(&DistanceUS_A, DISTANCE_US_CALLBACK_DISTANCE, (void*)us_A_callback, NULL);\n");
+						sb.append("distance_us_set_distance_callback_period(&DistanceUS_A, 10);\n");
+					} else {
+						sb.append("DistanceUS DistanceUS_B;\n");
+						sb.append("uid_us_B = \"" + sensor.getUniqueBrickletID() + "\";\n");
+						sb.append("distance_us_create(&DistanceUS_B, \"" +
+								sensor.getUniqueBrickletID() + "\", &brick_connection);\n");
+						sb.append("distance_us_register_callback(&DistanceUS_B, DISTANCE_US_CALLBACK_DISTANCE, (void*)us_B_callback, NULL);\n");
+						sb.append("distance_us_set_distance_callback_period(&DistanceUS_B, 10);\n");
+					}
+				}
+			}
+		}
+		if(useLaser) {
+			sb.append("LaserRangeFinder laser;\n");
+			sb.append("laser_range_finder_create(&laser, \"CQ9\", &brick_connection);\n");
+			sb.append("laser_range_finder_enable_laser(&laser);\n");
+			sb.append("laser_range_finder_register_callback(&laser, LASER_RANGE_FINDER_CALLBACK_DISTANCE, (void*)laser_callback, NULL);\n");
+			sb.append("laser_range_finder_set_distance_callback_period(&laser, 10);\n");
+		}
+		if(useDigits) {
+			sb.append("segment_display_4x7_create(&segment_display, \"wNK\", &brick_connection);\n");
+		}
+		if(useACC) {
+			sb.append("IMUV2 imu;\n");
+			sb.append("imu_v2_create(&imu, \"6xCD6s\", &brick_connection);\n");
+			sb.append("imu_v2_register_callback(&imu, IMU_V2_CALLBACK_LINEAR_ACCELERATION, (void*)acc_callback, NULL);\n");
+			sb.append("imu_v2_set_linear_acceleration_period(&imu, 5);\n");
+			sb.append("imu_v2_register_callback(&imu, IMU_V2_CALLBACK_ANGULAR_VELOCITY, (void*)angV_callback, NULL);\n");
+			sb.append("imu_v2_set_angular_velocity_period(&imu, 5);\n");
+		}
 		if(usePWM) {
-			sb.append("temp_actuator_initialize(\"/dev/ttyACM0\");\n\n");
+			sb.append("pwm_steering_fd = temp_actuator_initialize(\"/dev/ttyACM0\");\n");
+			sb.append("pwm_engine_fd = temp_actuator_initialize(\"/dev/ttyACM2\");\n\n");
 		}
 		if(useGamepad) {
 			sb.append("gamepad_configuration_t* gamepad_config = malloc(sizeof(gamepad_configuration_t));\n");
@@ -231,6 +609,19 @@ class MainGenerator {
 			sb.append("gamepad_config->button_callback = NULL;\n");
 			sb.append("gamepad_initialize(gamepad_config);\n\n");
 		}
+		if(useRumblepad) {
+			sb.append("while(access(\"/dev/input/js0\", F_OK) == -1) {\n");
+			sb.append("sleep(1);\n");
+			sb.append("printf(\"Could not access gamepad device. Trying again in 1s.\\n\");\n");
+			sb.append("}\n");
+			sb.append("rumblepad_configuration_t* rumblepad_config = malloc(sizeof(rumblepad_configuration_t));\n");
+			sb.append("rumblepad_config->device_id = \"/dev/input/js0\";\n");
+			sb.append("rumblepad_config->waiting_sleep_in_micros = " + WAITING_SLEEP_IN_MICROS +
+					";\n");
+			sb.append("rumblepad_config->axis_callback = NULL;\n");
+			sb.append("rumblepad_config->button_callback = NULL;\n");
+			sb.append("rumblepad_initialize(rumblepad_config);\n\n");
+		}
 		for(Pair<ExecutionUnit, Component> p : deployedComponents) {
 			Component c = p.getSecond();
 			sb.append(makeCall("init", c));
diff --git a/org.fortiss.af3.platform.raspberry/trunk/src/org/fortiss/af3/platform/raspberry/generator/executable/RaspberryPIExecutable.java b/org.fortiss.af3.platform.raspberry/trunk/src/org/fortiss/af3/platform/raspberry/generator/executable/RaspberryPIExecutable.java
index 3b13ce75c2c7eea3044ce624b744be7adecff834..2b3ca581f344c79b5cfd373f03881f8f880587d9 100644
--- a/org.fortiss.af3.platform.raspberry/trunk/src/org/fortiss/af3/platform/raspberry/generator/executable/RaspberryPIExecutable.java
+++ b/org.fortiss.af3.platform.raspberry/trunk/src/org/fortiss/af3/platform/raspberry/generator/executable/RaspberryPIExecutable.java
@@ -93,7 +93,8 @@ public class RaspberryPIExecutable extends ExecutionUnitExecutableBase<Raspberry
 			addLogicalComponentCode(deployedComponents, context, sourcePackage);
 			addEclipseCProjectFiles(sourcePackage, modelElement.getName());
 			addStaticLibraries(sourcePackage);
-			addConfigureAndMakedefsFiles(sourcePackage, modelElement.getName(), LIB_NAMES);
+			addConfigureAndMakedefsFiles(sourcePackage, modelElement.getName(),
+					LIB_NAMES_WITH_BRICK);
 			addMainFile(sourcePackage, deployedComponents, deployedPorts, context);
 		} catch(Exception ex) {
 			error(AF3PlatformRaspberryActivator.getDefault(), ex.getMessage(), ex);
diff --git a/org.fortiss.af3.platform.raspberry/trunk/src/org/fortiss/af3/platform/raspberry/generator/templates/RasPiCTemplates.java b/org.fortiss.af3.platform.raspberry/trunk/src/org/fortiss/af3/platform/raspberry/generator/templates/RasPiCTemplates.java
index 81490d838e8f6707e5977bed50b03fbc1458e451..19c9c1f2f5667cd42664e5f261f86982ac0a063d 100644
--- a/org.fortiss.af3.platform.raspberry/trunk/src/org/fortiss/af3/platform/raspberry/generator/templates/RasPiCTemplates.java
+++ b/org.fortiss.af3.platform.raspberry/trunk/src/org/fortiss/af3/platform/raspberry/generator/templates/RasPiCTemplates.java
@@ -61,14 +61,16 @@ public final class RasPiCTemplates {
 	}
 
 	/** Returns the 'main.c' file configured using the given arguments. */
-	public static AbstractUnit getSingleUnitMainCFile(String unitName, int cycletimeInMillis,
-			String systemIncludes, String systemInitCode, String workerCode) {
+	public static AbstractUnit
+			getSingleUnitMainCFile(String unitName, int cycletimeInMillis, String systemIncludes,
+					String systemInitCode, String workerCode, String sensorVariables) {
 		StringTemplate template = makeTemplate("SingleUnitMainFile.stg", "MainFile");
 		template.setAttribute("UNIT_NAME", unitName);
 		template.setAttribute("CYCLE_TIME_IN_MILLIS", cycletimeInMillis);
 		template.setAttribute("SYSTEM_INCLUDES", systemIncludes);
 		template.setAttribute("SYSTEM_INIT_CODE", systemInitCode);
 		template.setAttribute("WORKER_CODE", workerCode);
+		template.setAttribute("SENSOR_VARIABLES", sensorVariables);
 		StaticContentSourceUnit unit =
 				createStaticContentSourceUnit("main.c", template.toString(), false);
 		return unit;
diff --git a/org.fortiss.af3.platform.raspberry/trunk/src/org/fortiss/af3/platform/raspberry/generator/templates/SingleUnitMainFile.stg b/org.fortiss.af3.platform.raspberry/trunk/src/org/fortiss/af3/platform/raspberry/generator/templates/SingleUnitMainFile.stg
index 53f92dfd9b18d58c23ab822d74f2859b9e4caa85..68f436644436c8b71d99844094aa7478e2920b0b 100644
--- a/org.fortiss.af3.platform.raspberry/trunk/src/org/fortiss/af3/platform/raspberry/generator/templates/SingleUnitMainFile.stg
+++ b/org.fortiss.af3.platform.raspberry/trunk/src/org/fortiss/af3/platform/raspberry/generator/templates/SingleUnitMainFile.stg
@@ -4,7 +4,8 @@ MainFile(UNIT_NAME,
 	CYCLE_TIME_IN_MILLIS,
 	SYSTEM_INCLUDES,
 	SYSTEM_INIT_CODE,
-	WORKER_CODE) ::= <<
+	WORKER_CODE,
+	SENSOR_VARIABLES) ::= <<
 // due to current data dictionary declaration of GENTYPE_boolean
 // system include must be first
 $SYSTEM_INCLUDES$
@@ -24,7 +25,10 @@ $SYSTEM_INCLUDES$
 
 static uint64_t step = 0;
 
+$SENSOR_VARIABLES$
+
 static void worker() {
+	uint64_t curr_time = time_util_get_current_micros();
 	step++;
 	$WORKER_CODE$
 }
@@ -36,8 +40,10 @@ static uint64_t delta_time_in_micros;
 static uint64_t local_logical_clock;
 
 int main(int argc, char** argv) {
+    local_logical_clock = 1;
 	// set AF3 unit name used when communicating with CC
 	af3_set_execution_unit_identifier("$UNIT_NAME$");
+	uint32_t cycle_time = $CYCLE_TIME_IN_MILLIS$;
 	// TODO: initialize ControlCenter connection
 
 	$SYSTEM_INIT_CODE$