Digistump Forums

The Digispark => Digispark (Original) Support => Topic started by: ashgill on March 12, 2013, 08:00:28 am

Title: I2C Questions
Post by: ashgill on March 12, 2013, 08:00:28 am
Greetings.


I'm interfacing the Digispark with two different I2C devices (as two separate projects), and I'm seeing some unexpected results.


Since I have a model B Digispark, I've already cut the trace to isolate P0 (as described on http://digistump.com/wiki/digispark/tutorials/modelbi2c)


With device A (a TI INA219), I write the register address to the device address, and I get a zero as a return code from TinyWireM.endTransmission();. So far so good.


However, when I do a read to get the contents of that register, I just get back the same value that I wrote. The device documentation says that I should get back the contents of the register, not the address of the register.


With device B (a TI TCA9554), I write the register address to the device address, and I get a one as a return code from TinyWireM.endTransmission(); From reading the TinyWire source code, this means that the device is not responding. (I get the same result if I write to a non-existing device address).


In both cases I have pull-up resistors for SCA and SDA. I've also double-checked that everything is wired correctly.


Any suggestions for trying to figure out why this isn't working as expected?
Title: Re: I2C Questions
Post by: ashgill on March 12, 2013, 10:09:20 am
To make things more confusing, I wired up a third circuit, and I'm now getting return code value of 3 (Generated Start Condition not detected on bus) from TinyWireM.endTransmission, no matter what address I try to write to.


I've verified that SCL is wired to Pin 3 of the Digispark, and that SDA is wired to pin 1.


Everything is on the same power supply, 4.7k pull-up resistors on the I2C lines.... Ah, that's the problem here. No +5v to the pull up resistors...
Title: Re: I2C Questions
Post by: ashgill on March 12, 2013, 10:24:45 am
Eeyup, that was what the problem was.

Here's my code:

Code: [Select]
TinyWireM.beginTransmission(0x40);
TinyWireM.send(0x00);
result = TinyWireM.endTransmission();

TinyWireM.requestFrom(0x40, (uint8_t) 0x02);
low = (TinyWireM.receive());
high = (TinyWireM.receive());

I'm now getting the following output:

Code: [Select]
Result: 0
low: 57
high: 159

Converting that over to binary, that gives me 00111001 and 10011111, respectively.

The data sheet says that I should get back 00111001 10011111, which matches.

So, I have communication with the INA219 working.
Title: Re: I2C Questions
Post by: digistump on March 12, 2013, 01:15:39 pm
Glad you got it figured out! What are you using the INA219 for? I'm working on a digital bench supply that uses them!
Title: Re: I2C Questions
Post by: ashgill on March 12, 2013, 04:58:15 pm
I'm using the INA219 for a sensor controller that manages a 1.5 amp power budget (it's supplied by Power over Ethernet), so I need to be able to measure how much headroom is available before turning on sensors.

Here's my working test code for talking to the TCA9554. You can turn on and off lines 1 - 5 by sending the characters "1" through "5" over USB.

Code: [Select]
#include <TinyWireM.h>
#include <DigiUSB.h>

void setup()

  // Initialize Libraries
  DigiUSB.begin();
  TinyWireM.begin();

  DigiUSB.write("Init I2C...\n");

  // Set the TCA9554 outputs to all be off
  TinyWireM.beginTransmission(0x20);
  TinyWireM.send(0x01);
  TinyWireM.send(0x00);
  TinyWireM.endTransmission();

  // Set all I/O lines to be outputs
  TinyWireM.beginTransmission(0x20);
  TinyWireM.send(0x03);
  TinyWireM.send(0x00);
  TinyWireM.endTransmission();
 
  // Turn on the Ready LED
  pinMode(5, OUTPUT);
  digitalWrite(5, HIGH);
 
  DigiUSB.write("End Init\n");
}

void loop()
{
  uint16_t  value = 0; 
  uint16_t  result = 0; 
  char      buffer[26];
  uint8_t   charRead = 0;
  uint8_t   outValue = 0;

  if(DigiUSB.available())
  {
    charRead = DigiUSB.read();
   
    if     (charRead == '1') outValue = 0x01;
    else if(charRead == '2') outValue = 0x02;
    else if(charRead == '3') outValue = 0x04;
    else if(charRead == '4') outValue = 0x08;
    else if(charRead == '5') outValue = 0x10;
    else                     outValue = 0x00;

    TinyWireM.beginTransmission(0x20);
    TinyWireM.send(0x01);
    TinyWireM.send(outValue);
    TinyWireM.endTransmission();

    TinyWireM.requestFrom(0x20, (uint8_t) 0x01);
    value = TinyWireM.receive();

    sprintf(buffer, "Value: %u\n", value);
    DigiUSB.write(buffer);

  }

  // refresh the usb port
  DigiUSB.refresh();
  delay(10);
}

I never did figure out what wasn't working with my first board, but the second one is working nicely.

Those TSSOPs are _really_ nasty to solder.