2012-04-25 20 views
2

Arduinoプログラムが何の理由もなくハングする問題があります。私はプログラムを実行し、いくつかの不確定な点では、シリアルモニタは印刷出力を停止します。これまでテストしたことは次のとおりです。Arduinoでの予期しないプログラムの停止

  • 私の "com.init_drone()"メソッドでは、メソッドが返されたことを知らせる最後の行を除いてすべてコメントしました。私がこれをすると、私のプログラムはどこかでハングアップしますが、それでも無限ループにはなりません。
  • 私はメモリ使用量を出力していますが、私は450以上の数値を取得しています。これは、私が不合理な量のメモリを使用していないことを示しています。
  • 私は、プログラムに何の影響も与えていない、Timer1インスタンス化、割り込みのアタッチ/デタッチ、割り込みを削除しようとしました。
  • 私の.ino file(and Command) is located hereは、完全な画像を望んでおり、このコードをすべてスクロールしたくない場合は、以下で投稿します。


    ここまでは私のログ出力です。 トランケーションに注意してください!:ここ

     
    
    AT&F 
    AT+NMAC=00:1d:c9:10:39:6f 
    AT+WM=0 
    AT+NDHCP=1 
    AT+WA=ardrone_279440 
    AT+NCUDP=192.168.1.1,5556 
    S0AT*CONFIG=1,"general:navdata_demo","TRUE" 
    EAT*CONFIG=1,"general:navdata_demo","TRUE" 
    
    638 
    S0AT*CONFIG=2,"control:altitude_max","2000" 
    EAT*CONFIG=2,"control:altitude_max","2000" 
    
    638 
    S0AT*CONFIG=3,"control:euler_angle_max","0.35" 
    EAT*CONFIG=3,"control:euler_angle_max","0.35" 
    
    586 
    S0AT*CONFIG=4,"control:outdoor","FALSE" 
    EAT*CONFIG=4,"control:outdoor","FALSE" 
    
    635 
    S0AT*CONFIG=5,"control:flight_without_shell","FALSE" 
    EAT*CONFIG=5,"control:flight_without_shell","FALSE" 
    
    574 
    S0AT*CTRL=6,4,0 
    EAT*CTRL=6,4,0 
    
    629 
    S0AT*CTRL=7,0,0 
    EAT*CTRL=7,0,0 
    
    629 
    S0AT*CTRL=8,4,0 
    EAT*CTRL=8,4,0 
    
    629 
    S0AT*COMWDG=9 
    EAT*COMWDG=9 
    
    629 
    S0AT*COMWDG=10 
    EAT*COMWDG=10 
    
    629 
    S0AT*COMWDG=11 
    EAT*COMWDG=11 
    
    629 
    S0AT*COMWDG=12 
    EAT*COMWDG=12 
    
    629 
    S0AT*COMWDG=13 
    EAT*COMWDG=13 
    
    629 
    S0AT*FTRIM=14 
    EAT*FTRIM=14 
    
    629 
    

    は私の.inoファイルです:

    #include "Command.h" 
    #include "Streaming.h" 
    
    int debug = 1; 
    extern ring_buffer rx_buf; 
    extern resultint_ resultint; 
    
    Command com; 
    int sequenceNumber = 1; 
    String atcmd = ""; 
    
    #include "TimerOne.h" 
    #define LEDpin 13 
    
    
    
    void setup() 
    { 
        PCsrl.begin(9600); 
    
        com.start_wifi_connection(); 
    
        com.drone_is_init = com.init_drone(); 
    
        Timer1.initialize(COMWDG_INTERVAL_USEC); 
        Timer1.attachInterrupt(watchdog_timer); 
    
    } 
    
    void watchdog_timer() { 
        com.sendwifi(com.makeComwdg()); 
    } 
    
    void loop() 
    { 
    
        if (com.drone_is_init == 0) { 
         if (debug) { 
         // never use three ! together in arduino code 
         PCsrl.println("Drone wasn't initlized before loop() was called. Initalizing now.\r\n"); 
        } 
    
        } else { 
    
        com.drone_takeoff(); 
        com.drone_takeoff(); 
    
        com.sendwifi(com.makePcmd(1,0,0,0,0)); 
        com.sendwifi(com.makePcmd(1,0,0,0,0)); 
        delay(5000); 
    
        com.moveForward(1); 
        com.moveRotate(180); 
        com.moveForward(1); 
        com.moveRotate(180); 
    
        delay(500); 
    
        com.drone_landing(); 
        com.drone_landing(); 
    
        delay(500); 
    
        //end of program 
        Timer1.detachInterrupt(); 
        PCsrl.println("Program finished"); 
        while (1){}; 
    
        } 
    } 
    

    そして、私のCommand.cpp

    #ifndef GAINSPAN 
    #define GAINSPAN 
    #include "Command.h" 
    
    extern int sequenceNumber; 
    extern int debug; 
    
    ring_buffer rx_buf= {{0}, 0, 0}; 
    resultint_ resultint; 
    
    
    Command::Command() 
    { 
        at = ""; 
        command = ""; 
        s2ip_running = 0; 
        drone_is_init = 0; 
        drone_is_hover = 0; 
        emergency = 0; 
    } 
    
    
    void Command::sendwifi(String s) { 
    
        WIFIsrl.write(27); //esc 
        WIFIsrl.print("S0"); //choose connection CID 0 
        WIFIsrl.print(s); 
        WIFIsrl.write(27); 
        WIFIsrl.print("E"); 
    
    
        if(debug) PCsrl.println(s); 
    
        WIFIsrl.println(memoryTest()); 
    } 
    
    
    
    int Command::start_wifi_connection() 
    { 
        WIFIsrl.begin(9600); 
    
        WIFIsrl.println(""); 
        WIFIsrl.println("AT&F"); 
        //WIFIsrl.println("ATE0"); //turn off echo 
        WIFIsrl.print("AT+NMAC=00:1d:c9:10:39:6f\r"); //set MAC address 
        WIFIsrl.println("AT+WM=0"); 
    
        WIFIsrl.println("AT+NDHCP=1"); 
    
        /* drone's network profile, change if needed*/ 
        WIFIsrl.println("AT+WA=ardrone_279440"); 
        WIFIsrl.println("AT+NCUDP=192.168.1.1,5556"); 
        readARsrl(); 
    
        delay(3000); //need 3 seconds for connection to establish 
        return 0; 
    } 
    
    String Command::makeComwdg() 
    { 
        at = "AT*COMWDG="; 
        command = at + getSequenceNumber() + "\r\n"; 
        return command; 
    } 
    
    void Command::sendComwdg_t(int msec) 
    { 
        for (int i = 0; i < msec; i+=20) { 
        sendwifi(makeComwdg()); 
        delay(20); 
        } 
    } 
    
    void Command::sendFtrim() 
    { 
        at = "AT*FTRIM="; 
        command = at + getSequenceNumber() + "\r\n"; 
        sendwifi(command); 
    } 
    
    void Command::sendConfig(String option, String value) 
    { 
        at = "AT*CONFIG="; 
        command = at + getSequenceNumber() + ",\"" + option + "\",\"" + value + "\"\r\n"; 
        sendwifi(command); 
    } 
    
    void Command::sendRef(flying_status fs) 
    { 
        at = "AT*REF="; 
        if(fs == TAKEOFF){ 
        command = at + getSequenceNumber() + ",290718208\r\n"; //takeoff 
        } 
        else if(fs == LANDING){ 
        command = at + getSequenceNumber() + ",290717696\r\n"; //landing 
        } else if (fs == EMERGENCY_TOGGLE){ 
        command = at + getSequenceNumber() + ",290717952\r\n"; //landing 
        } 
    
        // emergency -> 290717952 
        sendwifi(command); 
    } 
    
    void Command::send_control_commands(){ 
        at = "AT*CTRL="; 
        sendwifi(at+getSequenceNumber()+",4,0\r\n"); 
        sendwifi(at+getSequenceNumber()+",0,0\r\n"); 
        sendwifi(at+getSequenceNumber()+",4,0\r\n"); 
    } 
    
    void Command::drone_emergency_reset() 
    { 
        at = "AT*REF="; 
        command = at + getSequenceNumber() + ",290717952\r\n"; 
        sendwifi(command); 
    } 
    
    /** Movement functions **/ 
    int Command::moveForward(float distanceInMeters) 
    { 
        float i = 0; 
        String moveForward = makePcmd(1, 0, -.855, 0, 0); 
        delay(1000*distanceInMeters); 
        sendPcmd(moveForward); 
        return 1; 
    } 
    
    int Command::moveRotate(float yawInDegrees) 
    { 
        int i = 0; 
        while (i < yawInDegrees) { 
        String stayRotate = makePcmd(1, 0, 0, 0, 0.17); 
        sendPcmd(stayRotate); 
        delay(150); 
        i += 8; 
        } 
        return 1; 
    } 
    
    String Command::makePcmd(int enable, float roll, float pitch, float gaz, float yaw) 
    { 
        at = "AT*PCMD="; 
        command = at + getSequenceNumber() + "," + enable + "," + fl2int(roll) + "," + fl2int(pitch) + "," + fl2int(gaz) + "," + fl2int(yaw) + "\r"; 
        return command; 
    } 
    
    void Command::sendPcmd(String command) 
    { 
        previousCommand = command; 
        sendwifi(command); 
    } 
    
    void Command::sendPcmd(int enable, float roll, float pitch, float gaz, float yaw) 
    { 
        at = "AT*PCMD="; 
        command = at + getSequenceNumber() + "," + enable + "," + fl2int(roll) + "," + fl2int(pitch) + "," + fl2int(gaz) + "," + fl2int(yaw) + "\r"; 
        sendwifi(command); 
    } 
    
    String Command::makeAnim(anim_mayday_t anim, int time) 
    { 
        at = "AT*ANIM="; 
        command = at + getSequenceNumber() + "," + anim + "," + time + "\r\n"; 
        return command; 
    } 
    
    void Command::doLEDAnim(int animseq, int duration) 
    { 
        PCsrl << "calling LEDAnim" << endl; 
        at = "AT*LED="; 
        command = at + getSequenceNumber() + "," + animseq + ",1073741824," + duration + "\r\n"; 
        sendwifi(command); 
    } 
    
    int Command::start_s2ip() 
    { 
        char temp; 
        //delay(20000); //wait for drone to start 
    
        readARsrl(); 
    
        if (debug) { 
        PCsrl << "trying to start s2ip" << endl; 
        } 
    
        ARsrl.print("\r\n"); 
        delay(500); 
        ARsrl.print("\r\n"); 
        delay(500); 
        ARsrl << "cd ~" << endl; 
    
        if (debug) { 
        readARsrl(); 
        } 
    
        delay(500); 
        ARsrl << "cd data/video/apps/" << endl; 
        delay(500); 
        ARsrl << "./s2ip.arm" << endl; 
        while ((int) temp != 2) { 
        temp = ARsrl.read(); 
        if (temp == 2) { 
         PCsrl << "s2ip is running" << endl; 
         ARsrl << "bullshit\r\n"; //to fix a delay bug 
         break; 
        } 
        //PCsrl << "s2ip not running" << endl; 
        } 
        if (debug) { 
        while (ARsrl.available()) { 
         PCsrl.write(ARsrl.read()); 
        } 
        } 
        return 1; 
    } 
    
    void Command::quit_s2ip() 
    { 
        ARsrl.println("EXIT"); 
        while (ARsrl.available()) { 
        PCsrl.write(ARsrl.read()); 
        } 
    } 
    
    int Command::init_drone() 
    { 
        sendConfig("general:navdata_demo","TRUE"); 
        sendConfig("control:altitude_max","2000"); 
        sendConfig("control:euler_angle_max","0.35"); 
        sendConfig("control:outdoor","FALSE"); 
        sendConfig("control:flight_without_shell","FALSE"); 
        send_control_commands(); 
        sendComwdg_t(90); 
        sendFtrim(); 
    
        drone_emergency_reset(); //clear emergency flag 
    
        return 1; 
    } 
    
    int Command::drone_takeoff() 
    { 
        sendRef(TAKEOFF); 
        int i = 0; 
        return 1; 
    } 
    
    int Command::drone_hover(int msec) 
    { 
        int i = 0; 
        while (i < msec) { 
        sendwifi(makePcmd(1, 0, 0, 0, 0)); 
        delay(100); 
        i += 100; 
        } 
        return 1; 
    } 
    
    int Command::drone_landing() 
    { 
        sendRef(LANDING); 
        return 1; 
    } 
    
    int Command::drone_move_up(int centimeter) 
    { 
        int i = 0; 
        while (i < centimeter) { 
        ARsrl << makePcmd(1, 0, 0, 0.6, 0); 
        delay(100); 
        i += 10; 
        } 
        return 1; 
    } 
    
    int Command::drone_move_down(int centimeter) 
    { 
        int i = 0; 
        while (i < centimeter) { 
        sendwifi(makePcmd(1, 0, 0, -0.5, 0)); 
        delay(100); 
        i += 10; 
        } 
        return 1; 
    } 
    
    long Command::fl2int(float value) 
    { 
        resultint.i = 0; 
        if (value < -1 || value > 1) { 
        resultint.f = 1; 
        } else { 
        resultint.f=value; 
        } 
    
        return resultint.i; 
    } 
    
    void Command::readARsrl() 
    { 
        while (ARsrl.available()) { 
        if (debug) { 
         PCsrl.write(ARsrl.read()); 
        } 
        } 
    } 
    
    
    //Memory test code from : http://www.faludi.com/2007/04/18/arduino-available-memory-test/ 
    int Command::memoryTest() { 
        int byteCounter = 0; // initialize a counter 
        byte *byteArray; // create a pointer to a byte array 
        // More on pointers here: http://en.wikipedia.org/wiki/Pointer#C_pointers 
    
        // use the malloc function to repeatedly attempt 
        // allocating a certain number of bytes to memory 
        // More on malloc here: http://en.wikipedia.org/wiki/Malloc 
        while ((byteArray = (byte*) malloc (byteCounter * sizeof(byte))) != NULL) { 
        byteCounter++; // if allocation was successful, then up the count for the next try 
        free(byteArray); // free memory after allocating it 
        } 
    
        free(byteArray); // also free memory after the function finishes 
        return byteCounter; // send back the highest number of bytes successfully allocated 
    } 
    
    int Command::getSequenceNumber(){ 
        return sequenceNumber++; 
    } 
    
    // Volatile, since it is modified in an ISR. 
    volatile boolean inService = false; 
    
    void SrlRead() 
    { 
        if (inService) { 
        PCsrl.println("timer kicked too fast"); 
        return; 
        } 
        interrupts(); 
        inService = true; 
        while(ARsrl.available()) { 
        unsigned char k = ARsrl.read(); 
        store_char(k, &rx_buf); 
        } 
        inService = false; 
    } 
    
    void read_rx_buf() 
    { 
        while (rx_buf.tail != rx_buf.head) { 
        if (debug) { 
         PCsrl.write(rx_buf.buffer[rx_buf.tail]); 
        } 
        rx_buf.tail = (unsigned int) (rx_buf.tail+ 1) % SERIAL_BUFFER_SIZE; 
        } 
    } 
    
    inline void store_char(unsigned char c, ring_buffer *buffer) 
    { 
        int i = (unsigned int)(buffer->head + 1) % SERIAL_BUFFER_SIZE; 
    
        // if we should be storing the received character into the location 
        // just before the tail (meaning that the head would advance to the 
        // current location of the tail), we're about to overflow the buffer 
        // and so we don't write the character or advance the head. 
        if (i != buffer->tail) { 
        buffer->buffer[buffer->head] = c; 
        buffer->head = i; 
        } 
        else { 
        Serial.println("ring buffer is too small"); 
        } 
    } 
    
    #endif 
    
    +2

    使用可能なメモリーをチェックする場合は、ここで説明する(最初の)メカニズムを使用することをお勧めします。http://arduino.cc/playground/Code/AvailableMemoryあなたのコードの 'memoryTest'ルーチンは、空きメモリを計算するためにかなり侵略的な(しかも時間がかかる)方法であるメモリを割り当てたり、割り当てを解除したりします。 –

    +1

    'setup()'( '#define PCsrl Serial'を使って)、' start_wifi_connection() '(' #define WIFIsrl Serial'を使って)で連続して 'Serial.begin()'を2回呼び出します。どのようにこれがぶら下がりを引き起こす可能性があるか分かりませんが、ちょうど確認するためにコメントする価値があるかもしれません。 –

    +0

    @MatthewMurdoch:私は気付かなかった。それは問題を解決しませんでしたが、私のコードのバグでした。ありがとう! – hwrdprkns

    答えて

    1

    progメモリに物を入れ始めると、私のプログラムは問題を解決し始めました。それは記憶の問題だったようです。

    +1

    あなたのコードを見ると、小さなマイクロコントローラにとって膨大な量の膨大なものがあります。 "ring buffer is too small"のようなものは、例外的な例外でなければならないことがあります。これは、 '〜10'のようなものを出力するsignal_exception(10)のようなものです。また、sendPcmdのようなものはmakePcmdを呼び出して送信するだけです。しかし、関係なく、定数の文字列はプログラムのメモリに置かれるのが最善であり、それらのローカル文字列定数の多くはRAMを解放するために移動することもできます。 – PeterJ

    2

    私はそれはArduinoのがなっていないときに時々、この問題が発生した、奇妙に聞こえるが、知っています十分な電源。 arduinoをUSBとは異なる電源に接続してみてください。

    0

    私は同じ問題がありましたが、問題はTimer1.initialize()でした。これを試してください:

    com.drone_is_init = com.init_drone(); 
    
        Serial.println("One"); 
        Serial.println("Two"); 
        Serial.println("Three"); 
    
        Timer1.initialize(COMWDG_INTERVAL_USEC); 
        Timer1.attachInterrupt(watchdog_timer); 
    

    シリアルモニタを開くと、「2」まで表示され、その後Arduinoがハングします。

    私はLiquidCrystal_I2Cライブラリのいくつかの関数を呼び出していましたが、割り込みルーチンが必要でした。タイマーISRがいくつかの割り込みを使用しているかどうかを確認してください。その場合は、このコードをプロジェクトの別の場所に移動する必要があります。

    関連する問題