Heltec ESP mit OLED DS18B20 und MQTT

Hallo Zusammen,

da ich neu im Thema bin bräuchte ich etwas Hilfe.
Es geht darum mit einem Heltec Wifi Kit 8( ESP8266 mit OLED 128x32) die Temperatur von meinem Kühlschrank anzuzeigen und per MQTT zu meinem IObroker zu schicken.

Ich habe das Beispielprogramm vom Lieferanten genommen und mit MQTT erweitert.

Um das Programm zu verschlanken wollte ich den ESPNow Teil entfernen da MQTT genutzt werden soll, aber sobald ich den auskommentiere bekomme ich Fehlermeldungen beim kompilieren.
Es wird "does not name a type" von allen möglichen Variablen gemeldet.

Was genau ist das extern "C" was es verursacht?

Ich hoffe ich habe es nicht zu kompliziert erklärt.

Danke im voraus

Gruß Frank

/* Esp8266 mit OLED Display als Thermometer mit MQTT
*/

//Bibliotheken für WiFi
#include <ESP8266WiFi.h>
//Bibliothek für OLED Display
#include <U8g2lib.h>
//Bibliotheken für DS18B20 Temperatur Sensor
#include <OneWire.h>
#include <DallasTemperature.h>
//Bibliothek für MQTT
#include <PubSubClient.h>
//Bibliothek für ESP-Now
extern "C" {
#include <espnow.h>
}

//Pins für Temperatursensor
const byte bus = 0;//pin GPIO0

//Protokoll zum Auslesen des Sensors
OneWire oneWire(bus);

//Sensor Instanz
DallasTemperature sensoren(&oneWire);

// Daten für WLAN
const char* ssid = "xxxxxx";
const char* password = "xxxxxxx";
const char* mqtt_server = "xxxxxxx";

WiFiClient espClient;
PubSubClient client(espClient);
long lastMsg = 0;
float temp = 0;
int inPin = 5;


//Array um Sensoradressen zu speichern
DeviceAddress adressen;

//Display initialisieren
U8G2_SSD1306_128X32_UNIVISION_F_SW_I2C u8g2(U8G2_R0, /* clock=*/ 5, /* data=*/ 4, /* reset=*/ 16);

//Offset zur Kalibrierung der Temperatur
const uint8_t offset = 0;

//Werte der Temperatursensoren -127 = der Wert,
//den man erhält wenn kein Sensor angeschlossen ist
float aussen = -127;
float innen = -127;

// Nach einem Reset ist die SSID sichtbar damit ein entfernter Sensor sich
// verbinden kann. Nach ca. 2 Minuten sollte die SSID versteckt werden
// Zähler zum Abschalten der sichtbaren SSID
int cnt = 1;

//Logos als Bitmap für Display
#define haus_width 16
#define haus_height 16
static unsigned char haus_bits[] = {
  0x80, 0x0c, 0xc0, 0x0d, 0x60, 0x0f, 0x30, 0x0e, 0x18, 0x0c, 0xcc, 0x19,
  0x46, 0x31, 0x47, 0x71, 0xc5, 0x51, 0x04, 0x10, 0xf4, 0x16, 0x94, 0x16,
  0x94, 0x16, 0x94, 0x10, 0x94, 0x10, 0xff, 0xff
};

#define baum_width 16
#define baum_height 16
static unsigned char baum_bits[] = {
  0x00, 0x00, 0x00, 0x00, 0xe0, 0x01, 0x10, 0x05, 0x08, 0x0a, 0x34, 0x13,
  0x04, 0x10, 0x02, 0x10, 0x02, 0x08, 0x04, 0x16, 0x18, 0x10, 0xd0, 0x17,
  0xa0, 0x09, 0x80, 0x01, 0x80, 0x01, 0xff, 0xff
};


//Datenstruktur für den Datenaustausch über ESP Now
struct DATEN_STRUKTUR {
  float temp = 0;
};

//Netzwerk Name
char* SSID = "T";

//Callback funktion wenn Daten empfangen wurden
void on_receive_data(uint8_t *mac, uint8_t *r_data, uint8_t len) {

  DATEN_STRUKTUR data;
  //wir kopieren die empfangenen Daten auf die Datenstruktur
  //um über die Datenstruktur zugreifen zu können
  memcpy(&data, r_data, sizeof(data));
  aussen = data.temp;
};

// function um eine Sensoradressen zu drucken
void printAddress(DeviceAddress adressen)
{
  for (uint8_t i = 0; i < 8; i++)
  {
    if (adressen[i] < 16) Serial.print("0");
    Serial.print(adressen[i], HEX);
  }
}


void setup_wifi() {
  delay(10);
  // Zum Wlan verbinden
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) 
  {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}

