How to set up a command-based communication using I2C

Dear all
I did lots of debugging today. Here are the results.

Evaluation 1
Let's check the datasheets which I2C configurations are possible, i.e. which clock frequencies are supportet. Having a look at my WeMos M0 clone, I can see that it has an "Atmel ATSAMD21" microcontroller.

[Here I would insert a picture of my M0 clone board such that other users could see the uP. But the forum does not allow me to do so. Thanks a lot!]

The other boards is as mentionned previously a nRF52840. Having a look in the datasheets reveals that 100kHz is supported for both boards.

[Here I would insert a snippled of the two datasheets with the I2C specifications. But the forum does not allow me to do so. Thanks a lot!]

Evaluation 2
Let's check which pins are used by the microcontollers.
On my Arduino M0 board:

SerialUSB.println(PIN_WIRE_SDA);  // This outputs '20'
SerialUSB.println(PIN_WIRE_SCL);  // This outputs '21'

And on my Adafruit Sense board:

Serial.prinln(PIN_WIRE_SDA); // This outputs '22'
Serial.prinlm(PIN_WIRE_SCL); // This outputs '23'

This seems to be in line with the datasheets.

Evaluation 3
I checket whether my master board (nRF uP) is sending something over the I2C interface. If I send some data via Wire.write() I can see the waveforms on the oscilloscope:

[Here I would insert a photo of my oscilloscope showing the waveforms. But the forum does not allow me to do so. Thanks a lot!]

So the master interface seems working. However, I noticed an issue:
When the nRF is idle, the SCL and SDA pin stay at high (as it should be); but when I connect the M0 board to it, the voltage sometimes drops to 0V unless the M0 board is pluged in / flashed with a software. The nRF is then unable to output a signal. Is this supposed to happen? I'm not sure what exactly the cause of this voltage drop is as it only happens sometimes, but not always.

If I plug in the slave first and flash a program, and then connect the master via I2C to it, everything seems to be ok according to the oscilloscope. However, I am still unable to receive any information by the slave. Wire.read() never never returns something, no matter if I call it in the main loop or in an interrupt handler.

Evaluation 4
Let's reverse the situation and see whether the slave (Arduino M0) outputs something on the SCL/SDA wires when I call Wire.write() (master not connected). Result: no signal can ever be observed on the oscilloscope. So maybe the pins are not correct? I was unable to find a scheematic for that particular M0 clone, so I used a multimeter to measure which pins are connected to the SDA/SCL wire. Here is the result:


Again, this matches the specifications of other M0 boards. So this seems to be ok. Nevertheless, I tested whether I can observe a signal on any of the digital pins when I continuously call Wire.write() in the loop function. Result: No digital pin outputs anything.

Evaluation 5
Maybe the Wire library is doing something odd? What about normal digital writes? I used this code for testing on my M0 board:

void setup() {
  SerialUSB.begin(115200);
  while (!SerialUSB) {}
  pinMode(PIN_WIRE_SDA, OUTPUT);
  pinMode(PIN_WIRE_SCL, OUTPUT);
}

void loop() {
  digitalWrite(PIN_WIRE_SDA, HIGH);
  digitalWrite(PIN_WIRE_SCL, LOW);
  delayMicroseconds(5);
  digitalWrite(PIN_WIRE_SDA, LOW);
  digitalWrite(PIN_WIRE_SCL, HIGH);
  delayMicroseconds(5);
}

Result: I can observe a square wave signal on my SDA and SCL pins (!)

Summary
Two issues have been found:

  1. There seems to be an electrical issue with the SCL/SDA connections (but I am not sure what it is)
  2. Using the Wire library on the slave never outputs something although the pin number is correct and the digital IO is working properly.