I have a working script that reads and displays temperature data from the SHT30 and SHT40 sensors. Both sensors are connected to the AtomS3 through Pa.HUB because they share the same I2C address.
Here is my setup:
As shown in the picture, if I connect the sensors to a specific port in the hub, I can retrieve readings from them. However, I want both sensors to work on any port I plug them into. I have been continuously trying to modify the script to achieve this, but all attempts have failed.
Here is my failing script:
#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 "M5UnitENV.h"
// Header files that contain the icons
#include "air.h"
#include "liquid.h"
#include "thermometer.h"
#define SCK 5
#define MISO 7
#define MOSI 8
#define CS 6
SHT3X sht3x;
SensirionI2cSht4x sht4x;
float temperature, pressure, humidity, liquid_temperature;
uint16_t error;
char errorMessage[256];
// 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"
"MIIDxxxx...\n"
"-----END CERTIFICATE-----\n";
const char my_key[] = "-----BEGIN RSA PRIVATE KEY-----\n"
"MIIExxxx...\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 = "a1xxxx....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, GPIO_NUM_10);
PubSubClient client(mqttServer, 8883, callback, ethClientSSL);
void reconnect()
{
// Loop until we're reconnected
while (!client.connected())
{
Serial.print("Attempting MQTT connection...");
if (client.connect("arduinoClient"))
{
Serial.println("connected");
client.subscribe("ENV_TEST");
}
else
{
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
delay(5000);
}
}
}
void publishMessage()
{
StaticJsonDocument<200> doc;
doc["air-temperature"] = temperature;
doc["air-humidity"] = humidity;
doc["liquid-temperature"] = liquid_temperature;
char jsonBuffer[512];
serializeJson(doc, jsonBuffer);
client.publish(AWS_IOT_PUBLISH_TOPIC, jsonBuffer);
}
void setup()
{
M5.begin();
M5.Power.begin();
M5.Lcd.setTextSize(2);
M5.Lcd.println("Init..");
SPI.begin(SCK, MISO, MOSI, -1);
Wire.begin();
Serial.begin(115200);
for (uint8_t port = 1; port < 6; port++)
{
Wire.beginTransmission(0x70);
Wire.write(port);
Wire.endTransmission();
delay(1000);
if (sht3x.begin(&Wire, SHT3X_I2C_ADDR, 2, 1, 400000U))
{
Serial.print("SHT3X sensor found on port ");
Serial.println(port);
}
sht4x.begin(Wire, SHT40_I2C_ADDR_44);
}
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(100);
}
}
if (Ethernet.linkStatus() == LinkOFF)
{
Serial.println("Ethernet cable is not connected.");
}
delay(1000);
ethClientSSL.setMutualAuthParams(mTLS);
client.connect("ENV_TEST");
}
void loop()
{
temperature = humidity = pressure = liquid_temperature = NULL;
if (!client.connected())
{
M5.Lcd.clear();
M5.Lcd.setCursor(0, 0);
M5.Lcd.println("reconnecting...");
reconnect();
}
else
{
for (uint8_t port = 1; port < 6; port++)
{
Wire.beginTransmission(0x70);
Wire.write(port);
Wire.endTransmission();
delay(500);
if (liquid_temperature == NULL)
{
if (sht3x.update())
{
liquid_temperature = sht3x.fTemp;
Serial.print("Temperature(L): ");
Serial.print(liquid_temperature);
Serial.print("\t");
}
}
if (temperature == NULL && humidity == NULL)
{
error = sht4x.measureHighPrecision(temperature, humidity);
if (!error)
{
Serial.print("Temperature(A):");
Serial.print(temperature);
Serial.print("\t");
Serial.print("Humidity:");
Serial.println(humidity);
} /**else {
errorToString(error, errorMessage, 256);
Serial.print("Error: ");
Serial.println(errorMessage);
}**/
}
}
// Celsius to Fahrenheit conversion
if (temperature != 0)
{
temperature = (temperature * 9 / 5) + 32;
}
M5.Lcd.clear();
M5.Lcd.setSwapBytes(true);
// Draw the icons
M5.Lcd.pushImage(0, 0, airWidth, airHeight, air);
M5.Lcd.pushImage(32, 0, thermometerWidth, thermometerHeight, thermometer);
M5.Lcd.pushImage(0, 45, airWidth, airHeight, air);
M5.Lcd.pushImage(32, 45, liquidWidth, liquidHeight, liquid);
M5.Lcd.pushImage(0, 90, liquidWidth, liquidHeight, liquid);
M5.Lcd.pushImage(32, 90, thermometerWidth, thermometerHeight, thermometer);
M5.Lcd.setCursor(70, 10);
if (temperature != 0)
{
M5.Lcd.printf("%2.1f", temperature);
M5.Lcd.setTextSize(1);
M5.Lcd.print("o");
M5.Lcd.setTextSize(2);
}
else
{
M5.Lcd.print("-");
}
M5.Lcd.setCursor(70, 55);
if (humidity != 0)
{
M5.Lcd.printf("%2.0f%%", humidity);
}
else
{
M5.Lcd.print("-");
}
M5.Lcd.setCursor(70, 100);
if (liquid_temperature != 0)
{
M5.Lcd.printf("%2.1f", liquid_temperature);
M5.Lcd.setTextSize(1);
M5.Lcd.print("o");
M5.Lcd.setTextSize(2);
}
else
{
M5.Lcd.print("-");
}
delay(100);
publishMessage();
}
client.loop();
delay(3000);
}
Can you guys help me with this? Any advice or alternative approach would be greatly appreciated.