Arduino Forum

Products => Arduino Due => Topic started by: Phillip_James on Feb 04, 2013, 01:23 am

Title: Due I2C not working
Post by: Phillip_James on Feb 04, 2013, 01:23 am
Hi Guys,

I am having trouble interfacing a 5v SRF02 sonar sensor with the Arduino Due. I have tried a few different level shifters, resistor combinations, and both I2C ports on the Due. Using an oscilloscope I can see the signal is being sent. There is just no response from the sensor.

Main program
Code: [Select]

//External Libraries
#include <Wire.h>

//Internal Headers
#include "IC2Sonar.h"

//Generate Sonar Objects
IC2Sonar sonar0(113);
IC2Sonar sonar1(114);
IC2Sonar sonar2(115);
IC2Sonar sonar3(116);

void setup()
{
  Wire.begin();
  Serial.begin(9600);
  delay(2000);
}

void loop()
{

  //SONAR DEBUG - must be running updateMap to fill SonarArray
   Serial.print(sonar0.updateSonar());
   Serial.print(" ");
   Serial.print(sonar1.updateSonar());
   Serial.print(" ");
   Serial.print(sonar2.updateSonar());
   Serial.print(" ");
   Serial.print(sonar3.updateSonar());
   Serial.println();

   delay(500);
}


Class for each sonar sensor
Code: [Select]

#ifndef __IC2SONAR_H__
#define __IC2SONAR_H__

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

class IC2Sonar {

  //Define class variables (private)
  int sensorVal;
  int sensorAddress;

public:
  //Constructor
  IC2Sonar(int address)
  {
    sensorVal = 200;
    sensorAddress = address; 
  };

  int updateSonar()
  {
    Wire.beginTransmission(sensorAddress);
    Wire.write(byte(0x00));                               
    Wire.write(byte(0x51));           
    Wire.endTransmission();

    delay(100);
   
    Wire.beginTransmission(sensorAddress);
    Wire.write(byte(0x02));                                           
    Wire.endTransmission();
   
    Wire.requestFrom(sensorAddress, 2);

    if(2 <= Wire.available())
   {   
      int reading = Wire.read();
      reading = reading << 8;    // shift high byte to be high 8 bits
      reading |= Wire.read();
      sensorVal = reading;
   }

    return sensorVal;
  }

private:
};

#endif // __IC2Sonar_H__


This program works fine on a Mega and returns 200 for each sensor not plugged in. The Due, however, always returns 0 for each sensor.
Your help is appreciated
Title: Re: Due I2C not working
Post by: Phillip_James on Feb 05, 2013, 12:00 am
Update:

I have gotten the sensor to work without level shifting it (as sda/scl are open collector). However it is very temperamental and will sometimes just not work at all. I also cannot get four devices to work, three will but not four. Again, this code and these devices work fine together on a Mega.

Does anyone have any experience with similar I2C problems?
Title: Re: Due I2C not working
Post by: SlightlyMadScientist on Feb 05, 2013, 02:23 pm
Yes, I've encountered I2C problems as well. And I am not the only one,

