New to programming - need to convert a number in to an array of 1s

Hello,

I have a project that will read a button press, and decrement an integer. I want that to read out on an LED bar graph, that is connected to a 7219 chip. I have the basic program working by brute force.

The basis is this:

I start with a number 60, and will need to light up all 60 bars on my LED bar graph. The button press will decrement the counter to 50, and turn off the 60th LED in the graph - and so-on until it is at zero.

I have managed to get the concept to work by connecting the LEDs as if they were an 8x8 matrix (missing the last 4 since there are only 60 of them) and using a function in the LEDcontrol library that turns the LEDs in each row of the maxtix using a byte that contains a 1 for each led you want on.

Example
Counter = 60

The associated array is a byte and looks like this

byte(8) = {D11111111,D11111111, D11111111, D11111111, D11111111, D11111111, D11111111, D11110000}

Counter = 59

Array byte(8) = {D11111111,D11111111, D11111111, D11111111, D11111111, D11111111, D11111111, D11100000}

Note there is one additional zero, or unlit LED in the second example.

Its all working and displaying as I want it to. THe thing I need help with is a smarter way to define the automatically based on the number of the counter. Currently I hard coded a few of the numbers and used and If function to call the correct one for the display based on the counter number. I don't want to do that 50 more times!

Is there a function I can use to automatically make the associated matrix of 1s based on just the counter value? It would greatly simplify the entire code.

Thanks,
Brian

PS: I know nothing about programming. All i've done so far is hack together a few example codes to get what I want going. I'm learning, but slowly so make sure to explain this to me like I'm a total noob.

I see no need for that :wink: Just loop over all 60 leds and turn it on if the counter is >= that led number, otherwise turn it off :slight_smile: Unless the library you use really needs that, otherwise it's a bit of a Ruby Goldberg machine. But then, the same "loop over all" can be applied to the array (of bytes) :slight_smile:

Can you show use a schematic? Hand drawing is proffered over a Fritzing mess :slight_smile:

And can you show us the code you have to control that bar graph at the moment? If you use a library, please link to it.

Thanks for the reply. There may totally be an easier way to do this. But I am not a programmer so that's why I'm asking!

Here is a link to the library:

https://playground.arduino.cc/Main/LedControl/#SingleMatrixControl

I based my initial attempts on the code in this tutorial, where you can see he defined an array with the 0s and 1s for each row necessary to draw his shapes. Still works, only my LED matrix is arranged like a Line.

Here is my current code. There are some extra variables in there for stuff I was setting up to do in the future, once I get this bar graph thing figured out.

/*
 Created by Rui Santos
 
 All the resources for this project:
 http://randomnerdtutorials.com/
*/

#include <LedControl.h>
#include <binary.h>
#include <IoAbstraction.h>
/*
 DIN connects to pin 12
 CLK connects to pin 11
 CS connects to pin 10 
*/
LedControl lc=LedControl(12,11,10,1);

// delay time between faces
unsigned long delaytime=50;

// happy face
//byte hf[8]= {B00111100,B01000010,B10100101,B10000001,B10100101,B10011001,B01000010,B00111100};
// neutral face
//byte nf[8]={B00111100, B01000010,B10100101,B10000001,B10111101,B10000001,B01000010,B00111100};
// sad face
//byte sf[8]= {B00111100,B01000010,B10100101,B10000001,B10011001,B10100101,B01000010,B00111100};
//line of 10
//byte ln[8] = {B11111111,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000};

byte ten[8] = {B11111111,B11000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000};
byte nine[8] = {B11111111,B10000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000};
byte eight[8] = {B11111111,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000};
byte seven[8] = {B11111110,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000};
byte six[8] = {B11111100,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000};
byte five[8] = {B11111000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000};
byte four[8] = {B11110000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000};
byte three[8] = {B11100000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000};
byte two[8] = {B11000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000};
byte one[8] = {B10000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000};
byte zero[8] = {B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000};

const int triggerpin = 2; //pin the button acting as the trigger is attached to
int triggerpushcounter = 300; //counter for the number of button presses
int buttonstate = 0; // current state of the button 
int lastbuttonstate = 0;  //last state of the button.
int magcount = 10;

void setup() {
  lc.shutdown(0,false);
  // Set brightness to a medium value
  lc.setIntensity(0,8);
  // Clear the display
  lc.clearDisplay(0);  

   // initialize serial communication:
  Serial.begin(9600);

  pinMode(2, INPUT_PULLUP);
}

void loop(){
  
  buttoncount();
  drawFaces();
  }

  