void reconnect() {
  // Loop wenn nicht verbunden
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Attempt to connect
    if (client.connect("arduinoClient_temperature_sensor")) {
      Serial.println("connected");
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}

void setup() {
  Serial.begin(115200);
   u8g2.begin();
      //ESOP-Now initialisieren
    if (esp_now_init() != 0) {
    ESP.restart();
    delay(1); 

setup_wifi(); 
  client.setServer(mqtt_server, 1883);
  pinMode(inPin, INPUT);
  sensoren.begin();
       
  }

  //Display vorbereiten
  u8g2.begin();
  u8g2.enableUTF8Print();
  u8g2.setFontMode(0);

  //Temperatursensor initialisieren
  sensoren.begin();
  Serial.print(sensoren.getDeviceCount(), DEC);
  Serial.println(" Sensoren gefunden.");
  //Nun prüfen wir ob der Bus im parasitären Modus ist
  Serial.print("Parasitärer Modus ist ");
  if (sensoren.isParasitePowerMode()) {
    Serial.println("EIN");
  } else {
    Serial.println("AUS");
  }
  //Nun prüfen wir ob einer der Sensoren am Bus ein Temperatur Sensor ist
  if (!sensoren.getAddress(adressen, 0)) {
    Serial.println("Kein Temperatursensor vorhanden!");
  }
  //adressen anzeigen
  Serial.print("Adresse: ");
  printAddress(adressen);
  Serial.println();
  sensoren.setResolution(adressen, 12);
  Serial.print("Auflösung = ");
  Serial.print(sensoren.getResolution(adressen), DEC);
  Serial.println();
  //Pullup Widerstand für Temperatursensor
  pinMode(0, INPUT_PULLUP);
}

void loop() {
  char text[50] = {0}; //Textbuffer für Display
  int tmp; //Temporär für Temperaturen
  sensoren.requestTemperatures(); // Sensor Messung starten
  delay(800);//Zeit um die Temperatur zu messen
  innen = sensoren.getTempC(adressen); //Temperatur vom Sensor lesen
  //Wir wandeln die Temperatur nach integer mit einer Dezimalstelle
  tmp = round(innen * 10);
  //Ausgabetext generieren
  sprintf(text, "%2d.%01dC°", tmp / 10 - offset, abs(tmp % 10));
  //und an Display senden
  u8g2.firstPage(); do {
    //zuerst das Logo
    u8g2.drawXBM( 0, 8, haus_width, haus_height, haus_bits);
    //dann den Text
    u8g2.setFont(u8g2_font_osb26_tf);
    u8g2.setFontDirection(0);
    u8g2.drawUTF8(20, 30, text);
  } while ( u8g2.nextPage() );
  delay(5000); //5 Sekunden warten
  //Zähler vermindern
  if (cnt > 0) cnt--;
  //Haben wir einen Wert von einem entfernten Sensor
  //Dann zeigen wir den an
  if (aussen != -127) {
    //Wir wandeln die Temperatur nach integer mit einer Dezimalstelle
    tmp = round(aussen * 10);
    //Ausgabetext generieren
    sprintf(text, "%2d.%01dC°", tmp / 10, abs(tmp % 10));
    //und an Display senden
    u8g2.firstPage(); do {
      //zuerst das Logo
      u8g2.drawXBM( 0, 8, baum_width, baum_height, baum_bits);
      //dann den Text
      u8g2.setFont(u8g2_font_osb26_tf);
      u8g2.setFontDirection(0);
      u8g2.drawUTF8(20, 30, text);
    } while ( u8g2.nextPage() );
    delay(5000); //5 Sekunden warten
   

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

  long now = millis();
  if (now - lastMsg > 60000) {
    lastMsg = now;
    sensoren.setResolution(12);
    sensoren.requestTemperatures(); // Befehl um Temperatur zu bekommen
    temp = sensoren.getTempCByIndex(0);
    Serial.println(temp);
    if((temp > -20) && (temp <60))
      {
      client.publish("ha/_temperature1", String(temp).c_str(),true);
      }
  }
  }
  
}

frankydee1980:
Ich habe das Beispielprogramm vom Lieferanten genommen und mit MQTT erweitert.
...
Was genau ist das extern "C" was es verursacht?

In keinem der von mir angesehenen Beispiele kam das vor, welches hast Du verwendet?

Zumindest Combie kennt es: https://forum.arduino.cc/index.php?topic=558478.0
Vlt kann er da weiterhelfen.

frankydee1980:
Was genau ist das extern "C" was es verursacht?

Damit wird das name-mangling abgeschaltet.

Was heißt das jetzt? Naja in C++ kannst du 2 Funktionen mit dem selben Namen, aber unterschiedlichen Parametern haben. Beim späteren zusammensetzen aller Einzelteile (linken) braucht man aber eindeutige Namen. Daher werden die Namen intern mit der Anzahl/Datentypen dekoriert.

C-Code hat kein Name-mangling. Daher mußt du beim Einbinden einer C-Lib dem Compiler sagen, das für diese Lib kein Name-mangling verwendet werden darf.

agmue:
In keinem der von mir angesehenen Beispiele kam das vor, welches hast Du verwendet?

Hab den Code von hier: