web-dev-qa-db-ja.com

ループarduinoを停止する方法

このループがありますが、どのようにループを終了しますか?

 void loop() {
      // read the pushbutton input pin:

       a ++;
      Serial.println(a);
        analogWrite(speakerOut, NULL);

      if(a > 50 && a < 300){
      analogWrite(speakerOut, 200);
      }

      if(a <= 49){
        analogWrite(speakerOut, NULL);
      }

      if(a >= 300 && a <= 2499){
          analogWrite(speakerOut, NULL);
      }
11
Beep

Arduinoは、実際に実行するコードが示すように、loop関数を終了する方法を特に提供しません。

setup();

for (;;) {
    loop();
    if (serialEventRun) serialEventRun();
}

それに加えて、マイクロコントローラでは、そもそも終了するものは何もありません。

最も近い方法は、プロセッサを停止することです。それはリセットされるまで処理を停止します。

9
Matti Virkkunen

これはArduino.ccでは公開されていませんが、実際には単純なexit(0)でループルーチンを終了できます。

これは、ボードリストにあるほぼすべてのボードでコンパイルされます。 IDE1.0.6。Uno、Mega、Micro Pro、さらにはAdafruit Trinketでもテストしました。

void loop() {
// All of your code here

/* Note you should clean up any of your I/O here as on exit, 
all 'ON'outputs remain HIGH */

// Exit the loop 
exit(0);  //The 0 is required to prevent compile error.
}

リセットピンにボタンを配線するプロジェクトでこれを使用します。基本的に、ループはexit(0)まで実行されます。そして最後の状態にとどまります。子供向けのロボットをいくつか作成しました。ボタンを押す(リセットする)たびに、コードはloop()関数の開始から始まります。

38
Zoul007

Matti Virkkunen は正しく言った。ループを止める「まともな」方法はない。それにもかかわらず、コードを見ていくつかの仮定を行うことで、特定の周波数の信号を出力しようとしていると思いますが、それを止めたいと考えています。

その場合、いくつかの解決策があります。

  1. ボタンの入力で信号を生成する場合は、次のことができます

    int speakerOut = A0;
    int buttonPin = 13;
    
    void setup() {
        pinMode(speakerOut, OUTPUT);
        pinMode(buttonPin, INPUT_PULLUP);
    }
    
    int a = 0;
    
    void loop() {
        if(digitalRead(buttonPin) == LOW) {
            a ++;
            Serial.println(a);
            analogWrite(speakerOut, NULL);
    
            if(a > 50 && a < 300) {
                analogWrite(speakerOut, 200);
            }
    
            if(a <= 49) {
                analogWrite(speakerOut, NULL);
            }
    
            if(a >= 300 && a <= 2499) {
                analogWrite(speakerOut, NULL);
            }
        }
    }
    

    この場合、ボタンピンをINPUT_PULLUPとして使用しています。 Arduino reference を読んでこのトピックの詳細を確認できますが、この構成では簡単に内部プルアップ抵抗を設定するため、外部抵抗を必要とせずにボタンをグランドに接続できます。 :これによりボタンのレベルが反転し、LOWが押され、HIGHがリリースされます。

  2. もう1つのオプションは、組み込みハードウェアタイマーの1つを使用して、割り込みで定期的に呼び出される関数を取得することです。 here は、それが何であり、どのように使用するかについてのすばらしい説明です。

9

思い浮かぶ3つのオプション:

1番目)void loop()while(1)...で終了するか、同等に... while(true)で終了します

_void loop(){
    //the code you want to run once here, 
    //e.g., If (blah == blah)...etc.

    while(1)        //last line of main loop
}
_

このオプションは、コードを1回実行してから、Ardを無限の「見えない」ループにキックします。おそらく最も良い方法ではありませんが、外見に関しては、仕事が完了します。
Ardは無限の円を描くように電流を流し続けます。たぶん、Ardを何秒、何分など後にスリープさせるようなタイマー機能を設定できます。ループ...ただの考え...確かにさまざまなスリープライブラリがあります。たとえば、Monk、Programming Arduino:Next Steps、pgs。、85-100などを参照してください。

2)2回目のパスで最初のテストが失敗する条件付き制御構造を持つ「メインループの停止」関数を作成します。
これには、グローバル変数を宣言し、終了時に変数の値を切り替える「メインループの停止」機能を必要とすることがよくあります。例えば。、

_boolean stop_it = false;         //global variable

void setup(){
    Serial.begin(9600); 
    //blah...
}

