Arduino Pro Mini 3.3V, XBee, MPU6050: Can I use them simultanoulsly?

Hi,
I'm considering using Arduino Pro Mini 3.3V or 5V in my project. The problem is that I'm not sure if 3.3V version can handle it.
I would like to connect MPU 6050 and XBee S2 at the same time to the Arduino. According to datasheets XBee S2 current draw is for both TX and RX around 50 mA and MPU 6050 current draw is really low. Arduino Pro Mini 3.3V is able to deliver 150 mA thus that should be enough.
The reason I prefer 3.3V version is that I want to use 3.7V Li-Po and it's possible to connect XBee directly.

Is this possible that 8 MHz 3.3V version would work fine while plugged into 3.7V Li-Po battery and using I2C, TX/RX (if yes, what baud rate?) and 4 PWM output pins?

Yes.
All baud rates.
Yes.

majk92:
Hi,
I'm considering using Arduino Pro Mini 3.3V or 5V in my project.

Is this possible that 8 MHz 3.3V version would work fine while plugged into 3.7V Li-Po battery and using I2C, TX/RX (if yes, what baud rate?) and 4 PWM output pins?

The 3.3V Pro Mini is an 8MHz device unless you build your own @ 12MHz. The problem I see is that the calculations for the MPU6050 can be intense depending on your design. For example, in one of my projects, an 8MHz ProMini parsed a GPS stream using the Adafruit library, calculated the current time and date, and displayed on an ILI9341, again using Adafruit libs. The loop{} time for this logic is approximately 500mS... after I optimized the Adafruit libs!

I would suggest you look to a 32-bit Teensy or STM32F103 Maple Mini which is a 3.3V native device. For battery technology, I like the LiFePO4 technology because it is "safe" and lithium is never a raw byproduct of charging/discharging.

Ray

Ok! I will try with Arduino Mini 3.3V
However, during my tests I'm using Arduino Uno R3.
To connect it with XBee I connect TX to pin 3 and Rx to pin 2. If I didn't do that, it wouldn't work - XBees don't talk to each other. If Tx/Rx pins are connected to 2/3 all works fine. In order to connect MPU 6050 I need an interrupt pin to be connected to pin no. 2. I can olny guess that pins 2 and 3 work as some kind of pull-up/pull-down resistors.
So this is a problem to use XBee and MPU 6050 simultanously. Do You know how to solve this problem? Are there any other solutions to make XBees comucnicate with each other while 2 pin is taken?

Now is the time that you need to show your code. All of it please. Use [ code ] tags.

I guess that you're using SoftwareSerial on pins 2 and 3 of the Arduino. You can move that to any other pair of pins on the Uno or Mini. But reading your description, you might be talking about pin 2 and 3 on the Xbee - it's not clear.

Pin 2 is a special interrupt pin on the Uno/Mini. Depending on the code for the MPU6050, I expect that it doesn't need to use that special pin. The person who wrote the library may not be using that special function and only picked it because of the name.

I will post codes in the next post.
The first one is copied from Rowberg's library and the second one is only getting data from the other XBee and converting it to Strings. Worth to notice is that I'm sending only yaw, pitch, roll part through serial.
I'm connecting pins Rx - 2 pin and Tx - 3 pin to make communication between XBees work (like in the image below). The connections are on Arduino. If these are not connected, the XBees are not getting in touch.
Yes, the 2 pin is dedicated for an interruption. I have tried to connect Rx to pin 3 and Tx to pin 4 to make place for the interrupt connection to pin 2, but XBees were not able to communicate.
Although, it worked when one Arduino was interfaced with MPU 6050 (Rx to 4 pin Tx to 3 pin and 2 to the interrupt from MPU) and the other like in the description above. I need both to leave pin 2 for an interruption because the second arduino will also use MPU 6050. Code in the next post.

Code 1:

//Copyright (c) 2012 Jeff Rowberg
// for both classes must be in the include path of your project
#include "I2Cdev.h"
#include "MPU6050_6Axis_MotionApps20.h"
#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
    #include "Wire.h"
