I2C problem while using Sparkfun Weather Shield on Arduino UNO WIFI REV2

I have a problem with the SparkFun Weather Shield.

I’ve loaded the example code on my Arduino UNO Wifi and it displays I2C error (reading 998).
Then, I tried with my Arduino UNO (the classic one) and it works.

Reading other posts I’ve found that the UNO Wifi don’t use A4/A5 pins for I2C communication (and I can see in the shield’s traces that they are being use).

Is there anything I can do?

Here’s the code:

#include <Wire.h> //I2C needed for sensors
#include <SparkFunHTU21D.h> // SparkFun HTU21D Humidity and Temperature Sensor Breakout
#include <SparkFunMPL3115A2.h> // SparkFun MPL3115A2 Altitude and Pressure Sensor Breakout


#define LED_BLUE 7
#define LED_GREEN 8


#define REFERENCE_3V3 A3
#define LIGHT A1
#define BATT A2 // voltage battery pin


#define I2C_ERROR 998


//Global Variables


MPL3115A2 myPressure; //Create an instance of the pressure sensor
HTU21D myHumidity; //Create an instance of the humidity sensor


void setup()
{
  Serial.begin(9600);


  // LEDs
  pinMode(LED_BLUE, OUTPUT);
  pinMode(LED_GREEN, OUTPUT);
  pinMode(LED_BUILTIN, OUTPUT);


  // analog inputs
  pinMode(REFERENCE_3V3, INPUT);
  pinMode(LIGHT, INPUT);
  pinMode(BATT, INPUT);


  // configure the pressure sensor
  myPressure.begin();
  myPressure.setModeBarometer(); // Measure pressure in Pascals from 20 to 110 kPa
  myPressure.setOversampleRate(7); // Set Oversample to the recommended 128
  myPressure.enableEventFlags(); // Enable all three pressure and temp event flags


  // configure the humidity sensor
  myHumidity.begin();
}


// print readings every second
void loop()
{
  digitalWrite(LED_BLUE, HIGH);


  //Check Humidity Sensor
  float humidity = myHumidity.readHumidity();


  if (humidity == I2C_ERROR) {
    //Humidty sensor failed to respond
    Serial.println("I2C communication to sensors is not working.");


    //Try re-initializing the I2C comm and the sensors
    myPressure.begin(); 
    myPressure.setModeBarometer();
    myPressure.setOversampleRate(7);
    myPressure.enableEventFlags();
    myHumidity.begin();
  }
  else {
    Serial.print("Humidity = ");
    Serial.print(humidity);
    Serial.print("%,");
    float temp_h = myHumidity.readTemperature();
    Serial.print(" temp_h = ");
    Serial.print(temp_h, 2);
    Serial.println("ºC");


    //Check Pressure Sensor
    float pressure = myPressure.readPressure();
    Serial.print("Pressure = ");
    Serial.print(pressure);
    Serial.println("Pa");


    //Check temp in F from pressure sensor
    //float tempf = myPressure.readTempF();


    //Check light sensor
    float light_lvl = get_light_level();
    Serial.print("Light = ");
    Serial.print(light_lvl);
    Serial.println("V");


    //Check batt level
    float batt_lvl = get_battery_level();
    Serial.print("Battery = ");
    Serial.print(batt_lvl);
    Serial.println("V");


    Serial.println();
  }


  digitalWrite(LED_BLUE, LOW);


  delay(1000);
}


//Returns the voltage of the light sensor based on the 3.3V rail
float get_light_level()
{
  float operatingVoltage = analogRead(REFERENCE_3V3);


  float lightSensor = analogRead(LIGHT);


  operatingVoltage = 3.3 / operatingVoltage; //The reference voltage is 3.3V


  lightSensor = operatingVoltage * lightSensor;


  return lightSensor;
}


//Returns the voltage of the raw pin based on the 3.3V rail
//Battery level is connected to the RAW pin on Arduino and is fed through two 5% resistors:
//3.9K on the high side (R1), and 1K on the low side (R2)
float get_battery_level()
{
  float operatingVoltage = analogRead(REFERENCE_3V3);


  float rawVoltage = analogRead(BATT);


  operatingVoltage = 3.3 / operatingVoltage; //The reference voltage is 3.3V


  rawVoltage = operatingVoltage * rawVoltage; //Convert the 0 to 1023 int to actual voltage on BATT pin


  rawVoltage *= 4.90; //(3.9k+1k)/1k - multiple BATT voltage by the voltage divider to get actual system voltage


  return rawVoltage;
}

