chipKIT® Development Platform

Inspired by Arduino™

I2C problem

Created Mon, 23 Feb 2015 21:57:45 +0000 by vincent84


vincent84

Mon, 23 Feb 2015 21:57:45 +0000

I using chipkit Max32, and i want to use the I2C.

The board transmit just 1 sequence (adress) not the follow ? why ?

my program :

#include <Wire.h>

// constants won't change. Used here to // set pin numbers: const int LD4 = 13; // the number of the LED pin const int LD5 = 86; // the number of the LED pin int ledState = LOW; // ledState used to set the LED

int Sortie;

int PCF8574_Address = 0x40; // 8-bit I2C address for PCF8574 int PCF8574A_Address = 0x70; // 8-bit I2C address for PCF8574A

int reading = 0; long previousMillis = 0; // will store last time LED was updated

// the follow variables is a long because the time, measured in miliseconds, // will quickly become a bigger number than can be stored in an int. long interval = 1000; // interval at which to blink (milliseconds)

void setup() {

// set the digital pin as output: pinMode(LD4, OUTPUT);
pinMode(LD5, OUTPUT);

Wire.begin(); // setup I2C Sortie = 0;

}

void loop() { unsigned long currentMillis = millis();

if(currentMillis - previousMillis > interval) // Clignotement LED { // save the last time you blinked the LED previousMillis = currentMillis; if (Sortie++ >=256) Sortie = 0;

Wire.beginTransmission(PCF8574_Address); Wire.send(Sortie);
Wire.endTransmission();

// if the LED is off turn it on and vice-versa:
if (ledState == LOW) ledState = HIGH;
else ledState = LOW;

// set the LED with the ledState of the variable:
digitalWrite(LD4, ledState);
digitalWrite(LD5, !ledState);

}

}


vincent84

Wed, 25 Feb 2015 13:38:04 +0000

Nobody have a idea, a solution ? I have a second max32 board, and it's the solution ?

it's a big problem for me, i want to drive RTC, relay, eeprom on I2C, .... all my application

why I2C send juste 1 frame (adress) and not data ?

thank


jmlynesjr

Wed, 25 Feb 2015 20:03:41 +0000

Vincent:

Are you seeing an ACK from the peripheral(9th bit)?

Are your I2C addresses correct. They should be 7 bits plus a R/W bit. i.e. should your 40 be 80 and your 70 be E0?

James


vincent84

Thu, 26 Feb 2015 08:52:28 +0000

Thank jmlynesjr for you reply

I think there isn't ACK from the peripheral. The adress for the PCF8574 is 0x40 :

start R/W S 0 1 0 0 A2 A1 A0 0

in my application A0...A2 is 0.

I'll see why there is no ACK on the peripheral.

thank


GrahamM242

Thu, 26 Feb 2015 11:02:17 +0000

Also, Wire.endTransmission() returns a result code which may be useful.

That said, on the chipKit boards I prefer using the DTWI library for I2C communication, partly because it does transfers in the background, partly because it supports all the I2C controllers on the chips and partly because it does a good amount of error checking. That allows me to check for things like missing pullup or other master talking right at the start of the transaction.


vincent84

Thu, 26 Feb 2015 12:23:56 +0000

Where can i find the DTWI library ? Do you have example ?

thank


GrahamM242

Fri, 27 Feb 2015 09:55:20 +0000

It ships with the mpide-0150 test releases (which can be found here). Sadly, I've not found brilliant documentation for it, but you can look through the code which will be in hardware\pic32\libraries\Wire\DTWI.CPP. You'll probably want to look at startMasterWrite, write, startMasterRead, read, available and stopMaster.

Some quickly knocked up example code here:

#include &lt;DTWI.h&gt;

DTWI0 TWIBus;

uint8_t buffer[2]={ 0x00, 0x00};
uint8_t addr=0x40;

  // Start transaction
  if(!TWIBus.startMasterWrite(addr)) { 
    // error - couldn't start transaction
    return -1;
  }
  // write buffer out (a whole byte!) we should really check that the write buffer
  // is not full.
  if (!TWIBus.write(buffer,1)) {
    // error - couldn't write to buffer
    return -1;
  }
  // Cause a repeated start for reading data back - needs a timeout
  while(!TWIBus.startMasterRead(addr,1)) { }
  
  // Wait until bus is available
  while(!TWIBus.available()) { }

  // issue a read command and claim buffer is 2 bytes
  // BytesRead is a uint32_t that tells us how many bytes we actually got
  BytesRead=TWIBus.read(buffer,2);

  // buffer now contains our data.

  // Tell bus that we're finished with it.
  while (!TWIBus.stopMaster()) { }

jmlynesjr

Fri, 27 Feb 2015 16:02:51 +0000

Potentially dumb question....

Did you install the external bus pullup resistors? I think I use 2.2K.

James


vincent84

Sun, 01 Mar 2015 08:40:05 +0000

I have found the problem : to write on I2C bus you must write 7-bit hexadecimal address without R/W !

for exemple i want to write at the adress 0x42 with R/W -> with the chip kit I put the adress 0x21

thank


jmlynesjr

Mon, 02 Mar 2015 17:54:50 +0000

Vincent:

Glad you got it working! I was half right....just shifted your addresses the wrong way. :D

I see in twi.c

twi.slarw = (address &lt;&lt; 1) and twi.slarw = (address &lt;&lt; 1) + 1

so the R/W bit is added by the library. Also error codes were given as: 0-success, 2-Address Sent/NACK Received, 3-Data Sent/NACK Received, and 4-Other Error.

James