Subversion Repositories MK3Mag

Rev

Rev 5 | Rev 8 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 5 Rev 7
Line 1... Line 1...
1
/*#######################################################################################
1
/*#######################################################################################
2
Flight Control
2
MK3Mag 3D-Magnet sensor
3
#######################################################################################*/
3
#######################################################################################*/
4
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
5
// + Copyright (c) 04.2007 Holger Buss
5
// + Copyright (c) 05.2008 Holger Buss
-
 
6
// + Thanks to Ilja Fähnrich 
6
// + Nur für den privaten Gebrauch
7
// + Nur für den privaten Gebrauch
7
// + www.MikroKopter.com
8
// + www.MikroKopter.com
8
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
9
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
9
// + Es gilt für das gesamte Projekt (Hardware, Software, Binärfiles, Sourcecode und Dokumentation), 
10
// + Es gilt für das gesamte Projekt (Hardware, Software, Binärfiles, Sourcecode und Dokumentation), 
10
// + dass eine Nutzung (auch auszugsweise) nur für den privaten (nicht-kommerziellen) Gebrauch zulässig ist. 
11
// + dass eine Nutzung (auch auszugsweise) nur für den privaten (nicht-kommerziellen) Gebrauch zulässig ist. 
Line 35... Line 36...
35
// +     from this software without specific prior written permission.
36
// +     from this software without specific prior written permission.
36
// +   * The use of this project (hardware, software, binary files, sources and documentation) is only permittet 
37
// +   * The use of this project (hardware, software, binary files, sources and documentation) is only permittet 
37
// +     for non-commercial use (directly or indirectly)
38
// +     for non-commercial use (directly or indirectly)
38
// +     Commercial use (for excample: selling of MikroKopters, selling of PCBs, assembly, ...) is only permitted 
39
// +     Commercial use (for excample: selling of MikroKopters, selling of PCBs, assembly, ...) is only permitted 
39
// +     with our written permission
40
// +     with our written permission
40
// +   * If sources or documentations are redistributet on other webpages, out webpage (http://www.MikroKopter.de) must be 
41
// +   * If sources or documentations are redistributet on other webpages, our webpage (http://www.MikroKopter.de) must be 
-
 
42
// +     clearly linked as origin 
41
// +     clearly linked as origin // +   * porting to systems other than hardware from www.mikrokopter.de is not allowed
43
// +   * porting to systems other than hardware from www.mikrokopter.de is not allowed
42
// +  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
44
// +  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
43
// +  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
45
// +  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
44
// +  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
46
// +  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
45
// +  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
47
// +  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
46
// +  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
48
// +  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
Line 49... Line 51...
49
// +  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN// +  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
51
// +  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN// +  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
50
// +  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
52
// +  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
51
// +  POSSIBILITY OF SUCH DAMAGE. 
53
// +  POSSIBILITY OF SUCH DAMAGE. 
52
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
54
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Line 53... Line 55...
53
 
55
 
54
 signed int OffsetN, OffsetR, OffsetZ;
-
 
55
/*
-
 
56
 signed int CalTabelleHorizontalN[4] = {67,-450,77,-411};    // Vier Messwerte 90° Horizontal gedreht
-
 
57
 signed int CalTabelleHorizontalR[4] = {-310,175,183,-333};  
-
 
58
 signed int CalTabelleHorizontalZ[4] = {-100,-390,-400,100}; // Messwinkel des Z-Sensors auch horizontal gemessen
-
 
59
*/
-
 
60
 signed int CalTabelleHorizontalN[4] = {  75,-180,-440,-166};    // Vier Messwerte 90° Horizontal gedreht
-
 
61
 signed int CalTabelleHorizontalR[4] = {  -5,-230,  66, 246};  
-
 
Line 62... Line 56...
62
 signed int CalTabelleHorizontalZ[4] = {-290,-280,  44,  33}; // Messwinkel des Z-Sensors auch horizontal gemessen
56
signed int OffsetN, OffsetR, OffsetZ;
63
 
57
 
64
  signed int RawMagnet1a,RawMagnet1b;  // reine AD-Messung
58
  signed int RawMagnet1a,RawMagnet1b;  // raw AD-Data
-
 
59
  signed int RawMagnet2a,RawMagnet2b;
65
  signed int RawMagnet2a,RawMagnet2b;
60
  signed int RawMagnet3a,RawMagnet3b;
66
  signed int RawMagnet3a,RawMagnet3b;
