Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: BufferedSoftSerial2 SDFileSystem-RTOS mbed mbed-rtos INA226_ver1
Fork of keiki2016ver5 by
main.cpp
00001 //計器プログラム 00002 #include "mbed.h" 00003 #include "rtos.h" 00004 #include "Cadence.h" 00005 #include "Fusokukei.h" 00006 #include "MPU6050.h" 00007 #include "BufferedSoftSerial.h" 00008 #include "SDFileSystem.h"//2014.6/5以前の環境で動作します。アップデートすると動きません。 00009 #include "INA226.hpp" 00010 00011 #define SOUDA_DATAS_NUM 28 //(yokutan 7 + input 7)*2 00012 #define YOKUTAN_DATAS_NUM 14 00013 #define WRITE_DATAS_NUM 34 // souda_datas_num + 6( rpy, airspeed, height, cadence) 00014 #define SD_WRITE_NUM 20 00015 #define MPU_LOOP_TIME 0.01 00016 #define AIR_LOOP_TIME 0.01//(0.002005) 00017 #define WRITE_DATAS_LOOP_TIME 1 00018 #define ROLL_R_MAX_DEG 1.5 00019 #define ROLL_L_MAX_DEG 1.5 00020 #define MPU_DELT_MIN 250 00021 #define INIT_SERVO_PERIOD_MS 20 00022 00023 //-----------------------------------(resetInterrupt def) 00024 //extern "C" void mbed_reset(); 00025 //InterruptIn resetPin(p25); 00026 //Timer resetTimeCount; 00027 //void resetInterrupt() 00028 //{ 00029 // while(resetPin) { 00030 // resetTimeCount.start(); 00031 // if(resetTimeCount.read()>3) mbed_reset(); 00032 // } 00033 // resetTimeCount.reset(); 00034 //} 00035 //------------------------------------------------------- 00036 00037 //SDFileSystem sd(p5, p6, p7, p8, "sd"); 00038 LocalFileSystem local("local"); 00039 FILE* fp; 00040 00041 //RawSerial pc(USBTX,USBRX); 00042 //Serial android(p9,p10); 00043 BufferedSoftSerial soudaSerial(p17,p18); 00044 BufferedSoftSerial twe(p11,p12); 00045 //Cadence cadence_twe(p13,p14); 00046 RawSerial android(p13,p14); 00047 00048 Ticker cadenceUpdateTicker; 00049 //Ticker writeDatasTicker; 00050 //Timer writeTimer; 00051 00052 InterruptIn FusokukeiPin(p24); 00053 Ticker FusokukeiTicker; 00054 Fusokukei air; 00055 volatile int air_kaitensu= 0; 00056 00057 //Timer sonarTimer; 00058 AnalogIn sonarPin(p15); 00059 double sonarDist; 00060 float sonarV; 00061 00062 00063 float sum = 0; 00064 uint32_t sumCount = 0; 00065 MPU6050 mpu6050; 00066 Timer t; 00067 Timer cadenceTimer; 00068 00069 //Ticker mpu6050Ticker; 00070 00071 DigitalOut RollAlarmR(p23); 00072 DigitalOut RollAlarmL(p22); 00073 DigitalOut led2(LED2); 00074 //DigitalOut led3(LED3); 00075 DigitalOut led4(LED4); 00076 I2C InaI2c(p9,p10); 00077 INA226 VCmonitor(InaI2c,0x9C); 00078 AnalogIn mgPin(p20); 00079 AnalogIn mgPin2(p16); 00080 00081 char soudaDatas[SOUDA_DATAS_NUM]; 00082 float writeDatas[SD_WRITE_NUM][WRITE_DATAS_NUM]; 00083 volatile int write_datas_index = 0; 00084 float inputR,inputL; 00085 int drugR,drugL; 00086 00087 void air_countUp(); 00088 void call_calcAirSpeed(); 00089 void sonarInterruptStart(); 00090 void sonarInterruptStop(); 00091 void updateCadence(double source, double input,double input2,bool isFFlag); 00092 void init(); 00093 void FusokukeiInit(); 00094 void MpuInit(); 00095 void mpuProcessing(void const *arg); 00096 void DataReceiveFromSouda(void const *arg); 00097 void SdInit(); 00098 void SDprintf(); 00099 void WriteDatas(); 00100 float calcAttackAngle(); 00101 float calcKXdeg(float x); 00102 int lastCadenceInput = 0; //1つ前のケイデンスのパルス値を取得します。これの取りうる値は0か1です。 00103 int lastCadenceInput2 = 0; //1つ前のケイデンスのパルス値を取得します。これの取りうる値は0か1です。 00104 double cadenceResult = 0.0; //最終的なケイデンスの値です。 00105 int cadenceCounter = 0; //クランクが一回転すると、二つのセンサがそれぞれ2回ずつ状態が変化するため、0~4をカウントするためのカウンタです。 00106 double V; 00107 00108 void air_countUp() 00109 { 00110 air_kaitensu++; 00111 // led3 = !led3; 00112 } 00113 00114 void call_calcAirSpeed() 00115 { 00116 air.calcAirSpeed(air_kaitensu); 00117 air_kaitensu = 0; 00118 } 00119 00120 void sonarInterruptStart() 00121 { 00122 // sonarTimer.start(); 00123 } 00124 00125 void sonarInterruptStop() 00126 { 00127 // sonarTimer.stop(); 00128 // sonarDistTime = sonarTimer.read_us(); 00129 // sonarTimer.reset(); 00130 // sonarDist = sonarDistTime*0.018624 - 13.511; 00131 } 00132 void sonarCalc() 00133 { 00134 sonarV = 0; 00135 for(int i = 0; i<20; i++) { 00136 sonarV += sonarPin.read(); 00137 wait(0.01); 00138 } 00139 sonarDist = (sonarV/20)*2064.5;// volt*3.3*1000/1.6 (電圧/距離:3.2mV/2cm) 00140 } 00141 00142 00143 // 定格12V電源の電圧値から定めた閾値を、oh182/E非接触回転速度センサ値が超えているかどうか 00144 // source: 定格12V電源の電圧値[mV], input: センサ値[mV] 00145 // return => 1:超えている, 0:超えていない, -1:エラー 00146 int isOh182eOverThreshold(double source, double input) 00147 { 00148 double a, b; 00149 if(source < 3200) 00150 return -1; 00151 00152 if(source < 5500) 00153 a = 0.233333333, b = -308.3333333; 00154 else if(source < 7000) 00155 a = 0.173333333, b = 21.66666667; 00156 else 00157 a = 0, b = 1235; 00158 00159 return (a * source + b < input) ? 1 : 0; 00160 } 00161 00162 //ケイデンスの値を取得します。 00163 // source: 定格12V電源の電圧値[mV], input: センサ値[mV] 00164 void updateCadence(double source, double input,double input2) 00165 { 00166 00167 static bool isFFlag = true; 00168 if(isFFlag) { 00169 lastCadenceInput = isOh182eOverThreshold(source,input); 00170 lastCadenceInput2 = isOh182eOverThreshold(source,input2); 00171 cadenceTimer.start(); 00172 isFFlag = false; 00173 return; 00174 } 00175 if((isOh182eOverThreshold(source,input) != lastCadenceInput) ||(isOh182eOverThreshold(source,input2) != lastCadenceInput2)) { 00176 if(cadenceCounter < 3) { 00177 cadenceCounter++; 00178 led3 = !led3; 00179 lastCadenceInput = isOh182eOverThreshold(source,input); 00180 lastCadenceInput2 = isOh182eOverThreshold(source,input2); 00181 return; 00182 } 00183 cadenceResult =60.0/ (cadenceTimer.read_us() / 1000000.0); //クランク一回転にかかる時間を取得 00184 cadenceTimer.reset(); 00185 cadenceCounter = 0; 00186 } 00187 lastCadenceInput = isOh182eOverThreshold(source,input); 00188 lastCadenceInput2 = isOh182eOverThreshold(source,input2); 00189 } 00190 00191 void init() 00192 { 00193 pc.printf("(BUILD:[" __DATE__ "/" __TIME__ "])\n\r"); 00194 //--------------------------------------(resetInterrupt init) 00195 // resetPin.rise(resetInterrupt); 00196 // resetPin.mode(PullDown); 00197 //----------------------------------------------------------- 00198 twe.baud(14400);//BufferedSoftSerialでは19200が上限。twelite側でもBPS無効化が必要 00199 android.baud(9600); 00200 //writeTimer.start(); 00201 FusokukeiInit(); 00202 // SdInit(); 00203 // MpuInit(); 00204 //writeDatasTicker.attach(&WriteDatas,1); 00205 00206 //-----for InterruptMode of sonar---------------------------- 00207 // sonarPin.rise(&sonarInterruptStart); 00208 // sonarPin.fall(&sonarInterruptStop); 00209 //----------------------------------------------------------- 00210 unsigned short val; 00211 val = 0; 00212 if(VCmonitor.rawRead(0x00,&val) != 0) { 00213 printf("VCmonitor READ ERROR\n"); 00214 // while(1) {} 00215 } 00216 VCmonitor.setCurrentCalibration(); 00217 } 00218 00219 void FusokukeiInit() 00220 { 00221 FusokukeiPin.rise(air_countUp); 00222 FusokukeiTicker.attach(&call_calcAirSpeed, AIR_LOOP_TIME); 00223 } 00224 00225 void MpuInit() 00226 { 00227 i2c.frequency(400000); // use fast (400 kHz) I2C 00228 t.start(); 00229 uint8_t whoami = mpu6050.readByte(MPU6050_ADDRESS, WHO_AM_I_MPU6050); // Read WHO_AM_I register for MPU-6050 00230 if (whoami == 0x68) { // WHO_AM_I should always be 0x68 00231 Thread::wait(100); 00232 mpu6050.MPU6050SelfTest(SelfTest); // Start by performing self test and reporting values 00233 Thread::wait(100); 00234 if(SelfTest[0] < 1.0f && SelfTest[1] < 1.0f && SelfTest[2] < 1.0f && SelfTest[3] < 1.0f && SelfTest[4] < 1.0f && SelfTest[5] < 1.0f) { 00235 mpu6050.resetMPU6050(); // Reset registers to default in preparation for device calibration 00236 mpu6050.calibrateMPU6050(gyroBias, accelBias); // Calibrate gyro and accelerometers, load biases in bias registers 00237 mpu6050.initMPU6050(); ////////////pc.printf("MPU6050 initialized for active data mode....\n\r"); // Initialize device for active mode read of acclerometer, gyroscope, and temperature 00238 Thread::wait(200); 00239 } else { 00240 } 00241 } else { 00242 //////pc.printf("out\n\r"); // Loop forever if communication doesn't happen 00243 } 00244 } 00245 00246 double calcPulse(int deg) 00247 { 00248 return (0.0006+(deg/180.0)*(0.00235-0.00045)); 00249 } 00250 00251 void mpuProcessing(void const *arg) 00252 { 00253 MpuInit(); 00254 while(1) { 00255 if(mpu6050.readByte(MPU6050_ADDRESS, INT_STATUS) & 0x01) { // check if data ready interrupt 00256 mpu6050.readAccelData(accelCount); // Read the x/y/z adc values 00257 mpu6050.getAres(); 00258 ax = (float)accelCount[0]*aRes - accelBias[0]; // get actual g value, this depends on scale being set 00259 ay = (float)accelCount[1]*aRes - accelBias[1]; 00260 az = (float)accelCount[2]*aRes - accelBias[2]; 00261 mpu6050.readGyroData(gyroCount); // Read the x/y/z adc values 00262 mpu6050.getGres(); 00263 gx = (float)gyroCount[0]*gRes; // - gyroBias[0]; // get actual gyro value, this depends on scale being set 00264 gy = (float)gyroCount[1]*gRes; // - gyroBias[1]; 00265 gz = (float)gyroCount[2]*gRes; // - gyroBias[2]; 00266 tempCount = mpu6050.readTempData(); // Read the x/y/z adc values 00267 temperature = (tempCount) / 340. + 36.53; // Temperature in degrees Centigrade 00268 } 00269 Now = t.read_us(); 00270 deltat = (float)((Now - lastUpdate)/1000000.0f) ; // set integration time by time elapsed since last filter update 00271 lastUpdate = Now; 00272 sum += deltat; 00273 sumCount++; 00274 if(lastUpdate - firstUpdate > 10000000.0f) { 00275 beta = 0.04; // decrease filter gain after stabilized 00276 zeta = 0.015; // increasey bias drift gain after stabilized 00277 } 00278 mpu6050.MadgwickQuaternionUpdate(ax, ay, az, gx*PI/180.0f, gy*PI/180.0f, gz*PI/180.0f); 00279 delt_t = t.read_ms() - count; 00280 if (delt_t > MPU_DELT_MIN) { 00281 yaw = atan2(2.0f * (q[1] * q[2] + q[0] * q[3]), q[0] * q[0] + q[1] * q[1] - q[2] * q[2] - q[3] * q[3]); 00282 pitch = -asin(2.0f * (q[1] * q[3] - q[0] * q[2])); 00283 roll = atan2(2.0f * (q[0] * q[1] + q[2] * q[3]), q[0] * q[0] - q[1] * q[1] - q[2] * q[2] + q[3] * q[3]); 00284 pitch *= 180.0f / PI; 00285 yaw *= 180.0f / PI; 00286 roll *= 180.0f / PI; 00287 myled= !myled; 00288 count = t.read_ms(); 00289 sum = 0; 00290 sumCount = 0; 00291 } 00292 Thread::wait(1); 00293 }//while(1) 00294 } 00295 00296 void DataReceiveFromSouda(/*void const *arg*/) 00297 { 00298 char cErebonR[6] = {}; 00299 char cErebonL[6] = {}; 00300 // while(1){ 00301 if(soudaSerial.readable()) { 00302 led2 = !led2; 00303 char c = soudaSerial.getc(); 00304 while( c != ';' ) { 00305 c = soudaSerial.getc(); 00306 } 00307 for(int i = 0; i < SOUDA_DATAS_NUM; i++) { 00308 soudaDatas[i] = soudaSerial.getc(); 00309 // pc.printf("%d,",(int)(soudaDatas[i] - '0')); 00310 } 00311 // pc.printf("\n\r"); 00312 // sscanf(soudaDatas+YOKUTAN_DATAS_NUM,"%5.2f,%d,%5.2,%d",&inputR,&drugR,&inputL,&drugL); 00313 for(int i = 14; i < 19; i++) { 00314 cErebonR[i-14] = soudaDatas[i]; 00315 } 00316 drugR = soudaDatas[19]- '0'; 00317 inputR = atof(cErebonR); 00318 for(int i = 21; i < 26; i++) { 00319 cErebonL[i-21] = soudaDatas[i]; 00320 } 00321 drugL = soudaDatas[26]- '0'; 00322 inputL = atof(cErebonL); 00323 00324 // pc.printf("erebonR:%5.5f, drugR:%d erebonL:%5.5f drugL:%d",inputR,drugR,inputL,drugL); 00325 // pc.printf("erebonR:%s, drugR:%d erebonL:%s drugL:%d",cErebonR,drugR,cErebonL,drugL); 00326 }//if 00327 // }//while(1) 00328 } 00329 00330 void SdInit() 00331 { 00332 // mkdir("/local/mydir", 0777); 00333 fp = fopen("/local/filetest.csv", "w"); 00334 if(fp == NULL) { 00335 printf("Could not open file for write\n"); 00336 return; 00337 } 00338 fprintf(fp, "Hello fun SD Card World!\n\r%f",0.1f); 00339 fclose(fp); 00340 } 00341 00342 void SDprintf(const void* arg) 00343 { 00344 SdInit(); 00345 while(1) { 00346 updateCadence(V,mgPin.read() * 3300.0,mgPin2.read() * 3300.0); 00347 // pc.printf("V:%5.5f mgPin:%5.5f mgPin2:%5.5f",V,mgPin.read() * 3300.0,mgPin2.read() * 3300.0); 00348 if(write_datas_index == SD_WRITE_NUM-1) { 00349 fp = fopen("/local/data.csv", "a"); 00350 if(fp == NULL) { 00351 error("Could not open file for write!!\n"); 00352 } 00353 for(int i = 0; i < SD_WRITE_NUM; i++) { 00354 for(int j = 0; j < WRITE_DATAS_NUM; j++) { 00355 fprintf(fp,"%f,", writeDatas[i][j]); 00356 } 00357 fprintf(fp,"\n"); 00358 } 00359 00360 fclose(fp); 00361 00362 write_datas_index=0; 00363 } 00364 Thread::wait(100); 00365 } 00366 } 00367 00368 void WriteDatas() 00369 { 00370 int i; 00371 for(i = 0; i < SOUDA_DATAS_NUM; i++) { 00372 //writeDatas[write_datas_index][i] = 0.0; 00373 writeDatas[write_datas_index][i] = (float)soudaDatas[i]; 00374 } 00375 writeDatas[write_datas_index][i++] = pitch; 00376 writeDatas[write_datas_index][i++] = roll; 00377 writeDatas[write_datas_index][i++] = yaw; 00378 writeDatas[write_datas_index][i++] = airSpeed; 00379 writeDatas[write_datas_index][i++] = sonarDist; 00380 writeDatas[write_datas_index][i++] = cadenceResult;//cadence_twe.cadence; 00381 //writeDatas[write_datas_index][i++] = writeTimer.read(); 00382 //for(i = 0; i < WRITE_DATAS_NUM; i++){ 00383 // ////pc.printf("%f ", writeDatas[write_datas_index][i]); 00384 // twe.printf("%f,", writeDatas[write_datas_index][i]); 00385 // } 00386 // //pc.printf("\n\r"); 00387 // twe.printf("\n\r"); 00388 if(write_datas_index == SD_WRITE_NUM-1) { 00389 // SDprintf(); 00390 write_datas_index=0; 00391 } else { 00392 write_datas_index++; 00393 } 00394 char sbuf[128]; 00395 int p=0; 00396 // twe.printf("con,"); 00397 p += sprintf(sbuf,"con,"); 00398 for(int i = 0; i <YOKUTAN_DATAS_NUM ; i++) { 00399 // pc.printf("%i ",soudaDatas[i]); 00400 // twe.printf("%i,",soudaDatas[i]); 00401 p += sprintf(sbuf+p,"%d,",soudaDatas[i]); 00402 00403 if(i == YOKUTAN_DATAS_NUM - 1) 00404 // twe.printf("%i\n",soudaDatas[i]); 00405 p += sprintf(sbuf+p,"%d\n",soudaDatas[i]); 00406 } 00407 twe.printf("%s",sbuf); 00408 // twe.printf("inp,%f,%i,%f,%i\n",soudaDatas[YOKUTAN_DATAS_NUM],soudaDatas[sizeof(float) + YOKUTAN_DATAS_NUM + 2],(int)soudaDatas[SOUDA_DATAS_NUM - sizeof(float) - 3],soudaDatas[SOUDA_DATAS_NUM-1]); 00409 twe.printf("inp,%f,%i,%f,%i\n",inputR,drugR,inputL,drugL); 00410 00411 /* 00412 送信文字列 00413 0-13翼端データ 00414 14-17 R erebon 00415 18 R DRUG 00416 19-22 L erebon 00417 23 LDRUG 00418 */ 00419 ////pc.printf("\n\r"); 00420 twe.printf("mpu,%f,%f,%f\n",pitch,roll,yaw); 00421 twe.printf("kei,%f,%f,%f\n",airSpeed,sonarDist,cadenceResult);//cadence_twe.cadence); 00422 00423 ////pc.printf("%f,%f,%f\n\r",calcKXdeg(kx_X.read()),calcKXdeg(KX_Y),calcKXdeg(KX_Z)); 00424 // pc.printf("%f,%f,%f\n\r",airSpeed,sonarDist,cadenceResult);//cadence_twe.cadence); 00425 // pc.printf("%d,%i,%d,%i,",soudaDatas[YOKUTAN_DATAS_NUM],soudaDatas[sizeof(int) + YOKUTAN_DATAS_NUM + 2],(int)soudaDatas[SOUDA_DATAS_NUM - sizeof(int) - 3],soudaDatas[SOUDA_DATAS_NUM-1]); 00426 // pc.printf("%f,%f,%f\n\r",pitch,roll,yaw); 00427 // printf("mgPin V:%f\n\r",mgPin.read()*3.3); 00428 // pc.printf("%d,%i,%d,%i\n%f,%f,%f\n%f,%f,%f\n\r", 00429 // soudaDatas[YOKUTAN_DATAS_NUM],soudaDatas[sizeof(int) + YOKUTAN_DATAS_NUM + 2],(int)soudaDatas[SOUDA_DATAS_NUM - sizeof(int) - 3],soudaDatas[SOUDA_DATAS_NUM-1], 00430 // pitch,roll,yaw, 00431 // airSpeed,sonarDist,cadenceResult); 00432 // pc.printf("cadence:%5.5f\n\r",cadenceResult); 00433 00434 // for(int i = 0; i < strlen(cadence_twe.myBuff); i++){ 00435 // ////pc.printf("%c",*(cadence_twe.myBuff+i)); 00436 // } 00437 // pc.printf("%f\t%f\t%f\t%f\n\r",airSpeed,air_sum[0],air_sum[1],air_sum[2]); 00438 if(android.writeable()) { 00439 // android.printf("%f,%f,%f,",pitch,roll,yaw); 00440 // android.printf("%f,%f,\r\n",airSpeed,sonarDist); 00441 android.printf("%4.2f,%4.2f,%4.2f,\n,",roll,airSpeed,cadenceResult);//cadence_twe.cadence); 00442 // led2 = !led2; 00443 } 00444 // SDprintf(); 00445 } 00446 00447 void WriteDatasF() 00448 { 00449 //pc.printf("airSpeed:%f\n\r",airSpeed); 00450 } 00451 00452 //float calcKXdeg(float x){ 00453 // return -310.54*x+156.65; 00454 //} 00455 00456 void RollAlarm() 00457 { 00458 if((roll < -ROLL_L_MAX_DEG ) && (roll > ROLL_L_MAX_DEG-180)) { 00459 RollAlarmL = 1; 00460 } else { 00461 RollAlarmL = 0; 00462 } 00463 00464 if((roll > ROLL_R_MAX_DEG) && (roll < 180-ROLL_R_MAX_DEG)) { 00465 RollAlarmR = 1; 00466 } else { 00467 RollAlarmR = 0; 00468 } 00469 } 00470 00471 int main() 00472 { 00473 Thread mpu_thread(&mpuProcessing); 00474 Thread SD_thread(&SDprintf); 00475 // Thread soudaSerial_thread(&DataReceiveFromSouda); 00476 init(); 00477 // int VCcounter = 0; 00478 while(1) { 00479 // if(VCcounter%20 == 0 ) { 00480 // if( VCmonitor.getVoltage(&V) == 0) { 00481 // pc.printf("e:%f\n",V); 00482 // } 00483 // } 00484 // VCcounter++; 00485 00486 // updateCadence(V,mgPin.read() * 3.3,mgPin2.read() * 3.3,isFirstCadenceFlag); 00487 //pc.printf("test\n\r"); 00488 // mpuProcessing(); 00489 sonarCalc(); 00490 Thread::wait(30); 00491 RollAlarm(); 00492 DataReceiveFromSouda(); 00493 WriteDatas(); 00494 led4 = !led4; 00495 } 00496 }
Generated on Sat Jul 16 2022 23:53:49 by
1.7.2
