Arduino Nano ESP32 - Verbindungsprobleme nur über Stromadapter

Guten Morgen

ich habe hier ein kleines Problem.

Hardware

  • Arduino Nano ESP32
  • I2C CHT8305C Temperatur und Feuchtigkeitssensor

Ich verwende für die Entwicklung PlatformIO mit logischerweise C++.

Problematik:
Ich habe für das Terrarium mit einem Uno R4 Wifi eine steuerung erstellt, dass den gleichen Sensor nutzt (sensor kann über 3.3 und 5V betribene werden) und noch ein paar andere Sensoren. Das funktioniert wunderbar.

Für den Nano ESP32 verwende ich jetzt nur noch den einen Sensor, alles andere ist weg. Jedoch ist die Logik gleich:

Nano macht eine Verbindung per WiFi, verbindet sich mit MQTT und sendet die Sensor daten an node-red. Funktioniert wunderbar, solange das Teil am Notebook angeschlossen ist und gleich ein Upload stattgefunden hat. Nehm ich diesen jetzt vom Strom, schliesse ihn entweder wieder an den Mac an oder per USB an die Steckdose, passiert nichts. Erst wenn ich die Arduino IDE öffne, wird eine Verbindung aufgebaut und die Daten werden dann wieder gesendet. Ich verstehe nicht warum das so ist? Beim Uno hatte ich dieses verhalten nicht.

Anbei mein Source Code und das entsprechende ini von PlatformIO.

Laut Beschreibung soll man die esptools für den Upload verwenden.

Ich bin noch Anfänger auf diesem Gebiet, komm jedoch von der dotnet Programmierung, das letzte mal C++ hab ich vor 20 Jahren Programmiert, also sorry, wenn der Code nicht so toll ist :wink:

Sketch:

#include <WiFi.h>
#include "Wire.h"
#include <PubSubClient.h>
#include <ArduinoJson.h>

unsigned long previousMillis = millis();

// WiFi connection
const char* ssid     = "SSID";
const char* password = "PWD";

// MQTT connection
String clientId = "livingRoom-";
const char *mqtt_server = "mqtt.domain.ch";
const char *mqtt_user = "admin";
const char *mqtt_password = "xxxxxxx";

WiFiClient espClient;
PubSubClient client(espClient);

// Sensor Temp & RH
#define sensorAddress 0x40

char dtaUart[15];
char dtaLen = 0;
uint8_t Data[100] = {0};
uint8_t buff[100] = {0};

uint8_t buf[4] = {0};
uint16_t data, data1;
float temperature;
float humidity;

void reconnect()
{
    while (!client.connected())
    {
        Serial.println("Attempting MQTT connection...");
        // Attempt to connect
        clientId += String(random(0xffff), HEX);
        if (client.connect(clientId.c_str(), mqtt_user, mqtt_password))
        {
            Serial.println("connected");
            // for this example not necessary
            // client.subscribe("topic");
            client.subscribe("testTopic");
        }
        else
        {
            Serial.print("failed, rc=");
            Serial.print(client.state());
            Serial.println(" try again in 5 seconds");
            // Wait 5 seconds before retrying
            delay(5000);
        }
    }
}

void connectAP()
{
    Serial.println("Connecting to WiFi..");
    WiFi.begin(ssid, password);

    int cnt = 0;
    while (WiFi.status() != WL_CONNECTED)
    {
        delay(1000);
        Serial.print(".");
        cnt++;

        if (cnt > 30) {
            //ESP.restart();
        }
    }
    Serial.println(WiFi.localIP());
}

// Callback for MQTT Input Topics
void callback(String topic, byte* message, unsigned int length) {
  String messageTemp;
  Serial.println(topic);
  for (int i = 0; i < length; i++) {
    messageTemp += (char)message[i];
  }
}

void setup() {
  Serial.begin(115200);
  while(!Serial);
  Serial.setDebugOutput(true);
  Serial.println();

  delay(1500);

  Wire.begin();

  connectAP();
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);
}

// Read Sensor for I2C
uint8_t readSensor(uint8_t reg, const void* pBuf, size_t size) {
    if (pBuf == NULL) {
        Serial.println("pBuf ERROR!! : null pointer");
    }
    uint8_t* _pBuf = (uint8_t*)pBuf;
    Wire.beginTransmission(sensorAddress);
    Wire.write(&reg, 1);
    if (Wire.endTransmission() != 0) {
        return 0;
    }
    delay(20);
    Wire.requestFrom(sensorAddress, (uint16_t)size);
    for (uint16_t i = 0; i < size; i++) {
        _pBuf[i] = Wire.read();
    }
    return size;
}

void sendMQTTMessage() {
  readSensor(0x00, buf, 4);
  data = buf[0] << 8 | buf[1];
  data1 = buf[2] << 8 | buf[3];
  temperature = ((float)data * 165 / 65535.0) - 40.0;
  humidity =  ((float)data1 / 65535.0) * 100;

  Serial.print("Temperatur: ");
  Serial.print(temperature);
  Serial.print(" | ");
  Serial.print("RH: ");
  Serial.println(humidity);

  DynamicJsonDocument doc(1024);
  doc["temperature"] = temperature;
  doc["humidity"] = humidity;

  char buffer[256];
  serializeJson(doc, buffer);
  bool result = client.publish("livingRoom", buffer);
}

void loop() {
  if (!client.connected()) {
      reconnect();
  }

  if (!client.loop()) {
      client.connect("livingRoom-MQTT");
  }

  unsigned long currentMillis = millis();

  if (currentMillis - previousMillis >= 5000)
  {
    previousMillis = currentMillis;
    sendMQTTMessage();
  }
}

PlatformIO Ini:

[env:arduino_nano_esp32]
platform = espressif32
board = arduino_nano_esp32
framework = arduino
board_build.mcu = esp32s3
board_build.f_cpu = 240000000L
upload_protocol = esptool
monitor_speed = 115200
lib_ldf_mode = deep+
lib_deps = 
	knolleary/PubSubClient@^2.8
	bblanchon/ArduinoJson@^7.0.4

Dann nimm das mal raus.

Ja, wie @HotSystems sagt: nimm das while(!Serial) raus. Zur Erklärung: dies sagt dem Controller, dass er solange in der whlie-Schleife bleiben soll, bis eine Serielle Verbindung hergestellt wurde - was natürlich, solange Dein Nano ESP32 nicht mit nem Laptop/PC verbunden ist. niemals passiert.

Danke für die ausführliche Beschreibung.

Gern geschehen. Erhoffe mir, dass es sich der TO so besser merken kann, wenn er genau weiss, was diese Anweisung bewirkt.

DANKE!

funktioniert. sage ja bin neu. hab wohl das mit dem serial bisschen falsch interpretiert und mich zu sehr auf Beispiele versteift.

was ne while schleife ist, weiss ich schon. in den sprachen die ich sonst entwickle nutzen wir die nie, da gibts bessere möglichkeiten.

gruss und viele dank für die schnelle und effiziente hilfe :slight_smile: