Converting hex to binary for 7 segments display

Hi! I'm working displaying numbers on 7 segment LED display by multiplexing. I want to convert hex values to binary for the 7 segments. I have an idea as to how to do this in other languages like Java but am unsure as to how to go about this using C/C++ in Arduino. I would also like to know if there's a way to display the segments with just the hex values. All help is much appreciated! Below is my code:

Array of hex values to be converted to binary:

char digitPatternsHex[PATTERN_COUNT][2] = { "3F", "06", "5B", "4F", "6E", "6B", "7D", "07", "7F", "6F", "00" };

What I have so far:

void hexaToBinaryArray(char[][] hexaArray){

  char digitPatterns[PATTERN_COUNT][SEGMENT_COUNT];
  
  for(int i=0; i<PATTERN_COUNT; i++){
    for(int j=1; j>=0;j--){ 
      switch(char[i][j]){ //3F  =  0111111

        case '0':
          
      }
    }
  }
}

UPDATE:

Thanks for all the help! I got it working using bitRead() :). My full code:

#define PATTERN_COUNT 11 //number of segment patterns, 0-9 and all off
#define SEGMENT_COUNT 7  //how many segments I'm controlling
#define DIGIT_COUNT  4   //how many digits I'm controlling



            //                    A,B,C,D,E,F,G
int segmentPins[SEGMENT_COUNT] = {2,3,4,5,6,7,8};

//the pins for each digit
int digitPins[] = { 9, 10, 11, 12 };
//                                                      0      1     2    3      4     5     6     7    8     9     OFF
byte digitPatternsHex[PATTERN_COUNT] = { 0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F, 0x00 };

//counter
int counter = 0;

void setup(){
    Serial.begin(9600);
    //init segment pins to output
    for(int thisPin=0; thisPin<SEGMENT_COUNT; thisPin++){
      pinMode(segmentPins[thisPin], OUTPUT);
    }

    //init digit pins to output
    for(int thisPin=0; thisPin<DIGIT_COUNT; thisPin++){
      pinMode(digitPins[thisPin], OUTPUT);
    }
}
 
//turn all digits off, HIGH because common cathode
void allDigitsOff(){
  for(int thisPin = 0; thisPin < DIGIT_COUNT; thisPin++){
    digitalWrite(digitPins[thisPin], HIGH);
  }
}

//turn specific digit on
void digitOn(int digitNum){
  
  digitalWrite(digitPins[digitNum], LOW);
  
  delay(2);
}


void setPattern(int pattern){
  allDigitsOff(); 
  
  //data pins, 8bits
    for(int thisPin=0; thisPin<SEGMENT_COUNT; thisPin++){
      if(bitRead(digitPatternsHex[pattern], thisPin) == 1){
        digitalWrite(segmentPins[thisPin], HIGH);
      }else{
        digitalWrite(segmentPins[thisPin], LOW);
      }
    }
  
}

void showNumber(int currentNumber){
  
  //display digit from right to left
  int digitInFront = currentNumber/10;
  for(int currentDigit = 0; currentDigit < DIGIT_COUNT; currentDigit++){
    
    //get number in the ones place
    int number = currentNumber % 10; //5
    
    currentNumber /= 10;

    setPattern(number); 
    
    digitOn(currentDigit);
        
  }
}

void loop(){
  
//return first 2 digits of ms, 1 sec = 1000 millisec, 1.5 sec = 1500 millisec
  
  int currentNumber = (millis()/1000); 
  
  showNumber(currentNumber);
}

You are using strings - use integers:

byte digitPatternsHex[PATTERN_COUNT] = { 0x3F, 0x06, 0x5B, 0x4F, 0x6E, 0x6B, 0x7D, 0x07, 0x7F, 0x6F, 0x00 };

Then its already in binary inside the array.

Thanks for letting me know! How do I then use these hex values to simultaneously send to all 7 pins (segments)? Here's what I have currently to light up each individual pin according to 1 or 0 inside an array containing binary values:

