Which library to use for SDA1 and SCL1 (second I2C) Arduino Due

Dear forum members,

I am trying to find a way to use a second I2C device on my Arduino Due using the SDA1 and SCL1 ports (NOT 20 and 21, the other 2). However, 20 and 21 do seem to work with the wire.h library but SDA1 and SCL1 are not working. I am also not able to find a "Wire1.h" file which should(?) support the secondary I2C ports. Can you help me out?

Greetings,

Maksud

1 Like

Anyone?

Someone should know this right, or does nobody use the second I2C on their Due?

I don't have any wire1.* files on 1.5, are there supposed to be some?

The second port does rate a small mention in the reference section

Due 20 (SDA), 21 (SCL), SDA1, SCL1

so would assume it is supported but as usual the documentation is woeful.


Rob

Hello maksudkan,

Try this with a workable SDA/SCL (first I2C) project.

#include <Wire.h>
extern TwoWire Wire1;

and then, replace all the Wire.xxxx() with Wire1.xxxx()

Here how it looks using example master_reader from

...\Arduino-1.5.x\hardware\arduino\sam\libraries\Wire\examples\master_reader

#include <Wire.h>
extern TwoWire Wire1;
void setup()
{
  Wire1.begin();        // join i2c bus (address optional for master)
  Serial.begin(9600);  // start serial for output
}

void loop()
{
  Wire1.requestFrom(2, 6);    // request 6 bytes from slave device #2

  while(Wire1.available())    // slave may send less than requested
  { 
    char c = Wire1.read(); // receive a byte as character
    Serial.print(c);         // print the character
  }

  delay(500);
}

Remember to use pins 70 (SDA1), 71 (SCL1)
Regards,
Palliser

My prior recommendation (reply#3) does not work. I just tested it using two DUEs with the master_writer and slave_receiver sketches.

I made a couple extra tests that work OK.

Test A: Master SDA1/SCL1 writes on Slave SDA/SCL.
(Using Wire1.xxx() in the master code. Using Wire.xxx() in the slave code).

Test B: Master SDA/SCL writes on Slave SDA1/SCL1
(using Wire.xxx() in the master code. Using Wire1.xxx() in the slave code).

So far so good, but maksudcan's problem remains. I can't establish communication between Master and Slave both in SDA1/SCL1.

There is only one Wire library (.h,.cpp) and one class (TwoWire).
The pin definition for Wire1 is defined in Wire (.h,.cpp) and variant (.h,.cpp).
I will try to make more time soon and do more tests.

Regards,
Palliser

I've been trying to do the same thing, and have been getting very frustrated. I'm using two Adafruit LSM303 accelerometers at different places in the system. Since the slave address is the same for both, I can't have them on the same I2C bus. I finally gave up and called a friend who's an embedded software ninja, and he had me running in no time.

Basically it's what Palliser said: you don't need any additional libraries, you just substitute "Wire1" for "Wire".

Let me know if you haven't solved your issue yet, and I'll post more details that hopefully will be helpful.

Ben

I just tested the master reader/slave sender example with two DUEs for second I2C (SDA1/SCL1) using 1K pull-up resistors and the communication is OK. Please, verify that. Regards, Palliser.

NOTE: Remember to use wire1.xxx() instead of wire.xxx() for the functions.
-P

1 Like

Dear Palliser,

I can verify that it works with your first recommendation, however, some devices wont work ond SDA1 and SCL1 and do work on SDA and SCL and vice versa, but I got my devices working:)!.

Thank you very much for your time!

Regards,

Maksud

Even I want to interface two I2C sensors with Arduino Due board,but I am unable to read the data from SDA1,SCK1.

Please show us your schematic. Or the schematic for the unspecified thing you've connected to SDA1 and SCK1.

The reason is that there's pullup resistors on the DUE board for the first I2C interface but not the second. You need to have pullups in your circuit.

Thank you, Palliser :slight_smile:

Here is my code for I2C wire0 and wire1
I use Arduino Mega.. But works on DUE as well:

some cpp file or directly in project.ino file:

#include <wire.h>
TwoWire Wire1;

//logMessage is my logger.. replace this by Serial.println or something..

 logMessage(0, "I2C scanner. Scanning bus 0...");
        for (byte i = 8; i < 127; i++)
        {
            Wire.beginTransmission(i);
            if (Wire.endTransmission() == 0)
            {
                logMessage(0, "Found address: " + String(i));
                // check address
                if ((i == 32) or (i == 39))
                {
                    // found device, do something..
                }

                delay(1);
            }
        }
        Wire.endTransmission();

        logMessage(0, "I2C scanner. Scanning bus 1...");
        for (byte i = 8; i < 127; i++)
        {
            Wire1.beginTransmission(i);
            if (Wire1.endTransmission() == 0)
            {
                logMessage(0, "Found address: " + String(i));
                // check address
                if (i == 64)
                {
                    // found device, do something..
                }

                delay(1);
            }
        }
        Wire1.endTransmission();

        logMessage(1, "I2C device check DONE.");

Members
I have read the above and Im not sure if this is correct. I am currently saving 1 number to the ext eeprom, but when I change the number from 123 to 456 I get a wrong Serial.print number back.

/*save2numbers
   DUE + one 24LC256
*/

#include <Wire.h>    //use SCl & SDA
extern TwoWire Wire1;// use SCL1 & SDA1
#define disk1 0x50    //Address of 24LC256 eeprom chip

