4-Digit 7-Segment LED Matrix Display

Adafruit 4-Digit 7-Segment LED Matrix Display FeatherWing + Feather M0 Basic  

4-Digit 7-Segment LED Matrix Display product

4-Digit 7-Segment LED Matrix Display Adafruit tutorial

Adafruit Feather M0 Basic Proto product

Adafruit Feather M0 Basic Proto tutorial


/*
Demonstrates using the 4-Digit 7-Segment LED Matrix Display
with the Adafruit Feather M0 Basic Proto.
Reads analog input and lipoly battery charge on the M0.


Adafruit Feather M0 Basic Proto - ATSAMD21 Cortex M0
The ATSAMD21G18 ARM Cortex M0 processor is the same as the new Arduino Zero.
https://www.adafruit.com/product/2772
https://learn.adafruit.com/adafruit-feather-m0-basic-proto?view=all
https://cdn-learn.adafruit.com/assets/assets/000/046/244/original/adafruit_products_Feather_M0_Basic_Proto_v2.2-1.png?1504885373
https://learn.adafruit.com/adafruit-feather-m0-basic-proto/adapting-sketches-to-m0

256KB of FLASH + 32KB of RAM
No EEPROM
32.768 KHz crystal for clock generation & RTC

6 x 12-bit analog inputs
A0 -  This pin is analog input A0 but is also an analog output due to 
      having a DAC (digital-to-analog converter). 
      You can set the raw voltage to anything from 0 to 3.3V, unlike 
      PWM outputs this is a true analog output
A1 thru A5 - These are each analog input as well as digital I/O pins.
A7 -  (pin #7).  This is also pin #9 (GPIO #9).  The analog input is connected 
      to a voltage divider for the lipoly battery for charge measurement.
      
The following pins can be configured for PWM without any signal conflicts 
as long as the SPI, I2C, and UART pins keep their protocol functions:
  Digital pins 5, 6, 9, 10, 11, 12, and 13
  Analog pins A3 and A4

For PWM, if you need a pin fully on (i.e. analogWrite(pin,255)), use 
digitalWrite(pin,HIGH) to insure it doesn't pulse to zero. 

Analog I/O

The ARef pin for a non-3.3V analog reference, the code to use 
is analogReference(AR_EXTERNAL).

10 bits -> 0 to 1023
12 bits -> 0 to 4095


Adafruit 4-Digit 7-Segment LED Matrix Display FeatherWing

For a clock + RTC example, see Adafruit example file clock_sevenseg_ds1307.ino
For a clock + GPS example, see Adafruit example file clock_sevenseg_gps.ino

*/

// M0  (Feather M0)
const byte pin_LED = 13;
const byte pin_BATT = A7;

//////////////////////////////////////////////////////////////////////////////
//  ADC constants
// Constants below used to conver raw ADC values to mV.
// 10 bit, 0 to 1023, or 1024 steps
// 12 bit, 0 to 4095, or 4096 steps
const float FSadc = 1024.0;
const float FSmV = 3300.0;
//////////////////////////////////////////////////////////////////////////////
//  lipoly battery
//  The pin is defined earlier as pin_BAT
// dAdj_mV is multiplied by the reading at pinADC in mV to get the input voltage to a
// voltage divider or other component. 
// Shunt cal voltage divider; R1 = 10k ohms, R2 = 2.2 k ohms; 
const float dAdj_mVbat = 2.0;
// 300000 ms = 5 min
// 60000 ms = 1 min
// 10000 ms = 10 sec = 0.1 Hz 
// 1000 ms = 1 sec = 1 Hz
// 100 ms = 0.1 sec = 10 Hz
// 10 ms = 0.01 sec = 100 Hz
const unsigned long timerInterval = 5000;  
unsigned long timerLast = 0;  // timer
//////////////////////////////////////////////////////////////////////////////
//  Analog input
const byte pinADC = A0;
// dAdj_mV is multiplied by the reading at pinADC in mV to get the input voltage to a
// voltage divider or other component. 
// Shunt cal voltage divider; R1 = 10k ohms, R2 = 2.2 k ohms; 
const float dAdj_mV = (10000.0+2200.0)/2200.0;
// 3.3 V full scale (3300 mV); 0 to 1023 steps (1024 total steps) for 10 bit
// 187 ADC reading * (3300/1024) = 600 mV
int iSamples = 0;
const int iMaxSamples = 100000;
float dCumAvg = 0.0;
float dLastAvg = 0.0;
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
// Show serial messages when DEBUG = true, otherwise minimize them.
// WARNING:   I experienced the Feather M0 waiting for the serial monitor to be
//            loaded from the IDE before the sketch would continue to run.  
//            For this reason, I am wrapping serial output around a DEBUG check.
#define DEBUG false
//////////////////////////////////////////////////////////////////////////////


