Stops receiving UDP packets / crashing / watchdog? [NodeMCU]
Posted: Sat Apr 01, 2017 11:09 am
This is my first project with the esp8266, i'm using it to control a WS2812B led strip of 300 leds (5 meters, 60 per meter). I'm using MaxMSP to send the list of RGB values over UDP. Everything runs fairly well most of the time. However i do experience a few issues:
I'll post my code here, and maybe someone can point out some glaring errors:
I'll also attach a picture of my hardware setup. I'm powering the ESP over USB, but the led strip has it's own dedicated power, but they are grounded together. I have a level shifter to bump the 3.3V signal to 5V for the strip. The capacitors are in there for when i'm powering both the strip and esp off the same external supply.
if any more information about my set up is required, please let me know. I've been running the leds with this code for 3.5 hours and no problem so far, so maybe i've solved them all, but i'm definitely looking for some people to review it.
Cheers.
- 1. Sometimes when i tell Max to stop sending values, the led strip will still be animating its lights until it also finally stops. This is strange to me, because with UDP, i figure it'd just forget old packets and just display the most recent one received, however this seems to indicate that it's storing the packets somewhere. It's not a big issue because it doesn't seem to happen often, just freak occurrences that confused me. Is there anyway to tell the ESP only to use the newest packets, or do i need a strip with a dedicated clock signal (APA102) to ensure that?
2. I have a thorough serial print going on that tells me: when packets are received, if wifi/udp are still connected, and the current runtime of the ESP. There were times in the past that the main loop would still be going, however packets wouldn't be received (unfortunately this was before i implemented the wifi/udp connection serial print, and i have yet to run into it again) so i figured there was an issue with the wifi connection being dropped. This doesn't seem very typical, but I guess a fix would be if it sees that it is no longer connected, for it to run through the wifi connection again.
3. Sometimes the hardware watchdog gets triggered(?) and causes the board to reset (which the serial monitor states as what happened). However the board never fully resets and boots up again. I read this could be due to the GPIO0 pin reading LOW, and it needs a HIGH signal to reset into Run mode. So i connected a 5.6k resistor between it and a 3.3V pin and in my code set: pinMode(0, INPUT_PULLUP); however, this doesn't seem to have any effect. Is there anyway to ensure that the esp restarts correctly when watchdog resets it? I sometimes ever get a software reset, but it doesn't restart properly.
4. When i don't send any messages to the ESP for a while (in this case i tested overnight), and then i send again, it does take a couple seconds to start responding (which isn't a big issue, i'm assuming the wifi goes to sleep when unused for a long time), but then sometimes when it finally starts to respond, the leds are visually choppy/stuttering and doesn't fix itseld. Not really sure why that's the case, but if i stop sending it messages for a few minutes, and then begin again, the leds become smooth again.
I'll post my code here, and maybe someone can point out some glaring errors:
Code: Select all
#include <ESP8266WiFi.h>
#include <WiFiUDP.h>
#define FASTLED_ESP8266_NODEMCU_PIN_ORDER
//#define FASTLED_ALLOW_INTERRUPTS 0
#include <FastLED.h>
#define PIN 6
#define LED_COUNT 300
#define UDP_TX_PACKET_MAX_SIZE 1500
CRGB leds[LED_COUNT];
// wifi connection variables
const char* ssid = "PLGRM Theta Waves";
const char* password = "plgrmdoesitbetter";
boolean wifiConnected = false;
// UDP variables
unsigned int localPort = 8888;
IPAddress ip(192, 168, 2, 177);
IPAddress gateway(192, 168, 2, 1);
IPAddress subnet(255, 255, 255, 0);
WiFiUDP UDP;
boolean udpConnected = false;
char packetBuffer[UDP_TX_PACKET_MAX_SIZE];
char* confirmArray[] = {"N", "Y"};
int packetRecv = 0;
int newCycle = 1;
//run time variables
int prevRunSec = 0;
int runSec = 0;
int runMin = 0;
int runHr = 0;
void setup() {
//when watchdog resets the board, GPIO0 needs to be Pulled Up according to here:
//https://github.com/esp8266/Arduino/blob/master/doc/boards.md#minimal-hardware-setup-for-running-only
//https://learn.sparkfun.com/tutorials/esp8266-thing-hookup-guide/using-the-arduino-addon
//also added a resistor between GPIO0 and 3.3V pin
pinMode(0, INPUT_PULLUP);
FastLED.addLeds<WS2812B, PIN, GRB>(leds, LED_COUNT);
Serial.begin(115200);
wifiConnected = connectWifi();
if (wifiConnected) {
udpConnected = connectUDP();
}
}
void loop() {
ESP.wdtEnable(WDTO_8S);
ESP.wdtFeed();
runSec = (millis() / 1000) % 60;
runMin = (millis() / 60000) % 60;
runHr = millis() / 3600000;
if (runSec != prevRunSec) {
packetRecv = 0;
newCycle++;
}
if (wifiConnected) {
if (udpConnected) {
int packetSize = UDP.parsePacket();
if (packetSize) {
UDP.read(packetBuffer, UDP_TX_PACKET_MAX_SIZE);
for (uint16_t j = 0; j < LED_COUNT; j++) {
leds[j].setRGB (packetBuffer[(j * 3)],
packetBuffer[(j * 3) + 1],
packetBuffer[(j * 3) + 2]);
}
packetRecv = 1;
if (newCycle == 1) {
serialReporter();
}
newCycle = 0; //reset cycle count
FastLED.show();
}
//if it's gone through more than one cycle and is a new second, report no packets
else {
if (runSec != prevRunSec && newCycle > 1) {
serialReporter();
}
}
}
}
prevRunSec = runSec;
yield();
}
// connect to wifi – returns true if successful or false if not
boolean connectWifi() {
boolean state = true;
int i = 0;
WiFi.config(ip, gateway, subnet);
WiFi.begin(ssid, password);
Serial.println("");
Serial.println("Connecting to WiFi");
// Wait for connection
Serial.print("Connecting");
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
if (i > 10) {
state = false;
break;
}
i++;
}
if (state) {
Serial.println("");
Serial.print("Connected to ");
Serial.println(ssid);
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
}
else {
Serial.println("");
Serial.println("Connection failed.");
}
return state;
}
// connect to UDP – returns true if successful or false if not
boolean connectUDP() {
boolean state = false;
Serial.println("");
Serial.println("Connecting to UDP");
if (UDP.begin(localPort) == 1) {
Serial.println("Connection successful");
state = true;
}
else {
Serial.println("Connection failed");
}
return state;
}
//packet size, wifi connected, udp connected, runtime reporter
void serialReporter()
{
Serial.print("packet: ");
Serial.print(confirmArray[packetRecv]);
Serial.print(" | ");
Serial.print("wifi: ");
Serial.print(confirmArray[wifiConnected]);
Serial.print(" | ");
Serial.print("udp: ");
Serial.print(confirmArray[udpConnected]);
Serial.print(" | ");
Serial.print("Run Time: ");
Serial.printf("%02d", runHr);
Serial.print(":");
Serial.printf("%02d", runMin);
Serial.print(":");
Serial.printf("%02d", runSec);
Serial.println();
}
I'll also attach a picture of my hardware setup. I'm powering the ESP over USB, but the led strip has it's own dedicated power, but they are grounded together. I have a level shifter to bump the 3.3V signal to 5V for the strip. The capacitors are in there for when i'm powering both the strip and esp off the same external supply.
if any more information about my set up is required, please let me know. I've been running the leds with this code for 3.5 hours and no problem so far, so maybe i've solved them all, but i'm definitely looking for some people to review it.
Cheers.