It seems the I2C implementation on Due is still not working 100%, possibly because of issues with the implementation of the wire library.
Title: Re: Due I2C not working
Post by: chriskner on Feb 05, 2013, 06:04 pm
Need more details on the range finder (I've never used this one).  If it's a 5V uC on that board, then the I2C i/o may not play well at 3volt levels.  'Open-collector' has nothing to do with this specification.  Open-collector is a requirement of the I2C bus.  The voltage requirements are determined by the devices that you connect to the bus, and they must agree.

I expect that all bets are off if you don't use a level translator.  I believe that the Mega is a 5v system, and that's probably why the SRF02 works with that version.

I don't see any commands in your code that shouldn't work with the present, but limited, capabilities of the wire library.

Title: Re: Due I2C not working
Post by: Grumpy_Mike on Feb 05, 2013, 06:21 pm
Quote
I have gotten the sensor to work without level shifting it (as sda/scl are open collector).

Yes they are but what are they being pulled up to?
If it is more than 3V3 at the sensor end then they need some level translation. If there is no pull ups then you need some, but only to 3V3 on the Due end.
Title: Re: Due I2C not working
Post by: Phillip_James on Feb 06, 2013, 12:01 am
I was under the impression the Due had internal 3.3v pull up resistors on the I2C lines. Is this correct? Nevertheless it is working as is, but just not 100% reliable
Title: Re: Due I2C not working
Post by: chriskner on Feb 06, 2013, 02:30 pm

I was under the impression the Due had internal 3.3v pull up resistors on the I2C lines. Is this correct?

Yes, this is correct.  However, the DUE is a 3.3V system, and the SRF is most-likely a 5V gadget.  If that is the case, then you need a level translator, as the logic thresholds probably do not agree.
Quote
Nevertheless it is working as is, but just not 100% reliable

That is the point.

-Chris
Title: Re: Due I2C not working
Post by: Phillip_James on Feb 07, 2013, 12:48 am
Well this is where it gets confusing. It works without the logic converter. But not with the logic converter. I have tried two types of logic converters, both bi-directional. The signal comes through but the Arduino will not cooperate
Title: Re: Due I2C not working
Post by: bobcousins on Feb 07, 2013, 02:05 am
What speed are you running the I2C at? I imagine that with different pullups and level translators there could be a lot of skew on the edges.

ETA: this link http://www.robot-electronics.co.uk/forum/viewtopic.php?f=2&t=250 (http://www.robot-electronics.co.uk/forum/viewtopic.php?f=2&t=250) suggest that the SFR02 uses a PIC micro with VIH = 4V, so a pullup to 3.3V seem to be insufficient. In that case though, I can't see how it works at all, unless there is a lot of tolerance on that 4V level.

I'm keen to find out if level translation on I2C is practical, or whether I need to spec peripherals to be 3.3V only. Unfortunately I haven't the kit to play with at the moment.
Title: Re: Due I2C not working
Post by: MartyMacGyver on Feb 07, 2013, 11:27 am
I'm facing a similar problem: I have a Mega and a Due side-by-side, and am testing a Chronodot and a Wii nunchuck dongle, each running at 3.3V.

Using I2Cscanner (http://playground.arduino.cc/Main/I2cScanner (http://playground.arduino.cc/Main/I2cScanner)) I can easily get the address of either device (just testing them independently) using the Mega and pins 20/21. The Due fails to see these devices with the same program via the same pins 20/21. No additional pull-ups were used (my understanding is that the appropriate resistors are already present on both boards). Since the peripherals are running at 3.3V Vcc shouldn't be an issue (if anything, I'd expect the Mega to have issues with that, NOT the Due!)

Considering I just spent a fair chunk of change on the Due, I'm a little surprised this is not working... I'm particularly worried that it's some sort of hardware issue (hopefully if it's a software thing that'll be fixed sooner than later). And I've been careful not to overload these inputs. I'm eager to see what you learn...

Note: the software was compiled with the 1.5.1r2 compiler, as well as the 1.5.2-beta (which I rebuilt a day ago). No difference, same symptoms.

Title: Re: Due I2C not working
Post by: SlightlyMadScientist on Feb 07, 2013, 02:42 pm


Using I2Cscanner (http://playground.arduino.cc/Main/I2cScanner (http://playground.arduino.cc/Main/I2cScanner)) I can easily get the address of either device (just testing them independently) using the Mega and pins 20/21. The Due fails to see these devices with the same program via the same pins 20/21. No additional pull-ups were used (my understanding is that the appropriate resistors are already present on both boards). Since the peripherals are running at 3.3V Vcc shouldn't be an issue (if anything, I'd expect the Mega to have issues with that, NOT the Due!)


I had the same issue with a digital pot from Microchip. The pot is -according to the datasheet- 3.3V compatible but I2CScanner can't find it, it work fine with an Uno (running the pot at 3.3V).

However, I AM able to write to and control the pot from the Due , so in the end it was not a problem. The moral of this story is that it might still work even if  I2Cscanner can't find the device.
Title: Re: Due I2C not working
Post by: chriskner on Feb 07, 2013, 02:53 pm
I2C Scanner will not work as expected with the DUE.

endTransmission is flawed with 1.5.1r2

See:
   
(I2C) Wire.endTransmission always returns non-zero.
: http://arduino.cc/forum/index.php/topic,144700.0.html (http://arduino.cc/forum/index.php/topic,144700.0.html)

-Chris
Title: Re: Due I2C not working
Post by: MartyMacGyver on Feb 08, 2013, 02:10 am

I2C Scanner will not work as expected with the DUE.
endTransmission is flawed with 1.5.1r2
See:(I2C) Wire.endTransmission always returns non-zero. : http://arduino.cc/forum/index.php/topic,144700.0.html (http://arduino.cc/forum/index.php/topic,144700.0.html)
-Chris

Whoa... thanks for the info. This is definitely a non-trivial issue then. I might've waited on the Due had I known that something as fundamental as I2C isn't actually working yet.
Title: Re: Due I2C not working
Post by: WayneChu on Feb 08, 2013, 06:37 am
I first noticed that the Due has two 1K pull up resistors on SCA and SDA pins when I read its schematic.  I have not seen an I2C circuit that uses such low value pull-ups and initially I thought that it was a misprint, but late verified that the schematic matches the PCB for the resistor value.  I don't know why the controller needs such low value pull-ups. These two 1K pull-ups may be the cause why the I2C works better without a 3.3V to 5V logic translator.  A translator chip like the TXB0108 has an internal 4K current limit resistor in series with each I/O pin.  It won't pull down an input pin low enough to make it as logic "0" if the input pin has a 1K pull-up, it does not even work if the pull-up is 10K. It requires a 50K pull-up as it's recommended by adafruit  http://www.adafruit.com/products/395  so it can pull the input pin down to (3.3V x 4)/54=0.135V.  If you use a MOSFET circuit as a logic level translator, the 5V output may not be able to pull down the 3.3V input lower enough to make Vgs large enough to fully turn on the MOSFET.   https://www.adafruit.com/products/757

If you are brave enough you can remove those two pull-up resistors, the I2C circuit should start to work normally. You can always add pull ups externally. The resistor network that contains the 2 pull up resistors has 4 resistors in its package, fortunately other two resistors are not used.

Without a proper 3.3V to 5V voltage translator, a 5V output pin will still be able to control a 3.3V input via a current limit resistor, but it will stress the microcontroller.  It may work for a while, but eventually the controller will die if the resistor value is not very large.  The lower resistance the shorter controller's life. With a 1M resistor it may last forever, with a 10K resistor it may last years, but with an 1 ohm resistor it may only last a few seconds.  That's one of reasons why some electronic products don't last forever.  So a proper voltage translator is important to prevent a microcontroller from degrading.
   
Just FYI,  the UNO does not have on-board pull-up resistors on I2C pins and the MEGA has two 10K pull ups, not 1K.


Title: Re: Due I2C not working
Post by: MartyMacGyver on Feb 08, 2013, 09:27 am
Just so it's clear, in my case I'm interfacing 3.3v I2C peripherals - no translation required. And the TXB0108 is specifically NOT recommended for I2C.

Per Chris, I think the main problem is the broken library. I'm beginning to wonder how you can ship a board without any library to test it against to validate the design (if I2C is incorrectly implemented here in terms of the circuitry - there could be valid reasons for the unusually low resistance - then it should have shown up in pre-production testing... but how was it tested without a working Wire library?)

Edit: I just opened the board file and the schematic as well. The pull-ups for SCL0-3/SDA0-3 (RN5) are marked 1K5 on the schematic (1.5Kohm?), yet the actual part on the board is marked 102 (1Kohm?) and the unused pins do measure at almost exactly 1Kohm. So, either they meant to have a 10K in there, or a 1.5K, or a 1Kohm resistance. Strange...

Edit2: And yes, the Mega does indeed have a 103 (which should be a 10Kohm part).
Title: Re: Due I2C not working
Post by: beautifulsmall on Feb 12, 2013, 09:47 am
Ive captured the SCL and SDA and I DO see the Ack and levels are good. But for some reason the Due is not seeing it . This is with the wire library. Ive since used the MPU6050 code with the I2Cdev library and it works. But I would like to get to the heart of the problem. Trying scan by using  error=I2Cdev::readbyte(addr++,0,buff);  in a loop still doesnt work find the Ack.
Title: Re: Due I2C not working
Post by: khyar on Feb 26, 2013, 07:47 am
I am also experiencing problems with I2C between two Dues. Nothing working at all so far, I even went back to the basic examples and nothing happened. Are the designers aware of this potential issue with either the pullups or the library (I hope it's the latter!!)? Please acknowledge.
Title: Re: Due I2C not working
Post by: chriskner on Feb 26, 2013, 03:00 pm

Ive captured the SCL and SDA and I DO see the Ack and levels are good. But for some reason the Due is not seeing it . This is with the wire library. Ive since used the MPU6050 code with the I2Cdev library and it works. But I would like to get to the heart of the problem. Trying scan by using  error=I2Cdev::readbyte(addr++,0,buff);  in a loop still doesnt work find the Ack.

The heart of the problem is that each time the wire library checks the TWI status register, the NACK bit is automatically cleared by hardware (34.11.6 TWI Status Register, page 748 in the SAM3X8E datasheet).  The wire library is broken in this regard.  If you need to detect NACK's, you will need to wait for updates, or spin your own interface.

However, it looks like you have trouble detecting ACK's.  I suspect that you probably have some other issue going on.  Try posting your code...

Do not connect two Due's together on a common I2C bus without a buffer of some sort.  The combination of both boards, and their pull-up resistors in parallel, will unnecessarily stress the DUE's TWI pins.  I recommend that the on-board pull-ups be removed from the DUE's pcb by default.  Use larger external pull-up resistors.

How big?  Check this out:
http://www.edn.com/design/analog/4371297/Design-calculations-for-robust-I2C-communications (http://www.edn.com/design/analog/4371297/Design-calculations-for-robust-I2C-communications)

-Chris
Title: Re: Due I2C not working
Post by: Patouf on Feb 26, 2013, 06:44 pm
Hi, I also have some trouble with the I2C: I am very new to this communication protocol, So I was trying to see how it works, and I tried making my Due and my Uno talk to each other. It worked, but when I send charters from the Due to the Uno, half is lost.
Here are my codes:
for the Uno (slave):
Code: [Select]
#include <Wire.h>
char buffer[64];
byte serialpos=0, wirepos=0;
void setup() {
  // put your setup code here, to run once:
   Wire.begin(0x02);
   Serial.begin(115200);
   Serial.println("I2C test Starting...");
   Wire.onRequest(handler);
   Wire.onReceive(receiver);
}

void loop() {
  if(Serial.available())
  {
    buffer[serialpos]=Serial.read();
    serialpos++;if(serialpos>64)serialpos=0;
  }
  // put your main code here, to run repeatedly:
 
}
void handler()
{
  if(wirepos<serialpos)
  {
  Wire.write(buffer[wirepos]);
  wirepos++;if(wirepos>64)wirepos=0;
  }
}
void receiver(int num)
{
  while(Wire.available())
  {
    char c=Wire.read();
    Serial.println(c);
  }
}

and for the Due (master):
Code: [Select]
#include <Wire.h>
int old, now;
void setup() {
  // put your setup code here, to run once:
   Wire.begin();
   Serial.begin(115200);
   Serial.println("I2C test starting...");
   old=millis();now=millis();
}

void loop() {
  if(Serial.available())
  {
    Wire.beginTransmission(0x02);
    Wire.write(Serial.read());
    Wire.endTransmission();
  }
  now=millis();
  if(now-old>1001)
  {
    old=now;
    Wire.requestFrom(0x02,1);
    delay(10);
    while(Wire.available())
    {
      char c=Wire.read();
      if(c>31)Serial.println(c);
    }
  }
  // put your main code here, to run repeatedly:
 
}


Any help will be appreciated. Thanks.
Title: Re: Due I2C not working
Post by: khyar on Feb 27, 2013, 01:41 am
I'm not even getting a clock signal on SCL1, just running the example file "master reader"! SCL1 just sits low at 0V (referenced to a gnd pin) and SCL(21) does the opposite (3.3V). I was surprised by how easy it was to pull SCL1 high even with a 100k resistor, as though it is not trying to pull down the line at all, ever. Is my Due faulty? Is there some special way that SCL should be terminated that I missed which is causing this behaviour? I would really appreciate a developer looking into this as my current project was designed around lots of Dues talking I2C.... oh dear :-( The previous posts suggest that both the Wire library is in error AND that the hardware has been badly designed with too small pullup resistors and that Dues therefore cannot be connected on a single I2C bus. Please confirm. This is such a fundamental (and disappointing) issue!
Title: Re: Due I2C not working
Post by: Patouf on Feb 27, 2013, 06:00 am
Actually, it's my code which was bad, I modified it and all worked fine for me :) Sorry for disturbing.
Title: Re: Due I2C not working
Post by: Markus_L811 on Feb 27, 2013, 07:34 am

Actually, it's my code which was bad, I modified it and all worked fine for me :) Sorry for disturbing.

It would be nice if you share your new code with us.
Title: Re: Due I2C not working
Post by: Patouf on Feb 27, 2013, 09:19 am
yep sorry. here it goes: for the Due (master)
Code: [Select]
#include <Wire.h>
int old, now;
void setup() {
  // put your setup code here, to run once:
   Wire.begin();
   Serial.begin(115200);
   Serial.println("I2C test starting...");
   old=millis();now=millis();
}

void loop() {
  if(Serial.available())
  {
    Wire.beginTransmission(0x02);
    Wire.write(Serial.read());
    Wire.endTransmission();
  }
    old=now;
    Wire.requestFrom(0x02,1);
    //delay(1);
    while(Wire.available())
    {
      char c=Wire.read();
      if(c>31)Serial.println(c);
    }
  // put your main code here, to run repeatedly:
 
}

and for the Uno:
Code: [Select]
#include <Wire.h>
char buffer[256];
byte serialpos=0, wirepos=0;
void setup() {
  // put your setup code here, to run once:
   Wire.begin(0x02);
   Serial.begin(115200);
   Serial.println("I2C test Starting...");
   Wire.onRequest(handler);
   Wire.onReceive(receiver);
}

void loop() {  // put your main code here, to run repeatedly:
 
}
void handler()
{
  if(Serial.available())
  {
    char c=Serial.read();
    Wire.write(c);
  }
}
void receiver(int num)
{
  while(Wire.available())
  {
    char c=Wire.read();
    Serial.println(c);
  }
}

Hope this helps :)
Title: Re: Due I2C not working
Post by: RaghavAbboy on Feb 26, 2014, 02:18 pm
Finally some good news that you've got I2C working..

I recently got my Due about a day back and tried using I2C, by sending a byte over to my target external ADC (that communicates using I2C). The device address is 0x0D, target register address is 0x80 and the byte to be sent is 0xA0.

Code: [Select]
#include <Wire.h>
byte result=0;
void setup()
{
  // put your setup code here, to run once:
 
  Serial.begin(9600);
  Wire.begin(0x0D);                                                  //device address
  delay(10);
}

void loop()
{
  //main code here, to run over and over again
  Wire.beginTransmission(0x80);                                                   //target register address
  delay(1);
  Wire.write(0xA0);                                                                       //data byte to be transmitted
  delay(1);
  result=Wire.endTransmission();                                                  //wanted to print the status of transmission as i cannot program my                                     
  delay(1);                                                                                             target IC (external ADC)
  Serial.write(result);
  Serial.println(" ");
  delay(100);
   
}


Im getting the following message on my serial monitor:

assertion "(address & 0x80) == 0" failed: file "../source/twi.c", line 261, function: TWI_StartWrite
Exiting with status 1.

I will be really grateful to anyone who can analyze Patouf's code in the previous post and point out the error (if any) in mine.

Thanks a lot guys.
Title: Re: Due I2C not working
Post by: WiFau on Mar 08, 2014, 09:30 pm
Hello, guys.

I am experiencing the same issues with the TWI interface with Arduino DUE. I am trying to read data from a MMA8452Q accelerometer. It's a 3.3V powered sensor. The strange things are the following:



It seems to be a software problem for the Wire library on Arduino DUE isn't it?
Title: Re: Due I2C not working
Post by: vanduino on Apr 25, 2014, 06:03 am
WIfAU
Did you ever figure out how to get the Due i2c to work?
Title: Re: Due I2C not working
Post by: WiFau on Apr 25, 2014, 06:57 pm
No, I haven't. I think I'll use a oscilloscope to understand what is the issue and then I'll try to fix it.
Title: Re: Due I2C not working
Post by: vanduino on Apr 26, 2014, 08:58 pm
Update: I got the my I2C devices working with the Due on both channels. 2.2K pullups on SDA1/SCL1. Haven't fully tested yet, but Due finds the device addresses. Used Newhobby's Wire library: http://forum.arduino.cc/index.php?topic=217442.msg1697527#msg1697527
Title: Re: Due I2C not working
Post by: johnflux on May 17, 2014, 01:58 am
I had the same problem with the GY-521.

Use the fix also worked for me.

Specifically:

Download:

https://raw.githubusercontent.com/bluesign2k/Arduino/d8d6d62853a5308c21b95dad4bdd64e358e857cc/hardware/arduino/sam/libraries/Wire/Wire.cpp

And overwrite in your arduino installation: hardware/arduino/sam/libraries/Wire/Wire.cpp

For me, this just fixed i2c.
Title: Re: Due I2C not working
Post by: projectgus on May 26, 2014, 08:22 am

Do not connect two Due's together on a common I2C bus without a buffer of some sort.  The combination of both boards, and their pull-up resistors in parallel, will unnecessarily stress the DUE's TWI pins.  I recommend that the on-board pull-ups be removed from the DUE's pcb by default.  Use larger external pull-up resistors.

How big?  Check this out:
http://www.edn.com/design/analog/4371297/Design-calculations-for-robust-I2C-communications (http://www.edn.com/design/analog/4371297/Design-calculations-for-robust-I2C-communications)


Hi Chris,

Great link! Someone pointed me to this post recently in concern about the 1.5K pullups I'd used in a Due-compatible design (the Freetronics EtherDue (http://freetronics.com/etherdue)). The 1.5K values I'd used were the same as the Due reference design. I calculate that under normal circumstances (including connecting two Dues together over i2c) the onboard pullup selection is fine, no need to remove them.

According to the SAM3X8E datasheet (http://www.atmel.com/devices/SAM3X8E.aspx) Table 46-2, the TWI pins on the Due (ports PB12,13 & PA17,18) can individually sink 6mA for VOL = 0.4V, or sink 9mA in "Relaxed" mode for VOL=0.6V.

Pulling 3.3V down to 0.4V through a 1.5K resistor means sinking 1.93mA. So you can connect three Dues to the same i2c bus, if you needed to, for a combined super low 500 ohm pullup resistance, before you risk the low level voltage floating above 0.4V.

If you're feeling adventurous you could add a fourth and probably a fifth Due to a common i2c bus and push the low voltage up to 0.6V ("relaxed mode") before you risk damaging anything by sinking more than 9mA (the Dues will still be able to talk to each other, as their VIL is maximum 1V.)

It is definitely worth checking any other i2c device's specifications though, to make sure they can sink at least 2mA at 0.4V. This should be well within the limit for most devices, though. Mixing more than one Due on a single i2c bus with multiple other devices also on the bus is perhaps potentially risky, as by this point you have relatively high currents (4mA, 6mA) which may exceed some device limits. The only way to be sure would be to check each device's datasheet.

Why are the comparatively low resistance values on the Due design useful, when most i2c pullups are 4.7k or 10k? The reason is probably to deal with situations of high bus capacitance, especially when using fast mode (400kHz.) This is discussed in the excellent PDF you linked above. At 400kHz it's probably not as essential as it would be if the Due supported 1Mbit or 3.4Mbit "Faster" TWI, but it's still helpful to have the bus return to a "high" value as quickly as possible.

TLDR: Unless I missed something (and please tell me if I did), I wouldn't worry about removing the Due's standard pullups under normal conditions.
Title: Re: Due I2C not working
Post by: projectgus on May 26, 2014, 08:33 am
Hi again Chris,

I just saw your post on the other i2c thread (http://forum.arduino.cc/index.php?topic=223513.msg1619990#msg1619990) about genuine Dues having 1K pullups, not 1.5K as shown on the schematic. I can confirm this on the genuine Due board I have here, as well.

In that case you're right that things are a bit more borderline, all calculations shown above get 50% worse. ie you can still connect most common i2c slave devices (specced as 0.4V / 3mA) without exceeding the specs, and two or three Dues can be joined together but probably no more. Mixing multiple Dues and other i2c devices all on the same bus is definitely a bad idea without removing some resistors.

I wonder why Arduino specced 1.5K pullups and then went with 1K in the factory!

- Angus
Title: Re: Due I2C not working
Post by: chriskner on May 27, 2014, 02:36 pm
projectgus ,

All True...  Except for if you produce a design based to operate just under the maximum allowed specifications, then you are making a product that has inherently reduced reliability and longevity (for no good reason).  Stay well away from the max specs for catastrophic electrical failure, and you'll be much, much happier.

Presumably, the DUE was designed for experimenter's and novices, using 'typical' (common) interfaces.  While pushing the speed boundaries of the I2C bus is a possibility, anyone serious about it would most likely use an I2C buffer with rise/fall time acceleration (and not rely on a uC's raw dio pin for drive capability).  Considering the intended audience, the DUE design should error on the safer-side of electrical failure.

I truly believe that the pull-up resistor choice on the DUE was a mistake, and it would have been done differently if they had the chance to do it all over again.  These things do happen.

Also, remember, the installed pull-up resistors are 1000 ohms, not 1500 (as shown in the prints).  Two DUE's connected together puts the I2C dio pins right near max spec.

Regards,

Chris
Title: Re: Due I2C not working
Post by: projectgus on May 28, 2014, 02:52 am
Hi Chris,

I agree with you that the 1K thing is definitely a mistake, compared to 1.5K as per the reference design.


All True...  Except for if you produce a design based to operate just under the maximum allowed specifications, then you are making a product that has inherently reduced reliability and longevity (for no good reason).  Stay well away from the max specs for catastrophic electrical failure, and you'll be much, much happier.


I agree also, but the limits we're talking about here aren't the limits for electrical failure. They're just the limits for normal operation with VOL<=0.4V (6mA). Exceed that limit and there's the next limit for VOL<=0.6V (9mA), also specified by the manufacturer as safe ("Relaxed mode").  Go past that and you've exceeded the safe specifications. The datasheet doesn't specify what the absolute limit is but you know for sure you can at least get to 9mA without compromising. Although I agree you want to design in headroom under normal operation.

Quote
Two DUE's connected together puts the I2C dio pins right near max spec.


This configuration puts the Due near the 6mA limit where the low voltage level may rise to 0.6V. No risk to the devices unless more than 50% more current draw appears from somewhere, to push past the "Relaxed Mode" specification of 9mA.

Of course if you connect some other i2c device to the same bus on top then it might not work, due to the low voltages possibly now being higher than 0.4V.

- Angus
Title: Re: Due I2C not working
Post by: johnflux on May 29, 2014, 10:40 am
This is a confirmed bug in the arduino Wire library:  https://github.com/arduino/Arduino/pull/1994

Specifically:

Download:

https://raw.githubusercontent.com/bluesign2k/Arduino/d8d6d62853a5308c21b95dad4bdd64e358e857cc/hardware/arduino/sam/libraries/Wire/Wire.cpp

And overwrite in your arduino installation: hardware/arduino/sam/libraries/Wire/Wire.cpp

For me, this just fixed i2c on the Due.

Other people said that it gave a compile error - I don't know why.
Title: Re: Due I2C not working
Post by: sethismyfriend on Mar 12, 2015, 06:18 pm
I tried the wire.cpp fix on my Due using the Adafruit motor sheild v2 - and just one motor and it fails as soon as the motor starts spinning - which makes me think something in the hardware is failing using the i2c protocol as these shields operate with i2c in version #2.
Title: Re: Due I2C not working
Post by: PafMei on Mar 15, 2017, 03:44 pm
This is my code below.  If works with the MEGA but the due gives you the

assertion "(address & 0x80) == 0" failed: file "../source/twi.c", line 279, function: TWI_StartWrite
Exiting with status 1.

error.

I have tried to shift the the high bit to the right but that did not work.  Any suggestions.
This this code has worked for a couple of years not problem


#include <Wire.h>
//////////////////////////////////////////////////////////////////////////////////////////
int temp_address = (0xFF); // Addres of Raytek Sensor//RAYTEK SETUP
unsigned int tek_temp;
unsigned char high, low, bytecount = 0;


void setup()
{
 Wire.begin();
 Serial.begin(9600);
 
 // put your setup code here, to run once:

}

void loop()
{
   Wire.beginTransmission(temp_address); //Begins transmission to Raytek sensor
   Wire.write(7); // Write to address 0x07 Target/Ambient temperature register
   Wire.endTransmission(false);//Ends transmisson to sensor but with False take staement allows sensor to still send back bytes
   Wire.requestFrom(temp_address, 2); //Allows only first two bytes to be read from Raytek sensor
   while (Wire.available())
   {
     if (bytecount == 0)// This buys some time
     {
       low = Wire.read();
       bytecount++;
     }
     if (bytecount == 1)// This buys some time
     {
       high = Wire.read();
       bytecount = 0;
     }
     tek_temp = (high * 256 + low) / 10; //Converts LSB AND MSB TO ACTUAL INT NUMBER

   }
   delay(1000);
   Serial.println(tek_temp);
  // raytek_time = millis() + 200;
   //genie.WriteObject(GENIE_OBJ_CUSTOM_DIGITS, 0x0B, tek_temp );

}