Flexible WS2812 LEB Matrix (32x8) Question/Problem with static Text

Hi guys,

I’m quite new to Arduino and habe spent the last two days researching stuff, testing demos/examples and so on.

I bought this flexible LED Matrix, because I wanted to make a simple digital clock with this. I know there are several, maybe better solutions with those MAX7129 Panels, however now I got this thing and I thought this wouldn’t be difficult at all and that there might already be similar projects out there :slight_smile:

I seems I was wrong or I underestimated the difficulty. I got the time acquirement via ntp implemented, but with displaying content I have some issues. There are 3 problems which I need to address and I’m hopefully looking for your help.

Attached is the video which shows 2 of the 3 problems.

  1. I’m getting random pixels lid, which in my opinion shouldn’t light up. A problem with the data line I guess? Too much noise? What should I do about this? Adding a cap oder resistor?

  2. The text which is displayed is “Instructables” but as you can see in the video, it is kinda hard to read because it looks like the text ist scrolling also up and down 1 pixel during the left/right scrolling. Not sure why this is. Maybe also caused by noise?

  3. The last and most frustrating problem so far is, that I don’t want the text to scroll. I just want to display on a fixes position it and update every second. I haven’t figured out how to do this. Either it is too simple or I’m just a retard :slight_smile:

If I remove the loop which is scrooling the text and enter a fixed position of the cursor, nothing shows up.

Here is the actual code:

// Adafruit_NeoMatrix example for single NeoPixel Shield.
// Scrolls 'Howdy' across the matrix in a portrait (vertical) orientation.

#include <Arduino.h>
#if defined(ESP8266)
#include <ESP8266WiFi.h>
#elif defined(ESP32)
#include <WiFi.h>
#endif

#include "ESPDateTime.h"
#include <Time.h>
#include <TimeLib.h>
#include <Adafruit_GFX.h>
#include <Adafruit_NeoMatrix.h>
#include <Adafruit_NeoPixel.h>

#ifndef PSTR
 #define PSTR // Make Arduino Due happy
#endif

#define PIN 32

#define PAR_MWIDTH 32
#define PAR_MHEIGHT 8
#define matrix_width matrix.width()

// MATRIX DECLARATION:
// Parameter 1 = width of NeoPixel matrix
// Parameter 2 = height of matrix
// Parameter 3 = pin number (most are valid)
// Parameter 4 = matrix layout flags, add together as needed:
//   NEO_MATRIX_TOP, NEO_MATRIX_BOTTOM, NEO_MATRIX_LEFT, NEO_MATRIX_RIGHT:
//     Position of the FIRST LED in the matrix; pick two, e.g.
//     NEO_MATRIX_TOP + NEO_MATRIX_LEFT for the top-left corner.
//   NEO_MATRIX_ROWS, NEO_MATRIX_COLUMNS: LEDs are arranged in horizontal
//     rows or in vertical columns, respectively; pick one or the other.
//   NEO_MATRIX_PROGRESSIVE, NEO_MATRIX_ZIGZAG: all rows/columns proceed
//     in the same order, or alternate lines reverse direction; pick one.
//   See example below for these values in action.
// Parameter 5 = pixel type flags, add together as needed:
//   NEO_KHZ800  800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
//   NEO_KHZ400  400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
//   NEO_GRB     Pixels are wired for GRB bitstream (most NeoPixel products)
//   NEO_RGB     Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)


// Example for NeoPixel Shield.  In this application we'd like to use it
// as a 5x8 tall matrix, with the USB port positioned at the top of the
// Arduino.  When held that way, the first pixel is at the top right, and
// lines are arranged in columns, progressive order.  The shield uses
// 800 KHz (v2) pixels that expect GRB color data.
Adafruit_NeoMatrix matrix = Adafruit_NeoMatrix(PAR_MWIDTH, PAR_MHEIGHT, PIN,
NEO_MATRIX_TOP + NEO_MATRIX_LEFT +
NEO_MATRIX_COLUMNS + NEO_MATRIX_PROGRESSIVE,
NEO_GRB + NEO_KHZ800);

const uint16_t colors[] = {
matrix.Color(255, 0, 0), matrix.Color(0, 255, 0), matrix.Color(0, 0, 255) };

char totaltime[6];
char yourText[64] = "";
int  pixelPerChar = 6;
int  maxDisplacement;

#ifndef WIFI_SSID
#define WIFI_SSID "****"
#define WIFI_PASS "****"
#endif

unsigned long lastMs = 0;

unsigned long ms = millis();

void setupWiFi() {
  WiFi.mode(WIFI_STA);
  WiFi.begin(WIFI_SSID, WIFI_PASS);
  Serial.println(millis());
  Serial.print("WiFi Connecting");
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println();
}

void setupDateTime() {
  // setup this after wifi connected
  // you can use custom timeZone,server and timeout
  // DateTime.setTimeZone(-4);
  //   DateTime.setServer("asia.pool.ntp.org");
  //   DateTime.begin(15 * 1000);
  DateTime.setTimeZone(8);
  DateTime.begin();
  if (!DateTime.isTimeValid()) {
    Serial.println("Failed to get time from server.");
  }
}

