SparkFun Qwiic Micro (SAMD21E) multi board project

Howdy Ya’ll
I have a project that requires using multiple controllers together. I had theorized with my limited experience that I could program one as a controller and the other as a responder and then use the Qwiic to easily connect everything.
I tried this code to test my theory but I’m so new at this I’m not sure what I’ve done wrong.

#include <Wire.h>

#define LED_PIN 13 // Built-in LED pin
#define RESPONDER_ADDR 0x10

volatile bool isConnected = false;

void setup() {
pinMode(LED_PIN, OUTPUT);
digitalWrite(LED_PIN, LOW);
Wire.begin(RESPONDER_ADDR); // Initialize as responder
Wire.onRequest(onRequest); // Register callback for when the controller requests data
Wire.onReceive(onReceive); // Register callback for when data is received
}

void loop() {
if (!isConnected) {
// Blink rapidly while waiting for a connection
digitalWrite(LED_PIN, HIGH);
delay(100);
digitalWrite(LED_PIN, LOW);
delay(100);
} else {
// Wait for ping-pong from the controller
delay(200);
}
}

// Callback: Respond to controller’s request
void onRequest() {
Wire.write(1); // Send acknowledgment
}

// Callback: Receive data from controller
void onReceive(int numBytes) {
if (numBytes > 0) {
isConnected = true; // Connection established
digitalWrite(LED_PIN, HIGH); // Set LED steady
}
}

and this for the Controller

#include <Wire.h>

#define LED_PIN 13 // Built-in LED pin
#define RESPONDER_ADDR 0x10 // I2C address of the responder

bool isConnected = false;

void setup() {
pinMode(LED_PIN, OUTPUT);
digitalWrite(LED_PIN, LOW);
Wire.begin(); // Initialize as controller
}

void loop() {
if (!isConnected) {
// Blink slowly while waiting for a connection
digitalWrite(LED_PIN, HIGH);
delay(500);
digitalWrite(LED_PIN, LOW);
delay(500);

// Check for responder presence
Wire.beginTransmission(RESPONDER_ADDR);
if (Wire.endTransmission() == 0) {
  isConnected = true; // Connection successful
  digitalWrite(LED_PIN, HIGH); // Set LED steady
  delay(1000); // Wait to stabilize
}

} else {
// Ping the responder and alternate the LED
digitalWrite(LED_PIN, HIGH);
delay(200);
Wire.beginTransmission(RESPONDER_ADDR);
Wire.write(1); // Send ping
Wire.endTransmission();

digitalWrite(LED_PIN, LOW);
delay(200);

// Wait for the responder's turn
Wire.requestFrom(RESPONDER_ADDR, 1);
if (Wire.available() > 0 && Wire.read() == 1) {
  delay(200); // Allow ping-pong timing
}

}
}

So the lights blink at different timing until it detects a connection and then they should ping pong the light back and forth but they don’t actually connect when I have them connected with the qwiic cables, ive tried powering 1 through USB and both and they just blink and never go solid or ping pong.

This is possible yeah?

Eh, there are a lot of differently timed delays…instead of trying to match blink rates, I would try getting them to perform ‘ping-pong’ serial prints or something that is less timing-dependent, then attempting to get the more complex version working afterward

What do you mean by timing delays? In the code or with I2C?
I think one of my boards has an issue bc it serial prints garbo…

Try Wire.setClock(100000); (100 kHz) in setup() on both devices.

In the code
If you do determine one is defective: Was it purchased from us? If so head over to Returns (contact vendor if purchased elsewhere) and we’ll get ya squared away

I’m not sure if this is one from you guys or from amazon but its no biggie, I have 2 more on the way now.

#include <Wire.h>

void setup() {
  SerialUSB.begin(115200);  // You can also use Serial.begin(...) if your board enumerates as a traditional COM port.
  while (!SerialUSB) {
    // Wait for serial to initialize on native USB boards.
  }

  SerialUSB.println("I2C Scanner for SAMD21");

  Wire.begin();  // Initialize I2C
}

