Seven segment neopixel display with scale

Hello everyone!

I recent built my first 7 segment display using a neopixel strip. I have 3 digits working with 4 leds per segment. I have successfully run example code to display digits counting up, down, and display of numbers.

Next I built a scale using HX711 and 5kg load cell. After testing I still cant get Arduino to read and display input to digits to the 7 segment display. For testing I bought a cheap HX711 with seven segment 4 digit display. It works perfectly with the scale and 3 digits (I calibrated it to display ounces and deleted decimal points). It's not Arduino controlled but displays the perfect numbers for my project.

Now I am trying to figure out how to combine both. Ideally my 7 segment display would show the value from my HX711, but large scale.

#include <Adafruit_NeoPixel.h>
#include <HX711.h>

#define PIXELS_PER_SEGMENT  4     // Number of LEDs in each Segment
#define PIXELS_DIGITS       3     // Number of connected Digits 
#define PIXELS_PIN          6     // GPIO Pin

#define HX711_DOUT 2
#define HX711_SCK 3

Adafruit_NeoPixel strip = Adafruit_NeoPixel(PIXELS_PER_SEGMENT * 7 * PIXELS_DIGITS, PIXELS_PIN, NEO_GRB + NEO_KHZ800);
HX711 scale;

// Define variables for weight and previous weight
float weight = 0.0;
float prevWeight = 0.0;

