Cannot read HMC5883L accelerometer (CJ-M49) with 16MHz AtTiny85 (I2C Wire.h)

Can anyone who’s used AtTiny85 to communicate (as a master) with any I2C chip give me the trick to make it work?

On an Uno it works: With the Wire library I can communicate with my device and it returns valid data…

It seems DigiStump’s AtTiny85’s library is implemented with bitBanging based off TinyWireM code (I don’t care about using DigiStump when I make this work, because I’ll program standalone chips).

The library comes with this example code which fails to find a device for me:

// --------------------------------------
// i2c_scanner
// Version 1
//    This program (or code that looks like it)
//    can be found in many places.
//    For example on the forum.
//    The original author is not know.
// Version 2, Juni 2012, Using Arduino 1.0.1
//     Adapted to be as simple as possible by user Krodal
// Version 3, Feb 26  2013
//    V3 by louarnold
// Version 4, March 3, 2013, Using Arduino 1.0.3
//    by user Krodal.
//    Changes by louarnold removed.
//    Scanning addresses changed from 0...127 to 1...119,
//    according to the i2c scanner by Nick Gammon
// Version 5, March 28, 2013
//    As version 4, but address scans now to 127.
//    A sensor seems to use address 120.
// This sketch tests the standard 7-bit addresses
// Devices with higher bit address might not be seen properly.

#include <Wire.h>
#include <DigiKeyboard.h>

void setup()

  DigiKeyboard.println("\nI2C Scanner");

void loop()
  byte error, address;
  int nDevices;


  nDevices = 0;
  for (address = 1; address < 127; address++ )
    // The i2c_scanner uses the return value of
    // the Write.endTransmisstion to see if
    // a device did acknowledge to the address.
    error = Wire.endTransmission();

    if (error == 0)
      DigiKeyboard.print("I2C device found at address 0x");
      if (address < 16)
      DigiKeyboard.print(address, HEX);
      DigiKeyboard.println("  !");

    else if (error == 4)
      DigiKeyboard.print("Unknow error at address 0x");
      if (address < 16)
      DigiKeyboard.println(address, HEX);
  if (nDevices == 0)
    DigiKeyboard.println("No I2C devices found\n");

  DigiKeyboard.delay(2000);           // wait 5 seconds for next scan

The device is a HMC5883L accelerometer board.


AtTiny P0 <--> SDA HMC5883L 
AtTiny P2 <--> SCL HMC5883L 
AtTiny 5V <--> 5V HMC5883L 
AtTiny Gnd <--> Gnd HMC5883L

I used P0 and P2 because it seems hardcoded in the USI_TWI_Master.h library:

#if defined(__AVR_ATtiny25__) | defined(__AVR_ATtiny45__) | defined(__AVR_ATtiny85__) | \
    defined(__AVR_AT90Tiny26__) | defined(__AVR_ATtiny26__) | defined(__AVR_ATtiny87__) | \
    #define DDR_USI             DDRB
    #define PORT_USI            PORTB
    #define PIN_USI             PINB
    #define PORT_USI_SDA        PORTB0
    #define PORT_USI_SCL        PORTB2
    #define PIN_USI_SDA         PINB0
    #define PIN_USI_SCL         PINB2

I've tried with an Adxl345 compass and it responds once diring the first scan and after that it stops responding.

I've decided to use variable potentiometers to set them exactly to 4.7kOhm.

I'm not sure what resets the bus and causes that board to respond once.

I2C Scanner
I2C device found at address 0x53  !

No I2C devices found

No I2C devices found

Well I got the ADXL345 to work with the digistump arduino compiler and

using pins P0 and P2.

Pin P1 is wired to the on-board LED and the code manages to light it up with proper angle. I also have valid console data output (I use DigisparkKeyboard).

I'm still not able to talk to the hmc5883l accelerometer.

My console display of its data sometimes lags depending on how I tweak pins, for example if I remove the 5V power line. The value of the resistors don't change anything.

I don't know where to look to fix this.

How do you power the module, and the ATtiny? You should use 3.3V for both, else the I2C interface will not work properly.

The AtTiny85 board is powered via its USB, so 5V.

The HMC5883L CJ-M49 board has a voltage regulator so it is spec'd to run 3.3V or 5V. In fact the Uno can access it directly with Wire.h.

The AtTiny85 fails (I tried with or without pullups). The bitBang Wire library for the AtTiny/Digistump does not clearly code how it handles the CPU frequency so I want to make sure it's known to work at 16 or 16.5MHz with F_CPU matching.

Sadly I just destroyed my ADXL345 while testing :( I wired the power backwards and I think the voltage regulator is fried (it was super hot and I noticed the typical smell) :'(

It looks like this stuff: Pins are Gnd, 3.3V (not wired), 5V, SCL, SDA, DRDY (not wired)


On an Uno it's simple: |500x264

On AtTiny85, this shows the pullups, similar setup to what I use for my I2C with PB0 and PB2 (except I use adjustable resistors, 4.7kOhm)


Even if the chip runs (internally) on 3.3V, its SCA and SCL are not rated for voltages above that voltage. The on-board pullups most probably are tied to that voltage, not to the external Vcc - check?

I don’t have an oscilloscope, so I can only read voltages which is unreliable.

I have been using pullups and not using them, both fail.

The fact I got data out of the ADXL345 before I burned it tends to tell me it is not a software problem, or if it is it is a timing issue where one chip is stricter than the other, or a config issue.

Again both chips work on a 16MHz, 5V Arduino UNO’s I2C Wire.h communication.
They are unreliable or non functional on an AtTiny85 5V 16.5MHz.
Both boards come with 3V <-> 5V regulators.