TLDR: example code i2c scanner works fine. adding a single pinMode() to the setup, without any other changes, stalls the program.
Hi All (first post!),
I'm troubleshooting a faulty PCB layout (not my own design) that was designed to interface an Atmega64 with 40 i2c accelerometer devices (LIS3DH) on a 50cm long flexible PCB. I have a box full of these PCBs and am determined to get at least one of them working in order to find out where the design fault is (i2c devices are not responding).
The LIS3DH i2c devices are powered directly from the Atmega64's GPIO pins in pairs of two, then read over shared i2c lines from their two individual addresses. Their individual current consumption is 11uA in normal mode, according to the datasheet.
I've flashed an arduino bootloader onto several of the boards with no problems using the MegaCore package that supports the Atmega64 (here on github).
I cut one of the PCBs down to 8 devices to test it out first with short i2c lines - less than 10cm long. I ran MegaCore's example 'i2c scanner' code without any extra code out of curiosity, which recognized the two slave addresses correctly with all eight of the devices seemingly powered on.
In a second sketch, I initialized the four power pins used for the devices using MegaCore's GPIO numbering system and switched them on and off in series successfully. This also worked.
The problem is that simply copying the identical "pinMode(GPIO pin number, OUTPUT)" from the setup of that sketch to the setup of the i2c scanner freezes the program (without any compiler errors) --- there are no i2c signals being generated at all after upload. Note that there is otherwise no change to the code --- only one pinMode() in the setup.
If the pinMode sets any non-connected GPIO pin to an output, the software runs fine. It's only when initializing the four pins that are connected to the power pins of the eight i2c devices as output pins. These pins have no interrupts attached, or any hardware function besides being a regular GPIO.
(As a side note, I have run the example software given for reading acceleration data from a single LIS3DH and it returns data successfully, though it's not immediately clear which one of the devices is being read.)
Here is the example i2c scanner code:
/* I2C SCANNER
http://playground.arduino.cc/Main/I2cScanner
This sketch tests the standard 7-bit addresses
Devices with higher bit address might not be seen properly.
*/
#include <Wire.h>
void setup()
{
Wire.begin();
Serial.begin(9600);
Serial.println("\nI2C Scanner");
}
void loop()
{
byte error, address;
int nDevices;
Serial.println("Scanning...");
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.
Wire.beginTransmission(address);
error = Wire.endTransmission();
if (error == 0)
{
Serial.print("I2C device found at address 0x");
if (address<16)
Serial.print("0");
Serial.print(address,HEX);
Serial.println(" !");
nDevices++;
}
else if (error==4)
{
Serial.print("Unknown error at address 0x");
if (address<16)
Serial.print("0");
Serial.println(address,HEX);
}
}
if (nDevices == 0)
Serial.println("No I2C devices found\n");
else
Serial.println("done\n");
delay(5000); // wait 5 seconds for next scan
}
and here is the standard MegaCore pinout.
The power pins are 35 - 38 (PC7 to PA6). I have no schematic but could draw one if it would help.
The problem may be within the Wire.endTransmission(), but I'm not sure where to start looking even if it is. MegaCore uses its own modified Wire library, and publicly available alternatives are not supported. I'm at the end of the line for solutions for this one, and any advice or directions would be most appreciated.
Many thanks and best!
Chris