user86404: I'm trying to read data being transferred via Infrared from my Smartmeter on my ESP8266 using the following sketch:
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <ESP8266HTTPUpdateServer.h>
#include <Ticker.h>
#include <AsyncMqttClient.h>

#ifndef STASSID
#define STASSID "mySSID"
#define STAPSK  "myPassword"
#endif

#ifndef MQTT_HOST
#define MQTT_HOST IPAddress(192, 168, 0, 100)
#define MQTT_PORT 1883
#endif

#ifndef IR
#define SerialDebug Serial1
#define IR Serial
#endif

AsyncMqttClient mqttClient;
Ticker mqttReconnectTimer;

WiFiEventHandler wifiConnectHandler;
WiFiEventHandler wifiDisconnectHandler;
Ticker wifiReconnectTimer;

const char* host = "esp8266-webupdate";

const byte firstByte = 0x7E;
const byte lastByte = 0x7E;

uint8_t i;

ESP8266WebServer httpServer(80);
ESP8266HTTPUpdateServer httpUpdater;

void connectToWifi() {
  SerialDebug.println("Connecting to WiFi ...");
  WiFi.begin(STASSID, STAPSK);
}

void connectToMqtt() {
  SerialDebug.println("Connecting to MQTT ...");
  mqttClient.connect();
}

void onWifiConnect(const WiFiEventStationModeGotIP& event) {
  SerialDebug.println("Connected to Wi-Fi.");
  connectToMqtt();
}

void onWifiDisconnect(const WiFiEventStationModeDisconnected& event) {
  SerialDebug.println("Disconnected from Wi-Fi.");
  mqttReconnectTimer.detach();
  wifiReconnectTimer.once(2, connectToWifi);
}

void onMqttConnect(bool sessionPresent) {
  SerialDebug.println("Connected to MQTT.");
  SerialDebug.print("Session present: ");
  SerialDebug.println(sessionPresent);
}

void onMqttDisconnect(AsyncMqttClientDisconnectReason reason) {
  SerialDebug.println("Disconnected from MQTT.");

  if (WiFi.isConnected()) {
    mqttReconnectTimer.once(2, connectToMqtt);
  }
}

void array_to_string(byte array[], unsigned int len, char buffer[]) {
  for (unsigned int i = 0; i < len; i++) {
    byte nib1 = (array[i] >> 4) & 0x0F;
    byte nib2 = (array[i] >> 0) & 0x0F;
    buffer[i*2+0] = nib1  < 0xA ? '0' + nib1  : 'A' + nib1  - 0xA;
    buffer[i*2+1] = nib2  < 0xA ? '0' + nib2  : 'A' + nib2  - 0xA;
  }
  buffer[len*2] = '\0';
}

void setup() {

  SerialDebug.begin(115200);
  IR.begin(9600);
  SerialDebug.println();
  SerialDebug.println("Booting Sketch...");
  
  wifiConnectHandler = WiFi.onStationModeGotIP(onWifiConnect);
  wifiDisconnectHandler = WiFi.onStationModeDisconnected(onWifiDisconnect);

  mqttClient.onConnect(onMqttConnect);
  mqttClient.onDisconnect(onMqttDisconnect);
  mqttClient.setServer(MQTT_HOST, MQTT_PORT);

  connectToWifi();

  httpUpdater.setup(&httpServer);
  httpServer.begin();

  mqttClient.setWill("smartmeter/online", 0, true, "no");
}

void loop() {
  httpServer.handleClient();
  
  uint32_t timeout = 2000;
  
  int readCnt = 0;
  uint32_t start_time = millis();
  byte tempChar = 0;
  byte *readMessage;
  uint32_t messageLen = 0;
  
  while ((tempChar != 0x7E) && (millis() - start_time < timeout)) {
    if (IR.available()) {
      tempChar = IR.read();
    }
  }
  
  start_time = millis();
  timeout = 1000;
  bool done = false;
  
  if (tempChar == firstByte) { // if first byte == 0x7E
    while ((millis() - start_time) < timeout && !done) {
      if (IR.available()) {
        tempChar = IR.read(); // second byte must be 0xA0
        if(tempChar == 0xA0) {
          while ((millis() - start_time) < timeout && !done) {
            if (IR.available()) {
              tempChar = IR.read(); // 3rd byte tells the legth of the message
    
              readMessage = new byte[tempChar+2];
              memset(readMessage, 0, tempChar+2);
              readMessage[0] = firstByte;
              readMessage[1] = 0xA0;
              readMessage[2] = tempChar;
              messageLen = ((uint32_t)(tempChar))+2;
              readCnt = 3;
      
              while ( readCnt < messageLen && ((millis() - start_time) < timeout)) { // minimum len 120 chars for 0x7E format
                if (IR.available()) {
                  readMessage[readCnt] = IR.read(); 
                  readCnt++; 
        
                  if(readCnt == tempChar+2 && readMessage[readCnt-1] != lastByte) { // correct len but last byte not 0x7E
                    done = true;
                    SerialDebug.printf("Wrong end byte found - %d\n", readMessage[readCnt-1]);
                  } else if(readCnt == tempChar+2) { // correct len and correct last byte
                    done = true;
                    char str[251] = "";
                    array_to_string(readMessage, readCnt, str);
                    mqttClient.publish("smartmeter/raw", 0, false, str);
                  }
                }
              }
            }
          }
        }
      }
    }
  }
  mqttClient.publish("smartmeter/online", 0, true, "yes");
  char heap[6] = "";
  itoa(ESP.getFreeHeap(), heap, 10);
  mqttClient.publish("smartmeter/freeHeap", 0, false, heap);
}