void loop() {
  byte error, address;
  int nDevices = 0;

  SerialUSB.println("\nScanning I2C bus...");

  // Iterate through all I2C addresses (0x01 to 0x7F)
  for (address = 1; address < 127; address++) {
    Wire.beginTransmission(address);
    error = Wire.endTransmission(); // endTransmission returns 0 if the device acknowledged the address

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

      nDevices++;
    } else if (error == 4) {
      SerialUSB.print("Unknown error at address 0x");
      if (address < 16) {
        SerialUSB.print("0");
      }
      SerialUSB.println(address, HEX);
    }
  }

  if (nDevices == 0) {
    SerialUSB.println("No I2C devices found.\n");
  } else {
    SerialUSB.println("Done scanning.\n");
  }

  delay(5000); // Wait 5 seconds before scanning again
}


I tried this and the first time it ran with nothing connected it correctly reported nothing was connected, then i connected it to another board with a slave address and it reported that there was a device at EVERY address, then I unplug it and its still reporting a device at every address with nothing but the usb connected so I’m really confused.
This was tested on a brand new board

-edit-, when nothing is plugged in the i2c scanner detects nothing. As soon as I connect any of the Qwiic cables I have it detects a device at every address even with nothing on the other end of the cable.

I just used that I2C scanner on 2 fresh out the packaging boards and it found every address as well.

I2C Scanner for SAMD21

Scanning I2C bus…
I2C device found at address 0x01 !
I2C device found at address 0x02 !
I2C device found at address 0x03 !
I2C device found at address 0x04 !
I2C device found at address 0x05 !
I2C device found at address 0x06 !
I2C device found at address 0x07 !
I2C device found at address 0x08 !
I2C device found at address 0x09 !
I2C device found at address 0x0A !
I2C device found at address 0x0B !
I2C device found at address 0x0C !
I2C device found at address 0x0D !
I2C device found at address 0x0E !
I2C device found at address 0x0F !
I2C device found at address 0x10 !
I2C device found at address 0x11 !
I2C device found at address 0x12 !
I2C device found at address 0x13 !
I2C device found at address 0x14 !
I2C device found at address 0x15 !
I2C device found at address 0x16 !
I2C device found at address 0x17 !
I2C device found at address 0x18 !
I2C device found at address 0x19 !
I2C device found at address 0x1A !
I2C device found at address 0x1B !
I2C device found at address 0x1C !
I2C device found at address 0x1D !
I2C device found at address 0x1E !
I2C device found at address 0x1F !
I2C device found at address 0x20 !
I2C device found at address 0x21 !
etc.

// Wire Slave Sender
// by Nicholas Zambetti <http://www.zambetti.com>

// Demonstrates use of the Wire library
// Sends data as an I2C/TWI slave device
// Refer to the "Wire Master Reader" example for use with this

// Created 29 March 2006

// This example code is in the public domain.


#include <Wire.h>

void setup()
{
  Wire.begin(2);                // join i2c bus with address #2
  Wire.onRequest(requestEvent); // register event
}

void loop()
{
  delay(100);
}

// function that executes whenever data is requested by master
// this function is registered as an event, see setup()
void requestEvent()
{
  Wire.write("hello "); // respond with message of 6 bytes
                       // as expected by master
}

This is the code on the Slave.

I am also trying to get this boards to communicate with no luck.

Are you sure there are pull-up resistors in place on SDA and SCL to 3v3?

Are they not on the boards already? We just have one board connected to another board via the qwiic cables.

if you have these boards : SparkFun Qwiic Micro - SAMD21 Development Board

According to the schematic they are NOT on the MCU board.

Normally, mostly, they are NOT on the MCU board, but on the peripheral side. You can cut jumpers to disable them if there are more peripheral boards connected to the same MCU board. The pull-up are often either 4k7, 5k6 or 10K.

2 Likes

Oh :scream:
I assumed they were…those should be easy enough to add

The easiest is to add a cheap peripheral board in between that has pull-up resistors. e.g. SparkFun Temperature Sensor - STTS22H (Qwiic)