Go Down

Topic: I2C (SDA/SCL) on Due giving me a hard time ... (Read 10627 times) previous topic - next topic

ninja2

A couple of weeks back I was having a great time getting a Sparkfun MPU9250 working on a Due, using Kris Winer's MPU9250 library. At one point it ran really well - reporting at a Mahony Quaternion filter update rate of ~ 830Hz ... very cool. Little did I know my success was about to nose-dive!

The MPU9250 uses I2C so it was connected to SDA/SCL pins 20/21. But I wanted to move it to the other I2C port SDA1/SCL1 on pins 70/71 (Wire1). Things have been going downhill ever since ... I never got SDA1/SCL1 working, but worse I cannot even get SDA/SCL working any more.

I've tried various hardware. First I tried using my second Due with another MPU9250. No go. Then I reverted to a BMP180 pressure sensor which also uses the I2C port, and a different sketch. None of this worked.

So I checked all the peripherals and sketches on a Uno - everything worked!

Perhaps I've damaged both my Due boards (they work fine otherwise) but maybe I've got something wrong in the way I have coded for the I2C port. I've attached two of the three sketches I tried, one reads a BMP-180 the other is for calibrating the magnetometer on a MPU9250.

All my sketches use this code to initialise the I2C port, for Uno or Due:

Code: [Select]
 #if  !defined(DUE)                                        // (not for Due)
      TWBR = 12;                                            // TWI (I2C) Bit Rate Register: set fast mode 400kb/s
      Serial << F(" * [UNO] TWBR: ") << TWBR << '\n';
  #elif defined(DUE)
    //#define Wire Wire1                                    // use Due's second I2C port: SDA1/SCL1 on pins D70/D71
    //extern TwoWire Wire1;
    //Serial << F("* using Wire1") << '\n';                 //won't compile. Due equivalent to TWBR on Uno?)
      Wire.begin();                                         // not needed UNO !
      Serial << F(" * [DUE]\n");
    //Serial << F(" * [DUE] TWI_CWGR:") << TWI_CWGR << '\n'; // won't compile! what is Due equivalent to Uno's TWBR ?
  #endif


I never found out how to ensure the Due I2C was in FAST mode (400kHz) . Maybe this is the issue?

Hopefully I've just missed something in the code - any / all suggestions appreciated
TIA

RayLivingston

The second I2C port on the Due requires pull-up resistors to be added to the SCL and SDA signals.  Also, IIRC, those two pins are paralleled to two other pins, so those pins must be configured as inputs, so they don't interfere with the I2C functionality.  Both I2C ports DO work perfectly.  I use them all the time, and never had a problem.

Regards,
Ray L.

ninja2

#2
Sep 24, 2016, 12:05 am Last Edit: Sep 24, 2016, 12:07 am by ninja2
Ray (or anyone else), can you share an example sketch of yours that works with I2C? TIA

I can't get either port working at present so I'm focusing on SDA/SCL pins 20/21 for now. Once I get that working (again!) I will want to get Wire1 on 70/71 working ASAP.

I am aware of need for pull-up resistors on Wire1 port, but not the paralleled pins you mention to be set as inputs. Anyone know which pins these are ?

By the way the MPU9250 does have 10K pull-ups in-built, although the BMP-180 has none. As I understand the Due does have in-built pull-ups on pins 20/21 so both these peripherals should work without adding resistors on that port.

ninja2

bump

still hoping someone will post know good code using I2C on a Due (or even a code snippet)

.... anyone?

ghlawrence2000

The easiest way of testing is just good ol' pinMode, digitalWrite on your SCL/SDA pins to at least prove they are not dead. Sorry can't help further.

G
UTFT_SdRaw now included in library manager!! ;) High speed image drawing from SD card to UTFT displays for Mega & DUE.
UTFT_GHL - a VASTLY upgraded version of UTFT_CTE. Coming soon to a TFT near you! 8) Shipping April 1 2016!

ninja2

that's worth a try. at least then I'll know if its a h/w or s/w issue
tks

