NOT FINISHED YET!!! My first try to get a self built fully working Quadrocopter based on an mbed, a self built frame and some other more or less cheap parts.

Dependencies:   mbed MODI2C

Files at this revision

API Documentation at this revision

Comitter:
maetugr
Date:
Wed Oct 31 14:44:07 2012 +0000
Parent:
15:753c5d6a63b3
Child:
17:e096e85f6c36
Commit message:
nach Kompassumstellung auf I2C_Sensor (nicht getestet)

Changed in this revision

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/BMP085/BMP085.cpp Show diff for this revision Revisions of this file
Sensors/BMP085/BMP085.h 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/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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Sensors/Alt/BMP085.cpp	Wed Oct 31 14:44:07 2012 +0000
@@ -0,0 +1,9 @@
+#include "mbed.h"
+#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!
+    
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Sensors/Alt/BMP085.h	Wed Oct 31 14:44:07 2012 +0000
@@ -0,0 +1,35 @@
+#ifndef BMP085_H
+#define BMP085_H
+
+#include "mbed.h"
+#include "I2C_Sensor.h"
+
+// I2C address
+#define BMP085_I2C_ADDRESS 0xEE
+
+class BMP085 : public I2C_Sensor
+{           
+    public:
+        BMP085(PinName sda, PinName scl);
+        
+        float data[3];
+        
+        void read();
+        
+        void calibrate(int s);
+        
+        float get_angle();
+         
+    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
--- a/Sensors/BMP085/BMP085.cpp	Mon Oct 29 16:43:10 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,9 +0,0 @@
-#include "mbed.h"
-#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!
-    
-}
\ No newline at end of file
--- a/Sensors/BMP085/BMP085.h	Mon Oct 29 16:43:10 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,34 +0,0 @@
-#ifndef BMP085_H
-#define BMP085_H
-
-#include "I2C_Sensor.h"
-
-// I2C address
-#define BMP085_I2C_ADDRESS 0xEE
-
-class BMP085 : public I2C_Sensor
-{           
-    public:
-        BMP085(PinName sda, PinName scl);
-        
-        float data[3];
-        
-        void read();
-        
-        void calibrate(int s);
-        
-        float get_angle();
-         
-    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
--- a/Sensors/Gyro/L3G4200D.cpp	Mon Oct 29 16:43:10 2012 +0000
+++ b/Sensors/Gyro/L3G4200D.cpp	Wed Oct 31 14:44:07 2012 +0000
@@ -2,96 +2,69 @@
 #include "L3G4200D.h"
 #include <math.h>
 
-#define L3G4200D_I2C_ADDRESS 0xD0
-
+#define L3G4200D_I2C_ADDRESS 0xD0               // TODO: Adressen???
 
-L3G4200D::L3G4200D(PinName sda, PinName scl) : i2c(sda, scl)
+L3G4200D::L3G4200D(PinName sda, PinName scl) : I2C_Sensor(sda, scl, L3G4200D_I2C_ADDRESS)
 {
-    i2c.frequency(400000);
     // Turns on the L3G4200D's gyro and places it in normal mode.
-    // Normal power mode, all axes enabled
+    // Normal power mode, all axes enabled (for detailed info see datasheet)
     
-    //writeReg(L3G4200D_CTRL_REG2, 0x05); // control filter
-    writeReg(L3G4200D_CTRL_REG2, 0x00); // highpass filter disabled
-    writeReg(L3G4200D_CTRL_REG3, 0x00);
-    writeReg(L3G4200D_CTRL_REG4, 0x20); // acuracy 2000 dps
+    //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);
     
-    writeReg(L3G4200D_REFERENCE, 0x00);
-    //writeReg(L3G4200D_STATUS_REG, 0x0F);
-    writeReg(L3G4200D_INT1_THS_XH, 0x2C);
-    writeReg(L3G4200D_INT1_THS_XL, 0xA4);
-    writeReg(L3G4200D_INT1_THS_YH, 0x2C);
-    writeReg(L3G4200D_INT1_THS_YL, 0xA4);
-    writeReg(L3G4200D_INT1_THS_ZH, 0x2C);
-    writeReg(L3G4200D_INT1_THS_ZL, 0xA4);
-    //writeReg(L3G4200D_INT1_DURATION, 0x00);
-    //writeReg(L3G4200D_CTRL_REG5, 0x12);  // Filter einschalten
-    //writeReg(L3G4200D_CTRL_REG5, 0x01);  // hochpass Filter einschalten
-    writeReg(L3G4200D_CTRL_REG5, 0x00);  // Filter ausschalten
+    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);
     
-    writeReg(L3G4200D_CTRL_REG1, 0x0F); // Gogo
+    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
     
-    // calibrate gyro with an average of count samples (result to offset)
-    #define count 50
+    writeRegister(L3G4200D_CTRL_REG1, 0x0F);            // starts Gyro measurement
+    
+    // calibrate gyro with an average of count samples (result of calibration stored in offset[])
     for (int j = 0; j < 3; j++)
             offset[j] = 0;
             
-    float Gyro_calib[3] = {0,0,0}; // temporary to sum up
+    float Gyro_calib[3] = {0,0,0};                      // temporary var for the sum of calibration measurement
     
-    for (int i = 0; i < count; i++) {
+    for (int i = 0; i < 50; i++) {                      // read 50 times the data in a very short time
         read();
         for (int j = 0; j < 3; j++)
             Gyro_calib[j] += data[j];
-        wait(0.001); // maybe less or no wait !!
+        wait(0.001);          // TODO: maybe less or no wait !!
     }
     
     for (int j = 0; j < 3; j++)
-        offset[j] = Gyro_calib[j]/count;
-}
-
-// Writes a gyro register
-void L3G4200D::writeReg(byte reg, byte value)
-{
-    byte buffer[2];
-    buffer[0] = reg;
-    buffer[1] = value;
-    
-    i2c.write(L3G4200D_I2C_ADDRESS, buffer, 2);
+        offset[j] = Gyro_calib[j]/count;                // take the average of the calibration measurements
 }
 
-// Reads a gyro register
-byte L3G4200D::readReg(byte reg)
-{
-    byte value = 0;
-    
-    i2c.write(L3G4200D_I2C_ADDRESS, &reg, 1);
-    i2c.read(L3G4200D_I2C_ADDRESS, &value, 1);
-
-    return value;
-}
-
-// Reads the 3 gyro channels and stores them in vector g
 void L3G4200D::read()
 {
-    byte buffer[6]; // 8-Bit pieces of axis data
-    // assert the MSB of the address to get the gyro 
-    // to do slave-transmit subaddress updating.
+    char buffer[6];                                     // 8-Bit pieces of axis data
+    
     buffer[0] = L3G4200D_OUT_X_L | (1 << 7);
     
-    i2c.write(L3G4200D_I2C_ADDRESS, buffer, 1, true); 
-    i2c.read(L3G4200D_I2C_ADDRESS, buffer, 6, true); 
+    readMultiRegister(L3G4200D_OUT_X_L, buffer, 6);     // parameter: 
     
-    data[0] = (short) (buffer[1] << 8 | buffer[0]);
+    data[0] = (short) (buffer[1] << 8 | buffer[0]);     // compose 8-Bit pieces to 16-bit short integers
     data[1] = (short) (buffer[3] << 8 | buffer[2]);
     data[2] = (short) (buffer[5] << 8 | buffer[4]);
     
-    //with offset of calibration
     for (int j = 0; j < 3; j++)
-            data[j] -= offset[j];
+            data[j] -= offset[j];                       // add offset from calibration
 }
 
-// Reads the gyros Temperature
 int L3G4200D::readTemp()
 {
-    return (short) readReg(L3G4200D_OUT_TEMP);
+    return (short) readRegister(L3G4200D_OUT_TEMP);     // read the sensors register for the temperature
 }
\ No newline at end of file
--- a/Sensors/Gyro/L3G4200D.h	Mon Oct 29 16:43:10 2012 +0000
+++ b/Sensors/Gyro/L3G4200D.h	Wed Oct 31 14:44:07 2012 +0000
@@ -4,6 +4,7 @@
 #define L3G4200D_H
 
 #include "mbed.h"
+#include "I2C_Sensor.h"
 
 // register addresses
 #define L3G4200D_WHO_AM_I      0x0F
@@ -37,21 +38,16 @@
 #define L3G4200D_INT1_THS_ZL   0x37
 #define L3G4200D_INT1_DURATION 0x38
 
-typedef char byte;
-
-class L3G4200D
+class L3G4200D : public I2C_Sensor
 {
     public:            
-        L3G4200D(PinName sda, PinName scl); // constructor, uses i2c
-        void read(); // read all axis to array
-        int readTemp(); // read temperature from sensor
-        float data[3]; // where the measured data is saved
+        L3G4200D(PinName sda, PinName scl); // constructor, uses I2C_Sensor class
+        void read();                        // read all axis to array
+        float data[3];                      // where the measured data is saved
+        int readTemp();                     // read temperature from sensor
         
     private:
         float offset[3]; // offset that's subtracted from every measurement
-        I2C i2c; // i2c object to communicate
-        void writeReg(byte reg, byte value); // write one single register to sensor
-        byte readReg(byte reg); // read one single register from sensor
 };
 
 #endif
\ No newline at end of file
--- a/Sensors/I2C_Sensor.cpp	Mon Oct 29 16:43:10 2012 +0000
+++ b/Sensors/I2C_Sensor.cpp	Wed Oct 31 14:44:07 2012 +0000
@@ -28,26 +28,28 @@
     fclose(fp);
 }
 
+//--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+// ATTENTION!!! the I2C option "repeated" = true is important because otherwise interrupts while bus communications cause crashes (see http://www.i2c-bus.org/repeated-start-condition/)
+//--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+
 char I2C_Sensor::readRegister(char reg)
 {
     char value = 0;
     
-    i2c.write(L3G4200D_I2C_ADDRESS, &reg, 1, true);
-    i2c.read(L3G4200D_I2C_ADDRESS, &value, 1, true);
+    i2c.write(GET_I2C_WRITE_ADDRESS(i2c_address), &reg, 1, true);
+    i2c.read(GET_I2C_READ_ADDRESS(i2c_address), &value, 1, true);
 
     return value;
 }
 
 void I2C_Sensor::writeRegister(char reg, char data)
 { 
-    char buffer[2]; // TODO: Arraykonstruktion in eine Zeile
-    buffer[0] = reg;
-    buffer[1] = data;
-    i2c.write(GET_I2C_WRITE_ADDRESS(i2c_address), tx, 2, true);
+    char buffer[2] = {reg, data};
+    i2c.write(GET_I2C_WRITE_ADDRESS(i2c_address), buffer, 2, true);
 }
 
 void I2C_Sensor::readMultiRegister(char reg, char* output, int size)
-{ // ATTENTION! the I2C option repeated true is important because otherwise interrupts while bus communications cause crashes (see http://www.i2c-bus.org/repeated-start-condition/)
-    i2c.write (GET_I2C_WRITE_ADDRESS(i2c_address), &reg, 1, true);      //tell it from which register to read
-    i2c.read  (GET_I2C_READ_ADDRESS(i2c_address), output, size, true);      //tell it where to store the data read
+{
+    i2c.write (GET_I2C_WRITE_ADDRESS(i2c_address), &reg, 1, true); // tell register address of the MSB get the sensor to do slave-transmit subaddress updating.
+    i2c.read  (GET_I2C_READ_ADDRESS(i2c_address), output, size, true); // tell it where to store the data read
 }
\ No newline at end of file
--- a/Sensors/I2C_Sensor.h	Mon Oct 29 16:43:10 2012 +0000
+++ b/Sensors/I2C_Sensor.h	Wed Oct 31 14:44:07 2012 +0000
@@ -11,6 +11,10 @@
         void calibrate();
         
     protected:
+        // Calibration value saving
+        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);
--- a/main.cpp	Mon Oct 29 16:43:10 2012 +0000
+++ b/main.cpp	Wed Oct 31 14:44:07 2012 +0000
@@ -74,7 +74,7 @@
     
     // calculate new motorspeeds
     co = Controller.compute() - 1000;
