Using an 8Mhz Arduino Pro Mini with FreeIMU

Asked by Daniel Sjöstrand

Hi,

What about using an 8MHz ATMega328-based Arduino Pro Mini toghether with the FreeIMU, did you ever try that?

I'm concerned about this part of FreeIMU.cpp:

void FreeIMU::init(int acc_addr, int gyro_addr, bool fastmode, int newperiod) {
  delay(5);

  if(fastmode) { // switch to 400KHz I2C - eheheh
    TWBR = ((16000000L / 400000L) - 16) / 2; // see twi_init in Wire/utility/twi.c
    // TODO: make the above usable also for 8MHz arduinos..

Does this "only" concern 400KHz fast mode?
What's required to make fast mode work for 8MHz?

Thanks,

Daniel

Question information

Language:
English Edit question
Status:
Answered
For:
FreeIMU Edit question
Assignee:
No assignee Edit question
Last query:
Last reply:
Revision history for this message
Fabio Varesano (fabio-varesano) said :
#1

Hi Daniel,

I never used FreeIMU with a 8MHz Arduino.. however, you shouldn't have any problem..
the code there is only relevant if you use 400KHz I2C.. but you can make it work also on 8MHz by simply change 16000000L into 8000000L.

Hope this helps,

Fabio

Revision history for this message
Daniel Sjöstrand (daniel-plustecken) said :
#2

Hi,

I can't get the FreeIMU to report any values when trying with an Arduino Pro Mini (3.3V, 8MHz, Atmel MEGA328P).
The same FreeIMU reports values well when connected to a standard Duemilanove (5V, 16MHz, Atmel MEGA328).
P) - then it is connected via a logic converter board since the logic signal levels for SDA/SCL needs to be converted to 3.3V.

But for the Arduino Pro Mini, it is already at 3.3V.
Do I still need to disable the internall pull-ups in twi.c? I've tried this but it doesn't seems to make a difference.

Below is the code I'm using, it seems to never proceed past the "my3IMU.init()" statement.
So for the Pro Mini, it never enters the loop() method. But the same code works fine for Duemilanove.

 I've noticed there's a lot of hardware-specific parameters in twi.c, could a change be needed for my 8MHz Aruduino?

Below is my code that I run.

Thanks,

Daniel

----

#include <ADXL345.h>
#include <HMC5843.h>
#include <ITG3200.h>

#define DEBUG
#include "DebugUtils.h"

#include "FreeIMU.h"
#include <Wire.h>

int raw_values[9];
char str[512];
char str2[512];
float val[9];
int duepin=13;//For Duemilanove and Arduino Pro Mini the LED is on digital pin 13
int seedpin=8;//For Seeduino Film the LED is on digital pin 8
int led=duepin;

// Set the default object
FreeIMU my3IMU = FreeIMU();

void setup() {
  pinMode(led, OUTPUT);
  digitalWrite(led, HIGH); // set the LED on
  delay (1000); //wait 1 seconds
  digitalWrite(led, LOW); // set the LED off
  for (int i = 0; i < 10; i++) //make intial setup LED blink 10 times
  {
    digitalWrite(led, HIGH); // set the LED on
    delay(100); // wait for a second
    digitalWrite(led, LOW); // set the LED off
    delay(100);
  }
  Serial.begin(115200);
  Serial.println("In setup, just after Serial.begin");
  Wire.begin();
  Serial.println("In setup, just after Wire.begin");
  delay(500);
  Serial.println("In setup, about to blink 5 times");
  for (int i = 0; i < 5; i++) //make intial setup LED blink 10 times
  {
    digitalWrite(led, HIGH); // set the LED on
    delay(250); // wait for a second
    digitalWrite(led, LOW); // set the LED off
    delay(250);
  }
  Serial.println("In setup, about to execute my3IMU...");
  my3IMU.init(); // the parameter enable or disable fast mode
  Serial.println("In setup, execution of my3IMU completed");
  delay(500);

}

void loop() {
  Serial.println("In loop, about to run my3IMU.getRawValues");
  my3IMU.getRawValues(raw_values);
  Serial.println("In looop, my3IMU.getRawValues completed");
  //if(/*(raw_values[2] >500) ||*/ (raw_values[2] <-500)) //only if accelerometer values is greater than 500 or less than -500 we will
  // print something
  {

    //First the Data Numbers ranging from -4096 to 4096
    sprintf(str, "%d,%d,%d ,%d,%d,%d,%d,%d,%d", raw_values[0], raw_values[1], raw_values[2], raw_values[3], raw_values[4], raw_values[5], raw_values[6], raw_values[7], raw_values[8]);
    //Then we scale them to be between -16G to 16G
    sprintf(str2, "%dG,%dG,%dG ,%d,%d,%d,%d,%d,%d", raw_values[0] / 256, raw_values[1] /256, raw_values[2] / 256, raw_values[3], raw_values[4], raw_values[5], raw_values[6], raw_values[7], raw_values[8]);
    Serial.println(str);
    Serial.println(str2);
  }
  // Serial.print(10, BYTE);

  /*
  my3IMU.getValues(val);
   sprintf(str, "%d,%d,%d,%d,%d,%d,%d,%d,%d", int(val[0]), int(val[1]), int(val[2]), int(val[3]), int(val[4]), int(val[5]), int(val[6]), int(val[7]), int(val[8]));
   Serial.print(str);
   Serial.print(10, BYTE);
   */
}

Revision history for this message
Daniel Sjöstrand (daniel-plustecken) said :
#3

I've tried to use a PirateBus for the first time to see what happens :)
It took a couple of hours just to understand it and connect it correctly (I hope it is).

It gives the following output (first I just select I2C, speed, and enable power and pull-ups to ON as recommended for the I2C protocol).

I can see the following addresses:

"0x3C(0x1E W) 0x3D(0x1E R) 0xA6(0x53 W) 0xA7(0x53 R) 0xD0(0x68 W) 0xD1(0x68 R)"

Then I tried sniffing, nothing at first as expected. Then i reset the Pro Mini Arduino and the above ran.
I got the output:
"[0xA6+0x2D+0x08+][0xD0-][0xD0+0x16+][0xD1+0x00-][0xD0+][0xD0+0x16-][0xD0+0x16+][0xD1-][0xD0+][0xD0+0x16+0x00+][0xD0+0x3E-][0xD1+0x00-][0xD0+][0xD0+0x3E+0x01+][0xD0+][0xD1+0x00-][0xD0+][0xD0-][0xD0-][0xD1+0x4C-][0xD0+][0xD0+0x17+0x4D+][0xD0+0x1D+][0xD1-][0xD0+][0xD0+0x1D+][0xD1+0xFD+0x41+0x00+0xB2+0xF1+0xFB-][0xD0+][0xD0+0x1D+][0xD1+0xFB+0xFD+0xFD+0xFF+0xFF+0xFF-][0xD0+][0xD0+0x1D+][0xD1+0xFD+0x06+0x00+0xFF+0xFF+0xFF-][0xD0+][0xD0+0x1D+][0xD1+0xFD+0x00+0x00+0xC6+0xF8+0x86-][0xD0+][0xD0+0x1D+][0xD1+0xFD+0x33+0x00+0xCE+0xF8+0x8D-][0xD0+][0xD0+0x1D+][0xD1-][0xD0+][0xD0+0x1C-"

Then it stops.

Any thoughts?

Complete log below...

HiZ>m
1. HiZ
2. 1-WIRE
3. UART
4. I2C
5. SPI
6. 2WIRE
7. 3WIRE
8. LCD
9. DIO
x. exit(without change)

(1)>4
Set speed:
 1. ~5KHz
 2. ~50KHz
 3. ~100KHz
 4. ~400KHz

(1)>3
Ready
I2C>v
Pinstates:
1.(BR) 2.(RD) 3.(OR) 4.(YW) 5.(GN) 6.(BL) 7.(PU) 8.(GR) 9.(WT) 0.(Blk)
GND 3.3V 5.0V ADC VPU AUX SCL SDA - -
P P P I I I I I I I
GND 0.00V 0.00V 0.00V 0.00V L L L L L
I2C>W
Power supplies ON
I2C>v
Pinstates:
1.(BR) 2.(RD) 3.(OR) 4.(YW) 5.(GN) 6.(BL) 7.(PU) 8.(GR) 9.(WT) 0.(Blk)
GND 3.3V 5.0V ADC VPU AUX SCL SDA - -
P P P I I I I I I I
GND 3.26V 4.93V 0.00V 3.28V L H H L L
I2C>P
Pull-up resistors ON
I2C>(0)
 0.Macro menu
 1.7bit address search
 2.I2C sniffer
I2C>(1)
Searching I2C address space. Found devices at:
0x3C(0x1E W) 0x3D(0x1E R) 0xA6(0x53 W) 0xA7(0x53 R) 0xD0(0x68 W) 0xD1(0x68 R)

I2C>(2)
Sniffer
Any key to exit
[0xA6+0x2D+0x08+][0xD0-][0xD0+0x16+][0xD1+0x00-][0xD0+][0xD0+0x16-][0xD0+0x16+][0xD1-][0xD0+][0xD0+0x16+0x00+][0xD0+0x3E-][0xD1+0x00-][0xD0+][0xD0+0x3E+0x01+][0xD0+][0xD1+0x00-][0xD0+][0xD0-][0xD0-][0xD1+0x4C-][0xD0+][0xD0+0x17+0x4D+][0xD0+0x1D+][0xD1-][0xD0+][0xD0+0x1D+][0xD1+0xFD+0x41+0x00+0xB2+0xF1+0xFB-][0xD0+][0xD0+0x1D+][0xD1+0xFB+0xFD+0xFD+0xFF+0xFF+0xFF-][0xD0+][0xD0+0x1D+][0xD1+0xFD+0x06+0x00+0xFF+0xFF+0xFF-][0xD0+][0xD0+0x1D+][0xD1+0xFD+0x00+0x00+0xC6+0xF8+0x86-][0xD0+][0xD0+0x1D+][0xD1+0xFD+0x33+0x00+0xCE+0xF8+0x8D-][0xD0+][0xD0+0x1D+][0xD1-][0xD0+][0xD0+0x1C-

Revision history for this message
Daniel Sjöstrand (daniel-plustecken) said :
#4

I tried running the program three more times, and the output stops at various times.
Between each sniffer start below I reset the Arduino Pro Mini.

---

I2C>(2)
Sniffer
Any key to exit
[0xA6+0x2D+0x08+][0xD0+0x15+0x00+][0xD0+0x16-][0xD0+

I2C>(2)
Sniffer
Any key to exit
[0xA6+0x2D+0x08+][0xD0+0x15+0x00+][0xD0+0x16+][0xD1+0x00-][0xD0+][0xD0+0x16+0x18+][0xD0+0x16+][0xD1+0x18-][0xD0+][0xD0+0x16+0x18+][0xD0+0x3E+][0xD1+0x01-][0xD0+][0xD0+0x3E+0x01+][0xD0-][0xD1+0x00-][0xD0+][0xD0+0x17+0x04+][0xD0+0x16-

I2C>(2)
Sniffer
Any key to exit
[0xA6+0x2D+0x08+][0xD0+0x15+0x00+][0xD0+0x16+][0xD1+0x18-][0xD0+][0xD0-][0xD0+0x16+][0xD1+0x18-][0xD0+][0xD0+0x16+0x18+][0xD0+0x3E+][0xD1+0x01-][0xD0-][0xD0-][0xD0+0x17+][0xD1+0x04-][0xD0+][0xD0+0x17+0x04+][0xD0+0x17+][0xD1-][0xD0+][0xD0+0x17+0x05+][0xD0+0x1D+][0xD1+0xFF+0xAE+0x00+0x17+0xFF+0x0A-][0xD0+][0xD0+0x1D+][0xD1+0xFF+[0xD0+][0xD0+0x1D+][0xD1-][0xD0-][0xD0-][0xD1+0xFF+0xFD+0xFD+0xFD+0xFD+0xFB-][0xD0+][0xD0+0x1C-

Revision history for this message
Fabio Varesano (fabio-varesano) said :
#5

Hi Daniel, sorry if I didn't replied earlier, got a pretty busy day.

This looks like a communication issue rather than a problem in the 8MHz stuff. Would you mind posting a picture of your circuit? Do you have an oscilloscope with you? If so I'd like to see how your I2C signals looks. A good signal looks like http://www.varesano.net/blog/fabio/preview-freeimu-v03 (bottom of the page).

> Do I still need to disable the internall pull-ups in twi.c? I've tried this but it doesn't seems to make a difference.

Yes, you should do that. It's known that internal pullups performs very bad in term of signal quality. See http://www.dsscircuits.com/articles/effects-of-varying-i2c-pull-up-resistors.html

> I've noticed there's a lot of hardware-specific parameters in twi.c, could a change be needed for my 8MHz Aruduino?

It shouldn't be necessary as it should work for any arduino compatible hardware.

Revision history for this message
Daniel Sjöstrand (daniel-plustecken) said :
#6

Thank you for the input Fabio.

Unfortunately I don't have an oscilloscope with me as I'm at a friends apartment and only brough the basic stuff (which still occupies half of a kitchen table ;-)) I hope I will have time this weekend to compare to your graph.

I don't have a picture right now either, but the connections are like this:

A4/SDA from Pro Mini -> SDA on FreeIMU
A5/SCL from Pro Mini -> SCL on FreeIMU
VCC on FreeIMU -> 3VD on Arduino Duemilanove
GND on FreeIMU -> GND on Arduino Duemilanove

I also have soldered connections from:
-A lipo battery to Pro Mini RAW and GND input on Pro Mini (currently disabled by on/off switch since 3.3V power is taken from DueMilanove)
- The 6-pin programmer header from Pro Mini to a FTDI Basic for programming.

Thanks meanwhile!

/Daniel

Revision history for this message
Fabio Varesano (fabio-varesano) said :
#7

As you are using FreeIMU v0.1 you also need external pullups which
have to be connected to 3.3V.

Revision history for this message
Daniel Sjöstrand (daniel-plustecken) said :
#8

Thanks Fabio.
As I'm still a beginner and have very limited experience in using an oscilloscope and also with circuits I have some questions.

1) I have an old 20MHz Hitachi V202 analogue oscilloscope with two channels; I think this will be ok to measure the I2C bus signals since they are 100kHz in the standard mode, or what do you think? I've read recommendations that the oscilloscope bandwidth should be about 10x higher for what you want to measure.

2) How would I connect the oscilloscope probes? Only to SCL (using one of the channels on the oscilloscope) or also to SDA (using both)? I assume I connect the probes to SCL and ground, is that a correct assumption?

3) Currently I'm powering the Arduino Pro Mini from a battery connected to RAW input. The FreeIMU has been powered by the 3.3V output of a Duemilanove so far, but in the end it should be powered from VCC output of Arduino Pro Mini. Would this setup affect the pullup setup?

4) Should I use two 2.2kiloOhm resistors as pullups, connected between 3.3V input to FreeIMU v.01 and SDA/SCL respectively, is that right?

Thanks,

Daniel

Revision history for this message
Fabio Varesano (fabio-varesano) said :
#9

Hi Daniel, see my answers below:

1) Sure, that scope will be just fine.
2) You can connect both of them, just offset them so that you can see
them both clearly.
3) It shouldn't.
4) right, and disable the internal pullups of the ATMEGA.

