Voting resources, early voting, and poll worker information - VOTE. ... Adafruit is open and shipping.
0

Huzzah-Esp8266 + Neopixel > odd behaviour
Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.

Huzzah-Esp8266 + Neopixel > odd behaviour

by galaktika on Tue Feb 04, 2020 5:40 pm

Hi,

I'm using Huzzah Esp8266 with the TXB8108 logic level shifter and 60px/m RGB Neopixel strips.
I have a LED costume out of 5 different stripes with different lengths ( 16px, 16px, 59px, 60px, 106px => all together 257px).
I made a non-blocking script using FastLED library, checking intervals with millis() in the loop. Via UDP I send automatically and manually signals to start the LED animations.

The script works as expected with only one stripe in the led array. No matter how many pixels I add to the second, third, etc stripes the problem appears: although the processor calculates every step, not all the pixels have refreshed (hasn't changed color).
In every loop, I only change 1 pixel/stripes => "for" loop runs max 5 times in a loop. Not a heavy task, still doesn't work well.

I'm stuck and don't know how to solve this. Should I change Huzzah to M0 Wifi? Or is it the question of the code?

Thanks for any hints,
Sabi

galaktika
 
Posts: 14
Joined: Tue Jul 31, 2018 10:57 am

Re: Huzzah-Esp8266 + Neopixel > odd behaviour

by mikeysklar on Tue Feb 04, 2020 7:55 pm

Hi Sabi,

This sounds like a pretty cool project. I don't see a reason to change any of the hardware involved at this point as it sounds like a software issue.

Can you write a minimal test example (not using the FastLED library) that just initializes each strip with a single test color? This way we can eliminate any potential wiring issues or hardware problems and just focus on the code. Baby steps.

mikeysklar
 
Posts: 2007
Joined: Mon Aug 01, 2016 8:10 pm

Re: Huzzah-Esp8266 + Neopixel > odd behaviour

by galaktika on Wed Feb 05, 2020 12:39 pm

Hi Mikeysklar,

Thanks for the response and the kind words. I love this project and there's much more potential in it (in technical sense) then I can reach this point. I've attached an image just to get a sense of the costume (there's 60px at the back, 60px in the heart box, 106px in the skirt, 16px on each hand, 5x16px mirrored on the head).

LED animations are synchronized with the background projected animation and triggered automatically by the patch I made. The same goes for the theatre LED lights. All are fun, if you have time, have a look at the trailer: http://bandart.hu/en/ann-droid

At this time I only had time for clearing out the unnecessary code. What I left is the structure and one of the effects (LED animation) on which clearly visible the oddity.
If you only can help me with the Neopixel library then later today I rewrite the corresponding parts.

The whole structure is very simple, I don't think I should explain it. Hopefully, there's some obvious mistake I made which solve this issue. Thanks a lot for your time.

Code: Select all | TOGGLE FULL SIZE
#define FASTLED_FORCE_SOFTWARE_SPI
#define FASTLED_ESP8266_DMA
//#define FASTLED_ALLOW_INTERRUPTS 0
//#define FASTLED_INTERRUPT_RETRY_COUNT 1

#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
#include <FastLED.h>

//// WIFI ////////////////////////////////////////////////////////////

const char* ssid     = "******";
const char* password = "********";
int udpPort = 8888;
const char* host = "*********";

char packetBuffer[UDP_TX_PACKET_MAX_SIZE + 1]; //buffer to hold incoming packet,
//Static IP address configuration
IPAddress staticIP( ******* ); //ESP static ip
IPAddress gateway( ******** );   //IP Address of your WiFi Router (Gateway)
IPAddress subnet( ******** );  //Subnet mask
IPAddress dns( ******** );  //DNS
WiFiUDP udp;
unsigned long UdpInterval;
unsigned long lastUdpUpdate;

//// LED /////////////////////////////////////////////////////////////

#define ARRAY_SIZE(A) (sizeof(A) / sizeof((A)[0]))

uint16_t NUM_LEDS[] = { 16, 59, 106, 60, 16 };
#define NUMLEDS 16 + 59 + 106 + 60 + 16 // = 257
#define stripes 5
CRGB leds[ stripes ][ NUMLEDS ];

#define BRIGHTNESS 255//0..255 (96)

enum pattern             { menu,   menu2ndPhase };
const char* Patterns[] = { "menu", "menu2ndPhase" };
enum dir { FWD, BWD };
pattern  ActivePattern;  // which pattern is running
unsigned long Interval;   // milliseconds between updates
unsigned long lastUpdate; // last update of position
uint16_t TotalSteps;  // total number of steps in the pattern
uint16_t Index;  // current step within the pattern
bool Loop = false;
bool Completed;
void (*OnComplete)();  // Callback on completion of pattern
uint16_t prev[] = { -1,-1,-1,-1,-1 };
uint8_t dir[] = { FWD,FWD,FWD,FWD,FWD };
CRGB C1, C2;

bool test = true;
bool DEBUG = false;

uint8_t gHue = 0; // rotating "base color" used by many of the patterns

//// WIFI - UDP ///////////////////////////////////////////////////////

void WifiSetup() {
  WiFi.mode( WIFI_STA );
  WiFi.config( staticIP, subnet, gateway, dns );
  WiFi.begin( ssid, password ); 
 
  while ( WiFi.status() != WL_CONNECTED ) {
    delay(500);
    Serial.print(".");
  }

  // udp
  udp.begin( udpPort );
  Serial.print("Local port: ");
  Serial.println(udp.localPort());

  UdpInterval = 500;
}

void CheckingUDP() {
  if ((millis() - lastUdpUpdate) > UdpInterval) {
    lastUdpUpdate = millis();
   
    udp.flush();
   
    int packetSize = udp.parsePacket();
    if (packetSize > 0)
    {
      IPAddress remoteIp = udp.remoteIP();
      int n = udp.read(packetBuffer, UDP_TX_PACKET_MAX_SIZE);
      packetBuffer[n] = 0;

      packetReceived( packetBuffer );
      replyMessage( packetBuffer );
    }
  }
}

void replyMessage( char* task ) {
  int i = udp.beginPacket( udp.remoteIP(), udp.localPort() );
  udp.write( task );
  udp.endPacket();
}

//// LOOP /////////////////////////////////////////////////////////////

void setup() {
  WifiSetup();
  LEDSetup();
}

void loop() {
  LEDUpdate();
  CheckingUDP();
}

//// LED //////////////////////////////////////////////////////////////

void LEDSetup() {
  FastLED.addLeds<NEOPIXEL, 14>(leds[0], NUM_LEDS[0]); // 16 - hands / head
  FastLED.addLeds<NEOPIXEL, 12>(leds[1], NUM_LEDS[1]); // 59 - back
  FastLED.addLeds<NEOPIXEL, 13>(leds[2], NUM_LEDS[2]); // 106 - skirt
  FastLED.addLeds<NEOPIXEL, 15>(leds[3], NUM_LEDS[3]); // 60 - heart
  FastLED.addLeds<NEOPIXEL,  0>(leds[4], NUM_LEDS[4]); // 16 - hands / head

  FastLED.setBrightness( BRIGHTNESS );
  FastLED.clear();
  ResetAnimation();
  FastLED.show();
}

void Increment() {
  if (Index == TotalSteps) {
    Completed = true;
    ActivePattern = NONE;
    if (OnComplete != NULL) { OnComplete(); }
  } else {
    FastLED.show();
    Index++;
  }
}

void packetReceived( char* task ) {
  int No = -1;
  for (int i=0; i < ARRAY_SIZE( Patterns ); i++) {
    if ( strcmp(task,Patterns[i]) == 0 ) {
       No = i;
       break;
    }
  }
 
  if (No!=-1) {
    ResetAnimation();
  }
 
  switch ( No ) {
    case menu:
      ActivePattern = menu;
      Interval = 20;
      TotalSteps = 5000;
      OnComplete = menuComplete;
      menuStart();
    break;
  }
}

void LEDUpdate() {
  if (((millis() - lastUpdate) > Interval) && (!Completed)) {
    lastUpdate = millis();
    switch (ActivePattern)
    {
      case menu:
        menuUpdate();
        Increment();
      break;
    }
  }
}
//------------------------------------------------------------------------/
void ResetAnimation() {
  for (int i=0; i<ARRAY_SIZE( NUM_LEDS ); i++){
    fill_solid(leds[i], NUM_LEDS[i], CRGB::Black);
    prev[i] = UINT16_MAX;
  }
  Index = 0;
  Completed = false;
  OnComplete = AnimEnded;
  FastLED.show();
  digitalWrite( 0,LOW );
}
//------------------------------------------------------------------------/
void AnimEnded() {
  for (int i=0; i<ARRAY_SIZE( NUM_LEDS ); i++){
    fill_solid(leds[i], NUM_LEDS[i], CRGB::Black);
  }
  FastLED.show();
  replyMessage( "animEnded" );
  digitalWrite(0, HIGH);
}

void AnimEndedColorStays() {
  replyMessage( "animEndedWithColor" );
  digitalWrite(0, HIGH);
}

//------------------------------------------------------------------------/
void menuStart() {
  C1 = CRGB::Blue;
  C2 = CRGB::Red;
  for (int i; i<ARRAY_SIZE( NUM_LEDS ); i++) {
    prev[i] = 0;
    dir[i] = FWD;
    fill_solid(leds[i], NUM_LEDS[i], CRGB::Blue);
  }
}

void menuUpdate() {
  for (int i=0; i<ARRAY_SIZE( NUM_LEDS ); i++){
    if (dir[i]==FWD) {
      prev[i]++;
      if (prev[i]==NUM_LEDS[i]-1) {
        dir[i]=BWD;
        CRGB c = C1;
        C1 = C2;
        C2 = c;
      }
    } else if (dir[i]==BWD) {
      prev[i]--;
      if (prev[i]==0) {
        dir[i]=FWD;
        CRGB c = C1;
        C1 = C2;
        C2 = c;
      }
    }
    leds[ i ][ prev[i] ] = C2;
  }
}

void menuComplete() {
  AnimEndedColorStays();
}





mikeysklar wrote:Hi Sabi,

This sounds like a pretty cool project. I don't see a reason to change any of the hardware involved at this point as it sounds like a software issue.

Can you write a minimal test example (not using the FastLED library) that just initializes each strip with a single test color? This way we can eliminate any potential wiring issues or hardware problems and just focus on the code. Baby steps.
Attachments
ann.jpg
ann.jpg (249.24 KiB) Viewed 50 times

galaktika
 
Posts: 14
Joined: Tue Jul 31, 2018 10:57 am

Re: Huzzah-Esp8266 + Neopixel > odd behaviour

by mikeysklar on Wed Feb 05, 2020 6:42 pm

Sabi,

This is a wonderful trailer and performance you have been involved with.

In terms of your shared code I don't think this will help at all with debugging. You will want to create 5 line script which initializes neopixel strip in a solid core and does not do any networking. You need to start troubelshooting somewhere so let's just make sure you have the wiring correct and are able to communicate to eachs trip before moving on to your existing code base.

mikeysklar
 
Posts: 2007
Joined: Mon Aug 01, 2016 8:10 pm

Please be positive and constructive with your questions and comments.