Quick update on this - replacing Wire with Wire3 in the SX base library works a treat, and I was pleasantly surprised to see that this works with minimal fuss.
Now a follow-on question - because the m8 connector can be disconnected and reconnected, I’m trying to implement an i2c test/recover function that resets i2c if the m8 is removed.
I’ve consolidated my i2c startup code to:
void init_i2c() {
// cycle can pwr
Log.trace("Cycling can power");
digitalWrite(CAN_PWR, LOW);
delay(500);
digitalWrite(CAN_PWR, HIGH);
delay(500);
// start talking to i2c
io.begin(SX1509_ADDRESS);
// Wire3.setClock(100000);
for (int i = 0; i < NUM_BUTTONS; i++) {
Log.trace("Setting pin %d to INPUT",BUTTONS[i]);
io.pinMode(BUTTONS[i], INPUT);
delay(100);
}
// set led pins to outputs, give them a flash for good feels
for (int i = 0; i < NUM_LEDS; i++) {
Log.trace("Setting pin %d to ANALOG_OUTPUT",LEDS[i]);
io.pinMode(LEDS[i], ANALOG_OUTPUT);
delay(100);
io.analogWrite(LEDS[i], 255);
delay(100);
io.analogWrite(LEDS[i], 0);
// initialize our state tracker to off
LED_STATE[i] = 0;
}
}
In my setup(), I do:
void setup()
{
Tracker::instance().init();
// start i2c
init_i2c();
publishQueue.setup();
Particle.subscribe("LED_STATE", receive_led_state);
Particle.connect();
}
In loop() I do:
void loop()
{
Tracker::instance().loop();
// test i2c connected
byte error;
Wire3.beginTransmission(SX1509_ADDRESS);
error = Wire3.endTransmission();
if (error != 0) {
blinkRed.setActive(true);
Log.trace("No i2c devices connected (Error: %d)...trying again...", error);
init_i2c();
return;
}
blinkRed.setActive(false);
for (int i = 0; i < NUM_BUTTONS; i++) {
//Log.trace("Pin %d is: %d", BUTTONS[i], io.digitalRead(BUTTONS[i]));
if (io.digitalRead(BUTTONS[i]) == HIGH) {
while (io.digitalRead(BUTTONS[i]) == HIGH)
; //pause till button released
button_pressed(i);
}
}
}
The error detection works fine, and it appears to reset ok - and in fact, my buttons (INPUTS) read fine after multiple disconnect/reconnect cycles. But my LED (ANALOG_OUTPUT) never recovers and it will no longer go on/off via analogWrite() later in loop();
I’ve tried several variations of placing io.begin, etc inside my loop, in setup only, etc, and can’t seem to get the LED to recover. If the m8 is connected at boot time, the LED works fine. And after disconnect/reconnect, if I usb reset it also recovers fine.
Since tracker doesn’t have it’s own external reset button, I’d really like it if it just reconnected and kept going.
Thoughts?
(built on toolchain 3.0.0, tracker-edge v12)