61
  signed int Xmin = 0, Xmax = 0; Ymin = 0, Ymax = 0; Zmin = 0, Zmax = 0;
67
  signed int UncalMagnetN,UncalMagnetR,UncalMagnetZ;  // Messwert-Delta ohne Offset- und Verstärker korrektur
62
  signed int UncalMagnetN,UncalMagnetR,UncalMagnetZ;  // Messwert-Delta ohne Offset- und Verstärker korrektur
68
  signed int MagnetN,MagnetR,MagnetZ;                 // Kalibrierte Messerte
63
  signed int MagnetN,MagnetR,MagnetZ;
69
  unsigned int PwmHeading = 0;
64
  unsigned int PwmHeading = 0;
70
  unsigned char PC_Connected = 0;
65
  unsigned int PC_Connected = 0;
Line -... Line 66...
-
 
66
  unsigned int Heading;
-
 
67
#include "main.h"
-
 
68
 
-
 
69
uint16_t eeXmin EEMEM = 0;
-
 
70
uint16_t eeXmax EEMEM = 0;
-
 
71
uint16_t eeYmin EEMEM = 0;
-
 
72
uint16_t eeYmax EEMEM = 0;
Line 71... Line 73...
71
  int Heading;
73
uint16_t eeZmin EEMEM = 0;
72
#include "main.h"
74
uint16_t eeZmax EEMEM = 0;
73
 
75
 
74
 
76
 
Line 80... Line 82...
80
    dauer = (unsigned char)TCNT0 + dauer;
82
    dauer = (unsigned char)TCNT0 + dauer;
81
    while((TCNT0 - dauer) & 0x80);
83
    while((TCNT0 - dauer) & 0x80);
82
}
84
}
Line 83... Line 85...
83
 
85
 
84
void CalcFields(void)
86
void CalcFields(void)
85
{
87
{
86
 UncalMagnetN = (2 * UncalMagnetN + (RawMagnet1a - RawMagnet1b)) / 3;
88
 UncalMagnetN = (1 * UncalMagnetN + (RawMagnet1a - RawMagnet1b)) / 2;
87
 UncalMagnetR = (2 * UncalMagnetR + (RawMagnet3a - RawMagnet3b)) / 3;
89
 UncalMagnetR = (1 * UncalMagnetR + (RawMagnet3a - RawMagnet3b)) / 2;
-
 
90
 UncalMagnetZ = (1 * UncalMagnetZ + (RawMagnet2a - RawMagnet2b)) / 2;
-
 
91
 
-
 
92
 OffsetN = (Xmin + Xmax) / 2;
-
 
93
 OffsetR = (Ymin + Ymax) / 2;
-
 
94
 OffsetZ = (Zmin + Zmax) / 2;
88
 UncalMagnetZ = (2 * UncalMagnetZ + (RawMagnet2a - RawMagnet2b)) / 3;
95
 
89
 MagnetN = UncalMagnetN - OffsetN;
96
 MagnetN = (1024L * (long)(UncalMagnetN - OffsetN)) / (Xmax - Xmin);
90
 MagnetR = UncalMagnetR - OffsetR;
97
 MagnetR = (1024L * (long)(UncalMagnetR - OffsetR)) / (Ymax - Ymin);
91
 MagnetZ = UncalMagnetZ - OffsetZ;
98
 MagnetZ = (1024L * (long)(UncalMagnetZ - OffsetZ)) / (Zmax - Zmin);
Line 92... Line -...
92
}
-
 
93
 
99
}
94
//------------------------------------------------------
100
 
