RT-AICHIP-sample
AICHIPFunction.c
[詳解]
1 
10 #include "LPC13xx.h"
11 #include "core_cm3.h"
12 #include "type.h"
13 
14 #include "timer.h"
15 #include "pwm.h"
16 #include "AICHIPFunction.h"
17 #include "UserInterface.h"
18 
19 #include "mpu9150.h"
20 #include "debug.h"
21 #include "uart.h"
22 #include "tinyMathFunction.h"
23 
24 #include "usbTransmission.h"
25 
26 
28 extern volatile uint32_t UARTCount;
29 extern volatile uint8_t UARTBuffer[BUFSIZE];
31 static void moterEnable(uint8_t en);
32 static void execUARTCommand();
33 static void execCommand(uint8_t *cmd);
35 
36 volatile static float motor_duty = 0.0;
37 volatile static float degree = 0.0;
38 volatile static uint8_t flag_send_data_enable = 0;
39 
40 volatile static uint32_t time;
41 volatile static uint8_t flag_slope = 0; //1:坂を上っている 0:坂を上っていない
42 volatile static uint8_t flag_curve = 0; //1:curving 0:not curving
43 volatile static uint8_t flag_stop = 0; //1:stop 0:moving
44 
45 
52 void initAICHIP(void)
53 {
55 }
56 
64 {
65  flag_send_data_enable = en;
66 }
67 
74 static void moterEnable(uint8_t en)
75 {
76  if(en == 1) LPC_GPIO1->DATA |= 0x0800 ; //NSLEEP ON
77  if(en == 0) LPC_GPIO1->DATA &= ~(0x0800); //NSLEEP OFF
78 }
79 
80 
87 static void setRotationDir(int8_t dir)
88 {
89  if(dir == 1) LPC_GPIO0->DATA |=0x0080;
90  if(dir == -1) LPC_GPIO0->DATA &= ~(0x0080);
91 
92 
93 }
94 
101 void setDutyMotor(float pwm_duty)
102 {
103 
104  if(pwm_duty == 0.0)
105  {
106  moterEnable(0);
107  motor_duty = pwm_duty;
108  }
109  if(pwm_duty < 0.0)
110  {
111  if(pwm_duty < - 1.0) pwm_duty = -1.0;
112  motor_duty = pwm_duty;
113  Init_PWM2();
114 
115  moterEnable(1);
116  setRotationDir(-1);
117  setDutyPWM2 (1.0-(-1.0 * pwm_duty));
118  }
119  if(pwm_duty > 0.0)
120  {
121  if(pwm_duty > 1.0) pwm_duty = 1.0;
122  motor_duty = pwm_duty;
123  Init_PWM2();
124 
125  moterEnable(1);
126  setRotationDir(1);
127  setDutyPWM2 (1.0-pwm_duty );
128  }
129 
130 }
131 
138 float getDutyMotor(void)
139 {
140  return motor_duty;
141 }
142 
155 {
156 
157  static uint16_t count = 0;
158  GETDAT_T send_data;
159 
160  static uint8_t timestamp;
161  uint8_t i;
162  float acc_vec[3];
163  float acc_norm = 0.0;
164  float acc_norm_LPF = 0.0;
165  float gain_LPF = 0.01;
166  float omega_vec[3];
167  float omega_str_LPF_vec[3]; //強いローパスフィルタがかかった値を格納
168  float diff_omega[3]; //強いローパスフィルタをかけたジャイロの値と現在のジャイロの値の差分
169 
170  int16_t deg;
171  uint16_t duty;
172  uint16_t v_lipo;
173  uint16_t v_bat;
174 
175 
176  LPC_TMR32B1->IR=0x08; //clear interrupt flag
177 
178  //送信データ格納用変数のヘッダ
179  send_data.num = 43;
180  send_data.d[0] = 0xff;
181  send_data.d[1] = 0xff;
182  send_data.d[2] = 0x52;
183  send_data.d[3] = 0x54;
184  send_data.d[4] = 0x34;
185  send_data.d[5] = 0x57;
186  send_data.d[6] = 0x00;
187  send_data.d[7] = timestamp;
188 
189  if(timestamp == 0xff) timestamp = 0;
190  else timestamp++;
191 
192  //9軸センサの観測値を送信用配列に格納
193  getDataFromMPU6050( (uint8_t *)(&send_data.d[8]) );
194  getDataFromAK8975( (uint8_t *)(&send_data.d[22]) );
195 
196  //9軸センサの観測値を変数に格納
197  getOmega(&omega_vec[0]);
198  getAccLPF(&acc_vec[0]);
199  getOmegaStrLPF(&omega_str_LPF_vec[0]);
200  //静止状態の判定 omega < 0.1 deg/sec かつ |1-|a||<0.01
201  //もし静止状態ならば角速度を0.0にしてしまう.
202  acc_norm = tSqrt(acc_vec[0]*acc_vec[0]+acc_vec[1]*acc_vec[1]+acc_vec[2]*acc_vec[2]);
203  acc_norm_LPF = gain_LPF * acc_norm_LPF + (1.0-gain_LPF)*acc_norm;
204 
205  flag_stop = 0;
206  if( ABS(acc_norm_LPF - acc_norm )<0.02 )
207  {
208  for(i=0;i<3;i++)
209  {
210 
211  diff_omega[i] = omega_str_LPF_vec[i] - omega_vec[i] ;
212  if(ABS(diff_omega[i]) < DEG2RAD(0.3))
213  {
214  omega_vec[i] = 0.0;
215  }
216 
217  if(ABS(diff_omega[0]) < DEG2RAD(0.3) &&
218  ABS(diff_omega[1]) < DEG2RAD(0.3) &&
219  ABS(diff_omega[2]) < DEG2RAD(0.3)
220  ) flag_stop = 1;
221  }
222  }
223 
224  if(ABS(omega_vec[2]) > DEG2RAD(100)) flag_curve = 1;
225  else flag_curve = 0;
226 
227  if(ABS( 1- ABS(acc_vec[2])) >0.1 ) flag_slope = 1;
228  else flag_slope = 0;
229  //角度の積分処理
230  if(isStop() == 0)
231  {
232  degree += 0.01* omega_vec[2];
233  while(degree < 0){
234  degree += 2*PI;
235  }
236  while(degree > 2*PI)
237  {
238  degree -= 2*PI;
239  }
240  while(degree > PI)
241  {
242  degree -= 2*PI;
243  }
244 
245  }
246 
247  //角度情報を送信用配列に格納
248  deg = (int16_t)(degree/ (2*PI) * 32767.0);
249  send_data.d[28] = 0x00ff & deg;
250  send_data.d[29] = (0xff00 & deg)>>8;
251  //duty情報を送信用配列に格納
252  duty = (int16_t)(motor_duty * 32767.0);
253  send_data.d[30] = 0x00ff & duty;
254  send_data.d[31] = (0xff00 & duty)>>8;
255  //isStop(),isCurve(),isSlope()の情報を送信用配列に格納
256  send_data.d[32] = isStop();
257  send_data.d[33] = isCurve();
258  send_data.d[34] = isSlope();
259  //経過時間の情報を送信用配列に格納
260  time = getElapsedTime();
261  send_data.d[35] = 0x000000ff & time;
262  send_data.d[36] = (0x0000ff00 & time)>>8;
263  send_data.d[37] = (0x00ff0000 & time)>>16;
264  send_data.d[38] = (0xff000000 & time)>>24;
265  //Lipoの電圧を送信用配列に格納
266  v_lipo = (uint16_t)(getLipoVoltage() * 13107); //0.0~5.0を0から65535に変換
267  send_data.d[39] = 0x000000ff & v_lipo;
268  send_data.d[40] = (0x0000ff00 & v_lipo)>>8;
269  //Batteryの電圧を送信用配列に格納
270  v_bat = (uint16_t)(getMotorVoltage() * 13107); //0.0~5.0を0から65535に変換
271  send_data.d[41] = 0x000000ff & v_bat;
272  send_data.d[42] = (0x0000ff00 & v_bat)>>8;
273 
274 
275  //20Hzの周期でデータを送る (割り込み周期100Hz 5回に一回)
276  if(count % 5 == 0 && flag_send_data_enable == 1)
277  {
278  //UART経由でデータを送信
279  LPC_UART->IER = IER_THRE | IER_RLS; // Disable RBR
280  UARTSend(&send_data.d[0], send_data.num);
281  LPC_UART->IER = IER_THRE | IER_RLS | IER_RBR; // Re-enable RBR
282 
283  if(isUSBConfig() == 1) //USB接続確立
284  {
285  //USB経由でデータを送信
286  VCOM_SendData(send_data);
287 
288  }
289  }
290 
291  count++;
292 
293  //UART経由での受信データの処理
294  execUARTCommand();
295 
296 }
297 
304 static void execUARTCommand()
305 {
306  uint16_t i;
307 
308  if(UARTCount >9)
309  {
310  //UARTBufferにデータが10byte以上入っていてかつ'cmd'のパターンを見つけたら
311  //コマンドを実行
312  for(i=0;i< UARTCount-9; i++)
313  {
314  if(UARTBuffer[i] == 'c' &&
315  UARTBuffer[i+1] == 'm' &&
316  UARTBuffer[i+2] == 'd' &&
317  UARTCount -i >9)
318  {
319  execCommand( &UARTBuffer[i] );
320  }
321  }
322  }
323 
324  //UARTBufferのデータを10byte分だけ残して消去
325  //10byte分残すのはバッファにコマンドの断片が混じっている可能性があるため
326 
327  if(UARTCount >9){
328  for(i=0;i<10;i++)
329  {
330  UARTBuffer[9-i] = UARTBuffer[UARTCount-1-i];
331  }
332  UARTCount = 10;
333  }
334  //残した10byte分が意味のあるコマンドの場合は既に実行されているはずなのでバッファを空にする
335  if( UARTBuffer[0] == 'c' &&
336  UARTBuffer[1] == 'm' &&
337  UARTBuffer[2] == 'd' &&
338  UARTCount == 10)
339  {
340  UARTCount = 0;
341  }
342 
343 }
344 
366 static void execCommand(uint8_t *cmd)
367 {
368  uint8_t id = cmd[3];
369 
370  int16_t duty_int;
371  int16_t deg_int;
372  switch(id)
373  {
374  case 0:
375  duty_int = cmd[4] + (cmd[5]<<8);
376  if (duty_int > 32767) duty_int -= 65536;
377  setDutyMotor((float)(duty_int)/32767.0 );
378  break;
379  case 1: turnGreenLED(cmd[4]);
380  break;
381  case 2: turnRedLED(cmd[4]);
382  break;
383  case 3: flashGreenLED( cmd[4]+(cmd[5]<<8), cmd[6]+(cmd[7]<<8) );
384  break;
385  case 4: flashRedLED( cmd[4]+(cmd[5]<<8), cmd[6]+(cmd[7]<<8) );
386  break;
387  case 5:
388  deg_int = cmd[4] + (cmd[5]<<8);
389  if (deg_int > 32767) deg_int -= 65536;
390  setDegree( (float)(deg_int)/32767.0 * PI );
391  break;
392  }//switch
393 
394 }
395 
396 
403 float getDegree(void)
404 {
405  return degree;
406 };
407 
408 
415 void setDegree(float deg)
416 {
417  degree = deg;
418 };
419 
420 
428 {
429  return flag_stop;
430 }
431 
432 
440 {
441  return flag_curve;
442 }
443 
444 
452 {
453  return flag_slope;
454 }
455 
456 
464 {
465  myPrintfUART("########debug AICHIP#######\n");
466  myPrintfUART("motor duty : %f \n", getDutyMotor());
467  myPrintfUART("degree : %f \n", getDegree());
468  myPrintfUART("is stop : %d \n", isStop());
469  myPrintfUART("is curve : %d \n", isCurve());
470  myPrintfUART("is slope : %d \n", isSlope());
471 }
472 
473 
474 /******************************************************************************
475 ** End Of File
476 ******************************************************************************/
void getDataFromMPU6050(uint8_t *dest_array)
Definition: mpu9150.c:147
void debugAICHIP()
uint32_t getElapsedTime(void)
#define ABS(IN)
void getOmega(float *vec)
Definition: mpu9150.c:319
#define PI
void setSendDataEnable(uint8_t en)
void initAICHIP(void)
signed char int8_t
Definition: type.h:21
int myPrintfUART(const char *fmt,...)
Definition: debug.c:42
uint8_t isStop(void)
void setDutyMotor(float pwm_duty)
void setDegree(float deg)
volatile uint8_t UARTBuffer[BUFSIZE]
Definition: uart.c:20
CMSIS Cortex-M3 Core Peripheral Access Layer Header File.
void UARTSend(uint8_t *BufferPtr, uint32_t Length)
Definition: uart.c:165
unsigned char uint8_t
Definition: type.h:27
void flashRedLED(uint16_t on_count, uint16_t off_count)
volatile uint32_t UARTCount
Definition: uart.c:21
uint8_t isSlope(void)
#define IER_RLS
Definition: uart.h:21
void VCOM_SendData(GETDAT_T dat)
void startTimer32_1(void)
Definition: timer.c:76
float getDegree(void)
uint8_t d[100]
float getDutyMotor(void)
float getMotorVoltage(void)
float getLipoVoltage(void)
void Init_PWM2(void)
Definition: pwm.c:40
void getAccLPF(float *vec)
Definition: mpu9150.c:445
uint8_t isCurve(void)
#define IER_THRE
Definition: uart.h:20
#define IER_RBR
Definition: uart.h:19
signed short int int16_t
Definition: type.h:22
unsigned short int uint16_t
Definition: type.h:28
void getDataFromAK8975(uint8_t *dest_array)
Definition: mpu9150.c:261
void getOmegaStrLPF(float *vec)
Definition: mpu9150.c:457
#define BUFSIZE
Definition: i2c.h:16
uint8_t isUSBConfig(void)
#define DEG2RAD(deg)
void flashGreenLED(uint16_t on_count, uint16_t off_count)
void turnRedLED(uint8_t state)
float tSqrt(float x)
void setDutyPWM2(float duty)
Definition: pwm.c:72
void turnGreenLED(uint8_t state)
volatile float gain_LPF
Definition: mpu9150.c:45
void TIMER32_1_IRQHandler(void)
unsigned int uint32_t
Definition: type.h:29