// Adafruit 4-Digit 7-Segment LED Matrix Display FeatherWing.
#include  
// Libraries written by Limor Fried/Ladyada for Adafruit Industries. 
#include 
#include "Adafruit_LEDBackpack.h"
Adafruit_7segment matrix = Adafruit_7segment();
#ifndef _BV
  #define _BV(bit) (1<<(bit))
#endif


void setup() {  
  
  // WARNING:   I experienced the Feather M0 waiting for the serial monitor to be
  //            loaded from the IDE before the sketch would continue to run.  
  //            For this reason, I am wrapping serial output around a DEBUG check.
  #if DEBUG
    Serial.begin(9600);
    while (!Serial) {
      delay(1);
    }
    Serial.println("Setup complete");
  #endif

  // Adafruit 4-Digit 7-Segment LED Matrix Display FeatherWing
  matrix.begin(0x70);
  matrix.setBrightness(7);  // Set display brightness to medium (default is 15 max)
  FourDig7SegLedMatrixDispDemo();
  
  blinkLED(pin_LED);
  
} // setup()


void loop() {
  
  CheckADC();

  if (timerLast > millis())  timerLast = millis();
  if ((millis() - timerLast) > timerInterval) {
    timerLast = millis();
    LiPoBatt();
    blinkLED(pin_LED);
  } 
  
  // The yield() function allows ESP8266 microcontroller to run a 
  // number of utility functions in the background, without causing 
  // the ESP8266 to crash or reset. Include it within any 
  // while() + digitalRead() and other loops;
  yield();
  
} // loop()


void blinkLED(byte ledPIN){
  //  consumes 300 ms.
  for(int i = 5; i>0; i--){
    digitalWrite(ledPIN, HIGH);
    delay(30);
    digitalWrite(ledPIN, LOW);
    delay(30);
  }    
}

void CheckADC() {
  // Output the average pinADC value whenever it changes (only). 
  // (The comparison is integer based from the mV value)
  // Flash the pin_LED whenever iMaxSamples have been read. 
  if (iSamples < iMaxSamples) {
    iSamples += 1;
    dCumAvg += Get_mVfromADC(pinADC, dAdj_mV);   
    yield();
  } else {
    float mV = dCumAvg / iSamples;
    iSamples = 0;
    dCumAvg = 0.0;
    yield();
    if ((int)mV != (int)dLastAvg) {
      printADCmV(pinADC, dLastAvg);
      // Note that the mV going into the voltage divider = mV*(10000.0+2200.0)/2200.0)
    }
    dLastAvg = mV;
    //blinkLED(pin_LED);
  }
  yield();
}  //CheckADC()

