I2c between two arduino mkr wifi1010 not working

Hi everybody,
I can't understand why using the same sketches for I2C master and I2C slave into two different contexts in one case MKRWIFI1010 --> ARDUINO MICRO WORKS while in the other one MKRWIFI1010 --> MKRWIFI1010 DO NOT WORK

Here below the wiring that works:

And following the wiring that DO NOT WORK:

The master and slave code is very simple and comes directly from the samples that everybody is using out there. Sorry for long comments I'm using for my reference

Master here:

// Wire Master Writer
// by Nicholas Zambetti <http://www.zambetti.com>
// Demonstrates use of the Wire library
// Writes data to an I2C/TWI slave device
// Refer to the "Wire Slave Receiver" example for use with this
// Created 29 March 2006
//integrated with Pontenziometro by Andrea Pagliari June 2022
// to add potentiometer capabilities to mkrmotorcarrier and mkr wifi1010
// to set and drive motor speed
// transmits only 1 byte and only if the change has been greater or lower than 1
// in MotorDuty which is a map of the AnalogRead which can be very noisy and therefore
// transmit changes even if the potentiometer has not been touched
// the purpose is to not continously change the receiving lcd monitor
// 02 version to send out one sigle data

//*** typical definition of  PINs from Manual C  "get rid of magic numbers"
// #define IOPIN10 10
// #define IOPIN11 11
// #define IOPIN7 7
// #define IOPIN13 13
// #define IOPINA0 A0
#define IOPINA1 A1 //only one used here to read potentiometer
// #define IOPIN12 12

const int POTENTIOMETER = IOPINA1;// POTENTIOMETER label is a generic one that can be semantically contextualized
int SensorValueAnalog; //value of the sensor that will be analogically read
int SensorValueAnalogPrevious; // variable to store previous value and smooth odd signals


// Wire
#include <Wire.h>
byte MotorDuty = 0; //*** varable specific to be used as duty or speed and variable transmitted by Wire
byte MotorDutyPrevious = 0; // variable used to store previous value and transmit only when there is a plus or minus 1 difference
//end of Wire

void setup()
{
  //**Wire
  Wire.begin(); // join i2c bus (address optional for master)
  digitalWrite(SDA, 0);//added to disable internal pull up resistors
  digitalWrite(SCL, 0);//added to disable internal pull up resistors
  //endOfWire**

  //**SensorPlatform
  pinMode (POTENTIOMETER, INPUT); // pin Mode for potentiometer
  //EndOfSensorPlatform**

  //**SerialDebug
  Serial.begin(9600);
  //EndOfSerialDebug**
}


void loop()
{
  SensorValueAnalog = analogRead(POTENTIOMETER);// read the input pin
  MotorDuty = map(SensorValueAnalog, 0, 1023, 1, 100); // remap to M1.setDuty(int) where -100<int<100 and 0 means stop

  //**SerialDebug
  Serial.print("SensorValueAnalog=");
  Serial.println(SensorValueAnalog);
  Serial.print("Speed=");
  Serial.println(MotorDuty);
  //EndOfSerialDebug**

  delay(50);                                           // slight delay to stabilize the ADC

  if ((MotorDuty != MotorDutyPrevious) & (MotorDuty != (MotorDutyPrevious + 1)) & (MotorDuty != (MotorDutyPrevious - 1))) { // *** CORE IF LOGIC transmits only if the analogReadvalue changed of one minus/plus
    //Wire
    Wire.beginTransmission(4); // transmit to device #4
    Wire.write(MotorDuty);              // sends one byte
    Wire.endTransmission();    // stop transmitting
    delay(200);
    Serial.print("SENT OUT"); //debug
    //EndOfWire
  }
  SensorValueAnalogPrevious = SensorValueAnalog; // put previous equal to current value before starting the loop again
  MotorDutyPrevious = MotorDuty;

}

And SLAVE FOR ARDUINO MICRO here below:

// Wire Slave Receiver
// by Nicholas Zambetti <http://www.zambetti.com>
// Demonstrates use of the Wire library
// Receives data as an I2C/TWI slave device
// Refer to the "Wire Master Writer" example for use with this
// Created 29 March 2006
// This example code is in the public domain.
//Integrated June 2020 by Andrea Pagliari
// with LCD output capabilities
// LiquidCrystal(rs, enable, d4, d5, d6, d7)
// to monitor potentiometer run on MKR Motor carrier and show it real time on a remote LCD screen
// LCD screen is managed and controlled by additional Arduino Micro
//PINs reviewed to work with ArduinoMicro

//**Wire
#include <Wire.h>
//EndOfWire**

//**LCDScreen
#define PINRS 12
#define PINENABLE 11
#define PIND4 9
#define PIND5 6
#define PIND6 5
#define PIND7 4


#include <LiquidCrystal.h> //carica la specifica libreria
// LiquidCrystal lcd(12, 11, 5, 4, 3, 2); //versione Arduino Uno definisce quali sono i PIN di comunicazione con il monitor lcd si potrebbero sistemare come da best practice
LiquidCrystal lcd(PINRS, PINENABLE, PIND4, PIND5, PIND6, PIND7); //definisce quali sono i PIN di comunicazione con il monitor lcd si potrebbero sistemare come da best practice

