algoritmo logica difusa sensores navegacion

Dependencies:   GPS MODI2C SRF05 mbed HMC5883

Files at this revision

API Documentation at this revision

Comitter:
arturocontreras
Date:
Sat Jul 19 05:35:58 2014 +0000
Commit message:
logica difusa

Changed in this revision

BMP085/BMP085_old.cpp Show annotated file Show diff for this revision Revisions of this file
BMP085/BMP085_old.h Show annotated file Show diff for this revision Revisions of this file
GPS.lib Show annotated file Show diff for this revision Revisions of this file
MODI2C.lib Show annotated file Show diff for this revision Revisions of this file
SRF05.lib Show annotated file Show diff for this revision Revisions of this file
Sensors/Acc/ADXL345.cpp Show annotated file Show diff for this revision Revisions of this file
Sensors/Acc/ADXL345.h Show annotated file Show diff for this revision Revisions of this file
Sensors/Alt/BMP085.cpp Show annotated file Show diff for this revision Revisions of this file
Sensors/Alt/BMP085.h Show annotated file Show diff for this revision Revisions of this file
Sensors/Gyro/L3G4200D.cpp Show annotated file Show diff for this revision Revisions of this file
Sensors/Gyro/L3G4200D.h Show annotated file Show diff for this revision Revisions of this file
Sensors/HMC5883.lib Show annotated file Show diff for this revision Revisions of this file
Sensors/I2C_Sensor.cpp Show annotated file Show diff for this revision Revisions of this file
Sensors/I2C_Sensor.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/BMP085/BMP085_old.cpp	Sat Jul 19 05:35:58 2014 +0000
@@ -0,0 +1,150 @@
+
+#include "mbed.h"
+#include "BMP085_old.h"
+
+//I2C Adresse
+#define BMP085_ADRESS 0xEE
+
+#define xpow(x, y) ((long)1 << y)
+
+
+// Constructor
+// -----------------------------------------------
+BMP085_old::BMP085_old(PinName sda, PinName scl) : i2c_(sda, scl)
+    {
+    Init();
+    // MYINIT -------
+    oss = 0; //Oversampling des Barometers setzen
+    // MYINIT -------
+    }
+    
+
+// Temperatur und Druck auslesen und berechnen
+// -----------------------------------------------
+void BMP085_old::Update () 
+    {
+    long P, UTemp, UPressure, X1, X2, X3, B3, B5, B6;
+    unsigned long B4, B7;
+
+    twi_writechar(BMP085_ADRESS, 0xf4, 0x2e);
+    // Wait at least 4.5ms
+    wait(0.005);
+    UTemp = twi_readshort(BMP085_ADRESS, 0xf6);
+    
+    X1 = ((UTemp - AC6) * AC5) >> 15;
+    X2 = (MC << 11) / (X1 + MD);
+    B5 = X1 + X2;
+    Temperature = (float)((B5 + 8) >> 4)/10.0;
+
+    twi_writechar(BMP085_ADRESS, 0xf4, 0x34 + (oss << 6));
+    // Wait at least 4.5ms
+    wait(0.005);
+    UPressure = twi_readlong(BMP085_ADRESS, 0xf6) >> (8 - oss);
+
+    B6 = B5 - 4000;
+    X1 = (B2 * (B6 * B6) >> 12) >> 11;
+    X2 = (AC2 * B6) >> 11;
+    X3 = X1 + X2;
+    B3 = ((AC1 * 4 + X3) << oss) >> 2;    
+
+    X1 = (AC3 * B6) >> 13;
+    X2 = (B1 * (B6 * B6) >> 12) >> 16;
+    X3 = ((X1 + X2) + 2) >> 2;
+    B4 = AC4 * (X3 + 32768) >> 15;
+    
+    B7 = (unsigned long)(UPressure - B3) * (50000 >> oss);
+    
+    if (B7 < 0x80000000) 
+        {
+        P = (2 * B7) / B4;
+        }
+    else 
+        {
+        P = 2* (B7 / B4);
+        }
+    X1 = (P >> 8) * (P >> 8);
+    X1 = (X1 * 3038) >> 16;
+    X2 = (-7357 * P) >> 16;    
+    P = P + ((X1 + X2 + 3791) >> 4);
+    Pressure = (float)P / 100.0;
+    }
+
+
+// Hoehe u.M. berechnen  (Druck in hPa)
+// -----------------------------------------------
+float BMP085_old::CalcAltitude(float Press)
+    {
+    float A = Press/1013.25;
+    float B = 1/5.25588;
+    float C = pow(A,B);
+    
+    C = 1 - C;
+    C = C / 22.5577e-6;
+    return C;
+    }
+    
+        
+// Drucksensor initialisieren  
+// -----------------------------------------------
+void BMP085_old::Init () 
+    {
+    AC1 = twi_readshort(BMP085_ADRESS, 0xaa);
+    AC2 = twi_readshort(BMP085_ADRESS, 0xac);
+    AC3 = twi_readshort(BMP085_ADRESS, 0xae);
+    AC4 = twi_readshort(BMP085_ADRESS, 0xb0);
+    AC5 = twi_readshort(BMP085_ADRESS, 0xb2);
+    AC6 = twi_readshort(BMP085_ADRESS, 0xb4);
+    B1 = twi_readshort(BMP085_ADRESS, 0xb6);
+    B2 = twi_readshort(BMP085_ADRESS, 0xb8);
+    MB = twi_readshort(BMP085_ADRESS, 0xba);
+    MC = twi_readshort(BMP085_ADRESS, 0xbc);
+    MD = twi_readshort(BMP085_ADRESS, 0xbe);
+    }
+    
+    
+// -----------------------------------------------
+unsigned short BMP085_old::twi_readshort (int id, int addr) {
+    unsigned short i;
+
+    i2c_.start();
+    i2c_.write(id);
+    i2c_.write(addr);
+
+    i2c_.start();
+    i2c_.write(id | 1);
+    i = i2c_.read(1) << 8;
+    i |= i2c_.read(0);
+    i2c_.stop();
+
+    return i;
+}
+
+
+// -----------------------------------------------
+unsigned long BMP085_old::twi_readlong (int id, int addr) {
+    unsigned long i;
+
+    i2c_.start();
+    i2c_.write(id);
+    i2c_.write(addr);
+
+    i2c_.start();
+    i2c_.write(id | 1);
+    i = i2c_.read(1) << 16;
+    i |= i2c_.read(1) << 8;
+    i |= i2c_.read(0);
+    i2c_.stop();
+
+    return i;
+}
+
+
+// -----------------------------------------------
+void BMP085_old::twi_writechar (int id, int addr, int dat) {
+
+    i2c_.start();
+    i2c_.write(id);
+    i2c_.write(addr);
+    i2c_.write(dat);
+    i2c_.stop();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/BMP085/BMP085_old.h	Sat Jul 19 05:35:58 2014 +0000
@@ -0,0 +1,34 @@
+ 
+#ifndef BMP085_I2C_H
+#define BMP085_I2C_H
+
+#include "mbed.h"
+
+class BMP085_old
+    {
+    private:
+        I2C i2c_;
+        
+    public:
+        BMP085_old(PinName sda, PinName scl);
+    
+        void    Update();
+        float   Temperature;
+        float   Pressure;
+        float   CalcAltitude(float Press);
+        short   oss;
+    
+    protected:
+        void Init();
+        unsigned short twi_readshort (int, int);
+        unsigned long twi_readlong (int, int);
+        void twi_writechar (int, int, int);
+    
+    
+    private:
+    
+        short AC1, AC2, AC3, B1, B2, MB, MC, MD;
+        unsigned short AC4, AC5, AC6;
+    };
+
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/GPS.lib	Sat Jul 19 05:35:58 2014 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/simon/code/GPS/#15611c7938a3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MODI2C.lib	Sat Jul 19 05:35:58 2014 +0000
@@ -0,0 +1,1 @@
+https://mbed.org/users/Sissors/code/MODI2C/#ff579e7e8efa
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SRF05.lib	Sat Jul 19 05:35:58 2014 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/simon/code/SRF05/#e758665e072c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Sensors/Acc/ADXL345.cpp	Sat Jul 19 05:35:58 2014 +0000
@@ -0,0 +1,44 @@
+#include "ADXL345.h"
+
+ADXL345::ADXL345(PinName sda, PinName scl) : I2C_Sensor(sda, scl, ADXL345_I2C_ADDRESS)
+{
+    // Set Offset  - programmed into the OFSX, OFSY, and OFXZ registers, respectively, as 0xFD, 0x03 and 0xFE.
+    writeRegister(ADXL345_OFSX_REG, 0xFA); // to get these offsets just lie your sensor down on the table always the axis pointing down to earth has 200+ and the others should have more or less 0
+    writeRegister(ADXL345_OFSY_REG, 0xFE);
+    writeRegister(ADXL345_OFSZ_REG, 0x0A);
+ 
+    writeRegister(ADXL345_BW_RATE_REG, 0x0F); // 3200Hz BW-Rate
+    writeRegister(ADXL345_DATA_FORMAT_REG, 0x0B); // set data format to full resolution and +-16g
+    writeRegister(ADXL345_POWER_CTL_REG, 0x08); // set mode
+}
+
+void ADXL345::read(){
+    readraw();
+    for (int i = 0; i < 3; i++)
+        data[i] = raw[i] - offset[i]; // TODO: didnt care about units 
+}
+
+void ADXL345::readraw(){
+    char buffer[6];    
+    readMultiRegister(ADXL345_DATAX0_REG, buffer, 6);
+    
+    raw[0] = (short) ((int)buffer[1] << 8 | (int)buffer[0]);
+    raw[1] = (short) ((int)buffer[3] << 8 | (int)buffer[2]);
+    raw[2] = (short) ((int)buffer[5] << 8 | (int)buffer[4]);
+}
+
+void ADXL345::calibrate(int times, float separation_time)
+{
+    // calibrate sensor with an average of count samples (result of calibration stored in offset[])
+    float calib[3] = {0,0,0};                           // temporary array for the sum of calibration measurement
+    
+    for (int i = 0; i < times; i++) {                   // read 'times' times the data in a very short time
+        readraw();
+        for (int j = 0; j < 3; j++)
+            calib[j] += raw[j];
+        wait(separation_time);
+    }
+    
+    for (int i = 0; i < 2; i++)
+        offset[i] = calib[i]/times;                     // take the average of the calibration measurements
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Sensors/Acc/ADXL345.h	Sat Jul 19 05:35:58 2014 +0000
@@ -0,0 +1,65 @@
+// based on http://mbed.org/users/Digixx/code/ADXL345/
+
+#ifndef ADXL345_H
+#define ADXL345_H
+
+#include "mbed.h"
+#include "I2C_Sensor.h"
+
+#define ADXL345_I2C_ADDRESS    0xA6
+//the ADXL345 7-bit address is 0x53 when ALT ADDRESS is low as it is on the sparkfun chip: when ALT ADDRESS is high the address is 0x1D
+//when ALT ADDRESS pin is high:  
+//#define ADXL345_I2C_ADDRESS    0x3A 
+
+// register addresses
+#define ADXL345_DEVID_REG          0x00
+#define ADXL345_THRESH_TAP_REG     0x1D
+#define ADXL345_OFSX_REG           0x1E
+#define ADXL345_OFSY_REG           0x1F
+#define ADXL345_OFSZ_REG           0x20
+#define ADXL345_DUR_REG            0x21
+#define ADXL345_LATENT_REG         0x22
+#define ADXL345_WINDOW_REG         0x23
+#define ADXL345_THRESH_ACT_REG     0x24
+#define ADXL345_THRESH_INACT_REG   0x25
+#define ADXL345_TIME_INACT_REG     0x26
+#define ADXL345_ACT_INACT_CTL_REG  0x27
+#define ADXL345_THRESH_FF_REG      0x28
+#define ADXL345_TIME_FF_REG        0x29
+#define ADXL345_TAP_AXES_REG       0x2A
+#define ADXL345_ACT_TAP_STATUS_REG 0x2B
+#define ADXL345_BW_RATE_REG        0x2C
+#define ADXL345_POWER_CTL_REG      0x2D
+#define ADXL345_INT_ENABLE_REG     0x2E
+#define ADXL345_INT_MAP_REG        0x2F
+#define ADXL345_INT_SOURCE_REG     0x30
+#define ADXL345_DATA_FORMAT_REG    0x31
+#define ADXL345_DATAX0_REG         0x32
+#define ADXL345_DATAX1_REG         0x33
+#define ADXL345_DATAY0_REG         0x34
+#define ADXL345_DATAY1_REG         0x35
+#define ADXL345_DATAZ0_REG         0x36
+#define ADXL345_DATAZ1_REG         0x37
+#define ADXL345_FIFO_CTL           0x38
+#define ADXL345_FIFO_STATUS        0x39
+
+#define ADXL345_X           0x00
+#define ADXL345_Y           0x01
+#define ADXL345_Z           0x02
+
+typedef char byte;
+
+class ADXL345 : public I2C_Sensor
+{
+    public:
+        ADXL345(PinName sda, PinName scl);                  // constructor, uses I2C_Sensor class
+        virtual void read();                                // read all axis to array
+        
+        float offset[3];                                    // offset that's subtracted from every measurement
+        void calibrate(int times, float separation_time);   // calibration from 'times' measurements with 'separation_time' time between (get an offset while not moving)
+       
+    private:
+        virtual void readraw();
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Sensors/Alt/BMP085.cpp	Sat Jul 19 05:35:58 2014 +0000
@@ -0,0 +1,57 @@
+#include "BMP085.h"
+
+BMP085::BMP085(PinName sda, PinName scl) : I2C_Sensor(sda, scl, BMP085_I2C_ADDRESS)
+{
+    // initialize BMP085 with settings
+    //writeRegister(0xf4, 0x2e); // TODO: was macht das + register in header!
+    
+}
+
+/*void BMP085::read() 
+    {
+    long P, UTemp, UPressure, X1, X2, X3, B3, B5, B6;
+    unsigned long B4, B7;
+
+    // TODO: writeRegister(0xf4, 0x2e); ?!!!
+    twi_writechar(BMP085_ADRESS, 0xf4, 0x2e);
+    // Wait at least 4.5ms
+    wait(0.005);
+    UTemp = twi_readshort(BMP085_ADRESS, 0xf6);
+    
+    X1 = ((UTemp - AC6) * AC5) >> 15;
+    X2 = (MC << 11) / (X1 + MD);
+    B5 = X1 + X2;
+    Temperature = (float)((B5 + 8) >> 4)/10.0;
+
+    twi_writechar(BMP085_ADRESS, 0xf4, 0x34 + (oss << 6));
+    // Wait at least 4.5ms
+    wait(0.005);
+    UPressure = twi_readlong(BMP085_ADRESS, 0xf6) >> (8 - oss);
+
+    B6 = B5 - 4000;
+    X1 = (B2 * (B6 * B6) >> 12) >> 11;
+    X2 = (AC2 * B6) >> 11;
+    X3 = X1 + X2;
+    B3 = ((AC1 * 4 + X3) << oss) >> 2;    
+
+    X1 = (AC3 * B6) >> 13;
+    X2 = (B1 * (B6 * B6) >> 12) >> 16;
+    X3 = ((X1 + X2) + 2) >> 2;
+    B4 = AC4 * (X3 + 32768) >> 15;
+    
+    B7 = (unsigned long)(UPressure - B3) * (50000 >> oss);
+    
+    if (B7 < 0x80000000) 
+        {
+        P = (2 * B7) / B4;
+        }
+    else 
+        {
+        P = 2* (B7 / B4);
+        }
+    X1 = (P >> 8) * (P >> 8);
+    X1 = (X1 * 3038) >> 16;
+    X2 = (-7357 * P) >> 16;    
+    P = P + ((X1 + X2 + 3791) >> 4);
+    Pressure = (float)P / 100.0;
+    }*/
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Sensors/Alt/BMP085.h	Sat Jul 19 05:35:58 2014 +0000
@@ -0,0 +1,34 @@
+// based on http://mbed.org/users/okini3939/code/BMP085/
+
+#ifndef BMP085_H
+#define BMP085_H
+
+#include "mbed.h"
+#include "I2C_Sensor.h"
+
+#define BMP085_I2C_ADDRESS 0xEE
+
+class BMP085 : public I2C_Sensor
+{           
+    public:
+        BMP085(PinName sda, PinName scl);
+        
+        //virtual void read();
+        
+        void calibrate(int s);
+        
+        float get_height();
+         
+    private:
+        // raw data and function to measure it
+        int raw[3];
+        //void readraw();
+        
+        // calibration parameters and their saving
+        int Min[3];
+        int Max[3];
+        float scale[3];
+        float offset[3];
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Sensors/Gyro/L3G4200D.cpp	Sat Jul 19 05:35:58 2014 +0000
@@ -0,0 +1,71 @@
+#include "L3G4200D.h"
+
+L3G4200D::L3G4200D(PinName sda, PinName scl) : I2C_Sensor(sda, scl, L3G4200D_I2C_ADDRESS)
+{
+    // Turns on the L3G4200D's gyro and places it in normal mode.
+    // Normal power mode, all axes enabled (for detailed info see datasheet)
+    
+    //writeRegister(L3G4200D_CTRL_REG2, 0x05);               // control filter
+    writeRegister(L3G4200D_CTRL_REG2, 0x00);            // highpass filter disabled
+    writeRegister(L3G4200D_CTRL_REG3, 0x00);
+    writeRegister(L3G4200D_CTRL_REG4, 0x20);            // sets acuracy to 2000 dps (degree per second)
+    
+    writeRegister(L3G4200D_REFERENCE, 0x00);
+    //writeRegister(L3G4200D_STATUS_REG, 0x0F);
+    
+    writeRegister(L3G4200D_INT1_THS_XH, 0x2C); // TODO: WTF??
+    writeRegister(L3G4200D_INT1_THS_XL, 0xA4);
+    writeRegister(L3G4200D_INT1_THS_YH, 0x2C);
+    writeRegister(L3G4200D_INT1_THS_YL, 0xA4);
+    writeRegister(L3G4200D_INT1_THS_ZH, 0x2C);
+    writeRegister(L3G4200D_INT1_THS_ZL, 0xA4);
+    //writeRegister(L3G4200D_INT1_DURATION, 0x00);
+    
+    writeRegister(L3G4200D_CTRL_REG5, 0x00);            // deactivates the filters (only use one of these options)
+    //writeRegister(L3G4200D_CTRL_REG5, 0x12);          // activates both high and low pass filters
+    //writeRegister(L3G4200D_CTRL_REG5, 0x01);          // activates high pass filter
+    
+    writeRegister(L3G4200D_CTRL_REG1, 0x0F);            // starts Gyro measurement
+    
+    //calibrate(50, 0.01);
+}
+
+void L3G4200D::read()
+{
+    readraw();                                          // read raw measurement data
+    
+    for (int i = 0; i < 3; i++)
+            data[i] = (raw[i] - offset[i])*0.07;               // subtract offset from calibration and multiply unit factor (datasheet s.10)
+}
+
+int L3G4200D::readTemp()
+{
+    return (short) readRegister(L3G4200D_OUT_TEMP);     // read the sensors register for the temperature
+}
+
+void L3G4200D::readraw()
+{
+    char buffer[6];                                     // 8-Bit pieces of axis data
+    
+    readMultiRegister(L3G4200D_OUT_X_L | (1 << 7), buffer, 6); // read axis registers using I2C   // TODO: why?!   | (1 << 7)
+    
+    raw[0] = (short) (buffer[1] << 8 | buffer[0]);     // join 8-Bit pieces to 16-bit short integers
+    raw[1] = (short) (buffer[3] << 8 | buffer[2]);
+    raw[2] = (short) (buffer[5] << 8 | buffer[4]);
+}
+
+void L3G4200D::calibrate(int times, float separation_time)
+{
+    // calibrate sensor with an average of count samples (result of calibration stored in offset[])
+    float calib[3] = {0,0,0};                           // temporary array for the sum of calibration measurement
+    
+    for (int i = 0; i < times; i++) {                   // read 'times' times the data in a very short time
+        readraw();
+        for (int j = 0; j < 3; j++)
+            calib[j] += raw[j];
+        wait(separation_time);
+    }
+    
+    for (int i = 0; i < 3; i++)
+        offset[i] = calib[i]/times;                     // take the average of the calibration measurements
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Sensors/Gyro/L3G4200D.h	Sat Jul 19 05:35:58 2014 +0000
@@ -0,0 +1,56 @@
+// based on http://mbed.org/users/shimniok/code/L3G4200D/
+
+#ifndef L3G4200D_H
+#define L3G4200D_H
+
+#include "mbed.h"
+#include "I2C_Sensor.h"
+
+#define L3G4200D_I2C_ADDRESS    0xD0
+
+// register addresses
+#define L3G4200D_WHO_AM_I       0x0F
+
+#define L3G4200D_CTRL_REG1      0x20
+#define L3G4200D_CTRL_REG2      0x21
+#define L3G4200D_CTRL_REG3      0x22
+#define L3G4200D_CTRL_REG4      0x23
+#define L3G4200D_CTRL_REG5      0x24
+#define L3G4200D_REFERENCE      0x25
+#define L3G4200D_OUT_TEMP       0x26
+#define L3G4200D_STATUS_REG     0x27
+
+#define L3G4200D_OUT_X_L        0x28
+#define L3G4200D_OUT_X_H        0x29
+#define L3G4200D_OUT_Y_L        0x2A
+#define L3G4200D_OUT_Y_H        0x2B
+#define L3G4200D_OUT_Z_L        0x2C
+#define L3G4200D_OUT_Z_H        0x2D
+
+#define L3G4200D_FIFO_CTRL_REG  0x2E
+#define L3G4200D_FIFO_SRC_REG   0x2F
+
+#define L3G4200D_INT1_CFG       0x30
+#define L3G4200D_INT1_SRC       0x31
+#define L3G4200D_INT1_THS_XH    0x32
+#define L3G4200D_INT1_THS_XL    0x33
+#define L3G4200D_INT1_THS_YH    0x34
+#define L3G4200D_INT1_THS_YL    0x35
+#define L3G4200D_INT1_THS_ZH    0x36
+#define L3G4200D_INT1_THS_ZL    0x37
+#define L3G4200D_INT1_DURATION  0x38
+
+class L3G4200D : public I2C_Sensor
+{
+    public:            
+        L3G4200D(PinName sda, PinName scl);                 // constructor, uses I2C_Sensor class
+        virtual void read();                                // read all axis from register to array data
+        float offset[3];                                    // offset that's subtracted from every measurement
+        void calibrate(int times, float separation_time);   // calibration from 'times' measurements with 'separation_time' time between (get an offset while not moving)
+        int readTemp();                                     // read temperature from sensor
+        
+    private:
+        virtual void readraw();
+};
+
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Sensors/HMC5883.lib	Sat Jul 19 05:35:58 2014 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/caroe/code/HMC5883/#a5e06bb74915
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Sensors/I2C_Sensor.cpp	Sat Jul 19 05:35:58 2014 +0000
@@ -0,0 +1,56 @@
+#include "I2C_Sensor.h"
+
+// calculate the 8-Bit write/read I2C-Address from the 7-Bit adress of the device
+#define GET_I2C_WRITE_ADDRESS(ADR)  (ADR << 1&0xFE) // ADR & 1111 1110
+#define GET_I2C_READ_ADDRESS(ADR)   (ADR << 1|0x01) // ADR | 0000 0001
+
+I2C_Sensor::I2C_Sensor(PinName sda, PinName scl, char i2c_address) : i2c_init(sda, scl), i2c(sda, scl), local("local")
+{
+    I2C_Sensor::i2c_address = i2c_address;
+    i2c_init.frequency(400000); // standard speed
+    i2c.frequency(400000); // standard speed
+    //i2c.frequency(1500000); // ultrafast!
+}
+
+void I2C_Sensor::saveCalibrationValues(float values[], int size, char * filename)
+{
+    FILE *fp = fopen(strcat("/local/", filename), "w");
+    for(int i = 0; i < size; i++)
+        fprintf(fp, "%f\r\n", values[i]);
+    fclose(fp);
+}
+
+void I2C_Sensor::loadCalibrationValues(float values[], int size, char * filename)
+{
+    FILE *fp = fopen(strcat("/local/", filename), "r");
+    for(int i = 0; i < size; i++)
+        fscanf(fp, "%f", &values[i]);
+    fclose(fp);
+}
+
+//--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+// ATTENTION!!! there was a problem with other interrupts disturbing the i2c communication of the chip... that's why I use I2C to initialise the sonsors and MODI2C to get the data (only made with readMultiRegister)
+// IT DIDN'T WORK STABLE IN OTHER COMBINATIONS (if someone has an idea why please let me know)
+//--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+
+char I2C_Sensor::readRegister(char reg)
+{
+    char value = 0;
+    
+    i2c_init.write(i2c_address, &reg, 1);
+    i2c_init.read(i2c_address, &value, 1);
+
+    return value;
+}
+
+void I2C_Sensor::writeRegister(char reg, char data)
+{
+    char buffer[2] = {reg, data};
+    i2c_init.write(i2c_address, buffer, 2);
+}
+
+void I2C_Sensor::readMultiRegister(char reg, char* output, int size)
+{
+    i2c.write (i2c_address, &reg, 1); // tell register address of the MSB get the sensor to do slave-transmit subaddress updating.
+    i2c.read  (i2c_address, output, size); // tell it where to store the data read
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Sensors/I2C_Sensor.h	Sat Jul 19 05:35:58 2014 +0000
@@ -0,0 +1,40 @@
+// by MaEtUgR
+
+#ifndef I2C_Sensor_H
+#define I2C_Sensor_H
+
+#include "mbed.h"
+#include "MODI2C.h"
+
+class I2C_Sensor
+{           
+    public:
+        I2C_Sensor(PinName sda, PinName scl, char address);
+        
+        float data[3];                  // where the measured data is saved
+        virtual void read() = 0;        // read all axis from register to array data
+        //TODO: virtual void calibrate() = 0;   // calibrate the sensor and if desired write calibration values to a file
+        
+    protected:
+        // Calibration
+        void saveCalibrationValues(float values[], int size, char * filename);
+        void loadCalibrationValues(float values[], int size, char * filename);
+    
+        // I2C functions
+        char readRegister(char reg);
+        void writeRegister(char reg, char data);
+        void readMultiRegister(char reg, char* output, int size);
+        
+        // raw data and function to measure it
+        int raw[3];
+        virtual void readraw() = 0;
+        
+    private:
+        I2C i2c_init;       // original mbed I2C-library just to initialise the control registers
+        MODI2C i2c;         // I2C-Bus
+        char i2c_address;   // address
+        
+        LocalFileSystem local; // file access to save calibration values
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Sat Jul 19 05:35:58 2014 +0000
@@ -0,0 +1,364 @@
+#include "mbed.h"       // Standard Library
+#include "HMC5883.h"    // Comp (Compass)
+#include "GPS.h"
+#include "SRF05.h"
+
+#define PI             3.1415926535897932384626433832795
+DigitalOut myled(LED1);
+I2C I2CBus(p9, p10);
+Timer GlobalTime;
+
+SRF05 Ult1(p5, p6);
+SRF05 Ult2(p7, p8);
+SRF05 Ult3(p11, p12);
+SRF05 Ult4(p16, p15);
+
+Serial pc(USBTX, USBRX);
+HMC5883     Mag(I2CBus, GlobalTime);
+GPS gps(p13, p14);
+
+float longitud,latitud,ul1,ul2,ul3,ul4;
+int orientacion;
+
+
+void GPfuzzy(float P[],int n,float v,float GP[],int mf[]);         
+float min(float a,float b);
+float Sugeno(int v1,int v2,float P[],int n);
+float Centroide(int v1,int v2,float P[],int n);
+void GPIfuzzy(float P[],int n,int gx,float GP,float x[]);
+void EntradaU(float F[],float O[],int ultrasonico,float tetha,float entrada[],float gp[],int mf[]);
+int  reglas(int mf[],int mfrueda[],float gpin[],float gprueda[]);
+void desfuzzy(float Pm[],int n,int mfrueda[],float gprueda[],int size,float dutty[]);
+
+
+int HMC5883_getAngle(float x, float y)
+{
+float heading = atan2((float)y,(float)x); 
+// Your mrad result / 1000.00 (to turn it into radians).
+  float declinationAngle = 21.18  / 1000.0;
+  // If you have an EAST declination, use += declinationAngle, if you have a WEST declination, use -= declinationAngle
+  heading += declinationAngle;  
+if(heading < 0)  heading += 2*PI;// Correct for when signs are reversed.
+if(heading > 2*PI)   heading -= 2*PI; // Check for wrap due to addition of declination.
+return(heading * 180/PI); // Convert radians to degrees for readability.
+}
+
+int main() { // main programm for initialisation and debug output
+      // pc.baud(9600);
+  
+    I2CBus.frequency(400000);
+    GlobalTime.start();
+
+    Mag.Init();
+    #if 1
+        Mag.AutoCalibration= 1;                     //In Echtzeit kalibrieren
+    #else
+        short MagRawMin[3]= {-400, -400, -400};     //Gespeicherte Werte
+        short MagRawMax[3]= {400, 400, 400};
+        Mag.Calibrate(MagRawMin, MagRawMax);
+    #endif
+    
+   int size,n=5,ultrasonico=3,mfs[4],mfrueda[4];
+   float dutty[2],entrada[2],tetha,gradosp[4],gprueda[4];
+   float Pm[5]={0,25,50,75,100};//RANGO DE DUTTY PARA MOTORES (p.e. de 0 a 100)
+    
+    while(1) { 
+    
+    Mag.Update();
+       
+    printf("grader = %i \n",HMC5883_getAngle(Mag.Mag[0],Mag.Mag[1])); 
+    wait_ms(20);
+    
+ 
+    if(gps.sample()) {
+    myled = 1;//indica si el GPS esta enviando valores buenos
+    latitud=gps.latitude;
+    longitud=gps.longitude;
+    } 
+    
+
+    orientacion=HMC5883_getAngle(Mag.Mag[0],Mag.Mag[1]);
+    
+  //  beta=atan((F[0]-O[0])/(F[1]-O[1]))*57.29582790879777;
+    
+
+   
+//CONFIGURACION DE ENTRADAS A LA LOGICA FUZZY********************************************
+   
+   float O[]={0,0};//POSICION INICIAL SEGUN GPS, EN EL PLANO
+   float F[]={3,4};//OBJETIVO O POSICION FINAL
+   tetha=orientacion;//en sexagesimales, ang de la brujula medido desde el eje NORTE sentido horario(positivo)
+   ultrasonico=1;
+//fin de CONFIG DE ENTRADAS******************************************************
+
+ 
+    EntradaU(F,O,ultrasonico,tetha,entrada,gradosp,mfs);//hace la fuzzyfication
+
+   size=reglas(mfs,mfrueda,gradosp,gprueda);//esta funcion bota los vectores mfrueda y sus gprueda
+
+    desfuzzy(Pm,n,mfrueda,gprueda,size,dutty);
+    printf("\fdutty1 %f \ndutty2 %f",dutty[0],dutty[1]);
+    //wait_ms(100);
+    
+    
+    }
+}
+//*****************DESARROLLO DE FUNCIONES**************************
+void GPfuzzy(float P[],int n,float v,float GP[],int mf[]){//v==> valor eje x
+    int i;
+    for( i=0;i<n;i++){//
+        if(P[i]<=v && v<=P[i+1]){
+            GP[0]=1.0-(v-P[i])*1.3333/(P[i+1]-P[i]);
+            GP[1]=1.0+1.33333*(v-P[i+1])/(P[i+1]-P[i]);
+            if(GP[1]<0){GP[1]=0;}
+            if(GP[0]<0){GP[0]=0;}
+            mf[0]=i+1;
+            mf[1]=i+2;
+            break;
+        }
+    }
+}
+float min(float a,float b){
+    if(a<=b)return a;
+    else return b;
+}
+float max(float a,float b){
+    if(a>=b)return a;
+    else return b;
+}
+float Sugeno(int v1,int v2,float P[],int n){//bota el centroide
+    int i;
+    float a,GP1[3],GP2[3],num=0,area=0,mf[3];
+    for(i=1;i<=(v2-v1);i++){
+      /*  GPfuzzy(P,n,v1+i-1,GP1,mf);
+        GPfuzzy(P,n,v1+i,GP2,mf);*/
+        a=(max(GP1[0],GP1[1])+max(GP2[0],GP2[1]))/2;
+        num=num+a*max(GP1[0],GP1[1])/2;
+        area=area+a;
+    }
+
+    return num/area;
+}
+
+float Centroide(int v1,int v2,float P[],int n){//bota el centroide
+    int i,L=50;
+    float a,GP1[3],GP2[3],num=0,area=0;
+    for(i=1;i<=L;i++){
+        //GPfuzzy(P,n,v1+i-1,GP1,mf);
+        //GPfuzzy(P,n,v1+i,GP2,mf);
+        a=(max(GP1[0],GP1[1])+max(GP2[0],GP2[1]))/2;
+        num=num+a*max(GP1[0],GP1[1])/2;
+        area=area+a;
+    }
+    return num/area;
+}
+
+
+void GPIfuzzy(float P[],int n,int gx,float GP,float x[]){//1<=gx<=n ,, 0<=GP<=1
+    
+    if(gx==1){
+        x[0]=P[0];
+        x[1]=(1-GP)*(P[1]-P[0])/1.33333+P[0];
+    }
+    else{
+        if(gx<n){
+        x[0]=(GP-1)*(P[gx-1]-P[gx-2])/1.333333+P[gx-1];
+        x[1]=(1-GP)*(P[gx]-P[gx-1])/1.333333+P[gx-1];
+        }
+        if(gx==n){
+        x[0]=(GP-1)*(P[gx-1]-P[gx-2])/1.333333+P[gx-1];
+        x[1]=P[n-1];
+        }
+
+    }
+}
+
+
+void EntradaU(float F[],float O[],int ultrasonico,float tetha,float entrada[],float gp[],int mf[]){
+    //        ex_izq  muy_izqu  izqui  frente  dere  muy_der  ex_dere
+    //salidau   1        2        3      4      5      6         7
+    // entrada[0]==> entrada  fuzzy phi brujula
+    // entrada[1] ==> entrada fuzzy ultrasonico
+    //para el phi brujula
+    float gradop[2] = {0.0,0.0};
+    int mfi[2]={0,0};
+    float P[5]={-180,-90,0,90,180};//es decir entre -180 y 180
+   float beta;
+   beta=atan((F[0]-O[0])/(F[1]-O[1]))*57.29582790879777;
+    entrada[0]=beta-tetha;//degrees  phi
+    switch(ultrasonico){
+        case 0:{
+        if(entrada[0]>0)entrada[1]=7;//entrada[1] de ultrasonico
+        if(entrada[0]<0)entrada[1]=1;
+        break;}
+        case 2:{
+        if(entrada[0]>0)entrada[1]=7;
+        if(entrada[0]<0)entrada[1]=1;
+        break;}
+        case 5:{
+        if(entrada[0]>0)entrada[1]=6;
+        if(entrada[0]<0)entrada[1]=2;
+        break;}
+        case 1:{entrada[1]=6;
+        break;}
+        case 3:{entrada[1]=5;
+        break;}
+        case 7:{if(entrada[0]>0)entrada[1]=6;//entrada[1] de ultrasonico
+            if(entrada[0]<0)entrada[1]=2;//*cambie orden 7 con  1
+            break;}
+        case 6:{entrada[1]=3;
+        break;}
+        case 4:{entrada[1]=2;
+        break;}
+    }
+    /*//para el phi brujula
+    float gradop[2] = {0.0,0.0};
+    int mfi[2]={0,0};
+    float P[5]={-144,-72,0,72,144};//es decir entre -180 y 180*/
+    //printf("\nentrada[0]%f\n",entrada[0]);
+    GPfuzzy(P,5,entrada[0],gradop,mfi);
+    gp[0]=gradop[0];  mf[0]=mfi[0];
+    gp[1]=gradop[1];  mf[1]=mfi[1];
+
+    //para el ultrasonico
+    //GPfuzzy(P,5,entrada[1],gradop,mf);
+    gp[2]=1;  mf[2]=entrada[1];
+    gp[3]=0.5;  mf[3]=entrada[1]+1;
+}
+
+
+//reglas fuzzy
+int  reglas(int mf[],int mfrueda[],float gpin[],float gprueda[]){
+    //mf[0]==>mf      phi brujula
+    //mf[1]==>mf sgte brujula
+    //mf[2] mf ultrasonico
+    //mf[3]  mf sgte ultra
+    //gpin[0]  brujula primer grado de pertenencia
+    //gpin[1]  brujula segundo grado de pertencia
+    //gpin[2]  ultrasonico pro=imer gp
+    //gpin[3]  ultrasonico segundo gp
+    //rueda[0]==>rueda1
+    //rueda[1]==>rueda2
+
+    //mfgps[0]==>latitud
+    //mfgps[1]==>longtud
+    //k==> ultimo elem: gprueda[k+1]
+    int i,j;
+    int k=0;
+    //printf("\ngpin[]phi %f %f\n",gpin[0],gpin[1]);
+    //printf("\ngpin[]ultrasonico %f %f\n",gpin[2],gpin[3]);
+    //printf("\nmf[] %d %d %d %d\n",mf[0],mf[1],mf[2],mf[3]);
+    //mfrueda[6]=7;
+    //mfrueda[5]=7;
+
+//falta ve lo de la interrupcion del gps XD
+    //if((mfgps[0]==1)&&(mfgps[1]==1)){gprueda[0]=gpgps(0);gprueda[1]=gpgps[1];}//a parte del phi y el ultrasonico
+    if(mf[0]==3||mf[1]==3){i=1;if(mf[0]==3)i=0;
+        if(mf[2]==1||mf[3]==1){j=2;if(mf[3]==1)j=3;mfrueda[k]=1;mfrueda[k+1]=4;gprueda[k]=min(gpin[i],gpin[j]);gprueda[k+1]=min(gpin[i],gpin[j]);k=k+2;}
+        if(mf[2]==2||mf[3]==2){j=2;if(mf[3]==2)j=3;mfrueda[k]=1;mfrueda[k+1]=4;gprueda[k]=min(gpin[i],gpin[j]);gprueda[k+1]=min(gpin[i],gpin[j]);k=k+2;}
+        if(mf[2]==3||mf[3]==3){j=2;if(mf[3]==3)j=3;mfrueda[k]=2;mfrueda[k+1]=3;gprueda[k]=min(gpin[i],gpin[j]);gprueda[k+1]=min(gpin[i],gpin[j]);k=k+2;}
+        if(mf[2]==7||mf[3]==7){j=2;if(mf[3]==7)j=3;mfrueda[k]=3;mfrueda[k+1]=1;gprueda[k]=min(gpin[i],gpin[j]);gprueda[k+1]=min(gpin[i],gpin[j]);k=k+2;}
+        if(mf[2]==6||mf[3]==6){j=2;if(mf[3]==6)j=3;mfrueda[k]=2;mfrueda[k+1]=1;gprueda[k]=min(gpin[i],gpin[j]);gprueda[k+1]=min(gpin[i],gpin[j]);k=k+2;}
+        if(mf[2]==5||mf[3]==5){j=2;if(mf[3]==5)j=3;mfrueda[k]=3;mfrueda[k+1]=2;gprueda[k]=min(gpin[i],gpin[j]);gprueda[k+1]=min(gpin[i],gpin[j]);k=k+2;}
+        if(mf[2]==4||mf[3]==4){j=2;if(mf[3]==4)j=3;mfrueda[k]=3;mfrueda[k+1]=3;gprueda[k]=min(gpin[i],gpin[j]);gprueda[k+1]=min(gpin[i],gpin[j]);k=k+2;}
+    }
+//printf("\n1gprueda[]phi %f %f\n",gpin[0],gpin[1]);
+
+    if(mf[0]==4||mf[1]==4){i=1;if(mf[0]==4)i=0;//si brujula es POS
+        if(mf[2]==1||mf[3]==1){j=2;if(mf[3]==1)j=3;mfrueda[k]=1;mfrueda[k+1]=4;gprueda[k]=min(gpin[i],gpin[j]);gprueda[k+1]=min(gpin[i],gpin[j]);k=k+2;}
+        if(mf[2]==3||mf[3]==3){j=2;if(mf[3]==3)j=3;mfrueda[k]=1;mfrueda[k+1]=3;gprueda[k]=min(gpin[i],gpin[j]);gprueda[k+1]=min(gpin[i],gpin[j]);k=k+2;}
+        if(mf[2]==3||mf[3]==3){j=2;if(mf[3]==3)j=3;mfrueda[k]=4;mfrueda[k+1]=1;gprueda[k]=min(gpin[i],gpin[j]);gprueda[k+1]=min(gpin[i],gpin[j]);k=k+2;}
+        if(mf[2]==5||mf[3]==5){j=2;if(mf[3]==5)j=3;mfrueda[k]=3;mfrueda[k+1]=1;gprueda[k]=min(gpin[i],gpin[j]);gprueda[k+1]=min(gpin[i],gpin[j]);k=k+2;}
+        if(mf[2]==4||mf[3]==4){j=2;if(mf[3]==4)j=3;mfrueda[k]=1;mfrueda[k+1]=3;gprueda[k]=min(gpin[i],gpin[j]);gprueda[k+1]=min(gpin[i],gpin[j]);k=k+2;}
+    }
+
+    if(mf[0]==5||mf[1]==5){i=1;if(mf[0]==5)i=0;//si brujula es APOS
+        if(mf[2]==3||mf[3]==3){j=2;if(mf[3]==3)j=3;mfrueda[k]=1;mfrueda[k+1]=5;gprueda[k]=min(gpin[i],gpin[j]);gprueda[k+1]=min(gpin[i],gpin[j]);k=k+2;}
+        if(mf[2]==5||mf[3]==5){j=2;if(mf[3]==5)j=3;mfrueda[k]=5;mfrueda[k+1]=1;gprueda[k]=min(gpin[i],gpin[j]);gprueda[k+1]=min(gpin[i],gpin[j]);k=k+2;}
+        if(mf[2]==4||mf[3]==4){j=2;if(mf[3]==4)j=3;mfrueda[k]=1;mfrueda[k+1]=5;gprueda[k]=min(gpin[i],gpin[j]);gprueda[k+1]=min(gpin[i],gpin[j]);k=k+2;}
+    }
+    if(mf[0]==2||mf[1]==2){i=1;if(mf[0]==2)i=0;//si brujula es NEG
+        if(mf[2]==4||mf[3]==4){j=2;if(mf[3]==4)j=3;mfrueda[k]=1;mfrueda[k+1]=5;gprueda[k]=min(gpin[i],gpin[j]);gprueda[k+1]=min(gpin[i],gpin[j]);k=k+2;}
+    }
+    if(mf[0]==1||mf[1]==1){i=1;if(mf[0]==1)i=0;//si brujula es ANEG
+        if(mf[2]==4||mf[3]==4){j=2;if(mf[3]==4)j=3;mfrueda[k]=5;mfrueda[k+1]=1;gprueda[k]=min(gpin[i],gpin[j]);gprueda[k+1]=min(gpin[i],gpin[j]);k=k+2;}
+    }//llega hasta gprueda[k+1]
+return k;//size de mf y gprueda[]
+}
+//desfuzzyfication
+void desfuzzy(float Pm[],int n,int mfrueda[],float gprueda[],int size,float dutty[]){
+      //rueda1*********************************
+    float x[3],ar=0,num=0,x1,area=0,area1,x2,area2;
+    int a,b,i,mfmin,mfmax=1;
+   mfmin=n;
+//el sgte for fue modificado para casos de mfmax y mfmin q se repiten despues de las reglas
+    for(i=0;i<size;i=i+2){//ojo desde i=0
+        if(mfrueda[i]<=mfmin){if(mfrueda[i]<mfmin){mfmin=mfrueda[i];a=i;}
+                                if(mfrueda[i]=mfmin)b=i;}
+        if(mfrueda[i]>mfmax){mfmax=mfrueda[i];b=i;}
+    }
+
+    
+    //hallar %dutty de rueda1
+        //centroide de area1
+    GPIfuzzy(Pm,n,mfmin,gprueda[a],x);
+
+    for(i=0;i<gprueda[a]*100;i++){//*ojo con gprueda[a]*100
+        ar=0.01*(Pm[mfmin-1]-(i*0.01-1)/1.3333*(Pm[mfmin]-Pm[mfmin-1])-x[0]);
+        area=area+ar;
+        num=num+(ar*100/2+x[0])*ar;//ahhhhhhhhhhhhhhhhhhh
+    }
+    if(area!=0)x1=num/area;
+   else x1=0;
+    area1=area;
+
+        //centroide de area2
+    ar=0,num=0,area=0;
+    GPIfuzzy(Pm,n,mfmax,gprueda[b],x);
+
+    for(i=0;i<gprueda[b]*100;i++){
+        ar=0.01*(x[1]-(Pm[mfmax-1]+(i*0.01-1)/1.333333*(Pm[mfmax-1]-Pm[mfmax-2])));
+        area=area+ar;
+       num=num+(100*ar/2+ (x[1]-ar*100)   )*ar;
+    }
+    if(area!=0)x2=num/area;else x2=0;
+    area2=area;
+
+   dutty[0]=(x1*area1+x2*area2)/(area1+area2);
+
+    //rueda2************************************************
+
+   
+    mfmin=n,mfmax=1;ar=0,area=0,num=0;
+//el sgte for fue modificado para casos de mfmax y mfmin q se repiten despues de las reglas
+     for(i=1;i<size;i=i+2){//ojo desde i=1
+        if(mfrueda[i]<=mfmin){if(mfrueda[i]<mfmin){mfmin=mfrueda[i];a=i;}
+                                if(mfrueda[i]=mfmin)b=i;}
+        if(mfrueda[i]>mfmax){mfmax=mfrueda[i];b=i;}
+    }
+  
+    //hallar %dutty de rueda2
+        //centroide de area1
+    GPIfuzzy(Pm,n,mfmin,gprueda[a],x);
+    for(i=0;i<gprueda[a]*100;i++){//*ojo con gprueda[a]*100
+        ar=0.01*(Pm[mfmin-1]-(i*0.01-1)/1.3333*(Pm[mfmin]-Pm[mfmin-1])-x[0]);
+        area=area+ar;
+        num=num+(ar*100/2+x[0])*ar;//ahhhhhhhhhhhhhhhhhhh
+    }
+    if(area!=0) x1=num/area;
+   else x1=0;
+    area1=area;
+        //centroide de area2
+    ar=0,num=0,area=0;
+    GPIfuzzy(Pm,n,mfmax,gprueda[b],x);
+    for(i=0;i<gprueda[b]*100;i++){
+       ar=0.01*(x[1]-(Pm[mfmax-1]+(i*0.01-1)/1.333333*(Pm[mfmax-1]-Pm[mfmax-2])));
+        area=area+ar;
+       num=num+(100*ar/2+ (x[1]-ar*100)   )*ar;//ahhhhhhhhhh
+    }
+    if(area!=0)x2=num/area;
+   else x2=0;
+    area2=area;
+
+    dutty[1]=(x1*area1+x2*area2)/(area1+area2);
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Sat Jul 19 05:35:58 2014 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/e3affc9e7238
\ No newline at end of file