2

我有一个问题,我的 Arduino 程序无缘无故挂起。我运行我的程序,在某个未确定的时间点,串行监视器停止打印输出。这是我到目前为止测试过的内容:

  • 在我的“com.init_drone()”方法中,除了最后一行,我已将所有内容都注释掉,这表明该方法已返回。当我这样做时,我的程序挂在其他地方,但它仍然没有进入无限的 while 循环。
  • 我一直在输出内存使用情况,我得到的数字不低于 450——这告诉我我没有使用荒谬的内存量。
  • 我已经尝试删除对程序没有影响的 Timer1 实例化、中断附加/分离、bu。

我的.ino 文件(和命令)位于此处,供任何想要更全面的图片并且不想滚动浏览我将在下面发布的所有代码的人使用。


到目前为止,这是我的日志输出。注意截断!

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
吃*CTRL=6,4,0

629
S0AT*CTRL=7,0,0
吃*CTRL=7,0,0

629
S0AT*CTRL=8,4,0
吃*CTRL=8,4,0

629
S0AT*COMWDG=9
吃*COMWDG=9

629
S0AT*COMWDG=10
吃*COMWDG=10

629
S0AT*COMWDG=11
吃*COMWDG=11

629
S0AT*COMWDG=12
吃*COMWDG=12

629
S0AT*COMWDG=13
吃*COMWDG=13

629
S0AT*FTRIM=14
吃*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
4

3 回答 3

2

我知道这听起来很奇怪,但是有时当 arduino 没有获得足够的电源时会发生这种情况。尝试将 arduino 连接到不同于 USB 的电源。

于 2012-04-29T03:48:50.053 回答
1

一旦我开始把东西放在prog内存中,我的程序就开始清理它的打嗝。似乎是内存问题。

于 2012-09-12T12:32:51.997 回答
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);

打开串口监视器,看看……它会一直显示到“Two”,然后 Arduino 就会挂起。

问题是我调用了 LiquidCrystal_I2C 库的一些函数,这些函数需要中断例程。检查你的定时器 ISR 是否使用了一些中断。如果是这样,您应该将此代码移动到项目中的另一个位置。

于 2013-02-14T16:07:35.620 回答