Hoping someone can help me with an I2C issue. I have have a custom PCB with an artemis module and I2C connections at pins 5/D40 (SDA) and 6/D39 (SCL). However, when I run the Example05_wire_i2c code with those pins defined (Copied below), it does not detect the device. Any help is appreciated. Thanks!
/*
// This file is subject to the terms and conditions defined in
// file 'LICENSE.md', which is part of this source code package.
*/
/*
I2C functionality is accessed via TwoWire objects or their children.
On the Apollo3 the MbedI2C class inherits from the TwoWire class and
provides the actual implemenation based on mbed-os I2C
https://os.mbed.com/docs/mbed-os/v6.2/apis/i2c.html
Apollo3 features 6 IOM peripherals that can each be configured as either
SPI or I2C. Each IOM has only one set of pins that can be used. Check the
board schematic or Apollo3 Blue datasheet to determine which IOM
peripherals are available on your board. There are a few different ways
to access these ports:
- via pre-defined MbedI2C objects like Wire, Wire1 -> Wire5
- declaring your own MbedI2C object using pins that correspond to the correct IOM
Once you have an MbedI2C object to work with you can use all the standard
Arduino Wire API methods on it
https://www.arduino.cc/en/reference/wire
This example will use threads to organize I2C operations based on board
capabilities. The test function will list I2C devices detected on each I2C port
Wiring:
For each applicable I2C port:
SCL <--> sensor SCL
SDA <--> sensor SDA
3V3 <--> sensor 3V3
GND <--> sensor GND
*/
#include "Wire.h"
void testPortI2C(TwoWire &i2c);
// This thread will create its own MbedI2C object using IOM pins
// Define your own pins below to try it
#define mySDA 40
#define mySCL 39
#if (defined mySDA) && (defined mySCL)
TwoWire myWire(mySDA, mySCL);
#endif
void testPortI2C(TwoWire &i2c){
Serial.printf("Scanning... (port: 0x%08X), time (ms): %d\n", (uint32_t)&i2c, millis());
uint8_t detected = 0;
for(uint8_t addr = 1; addr < 127; addr++ ){
// use endTransmission to determine if a device is present at address
i2c.beginTransmission(addr);
uint8_t retval = i2c.endTransmission();
if(retval == 0){
Serial.printf("\t0x%02X detected\n", addr);
detected++;
}
}
if(!detected){
Serial.printf("\tNo device detected!\n");
}
Serial.println();
}
void setup() {
Serial.begin(115200);
Serial.println("Apollo3 - I2C");
pinMode(LED_BUILTIN, OUTPUT);
#if VARIANT_WIRE_INTFCS > 0
Wire.begin();
#endif
#if VARIANT_WIRE_INTFCS > 1
Wire1.begin();
#endif
#if (defined mySDA) && (defined mySCL)
myWire.begin();
#endif
}
void loop() {
#if VARIANT_WIRE_INTFCS > 0
testPortI2C(Wire);
#endif
#if VARIANT_WIRE_INTFCS > 1
testPortI2C(Wire1);
#endif
#if (defined mySDA) && (defined mySCL)
testPortI2C(myWire);
#endif
digitalWrite(LED_BUILTIN, LOW);
delay(1000);
digitalWrite(LED_BUILTIN, HIGH);
delay(1000);
}
Thanks for the reply. I’ve tried several scripts and configurations. I also have pins 6 and 5 exposed, which I’m also not able to connect to the device through.
Yes. For context, I think this might be a board variant definition issue with the Artemis module or potentially a software issue. I’ve tried several devices. They are detected when I connect the same circuit to a red board.
Thanks for the suggestion, I have tried that with no luck unfortunately. I’ve tried calling the sda and scl pins in a variety of formats e.g., D40, 40, pad number instead of pin number, etc). The variant.h file lists pins 9 and 8 as default. Unfortunately I don’t have those pins exposed, but from the Artemis documentation, it seems like using TwoWire should work to reconfigure the other GPIO pins. I just can’t figure out what the issue is.
What happens if you try with a sketch setting the pin D39 and D40 as output and in the loop setting this HIGH and LOW. And check with a meter or LED that you notice the change. If no meter or LED, you can connect the output to another INPUT pin as well
Thanks, Paul. That’s a really good suggestion. I tested out thought 1 with a multimeter and the connections look good (proper modulation between 0 and 3.3 V). I have tried thought 2 previously with no luck.
pffff… this is a hard one… Now I have observed a couple of times with the Artemis that if the connected device is using clock stretch you have to include a write() to get detected.
Try changing the default numbers (thought 2 above ) and now use this scanner… who knows …
#include <Wire.h>
void setup()
{
Serial.begin(115200);
Serial.println("Maybe we are lucky ");
Wire.begin();
// set wanted clock speed
Wire.setClock(100000);
for (byte address = 1; address < 127; address++ )
{
Wire.beginTransmission(address);
Wire.write (0x21); //write SOMETHING
byte error = Wire.endTransmission();
if (error == 0)
{
Serial.print("I2C device found at address 0x");
Serial.println(address, HEX);
}
else
{
Serial.print("I2C error ");
Serial.print(error);
Serial.print(" at address 0x");
Serial.println(address, HEX);
}
}
}
void loop()
{
}