esp8266 / esp8266/Arduino

Memory leak when using Adafruit_NeoPixel library and UDP

Open
#4,006 5 comments 0 reactions 0 assignees View on GitHub
Dominant language
C++
Stars
16.7k
Forks
13.1k
PR merge metrics
No merged PRs in 30d

Description

### Basic Infos
Receiving large amount of UDP datagrams while using Adafruit_NeoPixel library causes the ESP to start leaking memory until it runs out and reboots.

#### Hardware
Hardware: NodeMCU
Core Version: 2.3 and latest (12/20/17) git
OS: Linux (Debian Stretch)
Arduino: 1.8.4

### Description
I have a large application that involves updating Neopixel lights from data received in UDP datagrams. I had noticed that the ESP will often get into a memory leak "loop" in which the device will slowly start running out of memory before dying. I made the following observations:

- The problem occurs when using the stock WiFiUDP library and the ESPAsyncUDP library

- Usually, the ESP will disconnect from the WiFi AP once the memory leak starts. Other times, it will stay connected until running out of RAM

- Once the memory leak begins, it cannot be stopped. I've tried stopping NeoPixel updates and even deleting the entire Adafruit_NeoPixel strip instance once the leak starts, but the leak always continues

I understand that the Adafruit_NeoPixel library is not recommended for use with the ESP (because it stops interrupts while outputting LED data), but the fact that anything can cause the ESP (which is otherwise running properly) to start continuously leaking data seems like evidence of a larger issue.

### Settings in IDE

Module: NodeMCU 1.0
Flash Size: 4M (1M SPIFFS)
CPU Frequency: 80Mhz
Flash Mode: qio
Flash Frequency: 40Mhz
Upload Using: SERIAL
Reset Method: nodemcu
Debug Level: CORE+WIFI+HTTP_UPDATE+UPDATER+OTA
lwIP Variant: v2 Prebuilt

### Sketch

```cpp

#include

#include
#include

#include

const uint16_t PORT = 5492;

const char* SSID = "SSID";
const char* PSK = "PSK";

AsyncUDP socket;

int lightCount = 300;

Adafruit_NeoPixel strip(lightCount, 2, NEO_RGB | NEO_KHZ800);

void setup() {
Serial.begin(115200);

Serial.print("\nConnecting to AP");
WiFi.begin(SSID, PSK);
while(WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print('.');
}
Serial.println("done");

strip.begin();

if(socket.listen(PORT)) {
socket.onPacket([](AsyncUDPPacket p) {
Serial.print(".");
strip.show();
});
}
else {
Serial.println("[Error] Failed to listen on socket");
}

}

unsigned long nextTime = 0;
void loop() {
auto curTime = millis();
if(curTime >= nextTime) {
nextTime = curTime + 1000;

Serial.println(ESP.getFreeHeap());
}
}

```
### Python Script

This script can be used to start the memory leak:
```python

import socket;
import time;

ESP_IP = "192.168.1.181"
PORT = 5492

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
bigData = bytearray(905);
bigData[1] = 9;

while True:
sock.sendto(bigData, (ESP_IP, PORT))
time.sleep(0.01)

```
### Debug Messages

[MemoryLeak.log](https://github.com/esp8266/Arduino/files/1577894/MemoryLeak.log)

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.