soeren


ninja2

#7
May 06, 2018, 12:12 pm Last Edit: May 06, 2018, 12:15 pm by ninja2
From memory the pinmode check proved the pins were working OK. But then I lost interest and re-focussed on one of my (many) other Arduino projects, so not resolved yet AKAIK.

But why do you ask, are you experiencing similar issues?

soeren

#8
May 06, 2018, 12:21 pm Last Edit: May 06, 2018, 02:19 pm by soeren
From memory I lost interest and re-focussed on one of my (many) other Arduino projects, so not resolved yet AKAIK.

But why do you ask, are you experiencing similar issues?
Ah okay, too bad..

Yes, kind of similar. I had a mega2560 set up with an mcp23017 configured to as input for 10 push buttons.. all worked fine except i needed more SRAM so I upgraded to a Due, hooked everything up and at first everything seemed fine but after a few minutes my signals from the mcp23017 was just 11111111 constantly despite being initialized as 0 and with pull-down resistors and no buttons being pushed.

I tried both set of i2c pins (the 20/21 was much slower), and i tried setting the ports as inputs
I tried with and without pull-up resistors on sda and scl.
I tried 20 microsecond delays before each requestFrom..

I tried with requestFrom(0x20, 1, false) and requestFrom(0x20, 1, true).. I double checked my connections so many times, it's just pure 1's I receive.

I'm not using any 5v at all, and according to the datasheet the mcp23017 should be just fine with 3.3v.

my pull-down resistors (on all pins, also the ones I'm not using) are 15k ohms.

here's my code:

Code: [Select]
#include "Wire.h"

void setup() {
  Wire.begin();
  Serial.begin(9600);
  //pinMode(70, INPUT);
  //pinMode(71, INPUT);
  Serial.println("hello");

}

void loop() {

  byte gpb = 0; // MCP port b
  byte gpa = 0; // MCP port a

  delayMicroseconds(20);
  Wire.beginTransmission(0x20);
  Wire.write(0x13); // set MCP23017 memory pointer to GPIOB address
  Wire.endTransmission();

  delayMicroseconds(20);
  Wire.requestFrom(0x20, 1, false); // request one byte of data from MCP20317
  gpb = Wire.read(); // store the incoming byte into "inputs"


  delayMicroseconds(20);
  Wire.beginTransmission(0x20);
  Wire.write(0x12); // set MCP23017 memory pointer to GPIOA address
  Wire.endTransmission();

  delayMicroseconds(20);
  Wire.requestFrom(0x20, 1, false); // request one byte of data from MCP20317
 
  gpa = Wire.read(); // store the incoming byte into "inputs"

  Serial.println(gpb, BIN);
  Serial.println(gpa, BIN);ยด
}


EDIT: So I read on this post http://forum.arduino.cc/index.php?topic=223513.0 that adding additional pull-ups to the i2c ports (20/21) could potentially destroy the pins. I had no living clue this was the case.. I used 4k7 pullups on the mega2560 i2c for a long time and when upgrading to the due, reading on the arduino website it was unclear wether there were already resistors or not. At best, I read it as there are none on the due https://www.arduino.cc/en/Reference/Wire
Is it very likely that I simply destroyed the pins by having pullups for 5 minutes or so? And if so, would verifying this just be a matter of checking if they can act as normal IO pins ?

dang it if I have to buy another due..

EDIT II:
aand going back to pins 20/21 but this time WITHOUT the pullups - everything seems to be working again.. just for learning purposes, does anyone know how adding pullup resistors could have slowed down the Due ?

ninja2

4k7 pull-up resistors by themselves usually won't cause damage (the current is limited by the resistor).

There is a sweet spot for the resistance on the I2C pins, and from memory 4K7 is about right. But  if there are already internal pull-up resistors built in and you add external pull-ups they will be in parallel, so total pull-up resistance is reduced and thus current draw on the pin can increase when active low. Maybe this was a little too much current for the Due .... (depends on total current draw on the Due for your whole circuit)


Go Up