void LiPoBatt() {
  // The lipoly battery max charge is 4.2V, and have the best life when
  // the charge is maintained at 3.7V or more. At 3.2V you are getting
  // close to when the protection circuitry cuts it off. 
  // The pin naturally 'sits' at around 2VDC due to the resistor divider
  //
  // Note that digitialWrite(pin, HIGH) is the same as pinMode(pin, INPUT_PULLUP) 
  // HOWEVER - you cannot use digitialWrite(pin, HIGH) for the Feather M0 Basic Proto.  
  // This is because the pullup-selection register is the same as the 
  // output-selection register. For the M0, use pinMode(pin, INPUT_PULLUP) to 
  // turn on a pin as an input with a pullup resistor.
  // 
  // The safe method overall is to disable a pullup with digitalWrite(pin, LOW), and
  // use pinMode(pin, INPUT_PULLUP) to enable a pullup resister on a pin. 
  //
  // WARNING:  If using AF OLED FeatherWing, button A is on #9 (DIO9).  
  // Before you do an analog read, you must disable the pullup with a
  // digitalWrite(BUTTON_A, LOW) before the analogRead(), then follow with 
  // pinMode(BUTTON_A, INPUT_PULLUP) to enable it again. 
  // Check the lipoly battery charge every timerInterval ms
  // 
  float BATTmV = Get_mVfromADC(pin_BATT, dAdj_mVbat);
  
  #if DEBUG
    Serial.print("BATT = ");
    Serial.print(BATTmV);
    Serial.print(" mV  ");
    if (BATTmV >= 4100.0) {
      Serial.print("fully charged");
    } else if  ((BATTmV < 4100.0) && (BATTmV >= 3700.0)) {
      Serial.print("charging needed");
    } else if  (BATTmV < 3700.0) {
      Serial.print("charging needed (battery life in danger!)");
    }
    Serial.println("  ");   
  #endif

  // Show the LiPo battery avg voltage on the 4-Digit 7-Segment LED Matrix Display
  // Blink if battery needs charging
  matrix.setBrightness(7);  
  if (BATTmV >= 4100.0) {
    matrix.blinkRate(0);  // 0 = no blinking, 1,2,3 for blinking (fast .. slow)
  } else if  ((BATTmV < 4100.0) && (BATTmV >= 3700.0)) {
    matrix.blinkRate(3);  
  } else if  (BATTmV < 3700.0) {
    matrix.blinkRate(1);    
  }
  matrix.print(BATTmV);
  matrix.writeDisplay();

}  //LiPoBatt()


float Get_mVfromADC(byte pinADC, float mVadj) {
  // Read the value from the sensor and convert ADC to mV.
  // The input to pinADC in mV is multipled by mVadj to
  // correct for any voltage divider or other component.
  // Global variables FSmV and FSadc convert the raw ADC
  // values to the mV measured at pinADC.
  int ADCval = analogRead(pinADC);  // discard the 1st value
  yield();
  ADCval = analogRead(pinADC);
  yield();
  float mV = ADCval*(FSmV/FSadc);
  mV *= mVadj;
  return mV;
}  // Get_mVfromADC()


void printADCmV(byte pinADC, float mV) {
  #if DEBUG
    Serial.print("A (");
    Serial.print(pinADC);
    Serial.print(") = ");
    Serial.print(int(mV));
    Serial.println(" mV");
  #endif
} //printADCmVDC ()


