赤子を殺すより楽な作業よv2

Dependencies:   RemoteIR TextLCD

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 /* mbed Microcontroller Library
00002  * Copyright (c) 2019 ARM Limited
00003  * SPDX-License-Identifier: Apache-2.0
00004  */
00005 
00006 #include "mbed.h"
00007 #include "ReceiverIR.h"
00008 #include "rtos.h"
00009 #include <stdint.h>
00010 #include "platform/mbed_thread.h"
00011 #include "TextLCD.h"
00012 
00013 Serial pc(USBTX, USBRX);
00014 
00015 /* マクロ定義、列挙型定義 */
00016 #define MIN_V 2.0
00017 #define MAX_V 2.67
00018 #define     LOW     0       // 
00019 #define     HIGH    1       // 
00020 #define     NORMAL   0       // フラグ値
00021 #define     FAST   1       // フラグ値
00022 #define     VERYFAST   2       // フラグ値
00023 
00024 enum MODE{
00025     READY   = -1,
00026     ADVANCE = 1,
00027     RIGHT,
00028     LEFT,
00029     BACK,
00030     STOP,
00031     LINE_TRACE,
00032     AVOIDANCE,
00033     SPEED,
00034 };
00035 
00036 /* ピン配置 */
00037 ReceiverIR   ir(p5);        // リモコン操作
00038 DigitalOut  trig(p6);       // 超音波センサtrigger
00039 DigitalIn   echo(p7);       // 超音波センサecho
00040 DigitalIn   ss1(p8);        // ライントレースセンサ(左)
00041 DigitalIn   ss2(p9);        // ライントレースセンサ
00042 DigitalIn   ss3(p10);       // ライントレースセンサ
00043 DigitalIn   ss4(p11);       // ライントレースセンサ
00044 DigitalIn   ss5(p12);       // ライントレースセンサ(右)
00045 Serial      esp(p13, p14);  // Wi-Fiモジュール(tx, rx)
00046 AnalogIn    battery(p15);   // 電池残量読み取り(Max 3.3V)
00047 PwmOut      motorR2(p21);   // 右モーター後退
00048 PwmOut      motorR1(p22);   // 右モーター前進
00049 PwmOut      motorL2(p23);   // 左モーター後退
00050 PwmOut      motorL1(p24);   // 左モーター前進
00051 PwmOut      servo(p25);     // サーボ
00052 I2C         i2c_lcd(p28,p27);   // LCD(tx, rx)
00053 
00054 /* 変数宣言 */
00055 int mode;                   // 操作モード
00056 int run;                    // 走行状態
00057 int beforeMode;             // 前のモード
00058 int flag_sp = 0;             // スピード変化フラグ
00059 Timer viewTimer;            // スピ―ド変更時に3秒計測
00060 float motorSpeed[9] = {0.7, 0.8, 0.9, 0.75, 0.85, 0.95, 0.8, 0.9, 1.0};
00061                             // モーター速度設定(後半はライントレース用)
00062 Mutex  mutex;                       
00063 // ポートp15を赤外線受信モジュールの接続先に指定
00064 RemoteIR::Format format;
00065 uint8_t buf[32];
00066 uint32_t bitcount;
00067 uint32_t code;
00068 
00069 //bChangeのいろいろ
00070 TextLCD_I2C lcd(&i2c_lcd, (0x27 << 1), TextLCD::LCD16x2, TextLCD::HD44780);
00071 int b = 0;
00072 double test;
00073 int flag_b = 0;
00074 int flag_t = 0;
00075 
00076 // ライントレース
00077 int sensArray[32] = {0,0,0,0,0,0,0,0,   // ライントレースセンサパターン
00078                     0,0,0,0,0,0,0,0,
00079                     0,0,0,0,0,0,0,0,
00080                     0,0,0,0,0,0,0,0};
00081 
00082 /* 障害物検知用の変数設定 */
00083 Timer timer;            // 距離計測用タイマ
00084 int DT;                 // 距離
00085 int SC;                 // 正面   
00086 int SL;                 // 左
00087 int SR;                 // 右
00088 int SLD;                // 左前
00089 int SRD;                // 右前
00090 int flag_a = 0;           // 障害物有無のフラグ
00091 const int limit = 20;   // 障害物の距離のリミット(単位:cm)
00092 int far;                // 最も遠い距離
00093 int houkou;             // 進行方向(1:前 2:左 3:右)
00094 int i;                  // ループ変数
00095 
00096 
00097 
00098 /* プロトタイプ宣言 */
00099 void decodeIR(void const *argument);
00100 void motor(void const *argument);
00101 void changeSpeed();
00102 void avoidance(void const *argument);
00103 void trace(void const *argument);
00104 void watchsurrounding();
00105 int watch();
00106 void bChange();
00107 void display();
00108 void lcdBacklight(void const *argument);
00109 Thread thread1(decodeIR, NULL, osPriorityRealtime);//+3
00110 Thread thread2(motor, NULL, osPriorityHigh);//+2
00111 Thread thread3(avoidance, NULL, osPriorityHigh);//+2
00112 Thread thread4(trace, NULL, osPriorityHigh);//+2
00113 RtosTimer bTimer(lcdBacklight, osTimerPeriodic);
00114 
00115 DigitalOut led1(LED1);
00116 
00117 
00118 void decodeIR(void const *argument){ 
00119    while(1){ 
00120         // 受信待ち
00121         pc.printf("decodeIR\r\n");
00122         if (ir.getState() == ReceiverIR::Received) {
00123             // コード受信
00124             bitcount = ir.getData(&format, buf, sizeof(buf) * 8);
00125             if(bitcount > 1){
00126                 // 受信成功
00127                 code=0;
00128                 for(int j=0;j<4;j++){
00129                     code+=(buf[j]<<(8*(3-j)));
00130                 }
00131                 if(mode!=SPEED){
00132                     beforeMode=mode;
00133                 }
00134                 
00135                 //pc.printf("%0x\r\n",code);
00136                 switch(code){
00137                     case 0x40bf27d8://クイック
00138                         pc.printf("mode = SPEED\r\n");
00139                         mode = SPEED;
00140                         changeSpeed();
00141                         display();  
00142                         mode = beforeMode;
00143                         break;
00144                     case 0x40be34cb://レグザリンク
00145                         pc.printf("mode = INE_TRACE\r\n");
00146                         mode=LINE_TRACE;
00147                         display();
00148                         break;
00149                     case 0x40bf6e91://番組表
00150                         pc.printf("mode = AVOIDANCE\r\n");
00151                         mode=AVOIDANCE;
00152                         display();
00153                         break;
00154                     case 0x40bf3ec1://↑
00155                         pc.printf("mode = ADVANCE\r\n");
00156                         mode = ADVANCE;
00157                         run = ADVANCE;
00158                         display();
00159                         break;
00160                     case 0x40bf3fc0://↓
00161                         pc.printf("mode = BACK\r\n");
00162                         mode = BACK;
00163                         run = BACK;
00164                         display();
00165                         break;
00166                     case 0x40bf5fa0://←
00167                         pc.printf("mode = LEFT\r\n");
00168                         mode = LEFT;
00169                         run = LEFT;
00170                         display();
00171                         break;
00172                     case 0x40bf5ba4://→
00173                         pc.printf("mode = RIGHT\r\n");
00174                         mode = RIGHT;
00175                         run = RIGHT;
00176                         display();
00177                         break;
00178                     case 0x40bf3dc2://決定
00179                         pc.printf("mode = STOP\r\n");
00180                         mode = STOP;
00181                         run = STOP;
00182                         display();
00183                         break;
00184                     default:
00185                         ;
00186                 }
00187             }
00188         }
00189         if(viewTimer.read_ms()>=3000){
00190             viewTimer.stop();
00191             viewTimer.reset();
00192             display();
00193         }
00194         ThisThread::sleep_for(90);
00195     }       
00196 }
00197 void motor(void const *argument){
00198     while(true){
00199         pc.printf("motor\r\n");
00200         switch(run){
00201             case ADVANCE:
00202                 motorR1 = motorSpeed[flag_sp];
00203                 motorR2 = LOW;
00204                 motorL1 = motorSpeed[flag_sp];
00205                 motorL2 = LOW;
00206                 break;
00207             case RIGHT:
00208                 motorR1 = LOW;
00209                 motorR2 = motorSpeed[flag_sp];
00210                 motorL1 = motorSpeed[flag_sp];
00211                 motorL2 = LOW;
00212                 break;
00213             case LEFT:
00214                 motorR1 = motorSpeed[flag_sp];
00215                 motorR2 = LOW;
00216                 motorL1 = LOW;
00217                 motorL2 = motorSpeed[flag_sp];
00218                 break;
00219             case BACK:
00220                 motorR1 = LOW;
00221                 motorR2 = motorSpeed[flag_sp];
00222                 motorL1 = LOW;
00223                 motorL2 = motorSpeed[flag_sp];
00224                 break;
00225             case STOP:
00226                 motorR1 = LOW;
00227                 motorR2 = LOW;
00228                 motorL1 = LOW;
00229                 motorL2 = LOW;
00230                 break;
00231         }
00232         pc.printf("                motor\r\n");
00233         if(flag_sp > VERYFAST){
00234             flag_sp -= 3 * (flag_sp / 3);
00235         ThisThread::sleep_for(30);
00236     }
00237 }
00238 void changeSpeed(){
00239     if(flag_sp%3 == 2){
00240         flag_sp -= 2;
00241         
00242     }else{
00243         flag_sp = flag_sp + 1;   
00244     }  
00245 }
00246 void trace(void const *argument){
00247     while(true){ 
00248         if(mode==LINE_TRACE){        
00249             pc.printf("line trace\r\n");
00250             // センサー値読み取り
00251             int sensor1 = ss1;
00252             int sensor2 = ss2;
00253             int sensor3 = ss3;
00254             int sensor4 = ss4;
00255             int sensor5 = ss5;
00256         
00257             int sensD = 0;
00258             int sensorNum;
00259         
00260             if(sensor1 > 0) sensD |= 0x10;
00261             if(sensor2 > 0) sensD |= 0x08;
00262             if(sensor3 > 0) sensD |= 0x04;
00263             if(sensor4 > 0) sensD |= 0x02;
00264             if(sensor5 > 0) sensD |= 0x01;
00265     
00266             sensorNum = sensArray[sensD];
00267     
00268             switch(sensorNum){
00269                 case 1:
00270                     run = ADVANCE;
00271                     break;
00272                 case 2:
00273                     run = RIGHT;
00274                     break;
00275                 case 3:
00276                     run = LEFT;
00277                     break;
00278                 case 4:
00279                     flag_sp %= 3 + 3;
00280                     run = RIGHT;
00281                     break;
00282                 case 5:
00283                     flag_sp %= 3 + 3;
00284                     run = LEFT;
00285                     break;
00286                 case 6:
00287                     flag_sp %= 3 + 6;
00288                     run = RIGHT;
00289                     break;
00290                 case 7:
00291                     flag_sp %= 3 + 6;
00292                     run = LEFT;
00293                     break;
00294             }
00295             pc.printf("                          line trace\r\n");
00296             ThisThread::sleep_for(30);
00297         }else{          
00298             ThisThread::sleep_for(1);
00299         }
00300     }
00301 }
00302 
00303 /* 障害物回避走行 */
00304 void avoidance(void const *argument){
00305     while(1){  
00306         if(mode==AVOIDANCE){
00307             pc.printf("avoidance\r\n");
00308             pc.printf("%d  %d  %d  %d  %d  \r\n",SL,SLD,SC,SRD,SR); 
00309             
00310             if(flag_a == 0){                      // 障害物がない場合
00311                 run = ADVANCE;                  // 前進
00312             }
00313             else{                               // 障害物がある場合                   
00314                 i = 0;
00315                 if(SC < 15){                    // 正面15cm以内に障害物が現れた場合
00316                     run = BACK;                 // 後退
00317                     while(watch() < limit){     // 正面20cm以内に障害物がある間
00318                         if(mode!=AVOIDANCE){
00319                             break;    
00320                         }
00321                     }
00322                     run = STOP;                 // 停止                 
00323                 }
00324                 if(SC < limit && SLD < limit && SL < limit && SRD < limit && SR < limit){   // 全方向に障害物がある場合
00325                     run = LEFT;                 // 左折                   
00326                     while(i < 10){             // 進行方向確認
00327                         if(mode!=AVOIDANCE){
00328                                 break;    
00329                         }   
00330                         if(watch() > limit){    
00331                             i++;
00332                                          
00333                         }
00334                         else{                   
00335                             i = 0;              
00336                         }
00337                     }
00338                     run = STOP;                 // 停止
00339                 }
00340                 else {                          // 全方向以外                          
00341                     far = SC;                   // 正面を最も遠い距離に設定
00342                     houkou = 1;                 // 進行方向を前に設定
00343                     if(far < SLD || far < SL){  // 左または左前がより遠い場合
00344                         if(SL < SLD){           // 左前が左より遠い場合
00345                             far = SLD;          // 左前を最も遠い距離に設定
00346                         }
00347                         else{                   // 左が左前より遠い場合
00348                             far = SL;           // 左を最も遠い距離に設定
00349                         }
00350                         houkou = 2;             // 進行方向を左に設定
00351                     }
00352                     if(far < SRD || far < SR){  // 右または右前がより遠い場合
00353                         if(SR < SRD){           // 右前が右より遠い場合
00354                             far = SRD;          // 右前を最も遠い距離に設定
00355                         }
00356                         else{                   // 右が右前よりも遠い場合
00357                             far = SR;           // 右を最も遠い距離に設定
00358                         }
00359                         houkou = 3;             // 進行方向を右に設定
00360                     }
00361                     switch(houkou){                         // 進行方向の場合分け
00362                         case 1:                             // 前の場合
00363                             run = ADVANCE;                  // 前進
00364                             pc.printf("Advance\r\n");
00365                             thread_sleep_for(100);          // 1秒待つ
00366                             break;
00367                         case 2:                             // 左の場合
00368                             run = LEFT;                     // 左折
00369                             while(i < 10){                 // 進行方向確認
00370                                 pc.printf("left\r\n");
00371                                 if(mode!=AVOIDANCE){
00372                                         break;    
00373                                 }
00374                                 if(watch() > (far - 2)){    
00375                                     i++;
00376                                     
00377                                 }
00378                                 else{
00379                                     i = 0;
00380                                 }
00381                             }
00382                             run = STOP;                     // 停止
00383                             break;
00384                         case 3:                             // 右の場合
00385                             run = RIGHT;                    // 右折
00386                             while(i < 10){                 // 進行方向確認
00387                                 pc.printf("right\r\n");
00388                                 if(mode!=AVOIDANCE){
00389                                     break;    
00390                                 }
00391                                 if(watch() > (far - 2)){
00392                                     i++;
00393                                     
00394                                 }
00395                                 else{
00396                                     i = 0;
00397                                 }
00398                             }
00399                             run = STOP;                     // 停止
00400                             break;
00401                     }
00402                 }
00403             }
00404             pc.printf("こんにちは!\r\n");
00405             flag_a = 0;                   // フラグを0にセット
00406             watchsurrounding();
00407             pc.printf("                avoidance\r\n");
00408         }else{  
00409             ThisThread::sleep_for(1);
00410         }
00411     }   
00412 }
00413 int watch(){
00414     led1=0;
00415     pc.printf("watch\r\n");
00416     trig = 0;
00417     ThisThread::sleep_for(5);           // 5ms待つ
00418     trig = 1;
00419     ThisThread::sleep_for(15);          // 15ms待つ
00420     trig = 0;
00421     while(echo.read() == 0){
00422         led1=1;
00423         if(mode!=AVOIDANCE){
00424             break;    
00425         }
00426     }
00427     timer.start();                  // 距離計測タイマースタート
00428     while(echo.read() == 1){
00429     }
00430     timer.stop();                   // 距離計測タイマーストップ
00431     DT = (int)(timer.read_us()*0.01657);   // 距離計算
00432     if(DT > 100){                   // 検知範囲外なら400cmに設定
00433         DT = 100;
00434     }
00435     
00436     timer.reset();                  // 距離計測タイマーリセット
00437     //ThisThread::sleep_for(30);      // 30ms待つ
00438     pc.printf("私はDTである。%d\r\n",DT);
00439     return DT;
00440 }
00441 
00442 void watchsurrounding(){
00443     pc.printf("watchsurrounding\r\n");
00444     SC = watch();
00445     if(SC < limit){                 // 正面20cm以内に障害物がある場合
00446         run = STOP;                 // 停止
00447     }
00448     servo.pulsewidth_us(1925);      // サーボを左に40度回転
00449     ThisThread::sleep_for(250);           // 250ms待つ
00450     SLD = watch();
00451     if(SLD < limit){                // 左前20cm以内に障害物がある場合
00452         run = STOP;                 // 停止
00453     }
00454     servo.pulsewidth_us(2400);      // サーボを左に90度回転
00455     ThisThread::sleep_for(250);           // 250ms待つ
00456     SL = watch();
00457     if(SL < limit){                 // 左20cm以内に障害物がある場合
00458         run = STOP;                 // 停止
00459     }
00460     servo.pulsewidth_us(1450);
00461     ThisThread::sleep_for(100);
00462     servo.pulsewidth_us(925);       // サーボを右に40度回転
00463     ThisThread::sleep_for(250);           // 250ms待つ
00464     SRD = watch();
00465     if(SRD < limit){                // 右前20cm以内に障害物がある場合
00466         run = STOP;                 // 停止
00467     }
00468     servo.pulsewidth_us(500);       // サーボを右に90度回転
00469     ThisThread::sleep_for(250);           // 250ms待つ
00470     SR = watch();
00471     if(SR < limit){                 // 右20cm以内に障害物がある場合
00472         run = STOP;                 // 停止
00473     }
00474     servo.pulsewidth_us(1450);      // サーボを中央位置に戻す
00475     ThisThread::sleep_for(100);           // 100ms待つ
00476     if(SC < limit || SLD < limit || SL < limit || SRD < limit || SR < limit){ // 20cm以内に障害物を検知した場合
00477         flag_a = 1;                   // フラグに1をセット
00478     }
00479     pc.printf("                watchsurrounding\r\n");
00480 }
00481 
00482 void defaultView(){
00483     lcd.setAddress(0,0);
00484     lcd.printf("Battery:");
00485     lcd.setAddress(0,1);
00486     lcd.printf("Mode:");
00487 }
00488 
00489 void display(){
00490         mutex.lock();
00491         lcd.setAddress(0,1);
00492         switch(mode){
00493             case ADVANCE:
00494                 //strcpy(DispMode,"Mode:Advance");
00495                 lcd.printf("Mode:Advance    ");
00496                 break;
00497             case RIGHT:
00498                 //strcpy(DispMode,"Mode:Right");
00499                 lcd.printf("Mode:TurnRight  ");
00500                 break;
00501             case LEFT:
00502                 //strcpy(DispMode,"Mode:Left");
00503                 lcd.printf("Mode:TurnLeft   ");
00504                 break;
00505             case BACK:
00506                 //strcpy(DispMode,"Mode:Back");
00507                 lcd.printf("Mode:Back       ");
00508                 break;
00509             case STOP:
00510                 //strcpy(DispMode,"Mode:Stop");
00511                 lcd.printf("Mode:Stop       ");
00512                 break;
00513             case READY:
00514                 //strcpy(DispMode,"Mode:Stop");
00515                 lcd.printf("Mode:Ready      ");
00516                 break;
00517             case LINE_TRACE:
00518                 //strcpy(DispMode,"Mode:LineTrace");
00519                 lcd.printf("Mode:LineTrace  ");
00520                 break;
00521             case AVOIDANCE:
00522                 //strcpy(DispMode,"Mode:Avoidance");
00523                 lcd.setAddress(0,1);
00524                 lcd.printf("Mode:Avoidance  ");
00525                 break;
00526             case SPEED:
00527                 switch(flag_sp){
00528                     case(NORMAL):
00529                         lcd.printf("Speed:Normal    ");
00530                         break;
00531                     case(FAST):
00532                         lcd.printf("Speed:Fast      ");
00533                         break;
00534                     case(VERYFAST):
00535                         lcd.printf("Speed:VeryFast  ");
00536                         break;
00537                 }
00538                 viewTimer.reset();
00539                 viewTimer.start();  
00540                 break;              
00541         }
00542         mutex.unlock(); 
00543 }
00544 
00545 void lcdBacklight(void const *argument){
00546     if(flag_b == 1){
00547         lcd.setBacklight(TextLCD::LightOn);
00548     }else{
00549         lcd.setBacklight(TextLCD::LightOff);
00550     }
00551     flag_b = !flag_b;
00552 }
00553 
00554 void bChange(){
00555     lcd.setBacklight(TextLCD::LightOn);
00556     while(1){
00557         pc.printf("                                                                              bChange1\r\n");
00558         b = (int)(((battery.read() * 3.3 - MIN_V)/0.67)*10+0.5)*10;
00559         //pc.printf("%f",battery.read());
00560         if(b < 0){//すべての機能停止(今はなし)
00561             b = 0;
00562         }else if(b > 50){
00563             b = 50;
00564         }
00565         mutex.lock();
00566         lcd.setAddress(0,0);
00567         lcd.printf("Battery:%3d%%",b);
00568         pc.printf("                                                                              bChange2\r\n");
00569         mutex.unlock();
00570         if(b <= 30){
00571             if(flag_t == 0){
00572                 bTimer.start(500);
00573                 flag_t = 1;
00574             }
00575         }else{
00576             if(flag_t == 1){
00577                 bTimer.stop();
00578                 lcd.setBacklight(TextLCD::LightOn);
00579                 flag_t = 0;
00580             }
00581         }
00582     }
00583     ThisThread::sleep_for(500);    
00584 }
00585 int main() {
00586     mode = READY;
00587     beforeMode = READY;
00588     run = STOP;
00589     flag_sp = NORMAL;
00590     display();
00591     
00592     while(1){
00593         pc.printf("                                    main1\r\n");
00594         bChange();
00595         pc.printf("                                    main2\r\n");
00596         ThisThread::sleep_for(1);
00597     }
00598 }