//EndOfLCDScreen**


void setup()
{
  //**Wire
  Wire.begin(4);                // join i2c bus with address #4 which is the address the master send data to
  Wire.onReceive(receiveEvent); // register event
  //EndOfWire**

  //**LCDScreen
  lcd.begin(16, 2); //dichiara che lo schermo รจ 16 caratteri per 2 caratteri di dimensione
  //EndOfLCDScreen**

  //**SerialDebug
  Serial.begin(9600);           // start serial for debug output
  //EndOfSerialDebug**

}

void loop()
{
  delay(100);
}


// function that executes whenever data is received from master
// this function is registered as an event, see setup()
void receiveEvent(int howMany)
{
  lcd.clear();
  int i = 0;
  while (1 < Wire.available()) // loop through all but the last
  {
    char c = Wire.read(); // receive byte as a character
    lcd.setCursor(i, 0);
    lcd.print(c);         // print the character
    i ++;
  }
  int x = Wire.read();    // receive byte as an integer
  lcd.setCursor(0, 1);
  lcd.print(x);
  Serial.print("Speed=");
  Serial.println(x);         // print the integer

}

WHILE SLAVE FOR ARDUINO MKRWIFI1010 mounted on IOT CARRIER is following:

// Wire Slave Receiver
// by Nicholas Zambetti <http://www.zambetti.com>
// Demonstrates use of the Wire library
// Receives data as an I2C/TWI slave device
// Refer to the "Wire Master Writer" example for use with this
// Created 29 March 2006

//Modified June2022 by Andrea Pagliari
//To use LCD Screen on Arduino Iot MKR and MKR Wifi1010
//02 version to get only a single character and print it

//**Wire
#include <Wire.h>
//EndOfWire**

//**MKRIotCarrier
int ScreenSwitch=1;
#include <Arduino_MKRIoTCarrier.h>
/* Create a carrier object */
MKRIoTCarrier carrier;
//EndOf **MKRIotCarrier


void setup()
{
  //**Wire
  Wire.begin(4);  // join i2c bus with address #4 which is the address the master send data to
  digitalWrite(SDA, 0);//added to disable internal pull up resistors
  digitalWrite(SCL, 0);//added to disable internal pull up resistors
  Wire.onReceive(receiveEvent); // register event
  //EndOfWire**

  //Initialize the MKR IoT Carrier
  carrier.begin();
  carrier.display.setRotation(0);
  carrier.display.enableDisplay(1);
  
  //**SerialDebug
  Serial.begin(9600);           // start serial for debug output
  //EndOfSerialDebug**

}

void loop()
{
  
  delay(100);
}
// function that executes whenever data is received from master
// this function is registered as an event, see setup()
void receiveEvent(int howMany)
{
  Serial.print("EventRECEIVED");// debug
  int x = Wire.read();    // receive byte as an integer
  carrier.display.fillScreen(ST77XX_RED); //red background
  carrier.display.setTextColor(ST77XX_WHITE); //white text
  carrier.display.setTextSize(6); //medium sized text
  carrier.display.setCursor(80, 100); //sets position for printing (x and y)
  carrier.display.print(x); // print the integer  
  Serial.print("Speed=");
  Serial.println(x);         // print the integer

}

Any help will be higly appreciated and thanks in advance for your support!
Andrea

in your Fritzy the depicted board is "continuous" meaning the power rails are going all the way from left to right

some breadboards are "cut in the middle"

โžœ do you have such a continuous breadboard?

1 Like

Hi J-M-L,

thanks for suggesting this angle but unfortunately this is not the case. The connections are granted and physically are the same for both cases.

Anyway thanks for your attention and contribution here .

take care,

Andrea

was worth checking as the pull-ups were not on the same side of the breadboard in the drawings

One difference is that your Arduino Micro is a 5V device. Wondering how it plays out as I would use an I2C level shifter in the first case

Actually, no one is using those examples. The I2C bus works best with packages of binary data with a fixed size.

Take a step back. Make an empty sketch for Slave with only "Wire.begin(4);" in setup().
Then run a I2C Scanner sketch in the Master, it should detect the Slave.

Do you know if the Slave (Target) mode works for the Arduino MKR WiFi 1010 ?
It uses a ATSAMD21G18 processor, I think it should work.
Can you try to transmit a single byte ? Try to send a single byte, then try to request a single byte.

Did you know that the I2C bus is not good to transmit data between processors ? It is not that kind of bus.

Hi Koepel,
thanks for your answer. Will do the best possible use of it.

Hi J-M-L, your question is interesting even if the Arduino Micro in reality is working :grinning: Think I'll first try to understand the reason why wifi 1010 is not.

My next try will not to use 4 (decimal) I2C address since despite the public code sample using this address I recently read into documentation tha I2C addresses up to 7 are reserved... and then I'll try using greater numbers with hex notation as it is done in other sketeches with sensors. Keep posted here in case some positive outcome will pop up.

try a simpler setup for the start with just the pull-up and the 2 boards and a simple code like indeed setting up the slave and trying to detect the slave from the other arduino as suggested by @Koepel

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.