LED Matrix Flickering - Adafruit IS31FL3731

Hi guys,

I am trying to get a Adafruit IS31FL3731 - 16x9 LED matrix to work. It is displaying numbers fine, however there is a flicker. I am assuming it is due to the ledmatrix.clear() which is required to clear the screen before a new update. However I have tried so many things to get this to work now I am out of ideas.

The project is a display that takes data from UART and displays the values on the LED Matrix. Code included below, many thanks for any help!

Jack

#include <VescUart.h> // Thanks SolidGeek!
#include <SimpleKalmanFilter.h>
#include <Wire.h>
#include <Adafruit_GFX.h> // Thanks Adafruit!
#include <Adafruit_IS31FL3731.h>

#include <Fonts/Dotty5px7b.h> // edit font here - https://tchapi.github.io/Adafruit-GFX-Font-Customiser/
#include <Fonts/goodbyeDespair7pt7b.h> // this font has been edited, only numbers are refined, other glyphs are not tested

// If you're using the full breakout...
Adafruit_IS31FL3731 ledmatrix = Adafruit_IS31FL3731(); // Adafruit_IS31FL3731(11,7);

/** Initiate VescUart class */
VescUart UART;

unsigned long previousMillis = 0;        // timer for updating the display instead of using blocking delay

// VESC LED Matrix Display - for 16x9 LED Matrix 

// Connect VESC TX to Arduino RX
// Connect VESC RX to Arduino TX
// Connect VESC 5v to Arduino VIN
// Connect VESC GND to Arduino GND


///////// User Set Values //////////

// These are specific values that need to be set based on your device.

const long updateInterval = 100; // interval at which to refresh the display (milliseconds)
const int displayBrightness = 20; // 0-255 - Sets Brightness of LEDs - could set levels with a LDR based on daylight level
const int motorPolePairs = 7; // The '7' is the number of pole pairs in the motor. Most motors have 14 poles, therefore 7 pole pairs
const float wheelDia = 0.6; // Wheel Diameter in m - measure the outer most tyre for accurate measurements
const int motorPulley = 1; // Num Teeth - Set to 1 for direct drive e.g. Hub Motor
const int wheelPulley = 1; // Num Teeth - Set to 1 for direct drive e.g. Hub Motor
const int BattNumCells = 12; // Number of series cells in battery e.g. 4.2*12=50.4v pack
const float cellDischargelevel = 3.2; // Lowest discharge level for battery - used for batt percentage
const int metersinMeterKm = 1000; // set to 1000 for Kph or 1609 for Mph

// Which display style to use? Future plan is to have buttons for user to cycle the screens

const int displayStyle = 1;

/*
 *  1 - Large Numbers (Speed Only)
 *  2 - Smaller Numbers Speed & Distance + batt percent bar at bottom
 *  
 * 
 */

 
///////// END User Set Values //////////

// define variables
int rpm;
float voltage;
float current;
float power; //int power
float amphour;
float tach;
float distance;
float velocity;
float watthour;
float batpercentage;

//SimpleKalmanFilter Filter1(2, 2, 0.01);


void setup() {

Serial.begin(115200);

  if (! ledmatrix.begin()) {
    Serial.println("IS31 not found");
    while (1);
  }
  Serial.println("IS31 Found!");

while (!Serial) {;}

  /** Define which ports to use as UART */
 UART.setSerialPort(&Serial);


 // STARTUP SCREEN

  ledmatrix.setTextColor(displayBrightness); // quarter brightness
  ledmatrix.setFont(&goodbyeDespair7pt7b);
  ledmatrix.setCursor(0,8);
  ledmatrix.setTextSize(1);
  ledmatrix.print("UE");
  delay(1000);
  ledmatrix.clear(); // clear display ready for next update
} // end setup


  void LargeNumbers() // Screen 1 - see above for desc
{
  
  ledmatrix.setFont(&Dotty5px7b); // Dotty5px7b  goodbyeDespair7pt7b
  if (voltage > 9){ 
    ledmatrix.setCursor(0,7); // double digits XY 
    }
  else { 
    ledmatrix.setCursor(5,7); // single digits XY
    }
  ledmatrix.clear(); // clear display ready for next update
  ledmatrix.print(voltage);
}


  void SmallNumbers2() // Screen 2 - see above for desc
{
  ledmatrix.setFont(&Dotty5px7b);
  
  // Voltage
  if (voltage > 9){            
    ledmatrix.setCursor(0,4); // double digits XY 
    }
  else { 
    ledmatrix.setCursor(2,4); // single digits XY
    }  
  ledmatrix.print(voltage);
  
  // distance
  if (distance > 9){          
    ledmatrix.setCursor(9,4); // double digits XY centre is 5,5
    } 
  else { 
    ledmatrix.setCursor(11,4); // single digits centre is 7,5
    }
  ledmatrix.print(distance);

  // Bottom Batt Percentage Bar
  int ledLevel = map(batpercentage, 0, 100, 0, 16); // maps percentage to num of LEDS on bottom // map(value, fromLow, fromHigh, toLow, toHigh) //16 is the number of LEDs on the bottom
            
  ledmatrix.drawRect(0, 7, ledLevel, 2, displayBrightness); // x, y, width, height, brightness
  ledmatrix.clear(); // clear display ready for next update
}