I'm getting the encoded HEX-data published on my MQTT Topic as desired, the outputs length is 250 characters long (= 125 Bytes) which is correct:

7ea07bcf000200231362b1e6e700db08534d536770075f626120000e32e62addedaede38e64c8c3173035a0a853851a28efc57f7fd76a9df59dbb152f796939328ff0f28df7f257d20b5cb2a458c4eb9188e2c1c251701c891244d859ed9c159714bb4451c090d9b1ed3bbb1fc89785ebafbf59ec4f9d540eb4c90d47e

As I found out, the ESP's heap is decreasing by 100-300 by each iteration of the loop (data is being transmitted every second via Infrared from the power-grid Smartmeter) until the ESP will eventually be rebooted by the watchdog after like 5-8 minutes.
I explicitly did not use String variables in the sketch but I legit cannot find the reason for the memory leak. Tried turning off wifi, webserver and mqtt one after each other which didn't actually made a difference.
The heap-size stays at a constant level though when there is no data being received via the Infrared serial port, so I imagine something is fishy when storing the data in the byte array "readMessage".
Anything obvious that immediately pops into someones eye that I missed?

user31105: You do a new inside the loop
 readMessage = new byte[tempChar+2];

which causes the heap to be filled with tempChar+2 bytes, but you never delete this.
Try reusing this memory (making it a local, or make it 'dirty' global).
Probably (not tested) the above line can be rewritten as:
byte readMessage[tempChar+2];


86404: <p>I'm trying to read data being transferred via Infrared from my Smartmeter on my ESP8266 using the following sketch:</p>
<pre><code>#include &lt;ESP8266WiFi.h&gt;
#include &lt;ESP8266WebServer.h&gt;
#include &lt;ESP8266HTTPUpdateServer.h&gt;
#include &lt;Ticker.h&gt;
#include &lt;AsyncMqttClient.h&gt;

#ifndef STASSID
#define STASSID &quot;mySSID&quot;
#define STAPSK  &quot;myPassword&quot;
#endif

#ifndef MQTT_HOST
#define MQTT_HOST IPAddress(192, 168, 0, 100)
#define MQTT_PORT 1883
#endif

#ifndef IR
#define SerialDebug Serial1
#define IR Serial
#endif

AsyncMqttClient mqttClient;
Ticker mqttReconnectTimer;

WiFiEventHandler wifiConnectHandler;
WiFiEventHandler wifiDisconnectHandler;
Ticker wifiReconnectTimer;

const char* host = &quot;esp8266-webupdate&quot;;

const byte firstByte = 0x7E;
const byte lastByte = 0x7E;

uint8_t i;

ESP8266WebServer httpServer(80);
ESP8266HTTPUpdateServer httpUpdater;

void connectToWifi() {
  SerialDebug.println(&quot;Connecting to WiFi ...&quot;);
  WiFi.begin(STASSID, STAPSK);
}

void connectToMqtt() {
  SerialDebug.println(&quot;Connecting to MQTT ...&quot;);
  mqttClient.connect();
}

void onWifiConnect(const WiFiEventStationModeGotIP&amp; event) {
  SerialDebug.println(&quot;Connected to Wi-Fi.&quot;);
  connectToMqtt();
}

void onWifiDisconnect(const WiFiEventStationModeDisconnected&amp; event) {
  SerialDebug.println(&quot;Disconnected from Wi-Fi.&quot;);
  mqttReconnectTimer.detach();
  wifiReconnectTimer.once(2, connectToWifi);
}

void onMqttConnect(bool sessionPresent) {
  SerialDebug.println(&quot;Connected to MQTT.&quot;);
  SerialDebug.print(&quot;Session present: &quot;);
  SerialDebug.println(sessionPresent);
}

void onMqttDisconnect(AsyncMqttClientDisconnectReason reason) {
  SerialDebug.println(&quot;Disconnected from MQTT.&quot;);

  if (WiFi.isConnected()) {
    mqttReconnectTimer.once(2, connectToMqtt);
  }
}

void array_to_string(byte array[], unsigned int len, char buffer[]) {
  for (unsigned int i = 0; i &lt; len; i++) {
    byte nib1 = (array[i] &gt;&gt; 4) &amp; 0x0F;
    byte nib2 = (array[i] &gt;&gt; 0) &amp; 0x0F;
    buffer[i*2+0] = nib1  &lt; 0xA ? '0' + nib1  : 'A' + nib1  - 0xA;
    buffer[i*2+1] = nib2  &lt; 0xA ? '0' + nib2  : 'A' + nib2  - 0xA;
  }
  buffer[len*2] = '\0';
}

