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.
HMC5883/HMC5883.cpp@5:818c0668fd2d, 2012-10-13 (annotated)
- Committer:
- maetugr
- Date:
- Sat Oct 13 08:59:03 2012 +0000
- Revision:
- 5:818c0668fd2d
- Child:
- 9:4e0c3936c756
?bergang von LCD auf PC-Terminal
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
maetugr | 5:818c0668fd2d | 1 | #include "mbed.h" |
maetugr | 5:818c0668fd2d | 2 | #include "HMC5883.h" |
maetugr | 5:818c0668fd2d | 3 | |
maetugr | 5:818c0668fd2d | 4 | #define I2CADR_W(ADR) (ADR<<1&0xFE) |
maetugr | 5:818c0668fd2d | 5 | #define I2CADR_R(ADR) (ADR<<1|0x01) |
maetugr | 5:818c0668fd2d | 6 | |
maetugr | 5:818c0668fd2d | 7 | //Initialisieren |
maetugr | 5:818c0668fd2d | 8 | HMC5883::HMC5883(PinName sda, PinName scl, Timer & GlobalTime_) : i2c_(sda, scl), GlobalTime(GlobalTime_) |
maetugr | 5:818c0668fd2d | 9 | { |
maetugr | 5:818c0668fd2d | 10 | Init(); |
maetugr | 5:818c0668fd2d | 11 | } |
maetugr | 5:818c0668fd2d | 12 | |
maetugr | 5:818c0668fd2d | 13 | void HMC5883::Init() |
maetugr | 5:818c0668fd2d | 14 | { |
maetugr | 5:818c0668fd2d | 15 | //Nullsetzen |
maetugr | 5:818c0668fd2d | 16 | MeasurementError= 0; |
maetugr | 5:818c0668fd2d | 17 | AutoCalibration= 0; |
maetugr | 5:818c0668fd2d | 18 | #pragma unroll |
maetugr | 5:818c0668fd2d | 19 | for(int i= 0; i < 3; i++) |
maetugr | 5:818c0668fd2d | 20 | { |
maetugr | 5:818c0668fd2d | 21 | RawMin[i]= -400; |
maetugr | 5:818c0668fd2d | 22 | RawMax[i]= 400; |
maetugr | 5:818c0668fd2d | 23 | Offset[i]= 0; |
maetugr | 5:818c0668fd2d | 24 | Scale[i]= 1.0; |
maetugr | 5:818c0668fd2d | 25 | RawMag[i]= 0; |
maetugr | 5:818c0668fd2d | 26 | Mag[i]= 0; |
maetugr | 5:818c0668fd2d | 27 | } |
maetugr | 5:818c0668fd2d | 28 | |
maetugr | 5:818c0668fd2d | 29 | |
maetugr | 5:818c0668fd2d | 30 | //HMC5883 initialisieren |
maetugr | 5:818c0668fd2d | 31 | char tx[4]; |
maetugr | 5:818c0668fd2d | 32 | |
maetugr | 5:818c0668fd2d | 33 | //1 Sample pro Messung |
maetugr | 5:818c0668fd2d | 34 | //75Hz Output Rate |
maetugr | 5:818c0668fd2d | 35 | //Range: +- 1.3 Gauss |
maetugr | 5:818c0668fd2d | 36 | //Continuous-Measurement Mode |
maetugr | 5:818c0668fd2d | 37 | tx[0]= 0x00; |
maetugr | 5:818c0668fd2d | 38 | tx[1]= 0x78; //Configuration Register A |
maetugr | 5:818c0668fd2d | 39 | tx[2]= 0x20; //Configuration Register B |
maetugr | 5:818c0668fd2d | 40 | tx[3]= 0x00; //Mode Register |
maetugr | 5:818c0668fd2d | 41 | i2c_.write(I2CADR_W(HMC5883_ADRESS), tx, 4); |
maetugr | 5:818c0668fd2d | 42 | |
maetugr | 5:818c0668fd2d | 43 | |
maetugr | 5:818c0668fd2d | 44 | Update(); |
maetugr | 5:818c0668fd2d | 45 | } |
maetugr | 5:818c0668fd2d | 46 | |
maetugr | 5:818c0668fd2d | 47 | //Rohdaten lesen |
maetugr | 5:818c0668fd2d | 48 | void HMC5883::ReadRawData() |
maetugr | 5:818c0668fd2d | 49 | { |
maetugr | 5:818c0668fd2d | 50 | //Drehrate aller Axen abholen |
maetugr | 5:818c0668fd2d | 51 | char tx[1]; |
maetugr | 5:818c0668fd2d | 52 | char rx[6]; |
maetugr | 5:818c0668fd2d | 53 | |
maetugr | 5:818c0668fd2d | 54 | tx[0]= 0x03; |
maetugr | 5:818c0668fd2d | 55 | i2c_.write(I2CADR_W(HMC5883_ADRESS), tx, 1); |
maetugr | 5:818c0668fd2d | 56 | i2c_.read (I2CADR_R(HMC5883_ADRESS), rx, 6); |
maetugr | 5:818c0668fd2d | 57 | |
maetugr | 5:818c0668fd2d | 58 | //Aus den einzelnen Bytes den 16-Bit-Wert zusammenbauen |
maetugr | 5:818c0668fd2d | 59 | short r[3]; |
maetugr | 5:818c0668fd2d | 60 | r[0]= rx[0]<<8|rx[1]; |
maetugr | 5:818c0668fd2d | 61 | r[1]= rx[4]<<8|rx[5]; |
maetugr | 5:818c0668fd2d | 62 | r[2]= rx[2]<<8|rx[3]; |
maetugr | 5:818c0668fd2d | 63 | |
maetugr | 5:818c0668fd2d | 64 | //Grober Messfehler? |
maetugr | 5:818c0668fd2d | 65 | if(r[0] == -4096 |
maetugr | 5:818c0668fd2d | 66 | || r[1] == -4096 |
maetugr | 5:818c0668fd2d | 67 | || r[2] == -4096) |
maetugr | 5:818c0668fd2d | 68 | MeasurementError= 1; |
maetugr | 5:818c0668fd2d | 69 | else |
maetugr | 5:818c0668fd2d | 70 | { |
maetugr | 5:818c0668fd2d | 71 | MeasurementError= 0; |
maetugr | 5:818c0668fd2d | 72 | RawMag[0]= r[0]; |
maetugr | 5:818c0668fd2d | 73 | RawMag[1]= r[1]; |
maetugr | 5:818c0668fd2d | 74 | RawMag[2]= r[2]; |
maetugr | 5:818c0668fd2d | 75 | } |
maetugr | 5:818c0668fd2d | 76 | } |
maetugr | 5:818c0668fd2d | 77 | |
maetugr | 5:818c0668fd2d | 78 | |
maetugr | 5:818c0668fd2d | 79 | //Update-Methode |
maetugr | 5:818c0668fd2d | 80 | void HMC5883::Update() |
maetugr | 5:818c0668fd2d | 81 | { |
maetugr | 5:818c0668fd2d | 82 | //Rohdaten lesen |
maetugr | 5:818c0668fd2d | 83 | ReadRawData(); |
maetugr | 5:818c0668fd2d | 84 | |
maetugr | 5:818c0668fd2d | 85 | if(AutoCalibration) |
maetugr | 5:818c0668fd2d | 86 | { |
maetugr | 5:818c0668fd2d | 87 | #pragma unroll |
maetugr | 5:818c0668fd2d | 88 | for(int i= 0; i < 3; i++) |
maetugr | 5:818c0668fd2d | 89 | { |
maetugr | 5:818c0668fd2d | 90 | //Neuer Min Max Wert? |
maetugr | 5:818c0668fd2d | 91 | RawMin[i]= RawMin[i] < RawMag[i] ? RawMin[i] : RawMag[i]; |
maetugr | 5:818c0668fd2d | 92 | RawMax[i]= RawMax[i] > RawMag[i] ? RawMax[i] : RawMag[i]; |
maetugr | 5:818c0668fd2d | 93 | |
maetugr | 5:818c0668fd2d | 94 | //Scale und Offset aus gesammelten Min Max Werten berechnen |
maetugr | 5:818c0668fd2d | 95 | //Die neue Untere und obere Grenze bilden -1 und +1 |
maetugr | 5:818c0668fd2d | 96 | Scale[i]= 2.0 / (float)(RawMax[i]-RawMin[i]); |
maetugr | 5:818c0668fd2d | 97 | Offset[i]= 1.0 - (float)(RawMax[i]) * Scale[i]; |
maetugr | 5:818c0668fd2d | 98 | } |
maetugr | 5:818c0668fd2d | 99 | } |
maetugr | 5:818c0668fd2d | 100 | |
maetugr | 5:818c0668fd2d | 101 | //Feldstaerke berechnen |
maetugr | 5:818c0668fd2d | 102 | Mag[0]= Scale[0] * (float)(RawMag[0]) + Offset[0]; |
maetugr | 5:818c0668fd2d | 103 | Mag[1]= Scale[1] * (float)(RawMag[1]) + Offset[1]; |
maetugr | 5:818c0668fd2d | 104 | Mag[2]= Scale[2] * (float)(RawMag[2]) + Offset[2]; |
maetugr | 5:818c0668fd2d | 105 | } |
maetugr | 5:818c0668fd2d | 106 | |
maetugr | 5:818c0668fd2d | 107 | |
maetugr | 5:818c0668fd2d | 108 | //Kalibrieren |
maetugr | 5:818c0668fd2d | 109 | void HMC5883::Calibrate(const short * pRawMin, const short * pRawMax) |
maetugr | 5:818c0668fd2d | 110 | { |
maetugr | 5:818c0668fd2d | 111 | #pragma unroll |
maetugr | 5:818c0668fd2d | 112 | for(int i= 0; i < 3; i++) |
maetugr | 5:818c0668fd2d | 113 | { |
maetugr | 5:818c0668fd2d | 114 | RawMin[i]= pRawMin[i]; |
maetugr | 5:818c0668fd2d | 115 | RawMax[i]= pRawMax[i]; |
maetugr | 5:818c0668fd2d | 116 | } |
maetugr | 5:818c0668fd2d | 117 | char AutoCalibrationBak= AutoCalibration; |
maetugr | 5:818c0668fd2d | 118 | AutoCalibration= 1; |
maetugr | 5:818c0668fd2d | 119 | Update(); |
maetugr | 5:818c0668fd2d | 120 | AutoCalibration= AutoCalibrationBak; |
maetugr | 5:818c0668fd2d | 121 | } |
maetugr | 5:818c0668fd2d | 122 | |
maetugr | 5:818c0668fd2d | 123 | void HMC5883::Calibrate(int s) |
maetugr | 5:818c0668fd2d | 124 | { |
maetugr | 5:818c0668fd2d | 125 | char AutoCalibrationBak= AutoCalibration; |
maetugr | 5:818c0668fd2d | 126 | AutoCalibration= 1; |
maetugr | 5:818c0668fd2d | 127 | |
maetugr | 5:818c0668fd2d | 128 | //Ende der Kalibrierung in ms Millisekunden berechnen |
maetugr | 5:818c0668fd2d | 129 | int CalibEnd= GlobalTime.read_ms() + s*1000; |
maetugr | 5:818c0668fd2d | 130 | |
maetugr | 5:818c0668fd2d | 131 | while(GlobalTime.read_ms() < CalibEnd) |
maetugr | 5:818c0668fd2d | 132 | { |
maetugr | 5:818c0668fd2d | 133 | //Update erledigt alles |
maetugr | 5:818c0668fd2d | 134 | Update(); |
maetugr | 5:818c0668fd2d | 135 | } |
maetugr | 5:818c0668fd2d | 136 | |
maetugr | 5:818c0668fd2d | 137 | AutoCalibration= AutoCalibrationBak; |
maetugr | 5:818c0668fd2d | 138 | } |
maetugr | 5:818c0668fd2d | 139 | |
maetugr | 5:818c0668fd2d | 140 | // Winkel berechnen |
maetugr | 5:818c0668fd2d | 141 | //--------------------------------------------------------------------------------------------------------------------------------------- |
maetugr | 5:818c0668fd2d | 142 | float HMC5883::getAngle(float x, float y) |
maetugr | 5:818c0668fd2d | 143 | { |
maetugr | 5:818c0668fd2d | 144 | #define Rad2Deg 57.295779513082320876798154814105 |
maetugr | 5:818c0668fd2d | 145 | #define PI 3.1415926535897932384626433832795 |
maetugr | 5:818c0668fd2d | 146 | |
maetugr | 5:818c0668fd2d | 147 | float Heading; |
maetugr | 5:818c0668fd2d | 148 | float DecAngle; |
maetugr | 5:818c0668fd2d | 149 | |
maetugr | 5:818c0668fd2d | 150 | DecAngle = 1.367 / Rad2Deg; //Missweisung = Winkel zwischen geographischer und magnetischer Nordrichtung |
maetugr | 5:818c0668fd2d | 151 | //Bern ca. 1.367 Grad Ost |
maetugr | 5:818c0668fd2d | 152 | //http://www.swisstopo.admin.ch/internet/swisstopo/de/home/apps/calc/declination.html |
maetugr | 5:818c0668fd2d | 153 | Heading = atan2((float)y,(float)x); |
maetugr | 5:818c0668fd2d | 154 | |
maetugr | 5:818c0668fd2d | 155 | Heading += DecAngle; //bei Ost-Deklination += DecAngle, bei West-Deklination -= DecAngle |
maetugr | 5:818c0668fd2d | 156 | |
maetugr | 5:818c0668fd2d | 157 | if(Heading < 0) |
maetugr | 5:818c0668fd2d | 158 | Heading += 2*PI; //korrigieren bei negativem Vorzeichen |
maetugr | 5:818c0668fd2d | 159 | |
maetugr | 5:818c0668fd2d | 160 | if(Heading > 2*PI) |
maetugr | 5:818c0668fd2d | 161 | Heading -= 2*PI; //auf 2Pi begrenzen |
maetugr | 5:818c0668fd2d | 162 | |
maetugr | 5:818c0668fd2d | 163 | return (Heading * 180/PI); //Radianten in Grad konvertieren |
maetugr | 5:818c0668fd2d | 164 | } |
maetugr | 5:818c0668fd2d | 165 | |
maetugr | 5:818c0668fd2d | 166 |