Skip to content

DUE as i2c slave: i2c connx to a master don't work - for the Mega code works fine #3885

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
shiftleftplusone opened this issue Sep 28, 2015 · 7 comments
Assignees
Labels
Board: Arduino Due Applies only to the Due Library: Wire The Wire Arduino library Type: Duplicate Another item already exists for this topic
Milestone

Comments

@shiftleftplusone
Copy link

I am running my DUE as an i2c slave to communicate to a i2c master (bitbanged i2c, it's a EV3):
the Due data transmission to the EV3 master don't work - to my Uno and Mega my code works fine nevertheless.
The code establishes a communication protocol to exchange data packages (arrays) between Arduino and EV3.

There are (at least) 2 possible error sources:

(1)
For the Mega I compellingly had to disable the internal pullups (patch in twi.c - for the Uno this was not necessary as there aren't internal pullups at all).
These pullup resistance is unusual for Arduinos but indispensable to make the EV3 master work with external devices.

//activate internal pullups for twi.
//digitalWrite(SDA, 1);
//digitalWrite(SCL, 1);

for the DUE I dont know if the patch works too, because twi.c is located in an avr subdir
As for external pullups, 2x 47k have to be used (actually 30k-80k are fine, tested by Uno and Mega),

(2)
there were issue reports about the i2c implementation on the DUE:
http://forum.arduino.cc/index.php?topic=348787.msg2415061#msg2415061

98d0a72

I tried both the old version coming with the 1.6.5 release and the patch copied to the Wire subdir.
Again I don't know neither if it affects the DUE as the Wire subdir again is in a avr subdir, nor if the patch generally is suited to fix the error in principle.

For the DUE I both tested Pullups to 3.3V and to 5V to play it safe. At both levels it didn't work

Anyway, as the code works with Uno and Mega the issue is supposed to be located on the DUE side.

First my question about (1):
are there internal pullups on the Due, and if they are: how to disable them?
Next question about (2), Wire.cpp for ARM:
are there known issues about ARM/DUE as an i2c slave and how to fix them?

transmission source code (containing some irrelevant relicts from a former UART protocol):

//  Arduino code to interface an Arduino to an EV3
//  Arduino as an I2C slave
//  compiles for MEGA and DUE, IDE 1.6.5
//  ver. 0.002c

#include  <SPI.h>
#include  <Wire.h>


//#include <ardustdio.h>

//=====================================================================================
// misc.  
//=====================================================================================

#define  clock()      millis()  


#define  SLAVE_ADDRESS 0x04
#define  MSGSIZE  30
byte     recvarray[MSGSIZE]; 
byte     sendarray[MSGSIZE];

int32_t  flag=0;


//=====================================================================================
//=====================================================================================
void setup() {
   char sbuf[128];   
   int32_t  i=0;

   // Serial terminal window
   i=115200;
   Serial.begin(i);  
   Serial.print("Serial started, baud="); Serial.println(i);

   // Wire (i2c)
   Wire.begin(SLAVE_ADDRESS);  //  start Arduino as a I2C slave, addr=0x04 (7-bit coded)
   Wire.onReceive(receiveData );
   Wire.onRequest(sendData );
   memset(sendarray, 0, sizeof(sendarray) );
   memset(recvarray, 0, sizeof(recvarray) );   
   Serial.println("I2C init: done.");

   sprintf(sbuf, "setup(): done.");
   Serial.println(); Serial.println(sbuf);   

}


//=====================================================================================


uint8_t  calcchecksum(uint8_t array[]) {
  int32_t  sum=0;
  for(int i=4; i<MSGSIZE; ++i) sum+=(array[i]);
  return (sum & 0x00ff);
}

//=====================================================================================

void loop()
{  
  char sbuf[128];

  if(flag==1)
   {  
     Serial.println(); Serial.println();

     // do something with the received data
     // and then do something to build the sendarray [4]...[31]
     sendarray[5] += 1;

     sendarray[0] = 0xff;
     sendarray[1] = calcchecksum(sendarray) ;
     sendarray[2] = SLAVE_ADDRESS; //ID check to handle several slaves
     sendarray[3] = flag; // 1= new data; 127=send again request
     //... feddisch!
     flag=0;     
   }
   else
   if(flag==127) {  // builds array with error flag 127
      Serial.println("ERROR! flag==127");
      memset(sendarray, 0, MSGSIZE);
      sendarray[3]=flag;
   }
   sprintf(sbuf, "Sendarr[4]=%4d,    [5]=%4d,    Recvarr[4]=%4d,    [5]=%4d", 
                  sendarray[4], sendarray[5], recvarray[4], recvarray[5]) ;
   Serial.println(sbuf);

   delay(2);  // short break for the cpu and the bus
}


//=====================================================================================

void receiveData(int byteCount) {
    int32_t i;
    byte val;

    while(Wire.available()<MSGSIZE) ; // wait for 30  bytes to complete
    i=0;  // init counter var
    while(Wire.available()&& (i<MSGSIZE) )         // read all bytes
    {
      val=Wire.read();
      recvarray[i++]=val;
    }
    // check for first 3 bytes and via calcchecksum() function
    if( (recvarray[0]==0xff) && (recvarray[1]==calcchecksum(recvarray)) && (SLAVE_ADDRESS==recvarray[2]) )    
    // if ok:
       flag=1;        // data ok
    else flag=127; // else handle receive error => flag =127  to send array back, request to send again
}

//=====================================================================================

void sendData(){
  // Wire.write writes data from a slave device in response to a request from a master
  Wire.write(sendarray, MSGSIZE); // send own 30 bytes back to master..
}


//=====================================================================================

@shiftleftplusone
Copy link
Author

now are there buit-in i2c pullups on the DUE or not ? (it seems, there are some).

How to disable them by software (like on the Mega) ?

@sandeepmistry sandeepmistry added the Board: Arduino Due Applies only to the Due label Oct 6, 2015
@sandeepmistry
Copy link
Contributor

@vogonjeltz there are built-in external pull-ups on the Due, they cannot be disable by software.

From the schematic:

screen shot 2015-10-06 at 9 34 04 am

@shiftleftplusone
Copy link
Author

that's a pity - for the MEGA it's possible to disable the built-in pullups though by software (twi.c).
Why not for the DUE?

@sandeepmistry sandeepmistry added the Library: Wire The Wire Arduino library label Oct 6, 2015
@sandeepmistry
Copy link
Contributor

Duplicate of #4007

@shiftleftplusone
Copy link
Author

is this not the same as for the Mega?
bf9b2876-6c0d-11e5-95ed-f157cd342f76 1

@ffissore ffissore modified the milestone: Release 1.6.7 Nov 6, 2015
@shiftleftplusone
Copy link
Author

it's still not quite clear what the difference is between Due and Mega pullups.

@per1234 per1234 added the Type: Duplicate Another item already exists for this topic label Jul 1, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Board: Arduino Due Applies only to the Due Library: Wire The Wire Arduino library Type: Duplicate Another item already exists for this topic
Projects
None yet
Development

No branches or pull requests

5 participants