void loop() {

  unsigned long currentMillis = millis();

  if (currentMillis - previousMillis >= updateInterval) {
    // save the last time you blinked the LED
    previousMillis = currentMillis;
    //ledmatrix.clear(); // clear display ready for next update
  
  
////////// Read values //////////  
 if ( UART.getVescValues() ) {

  rpm = (UART.data.rpm)/motorPolePairs;          // The '7' is the number of pole pairs in the motor. Most motors have 14 poles, therefore 7 pole pairs
  voltage = (UART.data.inpVoltage);
  current = (UART.data.avgInputCurrent);
  power = voltage*current;
  amphour = (UART.data.ampHours);
  watthour = amphour*voltage;
  tach = (UART.data.tachometerAbs)/((motorPolePairs*2)*3);          // The '42' is the number of motor poles multiplied by 3  tach = (UART.data.tachometerAbs)/42;
  distance = tach*3.142*(1/metersinMeterKm)*wheelDia*(motorPulley/wheelPulley);          // Motor RPM x Pi x (1 / meters in a mile or km) x Wheel diameter x (motor pulley / wheelpulley)
  velocity = rpm*3.142*(60/metersinMeterKm)*wheelDia*(motorPulley/wheelPulley);          // Motor RPM x Pi x (seconds in a minute / meters in a mile) x Wheel diameter x (motor pulley / wheelpulley)
  batpercentage = ((voltage-(cellDischargelevel*BattNumCells))/BattNumCells)*100;          // ((Battery voltage - minimum voltage) / number of cells) x 100




 ////////// Screen Selection //////////

  //ledmatrix.setTextColor(displayBrightness); // set LED brightness
  //ledmatrix.clear(); // clear display ready for next update
  
  if (displayStyle == 1){
    LargeNumbers(); // Screen 1 - see above for desc
    }
  if (displayStyle == 2){
    SmallNumbers2(); // Screen 2 - see above for desc
    }

 
 
 }
else // could not get values from the VESC ;(
  {    
              // Error X Symbol
  ledmatrix.setTextColor(displayBrightness); // quarter brightness
  ledmatrix.setFont(&goodbyeDespair7pt7b);
  ledmatrix.setCursor(5,8);
  ledmatrix.setTextSize(1);
  ledmatrix.print("X");
          // END Error X Symbol
  }
 }

} ////////// END OF LOOP //////////

  

what kind of flicker, when what comes on the matrix?

The text displays, but there is a very fast flicker, looks like the display is clearing then displaying the data. It is rather annoying.

Change
const long updateInterval = 100;

to
const long updateInterval = 1000;

that will update once per second.

Thanks for your suggestion, however the flicker is still there, it just makes the flicker happen once per second.

you can put a for() in your program that checks if the new value is different from the previous value, then display it. Clear the display before a new value is entered

Or you can only change the bits of the display that actually change. You need to draw a black box over the text to remove the old text and then rewrite the new values. Only write to the display once these two things have been done.

Thanks, yes I have done that before with larger displays, however this is only 16x9 LEDs (pixels) so the single number takes up the whole screen.

And the number should be fast to update as it will be speed in Kph so will not stay at the same value. Actually now I am typing that maybe the flicker wont be noticeable if the value is changing anyway, so a for loop might be a good solution.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.