🤖Have you ever tried Chat.M5Stack.com before asking??😎
    M5Stack Community
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Register
    • Login

    Error writing to I2C bus

    General
    5
    19
    6.4k
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • S
      Surya
      last edited by

      I'm just getting started with AtomS3. I'm attempting to read temperature values from both the "M5 ENVIV Unit" and "DS18B20" sensors simultaneously. However, I'm encountering an error, specifically Error writing to I2C bus, which prevents me from successfully reading from the "M5 ENVIV Unit" sensor.

      FYI: I can successfully read values from each sensor separately; the error only occurs when I try to read from both sensors simultaneously.

      Could someone please offer guidance or solutions to resolve this issue? Your help would be greatly appreciated.

      #include <M5Unified.h>
      #include <SensirionI2CSht4x.h>
      #include <Adafruit_BMP280.h>
      #include <OneWire.h>
      #include <DallasTemperature.h>
      
      const int oneWireBus = 1;
      
      void T2()
      {
          // Setup a oneWire instance to communicate with any OneWire devices
          OneWire oneWire(oneWireBus);
      
          // Pass our oneWire reference to Dallas Temperature sensor
          DallasTemperature sensors(&oneWire);
      
          sensors.begin();
      
          sensors.requestTemperatures();
      
          float temperatureC = sensors.getTempCByIndex(0);
      
          M5.Lcd.setCursor(0, 60);
          M5.Lcd.printf("T2:%2.0f", temperatureC);
      }
      
      void ENV()
      {
          float temperature, pressure, humidity;
          Adafruit_BMP280 bmp;
          SensirionI2CSht4x sht4x;
          bmp.begin(0x76);
      
          uint16_t error;
          char errorMessage[256];
      
          sht4x.begin(Wire, 0x44);
      
          bmp.setSampling(Adafruit_BMP280::MODE_NORMAL,
                          Adafruit_BMP280::SAMPLING_X2,
                          Adafruit_BMP280::SAMPLING_X16,
                          Adafruit_BMP280::FILTER_X16,
                          Adafruit_BMP280::STANDBY_MS_500);
      
          delay(1000);
          error = sht4x.measureHighPrecision(temperature, humidity);
          if (error)
          {
              Serial.print("Error trying to execute measureHighPrecision(): ");
              errorToString(error, errorMessage, 256);
              Serial.println(errorMessage);
          }
          else
          {
              Serial.print("Temperature:");
              Serial.print(temperature);
              Serial.print("\t");
              Serial.print("Humidity:");
              Serial.println(humidity);
          }
          pressure = bmp.readPressure();
          M5.Lcd.clear();
          M5.Lcd.setCursor(0, 0);
          M5.Lcd.printf("T:%2.0f", temperature);
          M5.Lcd.setCursor(0, 20);
          M5.Lcd.printf("P:%2.0f", pressure);
          M5.Lcd.setCursor(0, 40);
          M5.Lcd.print("H:");
          M5.Lcd.print(humidity);
          M5.Lcd.print("%");
      }
      
      void setup()
      {
      
          M5.begin();
          M5.Power.begin();
          M5.Lcd.setTextSize(2);
          Serial.begin(115200);
          Wire.begin();
          Wire.setClock(100000);
      }
      
      void loop()
      {
          ENV();
          T2();
          delay(100);
      }
      1 Reply Last reply Reply Quote 0
      • robskiR
        robski
        last edited by

        so you are mixing I2C sda/scl for ENV with DS18B20 sensor on same GPIO ports right?

        M5StickC, M5StickCPlus, M5StickCplus2,M5GO, M5Core, M5Tough, M5Core2, M5 Demo Board, M5Dial, M5Paper, M5Atom, M5Cardputer, M5StampS3, CoreMP135, StamPLC, AirQ

        S 1 Reply Last reply Reply Quote 0
        • felmueF
          felmue
          last edited by felmue

          Hello @Surya

          I2C uses two GPIOs (clock and data) whereas oneWire (as the name says) only uses one GPIO for both. AFAIK the two cannot share the same GPIOs.

          M5AtomS3 uses GPIO1 and GPIO2 on the Groove port for ENVIV unit. Therefore you cannot use GPIO1 for oneWire at the same time.

          Try to use a different GPIO for the DS18B20 sensor.

          Thanks
          Felix

          GPIO translation table M5Stack / M5Core2
          Information about various M5Stack products.
          Code examples

          S 2 Replies Last reply Reply Quote 1
          • S
            Surya @robski
            last edited by

            @robski Yes, both sensors are using the same ports.

            1 Reply Last reply Reply Quote 0
            • S
              Surya @felmue
              last edited by

              Thanks, @felmue, for the info!

              Both sensors use the same Grove connector pins, and since AtomS3 has only one Grove port, I've connected both sensors with Grove-T connectors.

              If they still don't work together, I'll try connecting one sensor directly to the GPIO port at the back of AtomS3. Any more suggestions are welcome!

              1 Reply Last reply Reply Quote 0
              • S
                Surya @felmue
                last edited by Surya

                @felmue

                In another script, I'm trying to upload 'ENV' sensor readings to AWS IoT Core using MQTT.

                I've connected AtomPoE Base to AtomS3 for Ethernet, using the port behind AtomS3, and attached the ENV sensor to the Grove port. Both AtomPoE and the ENV sensor use different ports. However, when I use MQTT_Client.connect(), it triggers a similar crash in the ENV sensor. Without the connection, the sensor works perfectly fine.

                Any advice on how to address this issue would be greatly appreciated!

                #include <M5AtomS3.h>
                #include <M5Unified.h>
                #include <SPI.h>
                #include <SSLClient.h>
                #include <M5_Ethernet.h>
                #include <PubSubClient.h>
                #include "certificates.h"
                #include <ArduinoJson.h>
                #include <SensirionI2CSht4x.h>
                #include <Adafruit_BMP280.h>
                #include <Adafruit_Sensor.h>
                
                #define SCK 5
                #define MISO 7
                #define MOSI 8
                #define CS 6
                
                Adafruit_BMP280 bmp;
                SensirionI2CSht4x sht4x;
                
                float temperature, pressure, humidity;
                
                // The MQTT topics that this device should publish/subscribe
                #define AWS_IOT_PUBLISH_TOPIC "AtomS3/env"
                #define AWS_IOT_SUBSCRIBE_TOPIC "AtomS3/msg"
                
                const char my_cert[] = "-----BEGIN CERTIFICATE-----\n"
                                       "MIIDWjCCAkKg...\n"
                                       "-----END CERTIFICATE-----\n";
                const char my_key[] = "-----BEGIN RSA PRIVATE KEY-----\n"
                                      "MIIEowIBAAKCAQEAk...\n"
                                      "-----END RSA PRIVATE KEY-----\n";
                
                SSLClientParameters mTLS = SSLClientParameters::fromPEM(my_cert, sizeof my_cert, my_key, sizeof my_key);
                
                byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x89};
                
                const char *mqttServer = "a1pexxx.amazonaws.com";
                
                void callback(char *topic, byte *payload, unsigned int length)
                {
                    Serial.print("Message arrived [");
                    Serial.print(topic);
                    Serial.print("] ");
                    for (int i = 0; i < length; i++)
                    {
                        Serial.print((char)payload[i]);
                    }
                    Serial.println();
                }
                
                EthernetClient ethClient;
                SSLClient ethClientSSL(ethClient, TAs, (size_t)TAs_NUM, 2);
                PubSubClient client(mqttServer, 8883, callback, ethClientSSL);
                
                void reconnect()
                {
                    // Loop until we're reconnected
                    while (!client.connected())
                    {
                        Serial.print("Attempting MQTT connection...");
                        // Attempt to connect
                        if (client.connect("arduinoClient"))
                        {
                            Serial.println("connected");
                            // Once connected, publish an announcement...
                            client.publish("outTopic", "hello world");
                            // ... and resubscribe
                            client.subscribe("ENV_TEST");
                        }
                        else
                        {
                            Serial.print("failed, rc=");
                            Serial.print(client.state());
                            Serial.println(" try again in 5 seconds");
                            // Wait 5 seconds before retrying
                            delay(5000);
                        }
                    }
                }
                
                void publishMessage()
                {
                    StaticJsonDocument<200> doc;
                    doc["temperature"] = temperature;
                    doc["humidity"] = humidity;
                    doc["pressure"] = pressure;
                    char jsonBuffer[512];
                    serializeJson(doc, jsonBuffer); // print to client
                
                    client.publish(AWS_IOT_PUBLISH_TOPIC, jsonBuffer);
                }
                
                void setup()
                {
                    M5.begin();
                    M5.Power.begin(); // Init power
                    M5.Lcd.setTextSize(2);
                    M5.Lcd.println("Init..");
                    SPI.begin(SCK, MISO, MOSI, -1);
                    Wire.begin();
                    Serial.begin(115200);
                    while (!bmp.begin(BMP280_ADDRESS_ALT))
                    {
                        M5.Lcd.println("Could not find a valid BMP280 sensor, check wiring!");
                        Serial.println(F("BMP280 fail"));
                    }
                    M5.Lcd.clear(); // Clear the screen.
                    Serial.println(F("BMP280 test"));
                
                    uint16_t error;
                    char errorMessage[256];
                
                    sht4x.begin(Wire, SHT40_I2C_ADDR_44);
                
                    bmp.setSampling(Adafruit_BMP280::MODE_NORMAL,
                                    Adafruit_BMP280::SAMPLING_X2,
                                    Adafruit_BMP280::SAMPLING_X16,
                                    Adafruit_BMP280::FILTER_X16,
                                    Adafruit_BMP280::STANDBY_MS_500);
                
                    Ethernet.init(CS);
                    M5.Lcd.println("Connecting ethernet...");
                    while (Ethernet.begin(mac) != 1)
                    {
                        Serial.println("Error getting IP address via DHCP, trying again...");
                        delay(1000);
                    }
                
                    // Check for Ethernet hardware present
                    if (Ethernet.hardwareStatus() == EthernetNoHardware)
                    {
                        Serial.println(
                            "Ethernet shield was not found.  Sorry, can't run without "
                            "hardware. :(");
                        while (true)
                        {
                            delay(1); // do nothing, no point running without Ethernet hardware
                        }
                    }
                    if (Ethernet.linkStatus() == LinkOFF)
                    {
                        Serial.println("Ethernet cable is not connected.");
                    }
                    delay(5000);
                
                    ethClientSSL.setMutualAuthParams(mTLS);
                    Serial.println(client.connect("ENV_TEST"));
                }
                
                void loop()
                {
                    if (!client.connected())
                    {
                        M5.Lcd.println("reconnecting...");
                        reconnect();
                    }
                    else
                    {
                        SPI.begin(SCK, MISO, MOSI, -1);
                        uint16_t error;
                        char errorMessage[256];
                
                        pressure = bmp.readPressure();
                        error = sht4x.measureHighPrecision(temperature, humidity);
                
                        if (error)
                        {
                            Serial.print("Error trying to execute measureHighPrecision(): ");
                            errorToString(error, errorMessage, 256);
                            Serial.println(errorMessage);
                        }
                        else
                        {
                            Serial.print("Temperature:");
                            Serial.print(temperature);
                            Serial.print("\t");
                            Serial.print("Humidity:");
                            Serial.println(humidity);
                        }
                        M5.Lcd.clear();
                        M5.Lcd.setCursor(0, 0); // Set the cursor to (0,0)
                        M5.Lcd.printf("T:%2.0f", temperature);
                        M5.Lcd.setCursor(0, 20);
                        M5.Lcd.printf("P:%2.0f", pressure);
                        M5.Lcd.setCursor(0, 40);
                        M5.Lcd.print("H:");
                        M5.Lcd.print(humidity);
                        M5.Lcd.print("%");
                
                        delay(100);
                        publishMessage();
                    }
                    client.loop();
                    delay(10000);
                }
                teastainT 1 Reply Last reply Reply Quote 1
                • teastainT
                  teastain @Surya
                  last edited by teastain

                  @surya As @felmue says, they cannot both run from the Grove port.
                  The DS18B20 is completely different and incompatible with I2C.
                  It only needs 1 wire, so you may use the Power and Ground from the Grove and connect the DS18B20 signal pin to any-other-pin on the bottom of the AtomS3.

                  Cheers, Terry!

                  100% M5Stack addict with several drawers full of product!

                  S 1 Reply Last reply Reply Quote 0
                  • S
                    Surya @teastain
                    last edited by

                    @teastain Thanks for the clarification!

                    Yeah, I understood that these sensors likely use different communication protocols. Also, I attempted to use a different GPIO pin for the DS18B20, and it worked perfectly for me.

                    Now, my only concern is my second script. Here, I'm using different ports for the ENV sensor and AtomPoE base in AtomS3. However, when I connect with the MQTT client, it breaks the ENV sensor's communication. Any advice is greatly appreciated!

                    0_1708666315261_d62524c3-fdf8-4e9f-bec5-8de0ac674050-image.png

                    1 Reply Last reply Reply Quote 0
                    • ajb2k3A
                      ajb2k3
                      last edited by

                      Have you check out my example in the Project zone as the MQTT has to be in a specific place in the code.

                      UIFlow, so easy an adult can learn it!
                      If I don't know it, be patient!
                      I've ether not learned it or am too drunk to remember it!
                      Author of the WIP UIFlow Handbook!
                      M5Black, Go, Stick, Core2, and so much more it cant be fit in here!

                      S 1 Reply Last reply Reply Quote 0
                      • S
                        Surya @ajb2k3
                        last edited by

                        @ajb2k3

                        I appreciate your input! Could you please share the link or specify the topic name related to the example you mentioned in the Project zone? I'm interested in diving deeper.

                        ajb2k3A 1 Reply Last reply Reply Quote 0
                        • ajb2k3A
                          ajb2k3 @Surya
                          last edited by ajb2k3

                          @surya https://uiflow2.m5stack.com/?pkey=c1c7d2ca888b497aab31505e1091adc6

                          Another member on the forum was having difficulties so I shared the code I use for sending data over MQTT to my private server hosted on a CM4Stack.

                          UIFlow, so easy an adult can learn it!
                          If I don't know it, be patient!
                          I've ether not learned it or am too drunk to remember it!
                          Author of the WIP UIFlow Handbook!
                          M5Black, Go, Stick, Core2, and so much more it cant be fit in here!

                          S 1 Reply Last reply Reply Quote 0
                          • S
                            Surya @ajb2k3
                            last edited by

                            @ajb2k3

                            Thank you so much for sharing your work!

                            Earlier, I successfully sent data over MQTT to AWS IoT Core in UIFlow2. However, in UIFlow2, I couldn't find a way to establish a (DHCP) Ethernet connection to AtomS3 using AtomPoE Base. That's why I decide to develop the code using PlatformIO. Do you have any reference Micropython script for an Ethernet connection?

                            1 Reply Last reply Reply Quote 0
                            • ajb2k3A
                              ajb2k3
                              last edited by

                              Alas no as I don’t have one of those

                              UIFlow, so easy an adult can learn it!
                              If I don't know it, be patient!
                              I've ether not learned it or am too drunk to remember it!
                              Author of the WIP UIFlow Handbook!
                              M5Black, Go, Stick, Core2, and so much more it cant be fit in here!

                              1 Reply Last reply Reply Quote 0
                              • felmueF
                                felmue
                                last edited by

                                Hello @Surya

                                looking at your Arduino code I think a possible issue is the long delay of 10 seconds in loop() blocking client.loop(). You need to get rid of the long delay. How to periodically execute code without blocking is shown here.

                                Thanks
                                Felix

                                GPIO translation table M5Stack / M5Core2
                                Information about various M5Stack products.
                                Code examples

                                S 1 Reply Last reply Reply Quote 0
                                • S
                                  Surya @felmue
                                  last edited by

                                  Hello @felmue

                                  I have already attempted a short delay, but unfortunately, that doesn't work for me. As for periodic code execution, I will give it a try.

                                  Thanks
                                  Surya

                                  1 Reply Last reply Reply Quote 0
                                  • S
                                    Surya
                                    last edited by

                                    Oops, I forgot to share the error message. Here it is
                                    0_1708690342175_ed5ae410-5ec1-4881-a73d-af18d629b2f6-image.png

                                    1 Reply Last reply Reply Quote 0
                                    • felmueF
                                      felmue
                                      last edited by felmue

                                      Hello @Surya

                                      after long hours of searching and debugging I found the reason why I2C would fail. It starts to fail as soon as SSL is invoked. The SSL library uses an analog GPIO as input for its random seed. And in your code you used GPIO2 which is one of M5AtomS3 Groove GPIOs.

                                      So to get rid of the I2C error try changing the GPIO used for random seed to GPIO10.

                                      //SSLClient ethClientSSL(ethClient, TAs, (size_t)TAs_NUM, 2);
                                      SSLClient ethClientSSL(ethClient, TAs, (size_t)TAs_NUM, GPIO_NUM_10);
                                      

                                      Thanks
                                      Felix

                                      GPIO translation table M5Stack / M5Core2
                                      Information about various M5Stack products.
                                      Code examples

                                      teastainT S 2 Replies Last reply Reply Quote 3
                                      • teastainT
                                        teastain @felmue
                                        last edited by

                                        @felmue Laughed out loud, in brotherhood.
                                        Great job!

                                        Cheers, Terry!

                                        100% M5Stack addict with several drawers full of product!

                                        1 Reply Last reply Reply Quote 2
                                        • S
                                          Surya @felmue
                                          last edited by

                                          Hello @felmue

                                          I implemented the change using GPIO10 for the random seed, and the I2C issue seems to be resolved. Your help is greatly appreciated!

                                          Thank you for your fix!
                                          Surya

                                          1 Reply Last reply Reply Quote 0
                                          • First post
                                            Last post