Arduino Cloud & I2C

Good morning to everyone,

I'm tring to send data from the I2C soil moisture sensor with a MKR1000Wifi to Arduino Cloud.

If I do not connect the board to Arduino Cloud, everything works perfectly: I read reasonable values of temperature light and moisture content.

The issue arises when I use try to connect and send data to the cloud:

-1) at the beginning the I2C sensor address is 9, and the version of the sensor is 24

-2) as you can see from the figure below, the sensor reads reasonable values

-3) but, when the board connects to Arduino cloud, the version resets (from 24 to FF)

-4) since the version is changed, the board is no more able to read reasonable values from the soil moisture sensor data, and reads 65535 and -0.10.

Do you have an idea of what happens?

Thank you very much!

I believe you’re bumping into an issue of your sensor being rendered useless when the crypto-chip comes into play.

What I do usually is to only initialise my i2c devices once IoT Cloud has already connected, and disable them when a disconnection happens, so at next reconnection they will be initialised again.
I also setup booleans to only use i2c peripherals when they are “active”.

Set aside the thingsProperties file which is in the attached .zip anyway, this is the sketch to use a MKR ENV Shield without problems.

Let me know if it works out for you :slight_smile:

The important part is when you subscribe to the 3 CONNECT/DISCONNECT/SYNC callback

ArduinoCloud.addCallback(ArduinoIoTCloudEvent::CONNECT, onIoTConnect);
ArduinoCloud.addCallback(ArduinoIoTCloudEvent::DISCONNECT, onIoTDisconnect);
ArduinoCloud.addCallback(ArduinoIoTCloudEvent::SYNC, onIoTSync);

full sketch here

Thank you very much ubidefeo for your fast and precise answer.

I tried your code, but probably due to some differences, it does not work for me.

I start by saying that I’m new to Arduino/C/C++ therefore I’m probably making very trivial mistakes.

I tried to adapt your code to my settings:

  • I’m not using a MRK ENV shield therefore in the following code I will not use #include <Arduino_MKRENV.h>

  • on the contrary, I’m using a I2C soil moisture sensor therefore I will use #include <I2CSoilMoistureSensor.h>


  • I initialized ENV as a I2CSoilMoistureSensor

  • I modified the initI2C() function. Since I2CSoilMoistureSensor.begin() is a void, I made some raw adaptation, using 2CSoilMoistureSensor.setAddress(). I expect the problem is mainly here.

Here I attach the code I used. Can you give me a hint of what I’m doing wrong?

Thank you very much!!!

test.ino (3.35 KB)

hi Tom

If you look at the library's example for changing address you'll see that it's not what you want to do.
Unfortunately I don't have one of these, but I'd change that section of code to this:

bool initI2C() {
  ENV.begin(true); // this will pause your program giving time to the sensor to startup (documentation)
  if(ENV.getAddress() == 0x20){ // default value for ADDR
    envEnabled = true;
    Serial.println("Failed to initialize i2c Moiture Sensor");
    envEnabled = false;
    return false;
  return true;

let me know if it works out