95
void CalcHeading(void)
101
void CalcHeading(void)
96
{
-
 
97
   double nick_rad, roll_rad, Hx, Hy, Cx, Cy, Cz;
102
{
Line 98... Line 103...
98
   float nick, roll, XEx, XEy, YEy, YEz, YE, XE, XrawCal, YrawCal, ZrawCal, XEz;
103
   double nick_rad, roll_rad, Hx, Hy, Cx, Cy, Cz;
99
   int heading, azimuthgrad;
104
   int heading;
100
   
-
 
101
   nick_rad = ((double)WinkelOut.Winkel[0]) * M_PI / (double)(180);
105
   
102
   roll_rad = ((double)WinkelOut.Winkel[1]) * M_PI / (double)(180);
-
 
103
   //roll_rad = 0;   nick_rad = 0;
-
 
104
 
-
 
105
/*
-
 
106
   Cx =  (double) (MicroMag.Axis[Y_AXIS] + CY_OFFSET) * 0.707f - (double) (MicroMag.Axis[X_AXIS]+ CX_OFFSET) * 0.707f;
-
 
107
   Cy =  ((double) (MicroMag.Axis[Y_AXIS]+ CY_OFFSET) * 0.707f + (double) (MicroMag.Axis[X_AXIS]+ CX_OFFSET) * 0.707f);
106
   nick_rad = ((double)ExternData.Winkel[0]) * M_PI / (double)(1800);
108
   Cz = -MicroMag.Axis[Z_AXIS] + CZ_OFFSET;
107
   roll_rad = ((double)ExternData.Winkel[1]) * M_PI / (double)(1800);
109
*/
108
 
-
 
109
   Cx = MagnetN;
-
 
110
   Cy = MagnetR;
-
 
111
   Cz = MagnetZ;
-
 
112
 
-
 
113
 if(ExternData.Orientation == 1)
-
 
114
  {
-
 
115
   Cx = MagnetR;
110
   Cx = MagnetN;
116
   Cy = -MagnetN;
111
   Cy = MagnetR;
117
   Cz = MagnetZ;
112
   Cz = -MagnetZ;
118
  }
113
   
119
 
Line 114... Line 120...
114
   Hx = Cx * (double)cos(nick_rad) +
120
   Hx = Cx * (double)cos(nick_rad) +
115
        Cy * (double)sin(nick_rad) * (double)sin(roll_rad) -
121
        Cy * (double)sin(nick_rad) * (double)sin(roll_rad) -
Line 116... Line 122...
116
        Cz * (double)sin(nick_rad) * (double)cos(roll_rad);      
122
        Cz * (double)sin(nick_rad) * (double)cos(roll_rad);      
117
               
123
               
118
   Hy = Cy * (double)cos(roll_rad) +
124
   Hy = Cy * (double)cos(roll_rad) +
119
        Cz * (double)sin(roll_rad);
125
        Cz * (double)sin(roll_rad);
120
 
126
 
Line 121... Line -...
121
               
-
 
122
   if(Hx == 0 && Hy < 0) heading = 90;
-
 
123
   else if(Hx == 0 && Hy > 0) heading = 270;
-
 
124
   else if(Hx < 0) heading  = 180 - (atan(Hy / Hx) * 180 / M_PI);
127
               
125
   else if(Hx > 0 && Hy < 0) heading = - (atan(Hy / Hx) * 180 / M_PI);
-
 
126
   else if(Hx > 0 && Hy > 0) heading  = 360 - (atan(Hy / Hx) * 180 / M_PI);
128
   if(Hx == 0 && Hy < 0) heading = 90;
127
 
-
 
128
  // DebugOut.Analog[14] = heading;
-
 
129
  // if (FromFlightCtrl.IntegralNick > 0) heading = heading + FromFlightCtrl.IntegralNick/60;
129
   else if(Hx == 0 && Hy > 0) heading = 270;
Line -... Line 130...
-
 
130
   else if(Hx < 0) heading  = 180 - (atan(Hy / Hx) * 180.0) / M_PI;
-
 
131
   else if(Hx > 0 && Hy < 0) heading = - (atan(Hy / Hx) * 180.0) / M_PI;
-
 
132
   else if(Hx > 0 && Hy > 0) heading  = 360 - (atan(Hy / Hx) * 180.0) / M_PI;
-
 
133
 
-
 
134
 if(abs(heading) < 361) Heading = heading;
-
 
135
 PwmHeading = Heading + 10;
-
 
136
}
-
 
137
 
-
 
138
 
-
 
139
void Calibrate(void)
-
 
140
{
-
 
141
 unsigned char cal;
-
 
142
 if(I2C_WriteCal.CalByte) cal = I2C_WriteCal.CalByte;
-
 
143
 else                     cal = ExternData.CalState;
-
 
144
 switch(cal)
-
 
145
  {
-
 
146
   case 0:
-
 
147
                LED_ON;
-
 
148
          break;
-
 
149
   case 1:
-
 
150
        Xmin =  10000;
-
 
151
        Xmax = -10000;
-
 
152
        Ymin =  10000;
-
 
153
        Ymax = -10000;
-
 
154
        Zmin =  10000;
-
 
155
        Zmax = -10000;
-
 
156
                LED_OFF;
-
 
157
          break;
-
 
158
   case 2:
-
 
159
                LED_ON;  // find Min and Max of the X- and Y-Sensors
-
 
160
              if(UncalMagnetN < Xmin) Xmin = UncalMagnetN;
-
 
161
              if(UncalMagnetN > Xmax) Xmax = UncalMagnetN;
-
 
162
              if(UncalMagnetR < Ymin) Ymin = UncalMagnetR;
-
 
163
              if(UncalMagnetR > Ymax) Ymax = UncalMagnetR;
-
 
164
          break;
-
 
165
   case 3:
-
 
166
                LED_OFF;
-
 
167
          break;
-
 
168
   case 4:
-
 
169
                LED_ON;  // find Min and Max of the Z-Sensor
-
 
170
          if(UncalMagnetZ < Zmin) Zmin = UncalMagnetZ;
-
 
171
              if(UncalMagnetZ > Zmax) Zmax = UncalMagnetZ;
-
 
172
          break;
-
 
173
   case 5:
-
 
174
                LED_OFF; // Save values
-
 
175
         if((Xmax - Xmin) > 150 && (Ymax - Ymin) > 150 && (Zmax - Zmin) > 150)
-
 
176
          {
-
 
177
               eeprom_write_word(&eeXmin, Xmin);
-
 
178
               eeprom_write_word(&eeXmax, Xmax);
-
 
179
               eeprom_write_word(&eeYmin, Ymin);
-
 
180
               eeprom_write_word(&eeYmax, Ymax);
-
 
181
               eeprom_write_word(&eeZmin, Zmin);
-
 
182
               eeprom_write_word(&eeZmax, Zmax);
-
 
183
           Delay_ms(2000);
-
 
184
          }
-
 
185
                LED_ON;
-
 
186
        break;
-
 
187
  }
-
 
188
}
-
 
189
 
-
 
190
 
-
 
191
void SetDebugValues(void)
-
 
192
{
-
 
193
         DebugOut.Analog[0] =  MagnetN;
-
 
194
         DebugOut.Analog[1] =  MagnetR;
-
 
195
         DebugOut.Analog[2] =  MagnetZ;
-
 
196
                 DebugOut.Analog[3] =  UncalMagnetN;
-
 
197
                 DebugOut.Analog[4] =  UncalMagnetR;
-
 
198
                 DebugOut.Analog[5] =  UncalMagnetZ;             
-
 
199
         DebugOut.Analog[6] =  ExternData.Winkel[0];
-
 
200
         DebugOut.Analog[7] =  ExternData.Winkel[1];
-
 
201
                 DebugOut.Analog[8] =  Xmin;
-
 
202
                 DebugOut.Analog[9] =  Xmax;
-
 
203
                 DebugOut.Analog[10] = Ymin;   
Line 130... Line 204...
130
   
204
                 DebugOut.Analog[11] = Ymax;
131
 if(heading < 361) DebugOut.Analog[14] = heading;
205
                 DebugOut.Analog[12] = Zmin;
132
 Heading = heading;
206
                 DebugOut.Analog[13] = Zmax;   
133
 PwmHeading = heading + 10;
207
                 DebugOut.Analog[14] = ExternData.CalState;
Line 156... Line 230...
156
    ADC_Init();
230
    ADC_Init();
157
        InitIC2_Slave();
231
        InitIC2_Slave();
158
    sei();//Globale Interrupts Einschalten
232
    sei();//Globale Interrupts Einschalten
159
    Debug_Timer = SetDelay(100);   // Sendeintervall    
233
    Debug_Timer = SetDelay(100);   // Sendeintervall    
Line 160... Line -...
160
                           
-
 
161
 
234
                           
-
 
235
        Xmin = eeprom_read_word(&eeXmin);
162
    OffsetN = (CalTabelleHorizontalN[0] + CalTabelleHorizontalN[1] + CalTabelleHorizontalN[2] + CalTabelleHorizontalN[3]) / 4;
236
        Xmax = eeprom_read_word(&eeXmax);
-
 
237
        Ymin = eeprom_read_word(&eeYmin);
163
    OffsetR = (CalTabelleHorizontalR[0] + CalTabelleHorizontalR[1] + CalTabelleHorizontalR[2] + CalTabelleHorizontalR[3]) / 4;
238
        Ymax = eeprom_read_word(&eeYmax);
-
 
239
        Zmin = eeprom_read_word(&eeZmin);
Line 164... Line 240...
164
    OffsetZ = (CalTabelleHorizontalZ[0] + CalTabelleHorizontalZ[1] + CalTabelleHorizontalZ[2] + CalTabelleHorizontalZ[3]) / 4;
240
        Zmax = eeprom_read_word(&eeZmax);
165
 
241
 
166
    VersionInfo.Hauptversion = VERSION_HAUPTVERSION;
242
    VersionInfo.Hauptversion = VERSION_HAUPTVERSION;
Line -... Line 243...
-
 
243
    VersionInfo.Nebenversion = VERSION_NEBENVERSION;
-
 
244
    VersionInfo.PCKompatibel = 7;
-
 
245
 
Line 167... Line 246...
167
    VersionInfo.Nebenversion = VERSION_NEBENVERSION;
246
    ExternData.Orientation = 0;
168
    VersionInfo.PCKompatibel = 7;
247
    ExternData.CalState = 0;
169
 
-
 
170
       
248
    I2C_WriteCal.CalByte = 0;
171
    while (1)
249
       
172
        {
250
    while (1)
173
    LED_ON;
251
        {
174
         FLIP_LOW;
252
         FLIP_LOW;
175
         Delay_ms(2);
253
         Delay_ms(2);
176
         RawMagnet1a = MessAD(0);
254
         RawMagnet1a = MessAD(0);
177
         RawMagnet2a = MessAD(1);
255
         RawMagnet2a = -MessAD(1);
178
         RawMagnet3a = MessAD(7);
256
         RawMagnet3a = MessAD(7);
179
         Delay_ms(1);
257
         Delay_ms(1);
180
LED_OFF;
258
 
181
         FLIP_HIGH;
259
         FLIP_HIGH;
182
         Delay_ms(2);
260
         Delay_ms(2);
Line 183... Line 261...
183
         RawMagnet1b = MessAD(0);
261
         RawMagnet1b = MessAD(0);
184
         RawMagnet2b = MessAD(1);
-
 
185
         RawMagnet3b = MessAD(7);
-
 
186
         Delay_ms(1);
-
 
187
 
-
 
188
         CalcFields();
-
 
189
         DebugOut.Analog[0] = MagnetN;
-
 
190
         DebugOut.Analog[1] = MagnetR;
-
 
191
         DebugOut.Analog[2] = MagnetZ;
-
 
192
         DebugOut.Analog[3] = UncalMagnetN;
-
 
193
         DebugOut.Analog[4] = UncalMagnetR;
-
 
194
         DebugOut.Analog[5] = UncalMagnetZ;
-
 
195
/*
-
 
196
         DebugOut.Analog[3] = RawMagnet1a;
-
 
197
         DebugOut.Analog[4] = RawMagnet1b;
-
 
198
         DebugOut.Analog[5] = RawMagnet3a;
262
         RawMagnet2b = -MessAD(1);
199
         DebugOut.Analog[6] = RawMagnet3b;*/
-
 
200
         DebugOut.Analog[6] = WinkelOut.Winkel[0];
-
 
201
         DebugOut.Analog[7] = WinkelOut.Winkel[1];
-
 
202
 
-
 
203
         DebugOut.Analog[8] =  WinkelOut.UserParameter[0];
-
 
204
         DebugOut.Analog[9] =  WinkelOut.UserParameter[1];
263
         RawMagnet3b = MessAD(7);
205
         DebugOut.Analog[10] = WinkelOut.UserParameter[2];
264
         Delay_ms(1);
206
         DebugOut.Analog[11] = WinkelOut.UserParameter[3];
-
 
-
 
265
 
207
 
266
         CalcFields();
208
 
267
         if(ExternData.CalState || I2C_WriteCal.CalByte) Calibrate();
-
 
268
         else CalcHeading();
209
         CalcHeading();
269
         BearbeiteRxDaten();
210
         BearbeiteRxDaten();
270
 
211
         PC_Connected = 100;
271
         if(PC_Connected)
212
         if(PC_Connected)
272
          {
213
          {
273
            DDRD  |= 0x02; // TXD-Portpin
214
            PC_Connected--;        
274
                UCR |= (1 << TXEN);
-
 
275
            DatenUebertragung();
215
            DatenUebertragung();
276
            PC_Connected--;        
216
            DDRD  |= 0x02; // TXD-Leitung
277
          }  
217
          }  
278
          else
218
          else
279
           {