void drawFaces(){
  // Display sad face
  if (magcount == 10){
    lc.setRow(0,0,ten[0]);
    lc.setRow(0,1,ten[1]);
    delay(delaytime);
  }
  if (magcount == 9){
    lc.setRow(0,0,nine[0]);
    lc.setRow(0,1,nine[1]);
    delay(delaytime);
  }
  if (magcount == 8){
    lc.setRow(0,0,eight[0]);
    lc.setRow(0,1,eight[1]);
    delay(delaytime);
  }
  if (magcount == 7){
    lc.setRow(0,0,seven[0]);
    delay(delaytime);
      }
  if (magcount == 6){
    lc.setRow(0,0,six[0]);
    delay(delaytime);
      }    
  if (magcount == 5){
    lc.setRow(0,0,five[0]);
    delay(delaytime);
      }    
  if (magcount == 4){
    lc.setRow(0,0,four[0]);
    delay(delaytime);
      }
  if (magcount == 3){
    lc.setRow(0,0,three[0]);
    delay(delaytime);
      }    
  if (magcount == 2){
    lc.setRow(0,0,two[0]);
    delay(delaytime);
      } 
  if (magcount == 1){
    lc.setRow(0,0,one[0]);
    delay(delaytime);
      }
  if (magcount == 0){
    lc.setRow(0,0,zero[0]);
    delay(delaytime);
      }
      
  //lc.setRow(0,0,sf[0]);
//  lc.setRow(0,1,sf[1]);
//  lc.setRow(0,2,sf[2]);
//  lc.setRow(0,3,sf[3]);
//  lc.setRow(0,4,sf[4]);
//  lc.setRow(0,5,sf[5]);
//  lc.setRow(0,6,sf[6]);
//  lc.setRow(0,7,sf[7]);
//  delay(delaytime);
//  
//  // Display neutral face
//  lc.setRow(0,0,nf[0]);
//  lc.setRow(0,1,nf[1]);
//  lc.setRow(0,2,nf[2]);
//  lc.setRow(0,3,nf[3]);
//  lc.setRow(0,4,nf[4]);
//  lc.setRow(0,5,nf[5]);
//  lc.setRow(0,6,nf[6]);
//  lc.setRow(0,7,nf[7]);
//  delay(delaytime);
//  
//  // Display happy face
//  lc.setRow(0,0,hf[0]);
//  lc.setRow(0,1,hf[1]);
//  lc.setRow(0,2,hf[2]);
//  lc.setRow(0,3,hf[3]);
//  lc.setRow(0,4,hf[4]);
//  lc.setRow(0,5,hf[5]);
//  lc.setRow(0,6,hf[6]);
//  lc.setRow(0,7,hf[7]);
//  delay(delaytime);
//}
}

void buttoncount() {
  // read the pushbutton input pin:
  buttonstate = digitalRead(triggerpin);

  // compare the buttonState to its previous state
 if (buttonstate != lastbuttonstate) {
    // if the state has changed, increment the counter
    if (buttonstate == HIGH) {
      // if the current state is HIGH then the button went from off to on:
     magcount--;
     if (magcount < 1) magcount = 10;
      Serial.println("on");
      Serial.print("number of button pushes: ");
      Serial.println(magcount);
    } else {
      // if the current state is LOW then the button went from on to off:
      Serial.println("off");
   }
    // Delay a little bit to avoid bouncing
    delay(50);
 
  // save the current state as the last state, for next time through the loop
  lastbuttonstate = buttonstate;
 }
}

HEre is a really rough sketch. The hardware is working. Just trying to simplify the code. There are not enough pins on the arduino to manage all those LEDs, so using the 7219 driver chip.

Thanks,

Brian

I looked through the library again, and I see a function that can set different LEDs individually, but I'm still thinking that would be more if statements to loop over than if I could get a function to create the proper byte array based on the INT number. Then I could feed that array directly in to the display portion of the loop and it would always be correct for the current number in the counter.

What do you guys think?

-Brian

Now don't expect too much as I'm still very much a novice and according to at least one medical practitioner, a "halfwit". but I think the following code demonstrates a function that does what you want...

void setup() {

  Serial.begin(115200);
  while (!Serial); // leonardo

  byte Array[8];
  int Counter = 59;
  intToArr(Counter , Array, sizeof( Array ) / sizeof( Array[0] ) );

  for ( int a = 0; a < sizeof( Array ) / sizeof( Array[0] ); a++ )
  {
    Serial.println(Array[a], BIN );
    Serial.println();
  }

}

void loop() {}

void intToArr( int val , byte arr[], size_t arrSize )
{
  memset( arr, 0, arrSize );
  uint8_t bytes = val / 8;
  uint8_t bits  = val % 8;
  for ( int a = 0; a < bytes; a++)
  {
    arr[a] = 255;
  }
  for ( int a = 0, b = 7; a < bits; a++)
  {
    arr[bytes] |= 1UL << b--;
  }
}

Thanks! I will have to check this out this weekend.

-Brian