void setup() {
  //pinMode(32,OUTPUT);

  delay(1000);
  Serial.begin(115200);
  setupWiFi();
  setupDateTime();
  Serial.println(DateTime.now());
  Serial.println(DateTime.getTime());
  Serial.println(DateTime.utcTime());
  Serial.println("--------------------");
  Serial.println(DateTime.toString());
  Serial.println(DateTime.toISOString());
  Serial.println(DateTime.toUTCString());
  Serial.println("--------------------");
  Serial.println(DateTime.format(DateFormatter::COMPAT));
  Serial.println(DateTime.format(DateFormatter::DATE_ONLY));
  Serial.println(DateTime.format(DateFormatter::TIME_ONLY));
  Serial.println("--------------------");
  DateTimeParts p = DateTime.getParts();
  Serial.printf("%04d/%02d/%02d %02d:%02d:%02d %ld %+05d\n", p.getYear(),
                p.getMonth(), p.getMonthDay(), p.getHours(), p.getMinutes(),
                p.getSeconds(), p.getTime(), p.getTimeZone());
  Serial.println("--------------------");
  time_t t = DateTime.now();
  Serial.println(DateFormatter::format("%Y/%m/%d %H:%M:%S", t));
  Serial.println(DateFormatter::format("%x - %I:%M %p", t));
  Serial.println(DateFormatter::format("Now it's %F %I:%M%p.", t));

  maxDisplacement = 12 * pixelPerChar + matrix.width();

  matrix.begin();
  matrix.setTextWrap(false);
  matrix.setBrightness(12);
  matrix.setTextColor(colors[0]);

}

int x = matrix_width;
int pass = 0;

void loop() {

  if (millis() - ms > 5000) {
    matrix.clear();
    ms = millis();
    Serial.println("--------------------");
    if (!DateTime.isTimeValid()) {
      Serial.println("Failed to get time from server, retry.");
      DateTime.begin();
    } else {
      Serial.printf("Up     Time:   %lu seconds\n", millis() / 1000);
      Serial.printf("Local  Time:   %ld\n", DateTime.now());
      Serial.printf("Local  Time:   %s\n", DateTime.toString().c_str());
      Serial.printf("UTC    Time:   %ld\n", DateTime.utcTime());
      Serial.printf("UTC    Time:   %s\n",
                    DateTime.formatUTC(DateFormatter::SIMPLE).c_str());
    }
  }

  matrix.fillScreen(0);
  matrix.setCursor(x, 0);
  matrix.print(F("Instructables"));
  if(--x < -maxDisplacement) {
    x = matrix.width();
    if(++pass >= 3) pass = 0;
    matrix.setTextColor(colors[pass]);
  }
  matrix.show();
  delay(100);
}

what arduino are you using and how is this powered ?

I’d suggest you first test the strip without things being too complicated

run this:

#include <Adafruit_NeoPixel.h>
const byte dataPin =  3;      //Data pin
const uint16_t nbPixels = 256 ; // 32x8
Adafruit_NeoPixel strip = Adafruit_NeoPixel(nbPixels, dataPin, NEO_GRB + NEO_KHZ800);

const uint32_t tempo = 100;

void setup()
{
  strip.begin();
}

void loop() {

  for (uint16_t i = 0; i < nbPixels; i++) {
    strip.setPixelColor(i, strip.Color(128, 0, 0));
    strip.show(); // This sends the updated pixel color to the hardware.
    delay(tempo);

    strip.setPixelColor(i, strip.Color(0, 128, 0));
    strip.show(); // This sends the updated pixel color to the hardware.
    delay(tempo);

    strip.setPixelColor(i, strip.Color(0, 0, 128));
    strip.show(); // This sends the updated pixel color to the hardware.
    delay(tempo);

    strip.clear();
  }
}

you should see all pixels lighting up one after the other in 3 primary colors. (modify tempo if it’s going too fast for each color)

It looks like you are using an ESP / NodeMCU of some sort and they usually use 3.3V logic. The WS2812 LED's require the logic voltage to be at least 70% of the supply voltage, so if the strip is powered by 5V, the logic must be at least 5*0.7=3.5V and this may be an issue. Also mind that the fully lit strip will consume (3 colors * 20mA per color * 256 LED's) more than 15A which requires a rather beefy power supply.

Thanks for your response

@J-M-L
I uploaded your code and here's a video how it looks like:

The code itself is working but there are still some LEDs which are lighting up where they shouldn't.

What could be causing this?

@Danois90
I'm aware of this. I'm using a 5A Lab power supply. In 99% of all test cases the strip did consume less than 1A current on 5V. Only if all LEDs are lid up in all colors the current draw can be that high, which in my purposed used case will never be the case :slight_smile:

I'm not sure but I guess this is not the problem. With J-M-L test sketch the matrix draws about 300mah.

The thing with the level of the logic voltage beeing to low is interesting and might be an issue. What would be the usual way to get around this issue?

I have that display. I was able to drive it first time with an UNO. WS2812B timing is tight, I'm almost surprised that you can drive it from an ESP at all. Use a level translator circuit to get from 3.3V to 5V. Keep all your connection wires short and run the signal wires adjacent to the ground wires.