boolean stop_main_loop(){        //fancy stop main loop function

    if(stop_it == false){   //which it will be the first time through

        Serial.println("This should print once.");

       //then do some more blah....you can locate all the
       // code you want to run once here....eventually end by 
       //toggling the "stop_it" variable ... 
    }
    stop_it = true; //...like this
    return stop_it;   //then send this newly updated "stop_it" value
                     // outside the function
}

void loop{ 

    stop_it = stop_main_loop();     //and finally catch that updated 
                                    //value and store it in the global stop_it 
                                    //variable, effectively 
                                    //halting the loop  ...
}
_

確かに、これは特にきれいではないかもしれませんが、機能します。
Ardを別の無限の「見えない」ループにキックしますが、今回はif(stop_it == false)stop_main_loop()条件を繰り返しチェックする場合です。最初の時間の後の時間。

3)もう一度グローバル変数を使用できますが、派手な「メインループを停止する」関数の代わりに単純なif (test == blah){}構造体を使用できます。

_boolean start = true;                  //global variable

void setup(){

      Serial.begin(9600);
}

void loop(){

      if(start == true){           //which it will be the first time through



           Serial.println("This should print once.");       

           //the code you want to run once here, 
           //e.g., more If (blah == blah)...etc.

     }

start = false;                //toggle value of global "start" variable
                              //Next time around, the if test is sure to fail.
}
_

厄介な無限のメインループを「停止」する方法は確かに他にもありますが、これらの3つと既に説明した方法を使用すると、開始できます。

3
philomech

これにより、割り込みがオフになり、CPUが(リセット/電源が切り替わるまで永続的な)スリープ状態になります。

cli();
sleep_enable();
sleep_cpu();

詳細については http://arduino.land/FAQ/content/7/47/en/how-to-stop-an-arduino-sketch.html も参照してください。

2
Sigivald
> #include <SPI.h>
> #include <MFRC522.h>
> #include <Ethernet.h>
> 
> #define RST_PIN 4
> #define SS_PIN 2
> 
> String content="";
> 
> byte mac[]={0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED}; IPAddress
> ip(192,168,3,15);
> 
> MFRC522 mfrc522(SS_PIN, RST_PIN); EthernetClient client;
> 
> void setup() {   Serial.begin(9600);                                  
> SPI.begin();   while(!Serial){;}   Ethernet.begin(mac, ip);           
> mfrc522.PCD_Init();             
>                                     //Serial.println(F("Silahkan Scan Kartu RFID Anda:")); }
> 
> void loop() {   rfid();   database(); }
> 
> void rfid(){   //membaca kartu RFID   if ( !
> mfrc522.PICC_IsNewCardPresent())    {
>     return;   }   // memilih salah satu card yang terdeteksi   if ( ! mfrc522.PICC_ReadCardSerial())    {
>     return;   }
>      //Serial.print("Kartu Anda Adalah :");   //String content= "";   //byte letter;   //for (byte i = 0; i < mfrc522.uid.size; i++) {
>      //Serial.print(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " ");
>      //Serial.print(mfrc522.uid.uidByte[i], HEX);
>      //content.concat(String(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " "));
>      //content.concat(String(mfrc522.uid.uidByte[i], HEX));   //}   //Serial.println();   //delay(1000); //change value if you want to
> read cards faster
> 
>   //mfrc522.PICC_HaltA();   //mfrc522.PCD_StopCrypto1(); }
> 
> void database(){   EthernetClient client;   rfid();   if
> (client.connect("192.168.3.12", 80)){
>     Serial.print("Kartu Anda Adalah :"); 
>     String content="";
>     byte letter;
>     for (byte i = 0; i < mfrc522.uid.size; i++) {
>      Serial.print(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " ");
>      Serial.print(mfrc522.uid.uidByte[i], HEX);
>      content.concat(String(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " "));
>      content.concat(String(mfrc522.uid.uidByte[i], HEX));   }   Serial.println();   delay(1000); //change value if you want to read
> cards faster   mfrc522.PICC_HaltA();   mfrc522.PCD_StopCrypto1();
>     
>     //Serial.println("connected");
>     Serial.print(content);
>     client.println("POST /gerbang2/insert.php HTTP/1.1");
>     client.println("Host: 192,168,3,12"); 
>     client.println("Connection: close");
>     client.print("Content-Type: application/x-www-form-urlencoded\n");
>     client.print("Content-Length: "); 
>     client.print(content.length());
>     client.print("\n\n");
>     client.print(content);
>     Serial.println(content);
>     delay (1000);
>     client.stop();     }   else{
>     Serial.println("Connection Failed.");  
>     Serial.println();
>     delay (1000);   } }

シリアルモニターでループを停止する方法は?

0
한룻디