// Define function to convert weight to 7 segment display values
void convertTo7Seg(float weight) {
  // Define array to store 7 segment display values
  int segValues[7];

  // Convert weight to integer
  int weightInt = (int)weight;

  // Loop through each digit of weight
  for (int i = 0; i < 7; i++) {
    // Get the last digit of weight
    int digit = weightInt % 10;

//Pixel Arrangement
/*
          a
        f   b
          g
        e   c
          d
*/

// Segment array
byte segments[7] = {
  //abcdefg
  0b0000001,     // Segment g
  0b0000100,     // Segment e
  0b0001000,     // Segment d
  0b0010000,     // Segment c
  0b0100000,     // Segment b
  0b1000000,     // Segment a
  0b0000010     // Segment f
};

//Digits array
byte digits[10] = {
  //abcdefg
  0b1111110,     // 0
  0b0110000,     // 1
  0b1101101,     // 2
  0b1111001,     // 3
  0b0110011,     // 4
  0b1011011,     // 5
  0b1011111,     // 6
  0b1110000,     // 7
  0b1111111,     // 8
  0b1110011      // 9
};

//Clear all the Pixels
void clearDisplay() {
  for (int i = 0; i < strip.numPixels(); i++) {
    strip.setPixelColor(i, strip.Color(0, 0, 0));
  }
  strip.show();
}

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

void loop() {
  disp_Digits(1000);            // Show digits from 0-9              (DelayTime)
 //disp_CountUP(500, 450);       // Count numbers in Ascending order  (NUMBER, DelayTime)
  //disp_CountUP2(999, 450); 
}



void disp_Digits(int wait) {
  clearDisplay();
  for (int i = 0; i < 10; i++) {
    for (int n = 0; n < PIXELS_DIGITS; n++) {
      writeDigit(n, i);
    }
    strip.show();
    delay(wait);
  }
}

void disp_CountUP(int num, int wait) {
  clearDisplay();
  for (int i = 0; i <= num; i++) {
    writeDigit(0, (i / 100) % 10);
    writeDigit(1, (i / 10) % 10);
    writeDigit(2, (i / 1) % 10);
    strip.show();
    delay(wait);
  }
}

void disp_CountUP2(int num, int wait) {
  clearDisplay();
  for (int i = 0; i <= num; i++) {
    writeDigit(0, (i / 100) % 10);
    writeDigit(1, (i / 10) % 10);
    writeDigit(2, (i / 1) % 10);
    strip.show();
    delay(wait);
  }
}





void writeDigit(int index, int val) {
  byte digit = digits[val];
  for (int i = 6; i >= 0; i--) {
    int offset = index * (PIXELS_PER_SEGMENT * 7) + i * PIXELS_PER_SEGMENT;
    uint32_t color;
    if (digit & 0x01 != 0) {
      if (val == 1) color = strip.Color(255, 0,  0);
      if (val == 2) color = strip.Color(255, 0, 0);
      if (val == 3) color = strip.Color(255, 0, 0);
      if (val == 4) color = strip.Color(255, 0,  0);
      if (val == 5) color = strip.Color(255, 0, 0);
      if (val == 6) color = strip.Color(255,  0, 0);
      if (val == 7) color = strip.Color(255, 0, 0);
      if (val == 8) color = strip.Color(255, 0, 0);
      if (val == 9) color = strip.Color(255, 0, 0);
      if (val == 0) color = strip.Color(255, 0, 0);
    }
    else
      color = strip.Color(0, 0, 0);

    for (int j = offset; j < offset + PIXELS_PER_SEGMENT; j++) {
      strip.setPixelColor(j, color);
    }
    digit = digit >> 1;
  }
}

void writeSegment(int index, int val) {
  byte seg = segments[val];
  for (int i = 6; i >= 0; i--) {
    int offset = index * (PIXELS_PER_SEGMENT * 7) + i * PIXELS_PER_SEGMENT;
    uint32_t color;
    if (seg & 0x01 != 0) {
      if (val == 0) color = strip.Color(50, 0, 0);
      if (val == 1) color = strip.Color(0, 50, 50);
      if (val == 2) color = strip.Color(0, 50, 0);
      if (val == 3) color = strip.Color(50, 0, 50);
      if (val == 4) color = strip.Color(50, 50, 50);
      if (val == 5) color = strip.Color(0, 0, 50);
      if (val == 6) color = strip.Color(50, 50, 0);
    }
    else
      color = strip.Color(0, 0, 0);

    for (int j = offset; j < offset + PIXELS_PER_SEGMENT; j++) {
      strip.setPixelColor(j, color);
    }
    seg = seg >> 1;
  }
}

I have tested different examples but cant figure out how to combine everything.

Very confusing, nowhere is the HX711 used. The code also does not compile.

... but in practice it displays.... ?

I think you may be missing something important here.

With your small 3 digit 7 segment display, the display must be multiplexed because only one digit can be illuminated at any instant. So the 3 digits have to be constantly re-drawn, one after the other, over and over, at rapid rate. Otherwise it would simply freeze with only one digit lit.

But your Neopixel display needs no multiplexing. You can draw all 3 digits, once, and then you don't need to draw anything again until the value changes.

Your code seems to be re-drawing the digits over and over, and I imagine this will cause them to flicker very badly. It's also making the code much more complex than it needs to be.

Is this for your small 7-seg display, or the Neopixel display? Or are they the same?

When I built my Neopixel 7-seg clock, I chose a different pixel arrangement, to make wiring easier:

//Pixel Arrangement
/*
          b
        a   c
          d
        e   g
          f
*/

Did you do anything similar?

It is for my Neopixel display. I used this pixel arrangement based off the example I found. I could rewire it to the same as yours if it will help make things more simple. Could you possibly share the code for the clock you made? it would be helpful and I want to make one now. Super cool!

Here is the latest version:

#include "HX711.h"
#include <Adafruit_NeoPixel.h>

HX711 scale;

const int buttonPin = 5;     // the number of the pushbutton pin
int buttonState = 0;         // variable for reading the pushbutton status

#define PIXELS_PER_SEGMENT  4     // Number of LEDs in each Segment
#define PIXELS_DIGITS       3     // Number of connected Digits 
#define PIXELS_PIN          2     // GPIO Pin
//  scale pins
uint8_t dataPin = 4;
uint8_t clockPin = 5;

//scale
float w1, w2, previous = 0;

Adafruit_NeoPixel strip = Adafruit_NeoPixel(PIXELS_PER_SEGMENT * 7 * PIXELS_DIGITS, PIXELS_PIN, NEO_GRB + NEO_KHZ800);

//Pixel Arrangement
/*
          a
        f   b
          g
        e   c
          d
*/

// Segment array
byte segments[7] = {
  //abcdefg
  0b0000001,     // Segment g
  0b0000100,     // Segment e
  0b0001000,     // Segment d
  0b0010000,     // Segment c
  0b0100000,     // Segment b
  0b1000000,     // Segment a
  0b0000010     // Segment f
};

//Digits array
byte digits[10] = {
  //abcdefg
  0b1111110,     // 0
  0b0110000,     // 1
  0b1101101,     // 2
  0b1111001,     // 3
  0b0110011,     // 4
  0b1011011,     // 5
  0b1011111,     // 6
  0b1110000,     // 7
  0b1111111,     // 8
  0b1110011      // 9
};

//Clear all the Pixels (possibly use with tare to reset leds)
void clearDisplay() {
  for (int i = 0; i < strip.numPixels(); i++) {
    strip.setPixelColor(i, strip.Color(0, 0, 0));
  }
  strip.show();
}

void setup() {

  // initialize the LED display pin as an output:
  pinMode(PIXELS_PIN, OUTPUT);
  // initialize the pushbutton pin as an input:
  pinMode(buttonPin, INPUT);
  
  strip.begin();

  Serial.begin(115200);
  Serial.println(__FILE__);
  Serial.print("HX711_LIB_VERSION: ");
  Serial.println(HX711_LIB_VERSION);
  Serial.println();

  scale.begin(dataPin, clockPin);

  Serial.print("UNITS: ");
  Serial.println(scale.get_units(10));

  //  load cell factor 20 KG
  //  scale.set_scale(127.15);
  //  load cell factor 5 KG
  scale.set_scale(420.0983);       //calibrate scale
  scale.tare();

  Serial.print("UNITS: ");
  Serial.println(scale.get_units(10));
}

void loop() {

  // Tare button
  // read the state of the pushbutton value:
  buttonState = digitalRead(buttonPin);

  // check if the pushbutton is pressed. If it is, the buttonState is HIGH:
  if (buttonState == HIGH) {
    // tare display to 000:
    //void clearDisplay()
    //scale.tare();
  } else {
    // do nothing
  }
  
  // scale
  
  //  read until stable
  w1 = scale.get_units(10);
  delay(100);
  w2 = scale.get_units();
  while (abs(w1 - w2) > 10)
  {
     w1 = w2;
     w2 = scale.get_units();
     delay(100);
  }

  Serial.print("UNITS: ");
  Serial.print(w1);
  if (w1 == 0)
  {
    Serial.println();
  }
  else
  {
    Serial.print("\t\tDELTA: ");
    Serial.println(w1 - previous);
    previous = w1;
  }
  delay(100);


  //Neopixel strip (change for display)
  
  disp_Digits(1000);            // Show digits from 0-9              (DelayTime)
 //disp_CountUP(500, 450);       // Count numbers in Ascending order  (NUMBER, DelayTime)
 //disp_CountDOWN(500, 250);     // Count numbers in Descending order (NUMBER, DelayTime)
}

void disp_Digits(int wait) {
  clearDisplay();
  for (int i = 0; i < 10; i++) {
    for (int n = 0; n < PIXELS_DIGITS; n++) {
      writeDigit(n, i);
    }
    strip.show();
    delay(wait);
  }
}

void disp_CountUP(int num, int wait) {
  clearDisplay();
  for (int i = 0; i <= num; i++) {
    writeDigit(0, (i / 100) % 10);
    writeDigit(1, (i / 10) % 10);
    writeDigit(2, (i / 1) % 10);
    strip.show();
    delay(wait);
  }
}

void disp_CountDOWN(int num, int wait) {
  clearDisplay();
  for (int i = num; i >= 0; i--) {
    writeDigit(0, (i / 100) % 10);
    writeDigit(1, (i / 10) % 10);
    writeDigit(2, (i / 1) % 10);
    strip.show();
    delay(wait);
  }
}


void writeDigit(int index, int val) {
  byte digit = digits[val];
  for (int i = 6; i >= 0; i--) {
    int offset = index * (PIXELS_PER_SEGMENT * 7) + i * PIXELS_PER_SEGMENT;
    uint32_t color;
    if (digit & 0x01 != 0) {
      if (val == 1) color = strip.Color(255, 0,  0);
      if (val == 2) color = strip.Color(255, 0, 0);
      if (val == 3) color = strip.Color(255, 0, 0);
      if (val == 4) color = strip.Color(255, 0,  0);
      if (val == 5) color = strip.Color(255, 0, 0);
      if (val == 6) color = strip.Color(255,  0, 0);
      if (val == 7) color = strip.Color(255, 0, 0);
      if (val == 8) color = strip.Color(255, 0, 0);
      if (val == 9) color = strip.Color(255, 0, 0);
      if (val == 0) color = strip.Color(255, 0, 0);
    }
    else
      color = strip.Color(0, 0, 0);

    for (int j = offset; j < offset + PIXELS_PER_SEGMENT; j++) {
      strip.setPixelColor(j, color);
    }
    digit = digit >> 1;
  }
}

void writeSegment(int index, int val) {
  byte seg = segments[val];
  for (int i = 6; i >= 0; i--) {
    int offset = index * (PIXELS_PER_SEGMENT * 7) + i * PIXELS_PER_SEGMENT;
    uint32_t color;
    if (seg & 0x01 != 0) {
      if (val == 0) color = strip.Color(50, 0, 0);
      if (val == 1) color = strip.Color(0, 50, 50);
      if (val == 2) color = strip.Color(0, 50, 0);
      if (val == 3) color = strip.Color(50, 0, 50);
      if (val == 4) color = strip.Color(50, 50, 50);
      if (val == 5) color = strip.Color(0, 0, 50);
      if (val == 6) color = strip.Color(50, 50, 0);
    }
    else
      color = strip.Color(0, 0, 0);

    for (int j = offset; j < offset + PIXELS_PER_SEGMENT; j++) {
      strip.setPixelColor(j, color);
    }
    seg = seg >> 1;
  }
}

Yes, I want to show the value of the scale on the display.

If "HIGH" (do nothing) else (do nothing).

Like this?

*  * **** ****
*  * *    *
*  * *    *
**** **** ****
   * *       *
   * *       *
**** **** ****

I know that, but that's not what I asked.