-    if (RC[2].read() > 1100) // zu SICHERHEIT! zum testen (ersetzt armed unarmed)
+    if (RC[2].read() > 1100) // zu SICHERHEIT! zum testen (später ersetzen armed unarmed)
     {
         /*Motor[0] = RC[2].read()+((RC[0].read() - 1500)/10.0)+40;
         Motor[2] = RC[2].read()-((RC[0].read() - 1500)/10.0)-40;*/
@@ -86,14 +86,14 @@
         Motor[2] = 1000;
         Motor[3] = 1000;
     }
-    /*Motor[0] = 1000 + (100 - (angle[1] * 500/90)) * (RC[2].read() - 1000) / 1000;
+    /*Motor[0] = 1000 + (100 - (angle[1] * 500/90)) * (RC[2].read() - 1000) / 1000; // test für erste reaktion der motoren entgegen der Auslenkung
     Motor[1] = 1000 + (100 - (angle[0] * 500/90)) * (RC[2].read() - 1000) / 1000;
     Motor[2] = 1000 + (100 + (angle[1] * 500/90)) * (RC[2].read() - 1000) / 1000;
     Motor[3] = 1000 + (100 + (angle[0] * 500/90)) * (RC[2].read() - 1000) / 1000;*/
 }
 
 int main() { // main programm only used for initialisation and debug output
-    NVIC_SetPriority(TIMER3_IRQn, 2); // set priorty of tickers below hardware interrupts
+    NVIC_SetPriority(TIMER3_IRQn, 1); // set priorty of tickers below hardware interrupts (standard priority is 0)
     
     //for(int i=0;i<3;i++)
         Controller.setInputLimits(-90.0, 90.0);