As long as interrupts are disabled while data is transmittet to the LED's, it is no problem using an ESP.

If you have one WS2812 laying around, you can actually use a nifty little hack to use that LED as logic level shifter.

Did you buy a quality component or a cheap version from Asia ?
Might have some poor connections in the matrix too...

Is it well grounded ? If you can from as many places as possible

The thing with the level of the logic voltage being to low is interesting and might be an issue. What would be the usual way to get around this issue?

I use 7400 TTL chips, WS281x are quite needy considering their logic high level, much more than 74xx00 series. If you are using an ESP, and you are planning to make use of the wifi capability, you should start using a different library to drive the strip. Neopixel.h only has a bit-banged method, which turns 'off' the interrupts for a while. This causes loss of wifi, really it won't work with wifi. Use Makuna/NeoPixelBus which has as a DMA mode which does not require interrupts to be turned off (only no more choice of pins. Now if the library that you use for filling the output buffer, actually write to the neopixel.h buffer or uses the functions that are included in it, you may need to modify that.

@aarg
I believe the voltage level logic is the problem. However the wires already are pretty short and should not be the problem.

@Danois90

Interesting! Will do this hack since I'd like to use this ESP32 (devkit v1) for this project

@J-M-L

Did you buy a quality component or a cheap version from Asia ?

Yes, it's a cheap knock off from Asia

Might have some poor connections in the matrix too...

Possible indeed, but in this case not the issue, see below :wink:

Is it well grounded ? If you can from as many places as possible

I think so. Added another ground line but no change.

@Deva_Rishi
Thanks, I already read about this library somewhere. Have to see if I'll be able to translate that with my knowledge.

@all

I made a simple test. I uploaded J-M-L's Test code onto an Arduino Mega 2560 and voila, the unsoppesedly lid up pixels are gone!

So the hint with the non matching voltage logic seems to be the issue and I'll try to use this WS2812 hack to make an level translator circuit and see how it works out.

Thanks a lot to @all so far, you really help out :slight_smile:

One question still remains. Does anybody has a hint or even example code how to display a static text (not scrolling), with any LED Library?

So I just implemented the WS2812 hack to manipulate the data line voltage, but now the unwanted effect is even bigger/stranger (before only some LEDs lid up, now with this hack they are additionally travelling some pixels).

Not sure why :confused:

One question still remains. Does anybody has a hint or even example code how to display a static text (not scrolling), with any LED Library?

I think the NeoMatrix library should do that for you in combination with the Adafruit_GFX, but of course only ready made in combination with neopixel.h. But it is not to complicated to tap into Adafruit_GFX. All you need to do is create a drawPixel() function (the vitual void in Adafruit_GFX)
Another option and probably even more straight forward is to delve into Adafruit_GFX and copy the method for extracting the pixels for every letter of a font, and map them to your matrix. This can be quite complex since GFX has Functions for every possible circumstance 1-bit 8-bit 16-bit etc, though you are probably after a 1 bit method, with set color. That GFX works with 16-bit color and you strip with 24-bit probably isn't helping. So nothing right out of the box, but custom made what probably be the easiest. You might want to use the adafruit glcfont.c, or you may want to you another font, still you will need to interface with it.

So I just implemented the WS2812 hack to manipulate the data line voltage, but now the unwanted effect is even bigger/stranger (before only some LEDs lid up, now with this hack they are additionally travelling some pixels).

Just get a 5v TTL chip, i usually use a 74hct04 (or LS or whatever i have) and run the signal through the 'not-gate' twice, that does the job. I then generally make sure that the power of the hole circuit is well balanced, 1uf cap on the 3.3v line, 10uF on the 5v line and 100uF on the 12v line, and create a protective circuit for the ESP-01 with a few resistors and a diode (probably overkill since it's connected to a logic input, though i have fried several ESP-01's )

Good to see you nailed the issue - clearly if that works with the mega then the strip is ok

You’ll need to adapt voltage

If esp is an issue too, Did you check FastLED Light — ESPHome ?

Hey guys,

I got it sorted mostly I guess.

@Deva_Rishi

I think the NeoMatrix library should do that for you in combination with the Adafruit_GFX, but of course only ready made in combination with neopixel.h. But it is not to complicated to tap into Adafruit_GFX. All you need to do is create a drawPixel() function (the vitual void in Adafruit_GFX)

Thanks for the hint. This was the first try but it didn't work. It turned out that the declaration of the matrix was not proper, therefore the text was displayed in an invisible area.

Just get a 5v TTL chip, i usually use a 74hct04

I already ordered some pcbs from Ebay "I2C Logic Level Converter Bi-Directional Module5V to3.3V For Arduino" for 3€ and hopefully when the arrive they'll solve the logic problem the ESP32 has.

@J-M-L

If esp is an issue too, Did you check FastLED Light — ESPHome ?

Got it working now with the Adafruit NeoMatrix and GFX Librarys but will check this out for future projects maybe, thanks for the linlk.

Now for designing and printing a suitable case :slight_smile: