mpu - Arduino freezes after x seconds -
i reading data mpu-6050 inertial measurement unit, using i2c, arduino @ sample rate of 25hz , worked fine. added second mpu-6050 read @ sample frequency of 25hz. have different addresses can access both of them in i2c. since added second one, arduino stops seems freeze after 1000 5000 loop() calls, freezing somewhere in loop (somewhere different each time, observed debugging sending characters serial connection pc). in each loop read data 1 of mpu-6050. code, using jeff rowberg's library, inspired code found @ http://forum.arduino.cc/index.php?phpsessid=t6lmv7i431eqeaf05ui619q2h6&topic=118937.msg1368958#msg1368958, presents same problem:
// i2c device class (i2cdev) demonstration arduino sketch mpu6050 class using dmp (motionapps v2.0) // 6/21/2012 jeff rowberg <jeff@rowberg.net> // updates should (hopefully) available @ https://github.com/jrowberg/i2cdevlib // i2cdev , mpu6050 must installed libraries, or else .cpp/.h files // both classes must in include path of project #include "i2cdev.h" #include <softwareserial.h> #include "mpu6050_6axis_motionapps20.h" //#include "mpu6050.h" // not necessary if using motionapps include file // arduino wire library required if i2cdev i2cdev_arduino_wire implementation // used in i2cdev.h #if i2cdev_implementation == i2cdev_arduino_wire #include "wire.h" #endif // class default i2c address 0x68 // specific i2c addresses may passed parameter here // ad0 low = 0x68 (default sparkfun breakout , invensense evaluation board) // ad0 high = 0x69 mpu6050 mpu_1; mpu6050 mpu_2(0x69); // <-- use ad0 high #define led_pin 13 // (arduino 13, teensy 11, teensy++ 6) bool blinkstate = false; // mpu control/status vars bool dmpready = false; // set true if dmp init successful uint8_t forcereadmpu = 1; uint8_t mpuintstatus_1; // holds actual interrupt status byte mpu uint8_t devstatus_1; // return status after each device operation (0 = success, !0 = error) uint16_t packetsize_1; // expected dmp packet size (default 42 bytes) uint16_t fifocount_1; // count of bytes in fifo bool mpuneedtoberead_1; uint8_t fifobuffer_1[64]; // fifo storage buffer uint8_t mpuintstatus_2; uint8_t devstatus_2; uint16_t packetsize_2; uint16_t fifocount_2; bool mpuneedtoberead_2; uint8_t fifobuffer_2[64]; // orientation/motion vars quaternion q; // [w, x, y, z] quaternion container vectorfloat gravity; // [x, y, z] gravity vector float ypr[3]; // [yaw, pitch, roll] yaw/pitch/roll container , gravity vector softwareserial xbee = softwareserial(4, 5); float measures[3]; byte serialbuffer[2*2*sizeof(measures)+1]; //two gyroscopes, 2 bytes per digit, 4 digit per measure + '\0' // ================================================================ // === interrupt detection routine === // ================================================================ volatile bool mpuinterrupt_1 = false; // indicates whether mpu interrupt pin has gone high volatile bool mpuinterrupt_2 = false; void dmpdataready_1() { mpuinterrupt_1 = true; } // función que invoca cuando detecta una interrupción en el mpu 2 void dmpdataready_2() { mpuinterrupt_2 = true; } // ================================================================ // === initial setup === // ================================================================ void setup() { xbee.begin(19200); serialbuffer[2*2*sizeof(measures)] = 0x00; // set '\0' @ end of array, serial.print // join i2c bus (i2cdev library doesn't automatically) #if i2cdev_implementation == i2cdev_arduino_wire wire.begin(); twbr = 24; // 400khz i2c clock (200khz if cpu 8mhz) #elif i2cdev_implementation == i2cdev_builtin_fastwire fastwire::setup(400, true); #endif // initialize serial communication // (115200 chosen because required teapot demo output, it's // depending on project) serial.begin(19200); //while (!serial); // wait leonardo enumeration, others continue // note: 8mhz or slower host processors, teensy @ 3.3v or ardunio // pro mini running @ 3.3v, cannot handle 115200 baud rate reliably due // baud timing being misaligned processor ticks. must use // 38400 or slower in these cases, or use kind of external separate // crystal solution uart timer. // initialize device serial.println(f("initializing i2c devices...")); mpu_1.initialize(); mpu_2.initialize(); // verify connection serial.println(f("testing device connections...")); serial.println(mpu_1.testconnection() ? f("mpu6050_1 connection successful") : f("mpu6050_1 connection failed")); serial.println(mpu_2.testconnection() ? f("mpu6050_2 connection successful") : f("mpu6050_2 connection failed")); // wait ready /* serial.println(f("\nsend character begin dmp programming , demo: ")); while (serial.available() && serial.read()); // empty buffer while (!serial.available()); // wait data while (serial.available() && serial.read()); // empty buffer again */ // load , configure dmp serial.println(f("initializing dmp...")); devstatus_1 = mpu_1.dmpinitialize(); devstatus_2 = mpu_2.dmpinitialize(); if (devstatus_1 == 0) { // turn on dmp, it's ready serial.println(f("enabling dmp...")); mpu_1.setdmpenabled(true); // enable arduino interrupt detection serial.println(f("enabling interrupt detection (arduino external interrupt 0)...")); attachinterrupt(0, dmpdataready_1, rising); // utilizamos la primera interrupción externa (número 0) que está en el pin digital 2 // cuando la interrupción tiene lugar invoca la función "dmp_1_dataready" // rising dispara la interrupción cuando el pin pasa de valor alto (high) bajo (low) mpuintstatus_1 = mpu_1.getintstatus(); // set our dmp ready flag main loop() function knows it's okay use serial.println(f("dmp ready! waiting first interrupt...")); // expected dmp packet size later comparison packetsize_1 = mpu_1.dmpgetfifopacketsize(); // supply own gyro offsets here, scaled min sensitivity mpu_1.setxgyrooffset(17); mpu_1.setygyrooffset(-22); mpu_1.setzgyrooffset(33); mpu_1.setxacceloffset(2310); mpu_1.setyacceloffset(1823); mpu_1.setzacceloffset(1477); }else { // error! // 1 = initial memory load failed // 2 = dmp configuration updates failed // (if it's going break, code 1) serial.print(f("dmp 1 initialization failed (code ")); serial.print(devstatus_1); serial.println(f(")")); } if (devstatus_2 == 0) { // turn on dmp, it's ready serial.println(f("enabling dmp...")); mpu_2.setdmpenabled(true); // enable arduino interrupt detection serial.println(f("enabling interrupt detection (arduino external interrupt 0)...")); attachinterrupt(1, dmpdataready_2, rising); // utilizamos la segunda interrupción externa (número 1) que está en el pin digital 3 // cuando la interrupción tiene lugar invoca la función "dmp_1_dataready" // rising dispara la interrupción cuando el pin pasa de valor alto (high) bajo (low) mpuintstatus_2 = mpu_2.getintstatus(); // set our dmp ready flag main loop() function knows it's okay use serial.println(f("dmp ready! waiting first interrupt...")); dmpready = true; // expected dmp packet size later comparison packetsize_2 = mpu_2.dmpgetfifopacketsize(); mpu_1.setxgyrooffset(-5); mpu_1.setygyrooffset(-60); mpu_1.setzgyrooffset(69); mpu_1.setxacceloffset(-1088); mpu_1.setyacceloffset(580); mpu_1.setzacceloffset(1936); }else { // error! // 1 = initial memory load failed // 2 = dmp configuration updates failed // (if it's going break, code 1) serial.print(f("dmp 2 initialization failed (code ")); serial.print(devstatus_2); serial.println(f(")")); } // configure led output pinmode(led_pin, output); } // ================================================================ // === main program loop === // ================================================================ void loop() { // if programming failed, don't try if (!dmpready) return; // wait mpu interrupt or packet(s) available. while ( !mpuinterrupt_1 && fifocount_1 < packetsize_1); mpuinterrupt_1 = false; mpuintstatus_1 = mpu_1.getintstatus(); fifocount_1 = mpu_1.getfifocount(); // check overflow (this should never happen unless our code inefficient) if ((mpuintstatus_1 & 0x10) || fifocount_1 == 1024) { // reset can continue cleanly mpu_1.resetfifo(); serial.println(f("fifo 1 overflow!")); // otherwise, check dmp data ready interrupt (this should happen frequently) } else if (mpuintstatus_1 & 0x02) { // wait correct available data length, should short wait while (fifocount_1 < packetsize_1) fifocount_1 = mpu_1.getfifocount(); // read packet fifo if (packetsize_1 >= 64) serial.println("packet size incoherence 1"); mpu_1.getfifobytes(fifobuffer_1, packetsize_1); // track fifo count here in case there > 1 packet available // (this lets read more without waiting interrupt) fifocount_1 -= packetsize_1; //mpu_1.resetfifo();// parce que j'arrive pas à trouver une fonction setfifosize(). juste espérer qu'elle ne se remplit pas pendant l'exécution de la ligne précédente... } while ( !mpuinterrupt_2 && fifocount_1 < packetsize_2); // reset interrupt flag , int_status byte mpuinterrupt_2 = false; mpuintstatus_2 = mpu_2.getintstatus(); fifocount_2 = mpu_2.getfifocount(); // check overflow (this should never happen unless our code inefficient) if ((mpuintstatus_2 & 0x10) || fifocount_2 == 1024) { // reset can continue cleanly mpu_2.resetfifo(); serial.println(f("fifo 2 overflow!")); // otherwise, check dmp data ready interrupt (this should happen frequently) } else if (mpuintstatus_2 & 0x02) { // wait correct available data length, should short wait while (fifocount_2 < packetsize_2) fifocount_2 = mpu_2.getfifocount(); // read packet fifo if (packetsize_2 >= 64) serial.println("packet size incoherence 2"); mpu_2.getfifobytes(fifobuffer_2, packetsize_2); // track fifo count here in case there > 1 packet available // (this lets read more without waiting interrupt) fifocount_2 -= packetsize_2; //mpu_2.resetfifo();// parce que j'arrive pas à trouver une fonction setfifosize(). juste espérer qu'elle ne se remplit pas pendant l'exécution de la ligne précédente... } }
no error reported serial output. led blinking (end of code) still on when arduino freezes. freeze, or crash? how resolve it?
i rid off freeze problem avoiding use of interrupts. don´t use them in code , don´t wire int pin of mpu6050. wire pin arduino digital input problem appears again.
Comments
Post a Comment