void setup() {

  SerialDebug.begin(115200);
  IR.begin(9600);
  SerialDebug.println();
  SerialDebug.println(&quot;Booting Sketch...&quot;);
  
  wifiConnectHandler = WiFi.onStationModeGotIP(onWifiConnect);
  wifiDisconnectHandler = WiFi.onStationModeDisconnected(onWifiDisconnect);

  mqttClient.onConnect(onMqttConnect);
  mqttClient.onDisconnect(onMqttDisconnect);
  mqttClient.setServer(MQTT_HOST, MQTT_PORT);

  connectToWifi();

  httpUpdater.setup(&amp;httpServer);
  httpServer.begin();

  mqttClient.setWill(&quot;smartmeter/online&quot;, 0, true, &quot;no&quot;);
}

void loop() {
  httpServer.handleClient();
  
  uint32_t timeout = 2000;
  
  int readCnt = 0;
  uint32_t start_time = millis();
  byte tempChar = 0;
  byte *readMessage;
  uint32_t messageLen = 0;
  
  while ((tempChar != 0x7E) &amp;&amp; (millis() - start_time &lt; timeout)) {
    if (IR.available()) {
      tempChar = IR.read();
    }
  }
  
  start_time = millis();
  timeout = 1000;
  bool done = false;
  
  if (tempChar == firstByte) { // if first byte == 0x7E
    while ((millis() - start_time) &lt; timeout &amp;&amp; !done) {
      if (IR.available()) {
        tempChar = IR.read(); // second byte must be 0xA0
        if(tempChar == 0xA0) {
          while ((millis() - start_time) &lt; timeout &amp;&amp; !done) {
            if (IR.available()) {
              tempChar = IR.read(); // 3rd byte tells the legth of the message
    
              readMessage = new byte[tempChar+2];
              memset(readMessage, 0, tempChar+2);
              readMessage[0] = firstByte;
              readMessage[1] = 0xA0;
              readMessage[2] = tempChar;
              messageLen = ((uint32_t)(tempChar))+2;
              readCnt = 3;
      
              while ( readCnt &lt; messageLen &amp;&amp; ((millis() - start_time) &lt; timeout)) { // minimum len 120 chars for 0x7E format
                if (IR.available()) {
                  readMessage[readCnt] = IR.read(); 
                  readCnt++; 
        
                  if(readCnt == tempChar+2 &amp;&amp; readMessage[readCnt-1] != lastByte) { // correct len but last byte not 0x7E
                    done = true;
                    SerialDebug.printf(&quot;Wrong end byte found - %d\n&quot;, readMessage[readCnt-1]);
                  } else if(readCnt == tempChar+2) { // correct len and correct last byte
                    done = true;
                    char str[251] = &quot;&quot;;
                    array_to_string(readMessage, readCnt, str);
                    mqttClient.publish(&quot;smartmeter/raw&quot;, 0, false, str);
                  }
                }
              }
            }
          }
        }
      }
    }
  }
  mqttClient.publish(&quot;smartmeter/online&quot;, 0, true, &quot;yes&quot;);
  char heap[6] = &quot;&quot;;
  itoa(ESP.getFreeHeap(), heap, 10);
  mqttClient.publish(&quot;smartmeter/freeHeap&quot;, 0, false, heap);
}
</code></pre>
<p>I'm getting the encoded HEX-data published on my MQTT Topic as desired, the outputs length is 250 characters long (= 125 Bytes) which is correct:</p>
<blockquote>
<p>7ea07bcf000200231362b1e6e700db08534d536770075f626120000e32e62addedaede38e64c8c3173035a0a853851a28efc57f7fd76a9df59dbb152f796939328ff0f28df7f257d20b5cb2a458c4eb9188e2c1c251701c891244d859ed9c159714bb4451c090d9b1ed3bbb1fc89785ebafbf59ec4f9d540eb4c90d47e</p>
</blockquote>
<p>As I found out, the ESP's heap is decreasing by 100-300 by each iteration of the loop (data is being transmitted every second via Infrared from the power-grid Smartmeter) until the ESP will eventually be rebooted by the watchdog after like 5-8 minutes.</p>
<p>I explicitly did not use String variables in the sketch but I legit cannot find the reason for the memory leak. Tried turning off wifi, webserver and mqtt one after each other which didn't actually made a difference.</p>
<p>The heap-size stays at a constant level though when there is no data being received via the Infrared serial port, so I imagine something is fishy when storing the data in the byte array &quot;readMessage&quot;.</p>
<p>Anything obvious that immediately pops into someones eye that I missed?</p>
 31105: <p>You do a <code>new</code> inside the loop</p>
<pre><code> readMessage = new byte[tempChar+2];
</code></pre>
<p>which causes the heap to be filled with <code>tempChar+2</code> bytes, but you never delete this.</p>
<p>Try reusing this memory (making it a local, or make it 'dirty' global).</p>
<p>Probably (not tested) the above line can be rewritten as:</p>
<pre><code>byte readMessage[tempChar+2];
</code></pre>
