Communication via I2C port doesn’t work

Hi,

I would like to communicate via the I2C Port of the “Wio Terminal”.
I have 2 “Wio Terminals” and I plug a Grove cable into the Grove I2C interface both. But it doesn’t work.

sender script
#include <Wire.h>

int x = 0;

void setup() {
  // Start the I2C Bus as Master
  Wire.begin(); 
}

void loop() {
  Wire.beginTransmission(9); // transmit to device #9
  Wire.write(x);              // sends x 
  Wire.endTransmission();    // stop transmitting
  x++; // Increment x
  if (x > 5) x = 0; // `reset x once it gets 6
  delay(500);
}

receiver script

#include <Wire.h>

int x = 0;

void setup() {

  Serial.begin(115200);
  
  // Start the I2C Bus as Slave on address 9
  Wire.begin(9); 
  // Attach a function to trigger when something is received.
  Wire.onReceive(receiveEvent);
}

void receiveEvent(int bytes) {
  x = Wire.read();    // read one character from the I2C
}

void loop() {
  if (x == '0') {
      Serial.println(0);
  }      
  if (x == '3') {
    Serial.println(3);
  }
}

The most common cause for non-working I²C port is the absence of pull-up resistors.

Check the schematics of the Wio Terminal to ensure the I²C port features those.

1 Like

You are sending INTEGERS 0 thru 5 but your if statement is checking for CHARACTERS ‘0’ and ‘3’.

It will never be equal character ‘0’ because that is asci value of 48 and you only go to 5.

Also mark x in your receiver code as volatile.

That is declare it:

volatile int x;

1 Like

Thank you for your help and responce. I recognize the mistake in the code and checked two setups of sender and receiver with the same code.

Setup 1 => not working

  • Sender: Wio Terminal
  • Receiver: Wio Terminal

Setup 2 => Working

  • Sender: Wio Terminal
  • Receiver: Seeeduino Lotus

Here is the new code of the receiver:

// Include the required Wire library for I2C<br>
#include <Wire.h>

volatile int x = 0;

void setup() {

  Serial.begin(115200);

  // Start the I2C Bus as Slave on address 9
  Wire.begin(9); 
  // Attach a function to trigger when something is received.
  Wire.onReceive(receiveEvent);
}

void receiveEvent(int bytes) {
  x = Wire.read();    // read one character from the I2C
}

void loop() {

  Serial.println(x);
  
  if (x == 1) {
      Serial.println(1);
  }
  if (x == 2) {    
    Serial.println(2);
  }
  if (x == 3) {    
    Serial.println(3);           
  }
  delay(500);
}

Have you checked the pull-up resistors?

Summary:
This seems to be a WIO bug. When WIO is an I2C slave and receives its first transmission from a master it hangs itself and hangs the I2C bus (holds the SCL and SDA low). Tried it with and without 10K pull up resistors but results were the same.

Description:
Ok here is what I did. I ran an Arduino Zero (because it is 3.3v) as a slave and the WIO as a master. I connected it off the backport instead of through the Grove connector (the pins marked I2C1_SDA and I2C_SCL). I also made sure to share the grounds between both boards. Everything worked fine as expected.

I then ran the exact same code with the Zero as a master and the WIO as a slave. The WIO seems to hang and it holds the SDA and SCL lines low. I determined this by using a logic analyzer.

It seems to do this this right in the middle of receiving its first message. I also tried an I2C scan from the Zero to the WIO and it would hang everything as soon as it got to it’s address (0x10);

Master

#include <Wire.h>
int x = 0;

void setup() {    
  Serial.begin(9600);    
  while(!Serial);
  Serial.println("Starting");
  delay(200);
  // Start the I2C Bus as Master
  Wire.begin(); 
}

void loop() {
  Wire.beginTransmission(0x0A); 
  Wire.write(x+'0');              // sends x as char 
  int err = Wire.endTransmission();    // stop transmitting
  Serial.println(err);

  x=(x+1)%6;    
  delay(25);
 }

Slave

#include <Wire.h>

volatile int x = 0;
volatile bool hit = false;

void setup() {
  // I took out Serial prints just to make sure there was no conflict.
  //Serial.begin(9600);
  //while(!Serial);
  
  Wire.begin(0x0A); 
  // Attach a function to trigger when something is received.
  Wire.onReceive(receiveEvent);
}

void receiveEvent(int bytes) {
  hit = true;
  x = Wire.read();    // read one character from the I2C
}

void loop() {
  //Serial.print(hit);
  //Serial.print('\t');
  //Serial.println((char)x);
  delay(100);
}

Below is the logic analyzer results. I narrowed it down to the part where the WIO is turned on. It literally holds the lines low as you can see.

2 Likes

I have recorded it and we will fix it as soon as possible.

1 Like

solved in new branch


which will merge into master soon.
2 Likes