Error writing to I2C bus
-
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); }
-
-
@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!
-
Have you check out my example in the Project zone as the MQTT has to be in a specific place in the code.
-
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.
-
@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.
-
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?
-
Alas no as I don’t have one of those
-
-
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 -
Oops, I forgot to share the error message. Here it is
-
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 -
@felmue Laughed out loud, in brotherhood.
Great job! -
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