#endif

MPU6050 mpu;
/* =========================================================================
   NOTE: In addition to connection 3.3v, GND, SDA, and SCL, this sketch
   depends on the MPU-6050's INT pin being connected to the Arduino's
   external interrupt #0 pin. On the Arduino Uno and Mega 2560, this is
   digital I/O pin 2. */

/* 

// uncomment "OUTPUT_READABLE_YAWPITCHROLL" if you want to see the yaw/
// pitch/roll angles (in degrees) calculated from the quaternions coming
// from the FIFO
#define OUTPUT_READABLE_YAWPITCHROLL
#define INTERRUPT_PIN 2  // use pin 2 on Arduino Uno
#define LED_PIN 13
bool blinkState = false;

// MPU control/status vars
bool dmpReady = false;  // set true if DMP init was successful
uint8_t mpuIntStatus;   // holds actual interrupt status byte from MPU
uint8_t devStatus;      // return status after each device operation (0 = success, !0 = error)
uint16_t packetSize;    // expected DMP packet size (default is 42 bytes)
uint16_t fifoCount;     // count of all bytes currently in FIFO
uint8_t fifoBuffer[64]; // FIFO storage buffer

// orientation/motion vars
Quaternion q;           // [w, x, y, z]         quaternion container
VectorInt16 aa;         // [x, y, z]            accel sensor measurements
VectorInt16 aaReal;     // [x, y, z]            gravity-free accel sensor measurements
VectorInt16 aaWorld;    // [x, y, z]            world-frame accel sensor measurements
VectorFloat gravity;    // [x, y, z]            gravity vector
float euler[3];         // [psi, theta, phi]    Euler angle container
float ypr[3];           // [yaw, pitch, roll]   yaw/pitch/roll container and gravity vector

// packet structure for InvenSense teapot demo
uint8_t teapotPacket[14] = { '

Code 2:

 void readXbee(String& strY, String& strP, String& strR){
   int i = 0;
   char incomingByte = 'f';
   while(Serial.available() < 40);
     strY = "000000", strP = "000000", strR = "000000";
     while(incomingByte != 'y') incomingByte = Serial.read();
     while(incomingByte != 'p'){
       incomingByte = strY[i] = Serial.read();
       i++;
     }
     i = 0;
     while(incomingByte != 'r'){
       incomingByte = strP[i] = Serial.read();
       i++;
     }
     i = 0;
     while(incomingByte != 'y'){
       incomingByte = strR[i] = Serial.read();
       i++;
     }
   
 }
int yaw, pitch, roll;
String stry, strp, strr;
void setup(){
  yaw = 0; pitch = 0; roll = 0;
  Serial.begin(38400);
}
void loop(){
    readXbee(stry, strp, strr);
    Serial.print("ypw\t");
    Serial.print(stry);
    Serial.print("\t");
    Serial.print(strp);
    Serial.print("\t");
    Serial.println(strr);
}

, 0x02, 0,0, 0,0, 0,0, 0,0, 0x00, 0x00, '\r', '\n' };

//INTERRUPT DETECTION ROUTINE
volatile bool mpuInterrupt = false;    // indicates whether MPU interrupt pin has gone high
void dmpDataReady() {
    mpuInterrupt = true;
}
void setup() {
    // join I2C bus (I2Cdev library doesn't do this automatically)
    #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
        Wire.begin();
        TWBR = 24; // 400kHz I2C clock. Comment this line if having compilation difficulties
    #elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE
        Fastwire::setup(200, true);
    #endif
    Serial.begin(38400);
    while (!Serial); // wait for Leonardo enumeration, others continue immediately
    // initialize device
    Serial.println(F("Initializing I2C devices..."));
    mpu.initialize();
    pinMode(INTERRUPT_PIN, INPUT);
    // verify connection
    Serial.println(F("Testing device connections..."));
    Serial.println(mpu.testConnection() ? F("MPU6050 connection successful") : F("MPU6050 connection failed"));

// wait for ready
    Serial.println(F("\nSend any character to begin DMP programming and demo: "));
    while (Serial.available() && Serial.read()); // empty buffer
    while (!Serial.available());                // wait for data
    while (Serial.available() && Serial.read()); // empty buffer again

// load and configure the DMP
    Serial.println(F("Initializing DMP..."));
    devStatus = mpu.dmpInitialize();

// supply your own gyro offsets here, scaled for min sensitivity
    mpu.setXAccelOffset(-1269);
    mpu.setYAccelOffset(-496);
    mpu.setZAccelOffset(2370);
    mpu.setXGyroOffset(-155);
    mpu.setYGyroOffset(47);
    mpu.setZGyroOffset(116); // 1688 factory default for my test chip

// make sure it worked (returns 0 if so)
    if (devStatus == 0) {
        // turn on the DMP, now that it's ready
        Serial.println(F("Enabling DMP..."));
        mpu.setDMPEnabled(true);

// enable Arduino interrupt detection
        Serial.println(F("Enabling interrupt detection (Arduino external interrupt 0)..."));
        attachInterrupt(0, dmpDataReady, RISING);
        mpuIntStatus = mpu.getIntStatus();

// set our DMP Ready flag so the main loop() function knows it's okay to use it
        Serial.println(F("DMP ready! Waiting for first interrupt..."));
        dmpReady = true;

// get expected DMP packet size for later comparison
        packetSize = mpu.dmpGetFIFOPacketSize();
    } else {
        // ERROR!
        // 1 = initial memory load failed
        // 2 = DMP configuration updates failed
        // (if it's going to break, usually the code will be 1)
        Serial.print(F("DMP Initialization failed (code "));
        Serial.print(devStatus);
        Serial.println(F(")"));
    }

// configure LED for output
    pinMode(LED_PIN, OUTPUT);
}

void loop() {
    // if programming failed, don't try to do anything
    if (!dmpReady) return;

// wait for MPU interrupt or extra packet(s) available
    while (!mpuInterrupt && fifoCount < packetSize) {
    }
    // reset interrupt flag and get INT_STATUS byte
    mpuInterrupt = false;
    mpuIntStatus = mpu.getIntStatus();

// get current FIFO count
    fifoCount = mpu.getFIFOCount();

// check for overflow (this should never happen unless our code is too inefficient)
    if ((mpuIntStatus & 0x10) || fifoCount == 1024) {
        // reset so we can continue cleanly
        mpu.resetFIFO();
        Serial.println(F("FIFO overflow!"));

// otherwise, check for DMP data ready interrupt (this should happen frequently)
    } else if (mpuIntStatus & 0x02) {
        // wait for correct available data length, should be a VERY short wait
        while (fifoCount < packetSize) fifoCount = mpu.getFIFOCount();

// read a packet from FIFO
        mpu.getFIFOBytes(fifoBuffer, packetSize);
       
        // track FIFO count here in case there is > 1 packet available
        // (this lets us immediately read more without waiting for an interrupt)
        fifoCount -= packetSize;
        #ifdef OUTPUT_READABLE_YAWPITCHROLL
            // display Euler angles in degrees
            mpu.dmpGetQuaternion(&q, fifoBuffer);
            mpu.dmpGetGravity(&gravity, &q);
            mpu.dmpGetYawPitchRoll(ypr, &q, &gravity);
            Serial.print("y");
            Serial.print(ypr[0] * 180/M_PI);
            Serial.print("p");
            Serial.print(ypr[1] * 180/M_PI);
            Serial.print("r");
            Serial.print(ypr[2] * 180/M_PI);
        #endif
        // blink LED to indicate activity
        blinkState = !blinkState;
        digitalWrite(LED_PIN, blinkState);
    }
}


Code 2:

§DISCOURSE_HOISTED_CODE_1§

OK, there is a way of using the MPU6050 that doesn't need to use the Arduino interrupt pin. But it's going to be easier to attack the other problem for now.

You photo looks like you've connected pin2 on the Arduino to pin0 (Rx) on the Arduino. That looks completely wrong. Even worse than that, there's a switch on the board which does that for you.

What happens when you switch the switch to the UART position?

================================================

If you want to change the Xbee shield to use different pins and use SoftwareSerial, then that's a good idea too. While the description at Sparkfun says "or any digital pins on the Arduino" making that change is a slightly delicate bit of soldering. The easy-to-solder holes marked DOUT and DIN are on the 3.3v side of the voltage converters so you can't use those.

Remove the solder from the solder jumper marked 2 on the board. Make sure it's clean and there's no connection between the two pads. Now solder a wire from the pad closest to the XBee to any of the other holes along that nearby row. Pin4 would be a good choice.

Double-check that the switch is in the DLINE position. Now you can edit your code to talk to the XBee on software serial using pins 3 and 4.

SoftwareSerial XbeePort(4,3); //(Rx, Tx)

Then change every example of Serial.anything() to XbeePort.anything().

If you need pin 3 on your Arduino for something else, do the same soldering job on the "3" solder pad.

Thank You for your answer!
Why is it wrong to connect pin 2 and Rx? Do You mean UART/DLine switch is for that?
I'm aware that in this case I can't use pin 2 for an interrupion pin. But is there another reason it's wrong? For now, it's the only way it works for me.
When I change the switch to UART XBees don't communicate (probably don't even connect - lights on shields indicate that).
If I connect pad 2 to a hole near pin 4 there will be a direct connection between pin 2 and pin 4 thus everyhing connected to pin 4 will let signals flow to pin 2 as well - that will give fake interruption signals from MPU 6050.
The picture below shows a current working communication (but not leaving pin 2 for an interruption signal). The left one doesn't use MPU6050 and the right one does - it sends data to the Xbee on left hand side:

The second picture shows not working communication. Although, the leds indicate that XBees connect, data sent isn't showing in the other one. I don't know why

What's the most importatnt thing! The end devices I will use will be Arduino Pro Mini 3.3V and no shields between Arduino and XBee. I plan to connect it like in the picture below (insted of arduino uno I will use Arduino Pro Mini 3.3V):


Do you think there will be any problems like here with Arduino Uno and shield? Of course, I will use pins 4 and 5 for I2C communication and 4 PWM outputs.

I don't have that hardware so I can't test it but the switch should allow you to use Tx/Rx hardware serial OR 2 and 3 software serial. It looks like your 'working' configuration has the switch in the 2&3 position and then you've wired that back to the hardware serial pins because your code uses hardware serial.

Take the MPU6050 away for the moment. Do the Xbees connect when you have no wires plugged into the shield? The switch should be in the UART position, if I'm reading the documentation correctly.

Show us the code for your 'not working' configuration. I'm interested to see how your code is using pin 4.

DON'T USE FRITZING!!!!!!!
I was writing a long paragraph about why that f***ing diagram won't work and then I re-read your comment that you're using a DIFFERENT THING TO WHAT'S IN THE PICTURE. Please don't use pictures that show hardware you don't have and don't intend to use. It's a waste of time.

That's the case! I didn't realize what is the swith for. Now it's working without using pin 2 and 3. Thank You!
While uploading the code the switch must be in DLine position. The code requires sending "activating" character, so it still must be in DLine position and after that, to communicate between XBees, it must be switched to hardware serial (UART position). That's why it didn't work if I just simply switched to UART. Now it's working.
Until now the work was done at Arduino Uno and XBee Shield. Now I'm going to use Arduino Pro Mini 3.3V.

Below is probably complete scheme. Do You think it will work? Mostly I'm concerned about Arduino Pro Mini 3.3V and XBee S2 connection. Should I disconnect Tx/Rx pins while uploading a code?

Hi,
Do You think it will work? I updated the picture

Neither picture is showing up for me.


This one should work :slight_smile:

No.