int digitPatternsBin[PATTERN_COUNT][SEGMENT_COUNT] = {
    { 0,1,1,1,1,1,1 }, //0
    { 0,0,0,0,1,1,0 }, //1
    { 1,0,1,1,0,1,1 }, //2
    { 1,0,0,1,1,1,1 }, //3
    { 1,1,0,0,1,1,0 }, //4
    { 1,1,0,1,1,0,1 }, //5
    { 1,1,1,1,1,0,1 }, //6
    { 0,0,0,0,1,1,1 }, //7
    { 1,1,1,1,1,1,1 }, //8
    { 1,1,0,1,1,1,1 }, //9
    { 0,0,0,0,0,0,0 }, //OFF
};
void setPattern(int pattern){
  allDigitsOff(); 

  //data pins, 8bits
  for(int thisPin=0; thisPin<SEGMENT_COUNT; thisPin++){
    digitalWrite(segmentPins[thisPin], digitPatternsBin[pattern][thisPin);
  }
}

Why didn't you do what MarkT told you but something different without explaining why?

And then, just have a look at bitwise operators in C :slight_smile: Or use Arduino functions like bitRead() and bitWrite().

Sorry about that. I did follow MarkT's code but I wasn't sure as to how to incorporate it into what I wanted to do so I posted what I currently have and hope that someone could help me change it using hex values. Thanks for the tip, I will look into those!

Thing to notice is that decimal, octal, hexadecimal, ASCII, binary etc are all just representations. In the end it's all stored binary. It's just like language. 1, one, één, eins, un, une, uno, bir, jeden etc all mean the same thing. As long as you tell what kind it is. So 97, 0x61, 0140, 'a', 0b1100001 all mean the same thing :slight_smile:

Just a note on the original code in the opening post

"3F" is three characters, not two. You need to cater for the terminating nul character.

Just for future reference.

@phnguyen0912

Tell us very clearly, what you want!

Do you want to say as follows?

1. I have a 4-digit cc(common cathode)-type 7-segment multiplexed display unit, and it is connected (assume) in the following way with the Arduino UNO:

Figure-1: 4-digit cc (common cathode)-type multiplxed display unit.

2. I have got an 8-bit unsigned binary number (say, 11101100).

3. I want to show my binary number as EC (compact form of Binary) on DP0 - DP1 positions of the display unit of Fig-1.

4. I also want to show the decimal value (236) of my binary number on DP0 - DP2 positions of the display unit.

5. Now, I want assistance to perform the above tasks.

//------------------------------------------------------------------------------------------------------------

@markT has advised you to start from the following array, which in fact is a Look Up Table (Digit vs cc-code). Start from here.

byte digitPatternsHex[PATTERN_COUNT] = { 0x3F, 0x06, 0x5B, 0x4F, 0x6E, 0x6B, 0x7D, 0x07, 0x7F, 0x6F, 0x00 };

If you want to see EC on the display, you need to enter the cc-codes for these digits into the array. It is better that you enter cc-codes for the digits A, B, C, D, E, and F; you will be able to see any digits (decimal and hex as well on the display.

The new array is:

byte digitPatternsHex[PATTERN_COUNT] = {

0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F, 0x77, 0x7C, 0x39, 0x5E, 0x79, 0x71, 0x00
                                                         };

Do we need to enter the null character exclusively? I think the null character is automatically inserted when the array is created.

//--------------------------------------------------------------------------------------------------------------

To see E on DP0 position, you can execute the following codes:

If you face problems to upload the sketch, please momentarily disconnect the PD0 and PD1 lines form the display unit. After uploading connect them back.

The current limiting resistors are not shown for simplicity. Please connect 220- 680 ohm resistors in series with each of the segment lines. If the circuit operation is for a short period, the resistors could be omitted.

//set the directions of the IO lines (PD7 - PD0 and PB3 - PB0) as needed
byte x = 0xEC;
x = x>>4;     // x = 0E
byte y = digitPatternsHex[x];  // y = 0x79 
PORTD = y;
PORTB = 0b111110;   // E has appeared on DP0 position.

//--------------------------------------------------------------------------------------------------------------

Moderator edit: CODE TAGS

GolamMostafa:
Do we need to enter the null character exclusively? I think the null character is automatically inserted when the array is created.

No it isn't, you are probably thinking of constant text strings.

No it isn't, you are probably thinking of constant text strings.

You are right!

The results of the following executable codes support your statement.

byte myAr[] = {0x41, 0x32};
byte Ar[] = "AB";
Serial.println(sizeof(myAr), DEC);   //shows: 2
Serial.println(sizeof(Ar), DEC);       //shows: 3