A quick look at the schematic on the Arduino website for the UNO WiFi Rev2 shows the I2C signals are routed to the 2 pins closest to the reset button above those labelled GND & AREF (looking at the pictures on the main website, they don't appear to be labelled). SCL is the one nearest the reset button, then SDA next to AREF. The schematic shows that the female header connections go SCL, SDA, AREF, GND, 13, 12, 11, 10 etc. They don't go to A4 & A5 like on the original UNO.

They are labeled, maybe I didn't explain myself.

The shield uses both SCL-SDA AND A5-A4 for I2C communication.
I should try wiring SCL with A5 and SDA with A4? Will that work?

I was a bit quick when looking at the Sparkfun board and didn’t immediately spot that it was actually a shield that plugged directly into an original UNO, and not just one of their breakout boards. I looked at the schematic and board layout for the Sparkfun shield and there are tracks that join A4 & A5 to SDA & SCL on the shield.

I guess the problem with the UNO WiFi is that when the Sparkfun shield is plugged into it, that creates a short between the actual SDA & SCL pins on the UNO WiFi and the A4 & A5 pins (which are nothing to do with I2C on the UNO WiFi).

If that really is the issue, then you could simply chop off the A4 & A5 pins on the bottom of the Sparkfun board. Another less drastic option may be to ensure that A4 & A5 are configured as inputs in your code so that they don’t interfere with the I2C comms.

The UNO Wifi schematic & board files show that there are no on-board devices connected to A4 & A5 so you shouldn’t loose any on-board functionality as it were.

markd833:
you could simply chop off the A4 & A5 pins on the bottom of the Sparkfun board. Another less drastic option may be to ensure that A4 & A5 are configured as inputs in your code so that they don’t interfere with the I2C comms.

No luck with either of two

Do you have pullup resistors on SCL and SDA?

Erik_Baas:
Do you have pullup resistors on SCL and SDA?

Remember that it does work with the Arduino UNO, so I don't think it's a wiring issue, it should be a board compatibility problem.
You can see the schematic if you want to.

The Sparkfun schematic shows 4K7 pullups on both SCL & SDA.

I wonder if something real basic like running an I2C scanner would help at all?

markd833:
running an I2C scanner would help at all?

Using I2CScanner execute program I was able to get only the 0x60 address.
Using it with the Arduino UNO it gets 0x40 and 0x60.

rogermiranda1000:
Using I2CScanner execute program I was able to get only the 0x60 address.
Using it with the Arduino UNO it gets 0x40 and 0x60.

Seems that I'm not the only one.

Using I2Cscanner without connecting the shield shows 0x60 is being detected.
According to this post it appears to be something related to the crypto chip. Is there something I can do now?

I don't think so as both the crypto unit and the humidity sensor are using the same I2C address. The addresses are fixed from what I can tell.

You could try a software I2C solution but you would need to perform some surgery on the board to disconnect the real hardware I2C signals first.

Can you buy a basic Uno board ?

You can blame Arduino for using the word “Uno” for the “Uno Wifi REV2” board. They should have given it an other name. Shall we call it the “Arduino Bitter Wifi” board ?

The Sparkfun Weather shield is for the basic Uno, it is not for your board.
Have you read this: “Note: This shield was designed for the SparkFun RedBoard and Arduino Uno and will not work with other boards (like the Arduino Yun, for example) without modification”.
You have to fix both the hardware and software if you want to use it.

Chopping pin A4 and A5 from the shield is good. It will still work with a basic Uno board.
Your board has a security chip at 0x60 and the pressure sensor on the shield is also at 0x60. That should be avoided. You could desolder the crypto chip from your board.

Shall I try to calculate the pullup for the I2C bus ?
Arduino Bitter Wifi board: Level shifter TXS0102 has internal 10k pullup on both sides, the chip seems to connect both sides when a low level is detected. No other pullup resistors.
Weather Shield: 4k7 on both sides of the level shifter.
Total sink current is 5V/10k + 3.3V/10k + 5V/4k7 + 3.3V/4k7 = 2.6 mA, that is good.
The microcontroller with a 5V I2C bus connected to two seperate levels shifters is no problem.

In the software, they use interrupt 0 and 1 for the rain and windspeed. That is not according to the preferred way for attachInterrupt(). You have to fix that of you are going to use that.

Koepel:
Can you buy a basic Uno board ?

I do have an Arduino UNO (that's why I know it works), but I want to use Wifi (for using Arduino IoT Cloud) and I don't want to have a ESP8266 attached to TX-RX.
I've seen that there are ways to solve this address conflicts (in both software and hardware ways).
Should I try to read as software (changing the sensor's code, because they use Wire.h), or remove the security chip (risking destroying the entire board)?

That is a good explanation how to use multiple I2C buses when devices have the same address :smiley:
However, you have everything connected to the same I2C bus. I don't know how to split that in a easy way. Both software and hardware solutions require that you split the I2C bus.

Security chip: ATECC608A or ATECC608B.
According to the datasheet, the ATECC608B has a programmable I2C address after data (secret) zone lock. I don't know what that means :o The full datasheet is available under NDA (Non-Disclosure Agreement). I did not check if there is a function in a Arduino library to change the I2C address.
Manufacturer's page of the ATECC608A: ATECC608A - Crypto Authentication
Manufacturer's page of the ATECC608B: ATECC608B - Crypto Authentication

Manufacturer's page of the MPL3115A2L is here.
It seems to have a fixed I2C address.

If you use a software solution, then you have to find two unused pins, disconnect the SDA and SCL to the shield and change all the libraries for the weather shield. I think it can be done, but it is not easy.

If you add a I2C multiplexer (hardware solution), then you might be able to make it work with a few changes to the sketch. Perhaps a minimal change to a library is required. You will need to re-route the I2C bus to the shield and re-route the I2C bus on the board.

The easiest solution is to heat up the entire security chip with its pins and let the chip fall off the board. Unless your board has libraries for Wifi that include code for the security chip :frowning: I did not check that.

Is the TX-RX the problem for the ESP8266 ? Will a ESP32 solve that problem ? Because everything else are ugly solutions. Maybe you should start all over. So you want a weather station ? Let's start with a ESP32 and see what can be added to that :wink:

The Wifi on your board is with a u-blox NINA-W102. Do you know what is inside that NINA block for Wifi ? There is a ESP32 inside !
If you can use a ESP32, then you have the latest firmware when uploading a sketch (the NINA block has not the latest firmware). I like this website: 130+ ESP32 Projects, Tutorials and Guides with Arduino IDE​ | Random Nerd Tutorials.

Just a thought and maybe a slightly less physically destructive solution, but if you were to get hold of an UNO prototyping shield, you could use that to route a couple of digital pins to the real SCL & SDA pins in the weather shield. You would then need a software I2C solution to talk to the sensors.

As it's a weather shield, I wouldn't imagine that you need to sample the environment at a particularly high speed.

Koepel:
According to the datasheet, the ATECC608B has a programmable I2C address after data (secret) zone lock. I don't know what that means :o

Neither do I.
I have seen it too, but there's almost no information about. Also the datasheet says something about "one time programmable".

Koepel:
Is the TX-RX the problem for the ESP8266 ? Will a ESP32 solve that problem ? Because everything else are ugly solutions. Maybe you should start all over. So you want a weather station ? Let's start with a ESP32 and see what can be added to that :wink:

The Wifi on your board is with a u-blox NINA-W102. Do you know what is inside that NINA block for Wifi ? There is a ESP32 inside !
If you can use a ESP32, then you have the latest firmware when uploading a sketch (the NINA block has not the latest firmware). I like this website: 130+ ESP32 Projects, Tutorials and Guides with Arduino IDE​ | Random Nerd Tutorials.

The shield are uno size (and with all its pins). Using a ESP32 means that I'll have to create an adapter (and as fas as I know you can only use Arduino IoT cloud with Arduino boards).
I'll try the I2C multiplexer and if it doesn't work I'll think if I remove the chip or use an Arduino UNO + ESP8266.
What are the consequences of removing the chip? I think it can be used for WEB validation, but is it being used for IoT Cloud?

rogermiranda1000:
What are the consequences of removing the chip?

I don’t know ! I did not check the libraries yet.

Do you want to use the Arduino cloud ? Then I would not remove the security chip and find an other shield or add a few sensor-modules.

Maybe the best conclusion is that your board does not work with that shield. period.

Inserting an I2C mux is going to involve some surgery on the UNO. I guess it comes down to how much you want to go with the weather shield you have. I had a quick look at the libraries for the sensors and they are not complicated. You should be able to adapt them for software I2C if you wanted.

markd833:
Inserting an I2C mux is going to involve some surgery on the UNO.

My idea it's to leave the chip on the main I2C bus and also add the I2C mux. The I2C mux will have the shield I2C bus. Thus, no on-board surgery.

markd833:
I had a quick look at the libraries for the sensors and they are not complicated. You should be able to adapt them for software I2C if you wanted.

I had never worked with I2C, but I'll try while the mux is being shipped (I have nothing to lose I guess...).