void FourDig7SegLedMatrixDispDemo() {
  
  // Set back to medium brightness, fast blinking
  // and print a number too long = prints "- - - -"
  matrix.setBrightness(7);  
  matrix.blinkRate(1);
  matrix.print(10000, DEC);
  matrix.writeDisplay();
  delay(5000);

  // print a hex number ("bEEF")
  matrix.print(0xBEEF, HEX);
  matrix.blinkRate(0);
  matrix.writeDisplay();
  delay(5000);

  // print a integer
  matrix.print(0055);  
  matrix.writeDisplay();
  //  matrix.print(1)     = "   1"  also .print(0.001)
  //  matrix.print(22)    = "  22"
  //  matrix.print(333)   = " 333"
  //  matrix.print(4444)  = "4444"
  //  matrix.print(0555)  = " 365"  // ????
  //  matrix.print(0055)  = "  45"  // ????
  delay(5000);
  
  // print a floating point number
  matrix.print(1.818);  
  matrix.writeDisplay();
  //  matrix.print(12.34) = "12.34"
  //  matrix.print(1.234) = " 1.23"
  //  matrix.print(0.001) = "    0"
  //  matrix.print(0.020) = " 0.02"
  //  matrix.print(0.033) = " 0.03"
  //  matrix.print(0.4)   = " 0.40"
  //  matrix.print(0.50)  = " 0.50"
  //  matrix.print(0.66)  = " 0.66"  
  //  matrix.print(0.717) = " 0.72"   last extra digit rounds 0.717 to 0.82
  //  matrix.print(1.818) = " 1.82"   last extra digit rounds 1.818 to 1.82
  delay(5000);
  
  // Demonstrate writing using method .writeDigitNum()
  // .writeDigitNum(location, number, bDrawDecimalPoint)
  // location (from left to right): 
  //  [0][1][2][3][4]
  //  [#][#][:][#][#]
  // number 0,1,2,...8,9
  // 
  // Display "0.123"
  matrix.writeDigitNum(0, 0, true);
  matrix.writeDigitNum(1, 1, false);
  matrix.writeDigitNum(3, 2, false);
  matrix.writeDigitNum(4, 3, false);
  matrix.writeDisplay();
  delay(5000);
  // Display "15:10"  (no blinking display)
  matrix.writeDigitNum(0, 1, false);
  matrix.writeDigitNum(1, 5, false);
  matrix.drawColon(true);
  matrix.writeDigitNum(3, 1, false);
  matrix.writeDigitNum(4, 0, false);
  matrix.setBrightness(0);  // 0 = lowest, 15 = brightest (default)
  matrix.writeDisplay();
  delay(5000);
  // Display "24:00"  (blink entire display, max brightness)
  // Note: Cannot display " 1:05" with .writeDigitNum()
  matrix.writeDigitNum(0, 2, false);
  matrix.writeDigitNum(1, 4, false);
  matrix.drawColon(true);
  matrix.writeDigitNum(3, 0, false);
  matrix.writeDigitNum(4, 0, false);
  matrix.blinkRate(2);  // 0 = no blinking, 1,2,3 for blinking (fast .. slow)
  matrix.setBrightness(15);
  matrix.writeDisplay();
  delay(5000);

  //  Display "23:45" with blinking colon (every second), medium brightness, no blinking display
  matrix.setBrightness(7);  
  matrix.blinkRate(0);
  boolean bDrawColon = false;
  for (uint16_t counter = 0; counter < 6; counter ++) {
    matrix.writeDigitNum(0, 2, false);
    matrix.writeDigitNum(1, 3, false);
    matrix.drawColon(bDrawColon);
    matrix.writeDigitNum(3, 4, false);
    matrix.writeDigitNum(4, 5, false);
    matrix.writeDisplay();
    if (bDrawColon == true) {
      bDrawColon = false;
    } else {
      bDrawColon = true;
    }
    matrix.writeDisplay();
    delay(1000);
  } // for
  
  // Paint one LED per row. 
  // The HT16K33 internal memory looks like a 8x16 bit matrix (8 rows, 16 columns)
  matrix.setBrightness(7);  
  matrix.blinkRate(0);
  uint8_t counter = 0;
  for (uint8_t j=0; j<16*3; j++) {
    for (uint8_t i=0; i<8; i++) {
      // draw a diagonal row of pixels
      matrix.displaybuffer[i] = _BV((counter+i) % 16) | _BV((counter+i+8) % 16)  ;
    }
    matrix.writeDisplay();
    delay(100);
    counter++;
    if (counter >= 16) counter = 0;  
  } // j

} // FourDig7SegLedMatrixDispDemo

////////////////////////////////////////////////////////////////////////////////////////////

Code fragment that is handy


void setup() {
  Serial.begin(115200);
  while (!Serial) {
    delay(1);
  }
  Serial.println("\nSerial ready");

  //  Adafruit 0.56" 4-Digit LED Display
  matrix.begin(0x70);
  matrix.setBrightness(7);  
  matrix.blinkRate(0);
  //  Adafruit 0.56" 4-Digit LED Display
  // paint one LED per row. The HT16K33 internal memory looks like a 8x16 bit matrix (8 rows, 16 columns)
  uint8_t counter = 0;
  for (uint8_t j=0; j<16*3; j++) {
    for (uint8_t i=0; i<8; i++) {
      // draw a diagonal row of pixels
      matrix.displaybuffer[i] = _BV((counter+i) % 16) | _BV((counter+i+8) % 16)  ;
    }
    // write the changes we just made to the display
    matrix.writeDisplay();
    delay(1);
    counter++;
    if (counter >= 16) {
      counter = 0;  
    }
  } // j
  matrix.print(11111);  // prints "----"
  matrix.writeDisplay();


} // setup()

 


Do you need help developing or customizing a IoT product for your needs?   Send me an email requesting a free one hour phone / web share consultation.  

 

The information presented on this website is for the author's use only.   Use of this information by anyone other than the author is offered as guidelines and non-professional advice only.   No liability is assumed by the author or this web site.