RoverInfraredSensor, RoverGY521 (accelerometer driver), RoverDHT22 classes added

Signed-off-by: Mustafa Ozcelikors <mozcelikors@gmail.com>
diff --git a/rover/include/roverapi/rover_dht22.hpp b/rover/include/roverapi/rover_dht22.hpp
new file mode 100644
index 0000000..6dfeb6a
--- /dev/null
+++ b/rover/include/roverapi/rover_dht22.hpp
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2017 FH Dortmund and others
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Description:
+ *     RoverDHT22 API - Interfaces for Rover DHT22 temperature and humidity sensor application development
+ *     Header file
+ *
+ * Contributors:
+ *    M.Ozcelikors <mozcelikors@gmail.com>, created RoverDHT22 class 04.12.2017
+ *
+ */
+
+#ifndef ROVERAPI_ROVER_DHT22_HPP_
+#define ROVERAPI_ROVER_DHT22_HPP_
+
+#include <roverapi/rover_sensor.hpp>
+
+/* Definitions related to DHT22 sensor */
+/**
+ *  @brief DHT22 sensor pin in wiringPi format
+ */
+static const int DHT22_RPI_PIN = 24;  //BCM19  -> wiringPi 24
+
+static const int MAX_TIMINGS = 85;
+
+namespace rover
+{
+	/**
+	 * @brief RoverDHT22 is a class that is inherited from RoverSensor abstract class. RoverDHT22 class contains member functions and variables to set up and read from DHT22 temperature and humidity sensor that is embedded on the rover.
+	 */
+	class RoverDHT22 : public RoverSensor
+	{
+		private:
+			/**
+			 * @brief Pin in wiringPi format for DHT22 signal
+			 */
+			int DHT22Pin;
+
+			/**
+			 * @brief Flag to hold if DHT22 is set up
+			 */
+			int DHT22_SETUP_;
+
+		public:
+			/**
+			 * @brief Constructor for the RoverDHT22 class
+			 */
+			explicit RoverDHT22 ();
+
+			/**
+			 * @brief Destructor for the RoverDHT22 class
+			 */
+			~RoverDHT22();
+
+			/**
+			 * @brief Function to setup DHT22 sensor
+			 * @return void
+			 */
+			void initialize (void);
+
+			/**
+			 * @brief Reads the temperature value from DHT22 (float).
+			 * @return temperature_val Temperature in Celcius (float).
+			 */
+			float read (void);
+
+			/**
+			 * @brief Reads the temperature value from DHT22 (float).
+			 * @return temperature_val Temperature in Celcius (float).
+			 */
+			float readTemperature (void);
+
+			/**
+			 * @brief Reads the humidity value from DHT22 (float).
+			 * @return humidity Humidity in Percentage (float).
+			 */
+			float readHumidity (void);
+
+			/**
+			 * @brief Sets the DHT22 pin in wiringPi format
+			 * @param pin Pin to set as DHT22's signal in wiringPi format
+			 * @return void
+			 */
+			void setDHT22Pin (const int pin);
+
+			/**
+			 * @brief Returns the DHT22 pin in wiringPi format
+			 * @return Pin to return as DHT22's signal in wiringPi format
+			 */
+			int getDHT22Pin (void);
+
+	};
+}
+
+
+#endif /* ROVERAPI_ROVER_DHT22_HPP_ */
diff --git a/rover/include/roverapi/rover_gy521.hpp b/rover/include/roverapi/rover_gy521.hpp
new file mode 100644
index 0000000..c7dc2b6
--- /dev/null
+++ b/rover/include/roverapi/rover_gy521.hpp
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2017 FH Dortmund and others
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Description:
+ *     RoverGY521 API - Interfaces for Rover GY521 accelerometer application development
+ *     Header file
+ *
+ * Contributors:
+ *    M.Ozcelikors <mozcelikors@gmail.com>, created RoverGY521 class 04.12.2017
+ *
+ * Disclaimer:
+ *    Adapted from https://github.com/OmarAflak/GY-521-Raspberry-Pi-C-/
+ *
+ */
+
+#ifndef ROVERAPI_ROVER_GY521_HPP_
+#define ROVERAPI_ROVER_GY521_HPP_
+
+#include <roverapi/rover_sensor.hpp>
+
+#include <stdint.h>
+#include <stdio.h>
+#include <unistd.h>
+
+
+namespace rover
+{
+	/**
+	 * @brief RoverGY521 is a class that is inherited from RoverSensor abstract class. RoverGY521 class contains member functions and variables to set up and read from GY521 accelerometer that is embedded on the rover.
+	 */
+	class RoverGY521 : public RoverSensor
+	{
+		private:
+			/**
+			 * @brief Flag to hold if RoverGY521 is initialized or not
+			 */
+			int ROVERGY521_SETUP_;
+
+			/**
+			 * @brief I2C address for overriding
+			 */
+			int i2CAddress;
+
+		public:
+			/**
+			 * @brief Default Constructor for the RoverGY521 class
+			 */
+			explicit RoverGY521 ();
+
+			/**
+			 * @brief Assigning Constructor for the RoverGY521 class
+			 * @param custom_i2c_address Custom I2C address to initialize RoverGY521 sensor with.
+			 */
+			explicit RoverGY521 (const int custom_i2c_address);
+
+			/**
+			 * @brief Destructor for the RoverGY521 class
+			 */
+			~RoverGY521();
+
+			/**
+			 * @brief Function to setup RoverGY521 sensor
+			 * @return void
+			 */
+			void initialize (void);
+
+			/**
+			 * @brief Overrided unused read function from RoverSensor class.
+			 */
+			float read (void);
+
+			/**
+			 * @brief Returns gyroscope output for X-axis
+			 * @return gyproscope_x_output
+			 */
+			int8_t getGyroX (void);
+
+			/**
+			 * @brief Returns gyroscope output for Y-axis
+			 * @return gyproscope_y_output
+			 */
+			int8_t getGyroY (void);
+
+			/**
+			 * @brief Returns gyroscope output for Z-axis
+			 * @return gyproscope_z_output
+			 */
+			int8_t getGyroZ (void);
+
+			/**
+			 * @brief Returns accelerometer output for X-axis
+			 * @return accelerometer_x_output
+			 */
+			int8_t getAccelX (void);
+
+			/**
+			 * @brief Returns accelerometer output for Y-axis
+			 * @return accelerometer_y_output
+			 */
+			int8_t getAccelY (void);
+
+			/**
+			 * @brief Returns accelerometer output for Z-axis
+			 * @return accelerometer_z_output
+			 */
+			int8_t getAccelZ (void);
+
+			/**
+			 * @brief Returns angle in the X-axis
+			 * @return angle_x
+			 */
+			float getAngleX (void);
+
+			/**
+			 * @brief Returns angle in the Y-axis
+			 * @return angle_y
+			 */
+			float getAngleY (void);
+
+			/**
+			 * @brief Returns angle in the Z-axis
+			 * @return angle_z
+			 */
+			float getAngleZ (void);
+
+	};
+}
+
+
+
+
+#endif /* ROVERAPI_ROVER_GY521_HPP_ */
diff --git a/rover/include/roverapi/rover_infraredsensor.hpp b/rover/include/roverapi/rover_infraredsensor.hpp
new file mode 100644
index 0000000..8eac61e
--- /dev/null
+++ b/rover/include/roverapi/rover_infraredsensor.hpp
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2017 FH Dortmund and others
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Description:
+ *    RoverInfraredSensor API - Interfaces for Rover infrared sensor application development
+ *    Header file
+ *
+ * Contributors:
+ *    M.Ozcelikors <mozcelikors@gmail.com>, created RoverInfraredSensor class 04.12.2017
+ *    Gael Blondelle, Eclipse Foundation, initial C-API and parameters
+ */
+
+#ifndef ROVERAPI_ROVER_INFRAREDSENSOR_HPP_
+#define ROVERAPI_ROVER_INFRAREDSENSOR_HPP_
+
+#include <roverapi/rover_sensor.hpp>
+
+namespace rover
+{
+	/**
+	 * @brief RoverInfraredSensor is a class that is inherited from RoverSensor abstract class. RoverInfraredSensor class contains member functions and variables to set up and read from SHARP infrared sensors that are embedded on the rover.
+	 */
+	class RoverInfraredSensor : public RoverSensor
+	{
+		private:
+			/**
+			 * @brief Sensor Identification
+			 */
+			RoverSensorID_t sensorID;
+
+			/**
+			 * @brief Flag to hold if RoverInfraredSensor is set up.
+			 */
+			int ROVERINFRAREDSENSOR_SETUP_;
+
+		public:
+
+			/**
+			 * @brief Constructor for the RoverInfraredSensor class
+			 * @param sensor_id Sensor to address
+			 */
+			explicit RoverInfraredSensor (const RoverSensorID_t sensor_id);
+
+			/**
+			 * @brief Destructor for the RoverInfraresSensor class
+			 */
+			~RoverInfraredSensor();
+
+			/**
+			 * @brief Function to setup Analog to Digital converter used in infrared sensors. Should be called once per program.
+			 * @return void
+			 */
+			void initialize (void);
+
+			/**
+			 * @brief Member function to read from infrared proximity sensor given its sensor id.
+			 * @return sensor_val Sensor value read in centimeters from sensor
+			 */
+			float read (void);
+	};
+}
+
+
+
+#endif /* ROVERAPI_ROVER_INFRAREDSENSOR_HPP_ */
diff --git a/rover/src/roverapi/rover_dht22.cpp b/rover/src/roverapi/rover_dht22.cpp
new file mode 100644
index 0000000..8614ae6
--- /dev/null
+++ b/rover/src/roverapi/rover_dht22.cpp
@@ -0,0 +1,263 @@
+/*
+ * Copyright (c) 2017 FH Dortmund and others
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Description:
+ *     RoverDHT22 API - Interfaces for Rover DHT22 temperature and humidity sensor application development
+ *
+ * Contributors:
+ *    M.Ozcelikors <mozcelikors@gmail.com>, created RoverDHT22 class 04.12.2017
+ *
+ */
+
+#include <roverapi/rover_dht22.hpp>
+#include <wiringPi.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <unistd.h>
+
+rover::RoverDHT22::RoverDHT22()
+:DHT22Pin(DHT22_RPI_PIN),
+ DHT22_SETUP_(0)
+{
+
+}
+
+rover::RoverDHT22::~RoverDHT22(){}
+
+void rover::RoverDHT22::initialize(void)
+{
+	this->DHT22_SETUP_ = 1;
+}
+
+float rover::RoverDHT22::read(void)
+{
+	if (this->DHT22_SETUP_ != 1)
+	{
+		fprintf(stderr,"You havent set up RoverDHT22. Use RoverDHT22::initialize() !\n");
+	}
+	else
+	{
+		return this->readTemperature();
+	}
+}
+
+float rover::RoverDHT22::readTemperature (void)
+{
+	if (this->DHT22_SETUP_ != 1)
+	{
+		fprintf(stderr,"You havent set up RoverDHT22. Use RoverDHT22::initialize() !\n");
+	}
+	else
+	{
+		int data[5] = { 0, 0, 0, 0, 0 };
+
+		uint8_t laststate;
+		uint8_t counter;
+		uint8_t j;
+		uint8_t i;
+
+		int try_again = 1;
+		float f, h, c;
+
+		while (try_again == 1)
+		{
+			data[0] = data[1] = data[2] = data[3] = data[4] = 0;
+			laststate = HIGH;
+			counter = 0;
+			j = 0;
+
+			/* pull pin down for 18 milliseconds */
+			pinMode( this->DHT22Pin, OUTPUT );
+			digitalWrite( this->DHT22Pin, LOW );
+			delay( 18 );
+
+			/* prepare to read the pin */
+			pinMode( this->DHT22Pin, INPUT );
+
+			/* detect change and read data */
+			for ( i = 0; i < MAX_TIMINGS; i++ )
+			{
+				counter = 0;
+				while ( digitalRead( this->DHT22Pin ) == laststate )
+				{
+					counter++;
+					delayMicroseconds( 1 );
+					if ( counter == 255 )
+					{
+						break;
+					}
+				}
+				laststate = digitalRead( this->DHT22Pin );
+
+				if ( counter == 255 )
+					break;
+
+				/* ignore first 3 transitions */
+				if ( (i >= 4) && (i % 2 == 0) )
+				{
+					/* shove each bit into the storage bytes */
+					data[j / 8] <<= 1;
+					if ( counter > 16 )
+						data[j / 8] |= 1;
+					j++;
+				}
+			}
+
+			/*
+			 * check we read 40 bits (8bit x 5 ) + verify checksum in the last byte
+			 * print it out if data is good
+			 */
+			if ( (j >= 40) &&
+				 (data[4] == ( (data[0] + data[1] + data[2] + data[3]) & 0xFF) ) )
+			{
+				h = (float)((data[0] << 8) + data[1]) / 10;
+				if ( h > 100 )
+				{
+					h = data[0];	// for DHT11
+				}
+				c = (float)(((data[2] & 0x7F) << 8) + data[3]) / 10;
+				if ( c > 125 )
+				{
+					c = data[2];	// for DHT11
+				}
+				if ( data[2] & 0x80 )
+				{
+					c = -c;
+				}
+				f = c * 1.8f + 32;
+	#ifdef DEBUG
+				printf( "Humidity = %.1f %% Temperature = %.1f *C (%.1f *F)\n", h, c, f );
+	#endif
+				try_again = 0;
+			}
+			else
+			{
+				/* Data not good */
+				try_again = 1;
+				//printf ("Data not good, skipping\n");
+
+			}
+		}
+
+		/* Return temperature */
+		return c;
+	}
+}
+
+float rover::RoverDHT22::readHumidity (void)
+{
+	if (this->DHT22_SETUP_ != 1)
+	{
+		fprintf(stderr,"You havent set up RoverDHT22. Use RoverDHT22::initialize() !\n");
+	}
+	else
+	{
+		int data[5] = { 0, 0, 0, 0, 0 };
+
+		uint8_t laststate;
+		uint8_t counter;
+		uint8_t j;
+		uint8_t i;
+
+		int try_again = 1;
+		float f, h, c;
+
+		while (try_again == 1)
+		{
+			data[0] = data[1] = data[2] = data[3] = data[4] = 0;
+			laststate = HIGH;
+			counter = 0;
+			j = 0;
+
+			/* pull pin down for 18 milliseconds */
+			pinMode( this->DHT22Pin, OUTPUT );
+			digitalWrite( this->DHT22Pin, LOW );
+			delay( 18 );
+
+			/* prepare to read the pin */
+			pinMode( this->DHT22Pin, INPUT );
+
+			/* detect change and read data */
+			for ( i = 0; i < MAX_TIMINGS; i++ )
+			{
+				counter = 0;
+				while ( digitalRead( this->DHT22Pin ) == laststate )
+				{
+					counter++;
+					delayMicroseconds( 1 );
+					if ( counter == 255 )
+					{
+						break;
+					}
+				}
+				laststate = digitalRead( this->DHT22Pin );
+
+				if ( counter == 255 )
+					break;
+
+				/* ignore first 3 transitions */
+				if ( (i >= 4) && (i % 2 == 0) )
+				{
+					/* shove each bit into the storage bytes */
+					data[j / 8] <<= 1;
+					if ( counter > 16 )
+						data[j / 8] |= 1;
+					j++;
+				}
+			}
+
+			/*
+			 * check we read 40 bits (8bit x 5 ) + verify checksum in the last byte
+			 * print it out if data is good
+			 */
+			if ( (j >= 40) &&
+				 (data[4] == ( (data[0] + data[1] + data[2] + data[3]) & 0xFF) ) )
+			{
+				h = (float)((data[0] << 8) + data[1]) / 10;
+				if ( h > 100 )
+				{
+					h = data[0];	// for DHT11
+				}
+				c = (float)(((data[2] & 0x7F) << 8) + data[3]) / 10;
+				if ( c > 125 )
+				{
+					c = data[2];	// for DHT11
+				}
+				if ( data[2] & 0x80 )
+				{
+					c = -c;
+				}
+				f = c * 1.8f + 32;
+	#ifdef DEBUG
+				printf( "Humidity = %.1f %% Temperature = %.1f *C (%.1f *F)\n", h, c, f );
+	#endif
+				try_again = 0;
+			}
+			else
+			{
+				/* Data not good */
+				try_again = 1;
+				//printf ("Data not good, skipping\n");
+			}
+		}
+
+		/* Return humidity */
+		return h;
+	}
+}
+
+void rover::RoverDHT22::setDHT22Pin (const int pin)
+{
+	this->DHT22Pin = pin;
+}
+
+int rover::RoverDHT22::getDHT22Pin (void)
+{
+	return this->DHT22Pin;
+}
+
+
diff --git a/rover/src/roverapi/rover_gy521.cpp b/rover/src/roverapi/rover_gy521.cpp
new file mode 100644
index 0000000..98d516e
--- /dev/null
+++ b/rover/src/roverapi/rover_gy521.cpp
@@ -0,0 +1,191 @@
+/*
+ * Copyright (c) 2017 FH Dortmund and others
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Description:
+ *     RoverGY521 API - Interfaces for Rover GY521 accelerometer application development
+ *
+ * Contributors:
+ *    M.Ozcelikors <mozcelikors@gmail.com>, created RoverGY521 class 04.12.2017
+ *
+ * Disclaimer:
+ *    Adapted from https://github.com/OmarAflak/GY-521-Raspberry-Pi-C-/
+ */
+
+#include <roverapi/rover_gy521.hpp>
+#include <wiringPi.h>
+#include <wiringPiI2C.h>
+#include <cmath>
+#include <stdint.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#define MPU6050_GYRO_XOUT_H        0x43   // R
+#define MPU6050_GYRO_YOUT_H        0x45   // R
+#define MPU6050_GYRO_ZOUT_H        0x47   // R
+
+#define MPU6050_ACCEL_XOUT_H       0x3B   // R
+#define MPU6050_ACCEL_YOUT_H       0x3D   // R
+#define MPU6050_ACCEL_ZOUT_H       0x3F   // R
+
+#define MPU6050_PWR_MGMT_1         0x6B   // R/W
+#define MPU6050_I2C_ADDRESS        0x68   // I2C
+
+static int gy521_fd = -1;
+
+rover::RoverGY521::RoverGY521()
+:ROVERGY521_SETUP_(0),
+i2CAddress(MPU6050_I2C_ADDRESS)
+{
+
+}
+
+rover::RoverGY521::RoverGY521(const int custom_i2c_address)
+{
+	this->i2CAddress = custom_i2c_address;
+	this->ROVERGY521_SETUP_ = 0;
+}
+
+rover::RoverGY521::~RoverGY521(){}
+
+void rover::RoverGY521::initialize (void)
+{
+	gy521_fd = wiringPiI2CSetup (this->i2CAddress);
+	if (gy521_fd == -1)
+	{
+		fprintf (stderr, "Unable to initialize GY521 sensor!\n");
+	}
+
+	wiringPiI2CReadReg8 (gy521_fd, MPU6050_PWR_MGMT_1);
+	wiringPiI2CWriteReg16(gy521_fd, MPU6050_PWR_MGMT_1, 0);
+
+	this->ROVERGY521_SETUP_ = 1;
+}
+
+float rover::RoverGY521::read (void)
+{
+	return 1.0;
+}
+
+int8_t rover::RoverGY521::getGyroX()
+{
+	if (this->ROVERGY521_SETUP_ != 1)
+	{
+		fprintf(stderr,"You havent set up RoverGY521. Use RoverGY521::initialize() !\n");
+	}
+	else
+	{
+		return (int8_t) wiringPiI2CReadReg8(gy521_fd, MPU6050_GYRO_XOUT_H);
+	}
+}
+
+int8_t rover::RoverGY521::getGyroY()
+{
+	if (this->ROVERGY521_SETUP_ != 1)
+	{
+		fprintf(stderr,"You havent set up RoverGY521. Use RoverGY521::initialize() !\n");
+	}
+	else
+	{
+		return (int8_t) wiringPiI2CReadReg8(gy521_fd, MPU6050_GYRO_YOUT_H);
+	}
+}
+
+int8_t rover::RoverGY521::getGyroZ()
+{
+	if (this->ROVERGY521_SETUP_ != 1)
+	{
+		fprintf(stderr,"You havent set up RoverGY521. Use RoverGY521::initialize() !\n");
+	}
+	else
+	{
+		return (int8_t) wiringPiI2CReadReg8(gy521_fd, MPU6050_GYRO_ZOUT_H);
+	}
+}
+
+int8_t rover::RoverGY521::getAccelX()
+{
+	if (this->ROVERGY521_SETUP_ != 1)
+	{
+		fprintf(stderr,"You havent set up RoverGY521. Use RoverGY521::initialize() !\n");
+	}
+	else
+	{
+		return (int8_t) wiringPiI2CReadReg8(gy521_fd, MPU6050_ACCEL_XOUT_H);
+	}
+}
+
+int8_t rover::RoverGY521::getAccelY()
+{
+	if (this->ROVERGY521_SETUP_ != 1)
+	{
+		fprintf(stderr,"You havent set up RoverGY521. Use RoverGY521::initialize() !\n");
+	}
+	else
+	{
+		return (int8_t) wiringPiI2CReadReg8(gy521_fd, MPU6050_ACCEL_YOUT_H);
+	}
+}
+
+int8_t rover::RoverGY521::getAccelZ()
+{
+	if (this->ROVERGY521_SETUP_ != 1)
+	{
+		fprintf(stderr,"You havent set up RoverGY521. Use RoverGY521::initialize() !\n");
+	}
+	else
+	{
+		return (int8_t) wiringPiI2CReadReg8(gy521_fd, MPU6050_ACCEL_ZOUT_H);
+	}
+}
+
+float rover::RoverGY521::getAngleX()
+{
+	if (this->ROVERGY521_SETUP_ != 1)
+	{
+		fprintf(stderr,"You havent set up RoverGY521. Use RoverGY521::initialize() !\n");
+	}
+	else
+	{
+		int x = getAccelX();
+		int y = getAccelY();
+		int z = getAccelZ();
+		float ax = atan(x/(sqrt(y*y+z*z)))* 180/M_PI;
+		return ax;
+	}
+}
+
+float rover::RoverGY521::getAngleY()
+{
+	if (this->ROVERGY521_SETUP_ != 1)
+	{
+		fprintf(stderr,"You havent set up RoverGY521. Use RoverGY521::initialize() !\n");
+	}
+	else
+	{
+		int x = getAccelX();
+		int y = getAccelY();
+		int z = getAccelZ();
+		float ay = atan(y/(sqrt(x*x+z*z)))* 180/M_PI;
+		return ay;
+	}
+}
+
+float rover::RoverGY521::getAngleZ()
+{
+	if (this->ROVERGY521_SETUP_ != 1)
+	{
+		fprintf(stderr,"You havent set up RoverGY521. Use RoverGY521::initialize() !\n");
+	}
+	else
+	{
+		int x = getAccelX();
+		int y = getAccelY();
+		int z = getAccelZ();
+		float az = atan((sqrt(y*y+x*x))/z)* 180/M_PI;
+		return az;
+	}
+}
diff --git a/rover/src/roverapi/rover_infraredsensor.cpp b/rover/src/roverapi/rover_infraredsensor.cpp
new file mode 100644
index 0000000..cbddeed
--- /dev/null
+++ b/rover/src/roverapi/rover_infraredsensor.cpp
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2017 FH Dortmund and others
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Description:
+ *     RoverInfraredSensor API - Interfaces for Rover infrared sensor application development
+ *
+ * Contributors:
+ *    M.Ozcelikors <mozcelikors@gmail.com>, created RoverInfraredSensor class 04.12.2017
+ *    Gael Blondelle, Eclipse Foundation, initial C-API and parameters
+ */
+
+#include <roverapi/rover_infraredsensor.hpp>
+#include <roverapi/basic_psys_rover.h>
+#include <mcp3004.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <unistd.h>
+
+rover::RoverInfraredSensor::RoverInfraredSensor (const RoverSensorID_t sensor_id)
+:ROVERINFRAREDSENSOR_SETUP_(0)
+{
+	if (sensor_id != ROVER_FRONT_LEFT &&
+		sensor_id != ROVER_FRONT_RIGHT &&
+		sensor_id != ROVER_REAR_LEFT &&
+		sensor_id != ROVER_REAR_RIGHT)
+	{
+		printf ("Invalid Sensor ID for the Infrared Sensor to constructor RoverInfraredSensor::RoverInfraredSensor().\n");
+		this->sensorID = ROVER_FRONT_LEFT;
+	}
+	else
+	{
+		this->sensorID = sensor_id;
+	}
+}
+
+rover::RoverInfraredSensor::~RoverInfraredSensor(){}
+
+void rover::RoverInfraredSensor::initialize (void)
+{
+	/* mcp3004Setup can only be called once per program, One solution: */
+	static class Once2 { public: Once2(){
+		/* Init the analog digital converter */
+		mcp3004Setup (BASE, SPI_CHAN); // 3004 and 3008 are the same 4/8 channels
+	}} Once2_;
+
+	this->ROVERINFRAREDSENSOR_SETUP_ = 1;
+}
+
+float rover::RoverInfraredSensor::read (void)
+{
+	if (this->ROVERINFRAREDSENSOR_SETUP_ != 1)
+	{
+		fprintf(stderr,"You havent set up RoverInraredSensor. Use RoverInfraredSensor()::initialize() !\n");
+	}
+	else
+	{
+		float x;
+		float y = analogRead (BASE+this->sensorID);
+
+		// 1/cm to output voltage is almost linear between
+		// 80cm->0,4V->123
+		// 6cm->3,1V->961
+		// => y=5477*x+55 => x= (y-55)/5477
+		if (y<123){
+			x=100.00;
+		} else {
+			float inverse = (y-55)/5477;
+			//printf("inverse=%f\n",inverse);
+		// x is the distance in cm
+			x = 1/inverse;
+		}
+
+		return x;
+	}
+}
+
+