<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Pa.HUB: use any port for connection.]]></title><description><![CDATA[<p dir="auto">I have a working script that reads and displays temperature data from the <strong>SHT30</strong> and <strong>SHT40</strong> sensors. Both sensors are connected to the <strong>AtomS3</strong> through <strong>Pa.HUB</strong> because they share the same I2C address.</p>
<p dir="auto"><strong>Here is my setup:</strong><br />
<img src="/assets/uploads/files/1718963965203-6252c4c7-e020-4940-b83a-ae8f03537f0f-image.png" alt="6252c4c7-e020-4940-b83a-ae8f03537f0f-image.png" class=" img-fluid img-markdown" /></p>
<p dir="auto">As shown in the picture, if I connect the sensors to a specific port in the hub, I can retrieve readings from them. However, <strong>I want both sensors to work on any port I plug them into</strong>. I have been continuously trying to modify the script to achieve this, but all attempts have failed.</p>
<p dir="auto"><strong>Here is my failing script:</strong></p>
<pre><code>#include &lt;M5AtomS3.h&gt;
#include &lt;M5Unified.h&gt;
#include &lt;SPI.h&gt;
#include &lt;SSLClient.h&gt;
#include &lt;M5_Ethernet.h&gt;
#include &lt;PubSubClient.h&gt;
#include "certificates.h"
#include &lt;ArduinoJson.h&gt;
#include &lt;SensirionI2CSht4x.h&gt;
#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 &lt; 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&lt;200&gt; 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 &lt; 6; port++)
    {
        Wire.beginTransmission(0x70);
        Wire.write(port);
        Wire.endTransmission();
        delay(1000);

        if (sht3x.begin(&amp;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 &lt; 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 &amp;&amp; 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);
}
</code></pre>
<p dir="auto">Can you guys help me with this? Any advice or alternative approach would be greatly appreciated.</p>
]]></description><link>https://community.m5stack.com/topic/6572/pa-hub-use-any-port-for-connection</link><generator>RSS for Node</generator><lastBuildDate>Wed, 29 Apr 2026 01:47:33 GMT</lastBuildDate><atom:link href="https://community.m5stack.com/topic/6572.rss" rel="self" type="application/rss+xml"/><pubDate>Fri, 21 Jun 2024 10:08:20 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Pa.HUB: use any port for connection. on Wed, 07 Aug 2024 13:03:00 GMT]]></title><description><![CDATA[<p dir="auto">Here are some additional details:</p>
<p dir="auto">When I initially scan for the I2C bus, it says:<br />
<strong>Scanning...<br />
I2C device found at address 0x70</strong></p>
<p dir="auto">After pressing the reset button in AtomS3, it says:<br />
<strong>Scanning...<br />
I2C device found at address 0x44<br />
I2C device found at address 0x70<br />
I2C device found at address 0x76</strong></p>
<p dir="auto">I tried using Wire.end() to end all I2C communication, but the addresses still remains open.  How to close them?</p>
<pre><code>void scanI2CBus()
{
    byte error, address;

    Serial.println("Scanning...");

    for (address = 1; address &lt; 127; address++)
    {
        // The I2C address 0x00 is reserved and the addresses should be between 0x01 and 0x7F
        Wire.beginTransmission(address);
        error = Wire.endTransmission();

        if (error == 0)
        {
            Serial.print("I2C device found at address 0x");
            if (address &lt; 16)
            {
                Serial.print("0");
            }
            Serial.print(address, HEX);
        }
    }
}
</code></pre>
]]></description><link>https://community.m5stack.com/post/26025</link><guid isPermaLink="true">https://community.m5stack.com/post/26025</guid><dc:creator><![CDATA[Surya]]></dc:creator><pubDate>Wed, 07 Aug 2024 13:03:00 GMT</pubDate></item><item><title><![CDATA[Reply to Pa.HUB: use any port for connection. on Tue, 02 Jul 2024 12:20:17 GMT]]></title><description><![CDATA[<p dir="auto">Unplugging and replugging the power supply also fixes the issue. Do you guys know how to programmatically restart the AtomS3, I2C bus, or sensor?</p>
]]></description><link>https://community.m5stack.com/post/25725</link><guid isPermaLink="true">https://community.m5stack.com/post/25725</guid><dc:creator><![CDATA[Surya]]></dc:creator><pubDate>Tue, 02 Jul 2024 12:20:17 GMT</pubDate></item><item><title><![CDATA[Reply to Pa.HUB: use any port for connection. on Mon, 01 Jul 2024 07:24:49 GMT]]></title><description><![CDATA[<p dir="auto"><img src="/assets/uploads/files/1719818684333-45c6aa4d-0e53-4863-b57b-a00ce26aa9cc-image.png" alt="45c6aa4d-0e53-4863-b57b-a00ce26aa9cc-image.png" class=" img-fluid img-markdown" /></p>
]]></description><link>https://community.m5stack.com/post/25718</link><guid isPermaLink="true">https://community.m5stack.com/post/25718</guid><dc:creator><![CDATA[Surya]]></dc:creator><pubDate>Mon, 01 Jul 2024 07:24:49 GMT</pubDate></item><item><title><![CDATA[Reply to Pa.HUB: use any port for connection. on Fri, 28 Jun 2024 10:11:57 GMT]]></title><description><![CDATA[<pre><code>void initializeSensors()
{
    for (int port = 0; port &lt; 6; port++)
    {
        Wire.beginTransmission(0x70);
        Wire.write(1 &lt;&lt; port);
        Wire.endTransmission();
        delay(10);

        Wire.beginTransmission(SHT40_I2C_ADDR_44);
        if (Wire.endTransmission() == 0)
        {
            float temp, hum;
            sht4x.begin(Wire, SHT40_I2C_ADDR_44);
            uint16_t error = sht4x.measureHighPrecision(temp, hum);
            if (error == 0)
            {
                sht4xPort = port;
                sht4x.begin(Wire, SHT40_I2C_ADDR_44);
                Serial.print("SHT4X found on port ");
                Serial.println(port);
                continue;
            }
        }
    }

    for (int port = 0; port &lt; 6; port++)
    {
        if (port == sht4xPort)
        {
            continue;
        }
        Wire.beginTransmission(0x70);
        Wire.write(1 &lt;&lt; port);
        Wire.endTransmission();
        delay(10);

        Wire.beginTransmission(SHT3X_I2C_ADDR);
        if (Wire.endTransmission() == 0)
        {
            // Try to read a unique characteristic of SHT3X
            if (sht3x.begin(&amp;Wire, SHT3X_I2C_ADDR, 2, 1, 400000U))
            {
                sht3xPort = port;
                Serial.print("SHT3X found on port ");
                Serial.println(port);
                continue;
            }
        }
    }
}

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);
    delay(3000);

    initializeSensors();

    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 = 0;
    if (!client.connected())
    {
        M5.Lcd.clear();
        M5.Lcd.setCursor(0, 0);
        M5.Lcd.println("reconnecting...");
        reconnect();
    }
    else
    {
        uint16_t error;
        char errorMessage[256];

        Serial.println(sht3xPort);
        Serial.println(sht4xPort);
        if (sht3xPort != -1)
        {
            Wire.beginTransmission(0x70);
            Wire.write(1 &lt;&lt; sht3xPort);
            Wire.endTransmission();
            delay(10);
            if (sht3x.update())
            {
                liquid_temperature = sht3x.fTemp;
                Serial.print("Temperature(L): ");
                Serial.print(liquid_temperature);
                Serial.print("\t");
            }
        }

        if (sht4xPort != -1)
        {
            Wire.beginTransmission(0x70);
            Wire.write(1 &lt;&lt; sht4xPort);
            Wire.endTransmission();
            delay(10);
            uint16_t error = sht4x.measureHighPrecision(temperature, humidity);

            if (error)
            {
                char errorMessage[256];
                errorToString(error, errorMessage, 256);
                Serial.print("Error: ");
                Serial.println(errorMessage);
            }
            else
            {
                Serial.print("Temperature(A): ");
                Serial.print(temperature);
                Serial.print("\tHumidity: ");
                Serial.println(humidity);
            }

            // Convert Celsius to Fahrenheit
            if (temperature != 0)
            {
                temperature = (temperature * 9 / 5) + 32;
            }
        }

        M5.Lcd.clear();
        // Swap the colour byte order when rendering
        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);
}
</code></pre>
<p dir="auto">This script collects sensor data wherever I connect it to the hub. However, I'm facing an issue: when I first connect it to the power supply, it works fine, but if I press the reset button on the AtomS3, I get this error: "<strong>[Wire.cpp:513] requestFrom(): i2cRead returned Error 263.</strong>"</p>
<p dir="auto">I found that this error is caused by the SHT3X sensor. When this happens, unplugging and re-plugging the sensor and then pressing the reset button makes it work again. I suspect that pressing the reset button breaks the loop without properly resetting the SHT3X sensor.</p>
<p dir="auto">I'm looking for a way to reset the SHT3X sensor before reinitializing it but haven't found a solution. Please help me with this.</p>
]]></description><link>https://community.m5stack.com/post/25699</link><guid isPermaLink="true">https://community.m5stack.com/post/25699</guid><dc:creator><![CDATA[Surya]]></dc:creator><pubDate>Fri, 28 Jun 2024 10:11:57 GMT</pubDate></item><item><title><![CDATA[Reply to Pa.HUB: use any port for connection. on Fri, 21 Jun 2024 14:18:57 GMT]]></title><description><![CDATA[<p dir="auto">Hello <a class="plugin-mentions-user plugin-mentions-a" href="/user/felmue" aria-label="Profile: felmue">@<bdi>felmue</bdi></a><br />
I'll investigate and give it a try. Thank you!</p>
]]></description><link>https://community.m5stack.com/post/25638</link><guid isPermaLink="true">https://community.m5stack.com/post/25638</guid><dc:creator><![CDATA[Surya]]></dc:creator><pubDate>Fri, 21 Jun 2024 14:18:57 GMT</pubDate></item><item><title><![CDATA[Reply to Pa.HUB: use any port for connection. on Fri, 21 Jun 2024 13:14:49 GMT]]></title><description><![CDATA[<p dir="auto">Hello <a class="plugin-mentions-user plugin-mentions-a" href="/user/surya" aria-label="Profile: Surya">@<bdi>Surya</bdi></a></p>
<p dir="auto">I think you might be selecting the channels/ports incorrectly. If you have a look at the <a href="https://m5stack.oss-cn-shenzhen.aliyuncs.com/resource/docs/datasheet/unit/TCA9548A_en.pdf" target="_blank" rel="noopener noreferrer nofollow ugc">datasheet</a> - section <em>8.5.4 Control Register</em> - you see that each channel/port is one bit of the control register byte.</p>
<p dir="auto">E.g. your for loop going from 1 to 5 actually selects channel/port 1, 2, 1+2, 3, 1+3, 2+3. Not exactly what you want.</p>
<p dir="auto">BTW: you can also see how the channels/ports are selected in the Adafruit library <a href="https://github.com/closedcube/ClosedCube_TCA9548A_Arduino/blob/master/src/ClosedCube_TCA9548A.cpp#L79" target="_blank" rel="noopener noreferrer nofollow ugc">here</a>.</p>
<p dir="auto">Thanks<br />
Felix</p>
]]></description><link>https://community.m5stack.com/post/25637</link><guid isPermaLink="true">https://community.m5stack.com/post/25637</guid><dc:creator><![CDATA[felmue]]></dc:creator><pubDate>Fri, 21 Jun 2024 13:14:49 GMT</pubDate></item><item><title><![CDATA[Reply to Pa.HUB: use any port for connection. on Fri, 21 Jun 2024 10:52:35 GMT]]></title><description><![CDATA[<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="/user/ajb2k3" aria-label="Profile: ajb2k3">@<bdi>ajb2k3</bdi></a> Thanks for your prompt response.<br />
If so, is there any way to detect which sensor is connected to which port? (Basically, I don't want a sensor to be statically assigned to a specific port)<br />
This way, I can detect the sensor port and get the temperature data using an appropriate command.</p>
]]></description><link>https://community.m5stack.com/post/25636</link><guid isPermaLink="true">https://community.m5stack.com/post/25636</guid><dc:creator><![CDATA[Surya]]></dc:creator><pubDate>Fri, 21 Jun 2024 10:52:35 GMT</pubDate></item><item><title><![CDATA[Reply to Pa.HUB: use any port for connection. on Fri, 21 Jun 2024 10:34:28 GMT]]></title><description><![CDATA[<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="/user/surya" aria-label="Profile: Surya">@<bdi>Surya</bdi></a> they have to be connected to the lowest free number port for some reason</p>
]]></description><link>https://community.m5stack.com/post/25635</link><guid isPermaLink="true">https://community.m5stack.com/post/25635</guid><dc:creator><![CDATA[ajb2k3]]></dc:creator><pubDate>Fri, 21 Jun 2024 10:34:28 GMT</pubDate></item></channel></rss>