void setup(void)
{
  Serial.begin(9600);
  Wire.begin();
  Wire1.begin();        // join i2c bus

  unsigned int address = 0;

  writeEEPROM(disk1, address, 123);//save the number '123'
  Serial.print(readEEPROM(disk1, address), DEC);
}

void loop() {}

void writeEEPROM(int deviceaddress, unsigned int eeaddress, byte data )
{
  Wire1.beginTransmission(deviceaddress);
  Wire1.write((int)(eeaddress >> 8));   // MSB
  Wire1.write((int)(eeaddress & 0xFF)); // LSB
  Wire1.write(data);
  Wire1.endTransmission();

  delay(5);
}

byte readEEPROM(int deviceaddress, unsigned int eeaddress )
{
  byte rdata = 0xFF;

  Wire1.beginTransmission(deviceaddress);
  Wire1.write((int)(eeaddress >> 8));   // MSB
  Wire1.write((int)(eeaddress & 0xFF)); // LSB
  Wire1.endTransmission();

  Wire1.requestFrom(deviceaddress, 1);

  if (Wire1.available()) rdata = Wire1.read();

  return rdata;
}

Thanks in advance

byte data ! is 456 a byte ?

ard_newbie:
byte data ! is 456 a byte ?

Please explain what you mean

void writeEEPROM(int deviceaddress, unsigned int eeaddress, byte data )

ard_newbie:
void writeEEPROM(int deviceaddress, unsigned int eeaddress, byte data )

Can somebody please explain what ard_newbie is trying to say/suggest?

456 is too big to fit in an 8-bit byte.

Please correct me if I'm wrong. As I understand it: Bits and Bytes

the largest number that can be saved by the above code is 255?

I tracked down another program that writes/ saves a string. The problem is that when I Serial.print I only receive 'DATA READ'

/*eeprom_LongStrings
   http://www.hobbytronics.co.uk/eeprom-page-write
   DUE + one 24LC256
*/

#include <Wire.h>      //use SCL & SDA
extern TwoWire Wire1;  //use SCL1 & SDA1
#define disk1 0x50     //Address of 24LC256 eeprom chip
#define WRITE_CNT 5

unsigned char rdata[32];

void setup(void)
{
  Serial.begin(9600);
  Wire.begin();
  Wire1.begin();        // join i2c bus
  unsigned int i;
  // define large string of data to be written
  char str_data[] = {"Hello-1234567890-and-abcdefghijklmnopqrstuvwxyz-Goodbye\n"};

  // Work out length of data
  char str_len = 0;
  do {
    str_len++;
  } while (str_data[str_len]);

  // Write out data several times consecutively starting at address 0
  for (i = 0; i < WRITE_CNT; i++) writeEEPROM(disk1, i * str_len, str_data);

  // read back the data 28 bytes at a time
  // reading data doesn't suffer from the page boundary rules
  Serial.println("DATA READ");
  for (i = 0; i < 10; i++) {
    readEEPROM(disk1, (i * 28), rdata, 28);
    Serial.write(rdata, 28);
  }

}

void loop() {
}

void writeEEPROM(int deviceaddress, unsigned int eeaddress, char* data)
{
  // Uses Page Write for 24LC256
  // Allows for 64 byte page boundary
  // Splits string into max 16 byte writes
  unsigned char i = 0, counter = 0;
  unsigned int  address;
  unsigned int  page_space;
  unsigned int  page = 0;
  unsigned int  num_writes;
  unsigned int  data_len = 0;
  unsigned char first_write_size;
  unsigned char last_write_size;
  unsigned char write_size;

  // Calculate length of data
  do {
    data_len++;
  } while (data[data_len]);

  // Calculate space available in first page
  page_space = int(((eeaddress / 64) + 1) * 64) - eeaddress;

  // Calculate first write size
  if (page_space > 16) {
    first_write_size = page_space - ((page_space / 16) * 16);
    if (first_write_size == 0) first_write_size = 16;
  }
  else
    first_write_size = page_space;

  // calculate size of last write
  if (data_len > first_write_size)
    last_write_size = (data_len - first_write_size) % 16;

  // Calculate how many writes we need
  if (data_len > first_write_size)
    num_writes = ((data_len - first_write_size) / 16) + 2;
  else
    num_writes = 1;

  i = 0;
  address = eeaddress;
  for (page = 0; page < num_writes; page++)
  {
    if (page == 0) write_size = first_write_size;
    else if (page == (num_writes - 1)) write_size = last_write_size;
    else write_size = 16;

    Wire1.beginTransmission(deviceaddress);
    Wire1.write((int)((address) >> 8));   // MSB
    Wire1.write((int)((address) & 0xFF)); // LSB
    counter = 0;
    do {
      Wire1.write((byte) data[i]);
      i++;
      counter++;
    } while ((data[i]) && (counter < write_size));
    Wire1.endTransmission();
    address += write_size; // Increment address for next write

    delay(6);  // needs 5ms for page write
  }
}

void readEEPROM(int deviceaddress, unsigned int eeaddress,
                unsigned char* data, unsigned int num_chars)
{
  unsigned char i = 0;
  Wire1.beginTransmission(deviceaddress);
  Wire1.write((int)(eeaddress >> 8));   // MSB
  Wire1.write((int)(eeaddress & 0xFF)); // LSB
  Wire1.endTransmission();

  Wire1.requestFrom(deviceaddress, num_chars);

  while (Wire1.available()) data[i++] = Wire1.read();

}

I have changed all the wire calls to wire1 but are not sure about the

Serial.write(rdata, 28);

Thanks for the help