Hope this helps,

Fabio

Revision history for this message
Fabio Varesano (fabio-varesano) said :
#10

Hey Daniel, have you been able to sort this out?

Revision history for this message
Daniel Sjöstrand (daniel-plustecken) said :
#11

Thanks for the follow-up :)

No, unfortunately I haven't been able to solve it yet. I've been occupied with my other work and private matters...but I did try to measure with my oscilloscope before this busy week, with "bad" results.

Actually, I started to try to measure signal levels when I had the FreeIMU connected to Logic Level Converter (LLC) - http://www.sparkfun.com/products/8745 - from SparkFun and to the standard Duemilanove to see what a "good" signal should look like. I use the the two bidirectional TX lines of the LLC and power it from the 3V3 and 5V of Duemilanove.

This configuration has been working good for reporting sensor data and also when tilting the FreeImu it reflects well in the cube.

But as soon as I connect the oscilloscope probes to SCL and GND, after a few seconds the serial data stream stops and the oscilloscope curve looks like rubbish - no clean signal at all! At some point I got a similar picture to yours, but that was for a very short while.

What is the function of the LLC in respect to pull-up resistors - why isn't pull-up resistors needed when using the LLC?
And why would the serial data flow stop when attaching the probes from the oscilloscope?

Here are pictures of the circuit:

http://www.dropbox.com/gallery/109216/2/Electronics/FreeIMU%20breadboard%20DueMilanove?h=d9365b

Thanks,

Daniel

I'll soon post a picture of the circuit setup.

Revision history for this message
Fabio Varesano (fabio-varesano) said :
#12

I always used external pullups when using the Sparkfun LLC. I would
suggest adding 2.2K resistors on the 2 3.3V signals as well as on the
5V signals (provided that you have the internal pullups disabled in
the FreeIMU lib code).

My guess is that, as you miss the external pullups your setup is
fragile, and when messed by the probes it breaks the communications.

Revision history for this message
Paolo (robomotic) said :
#13

This is the patch I used on my code:

  if(fastmode) { // switch to 400KHz I2C - eheheh
    //TWBR = ((16000000L / 400000L) - 16) / 2; // see twi_init in Wire/utility/twi.c
    // TODO: make the above usable also for 8MHz arduinos..
     TWBR = ((F_CPU / 400000L) - 16) / 2; // see twi_init in Wire/utility/twi.c
  }

so that you don't have to input manually the code every time.

Can you help with this problem?

Provide an answer of your own, or ask Daniel Sjöstrand for more information if necessary.

To post a message you must log in.