LED Binary Converter

So I decided to make an LED binary converter, and basically it takes a number as input and translates it to a string, which is then used to decide which LEDs to turn on. Here is the code:

int Led1 = 2;
int Led2 = 3;
int Led4 = 4;
int Led8 = 5;
int Led16 = 6;
int Led32 = 7;
int Led64 = 8;
int InputNumber = 0;
char BinaryNumber[8];

void setup()
{
  pinMode(Led1, OUTPUT);
  pinMode(Led2, OUTPUT);
  pinMode(Led4, OUTPUT);
  pinMode(Led8, OUTPUT);
  pinMode(Led16, OUTPUT);
  pinMode(Led32, OUTPUT);
  pinMode(Led64, OUTPUT);
  Serial.begin(9600);
}

void convert()
{
  itoa(InputNumber, BinaryNumber, 2);
  Serial.println(BinaryNumber);
}

void loop()
{
  InputNumber = Serial.read();
  if(InputNumber > 0)
  {
//    InputNumber += 51;
    Serial.println(InputNumber);
    convert();
    InputNumber = 0;
    Serial.end();
  }
  int i, j = 7;
  int x = strlen(BinaryNumber) - 8;
  for(i = 0; i < strlen(BinaryNumber); i++)
  {
    if(BinaryNumber[j] == '1')
    {
      digitalWrite(i + 2, HIGH);
    }
    j--;
  }
}

I have two main problems. First of all, I am not sure exactly how to get the LEDs to turn on correctly. In this configuration of the for loop, I get problems where the wrong LEDs turn on. I tried to do it backwards as well, where I start at the end of BinaryNumber and the beginning of the LEDs (in terms of the pin) but that did not work either. My other problem is that no matter what I enter, the computer thinks I entered 49. However, if I enter 49, it thinks I entered 52. Any help would be appreciated!

You have here a great mess! I'm sorry to say that.

You need to:
1 receive the number;
2 convert the ASCII to decimal number;
3 "convert" it to BINARY;
4 show that binary number.

I don't see where you do the step 2 and 3. Then you do this thing:

void convert()
{
  itoa(InputNumber, BinaryNumber, 2);
  Serial.println(BinaryNumber);
}

that I don't understand what you're trying to do with it. itoa() function converts integer to strings. But you need to do the opposite, convert string (or character in this case) to integer.

The other day, I wrote this code:

void showBits (byte number) {
   byte showBit;
   
   for (int i=0; i<8; i++) {
      showBit = ((number<<i) & 0x80) ? 1 : 0;
      
      Serial.print (showBit);
      
      if (i == 3) {
         Serial.print (" ");
      } else if (i == 7) {
         Serial.print ("\n");
      }
   }
}

void setup()
{
  Serial.begin(9600);
}


void loop() {
  byte binary;

  if (Serial.available()) {
    binary = Serial.read() - '0';
    
    Serial.print ("Original \"decimal\" number: ");
    Serial.println (binary);
    
    Serial.print ("Binary: ");
    showBits (binary);
  }
}

that receives a number from 0 to 9 by serial and converts it to binary and send it back by serial. Can you change it for do what you want?

From what I understand you enter a string such as "11001101" and you want to break it into 8 bits, one bit for each LEDs. Here is how I would do it: C code - 12 lines - codepad

Also, the Serial object sends things a byte at a time, and you need to know when it has "arrived" for your use. You probably need to look at Serial.available() for use in your code. Next, once Serial.available() is greater than 0, I would use Serial. readBytesUntil() and look for the newline character ('\n') which indicates the user has pressed the Enter key and is done entering the number. If you look in the Examples --> Communications menu, you'll find examples that should be helpful.

In case this helps, here is the output of the Serial Monitor when I input several values. I entered 100, then 50, then 200, then 300.

100
1100100
104
1101000
101
1100101
102
1100110

I do not want the converted binary number to be an integer. I would rather it be a string. I used itoa because I wanted to convert the integer InputNumber to the string BinaryNumber in base two, which is why I added the 2 as an extra parameter.

Can you wire all LEDs onto the same port? So that you could simplify a lot by just setting the port value to the received number...

I think you don't read my post, or that I don't explain my self when I wrote:

luisilva:
(...)
that receives a number from 0 to 9 by serial
(...)

So, if you want numbers like 100, 200, etc, try this version:

const int ledPin = 13;      // the pin that the LED is attached to

unsigned int integer=0;
byte count=0;
byte chRead;
char stringBits[17];

boolean valueCompleted = false;


void blinkLED (void) {
   digitalWrite(ledPin, HIGH);
   delay(200);
   digitalWrite(ledPin, LOW);
}

void getBits (unsigned int number) {
   char showBit;
   
   for (int i=0; i<16; i++) {
      stringBits[i] = ((number<<i) & 0x8000) ? '1' : '0';
   }
   stringBits[16] = '\0';
}

void setup()
{
  Serial.begin(9600);

  pinMode(ledPin, OUTPUT);
}


void loop() {
  
  if (Serial.available()) {
    chRead = Serial.read();
    
    if (chRead == '\n') {
       valueCompleted = true;
       count = 0;
    }
    else if (chRead >= '0' && chRead <= '9' && count < 4) {
       integer = integer*10 + chRead - '0'; 
       count++;
    }
    
  }   
  if (valueCompleted == true) {
    valueCompleted = false;
    
    blinkLED();
    
    Serial.print ("Original \"decimal\" number: ");
    Serial.println (integer);
    
    Serial.print ("Binary: ");
    getBits (integer);
    Serial.println (stringBits);
    
    integer = 0;
  }
}

The result is:

Original "decimal" number: 100
Binary: 0000000001100100
Original "decimal" number: 200
Binary: 0000000011001000
Original "decimal" number: 300
Binary: 0000000100101100
Original "decimal" number: 400
Binary: 0000000110010000

I changed the program a bit, and it seems to have helped. To clear up all the issues caused by the serial input and such, I decided to just set the InputNumber to whatever I wanted in the code, so all I have to do is convert it to binary and I don't have to worry about reading it from the Serial Monitor. My only problem now is that the LEDs still light up incorrectly.
No matter what number I input, I get an LED configuration of this: (0 represents off, 1 represents on)
1011110
I tried several values, but it seems that the LEDs remain in this configuration, which happens to correspond to 94 in decimal.

The updated program:

int Led1 = 2;
int Led2 = 3;
int Led4 = 4;
int Led8 = 5;
int Led16 = 6;
int Led32 = 7;
int Led64 = 8;
int InputNumber = 100;
char BinaryNumber[8];

void setup()
{
  pinMode(Led1, OUTPUT);
  pinMode(Led2, OUTPUT);
  pinMode(Led4, OUTPUT);
  pinMode(Led8, OUTPUT);
  pinMode(Led16, OUTPUT);
  pinMode(Led32, OUTPUT);
  pinMode(Led64, OUTPUT);
  Serial.begin(9600);
}

void convert()
{
  itoa(InputNumber, BinaryNumber, BIN);
  Serial.println(BinaryNumber);
}

void loop()
{
  if(InputNumber > 0)
  {
    Serial.println(InputNumber);
    convert();
    InputNumber = 0;
    Serial.end();
  }
  int i, j = 7;
  int x = strlen(BinaryNumber) - 8;
  for(i = 0; i < strlen(BinaryNumber); i++)
  {
    if(BinaryNumber[i] == '1')
    {
      digitalWrite(j + 1, HIGH);
    }
    j--;
  }
}

luisilva, itoa with base 2 will do the same thing.

guix:
luisilva, itoa with base 2 will do the same thing.

OK. Thank you, but I didn't know that (we are always learning).
But it will work as long as he enter a integer, right? He is entering a "char", don't? It can work, but it will never do what he want.

Take a look at this short program for converting from decimal to binary.

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  
  int val = 300;
  char result[15];
  
  DecimalToBinary(val, result);
  Serial.println(result);
  
}

void DecimalToBinary(int val, char *result)
{
  int i = 0;
  int j;
  int temp;
  char buff[15];

  while (val > 0) {
    temp = val % 2;
    if (temp == 1)
      buff[i++] = '1';
    else
      buff[i++] = '0';
    val /= 2;
  }
  temp = 0;
  for (j = i - 1; j >= 0; j--) {      // Need this loop because the answer is "backwards"
    result[temp++] = buff[j];
  }
}

void loop() {
  // put your main code here, to run repeatedly:

}

I must agree with econjack in one thing: Version with pointers is better.

After the last version, a few more changes and you have what you want:

const int ledPin = 13;      // the pin that the LED is attached to
const int pins[] = {8, 7, 6, 5, 4, 3, 2};
/*
int Led1 = 2;
int Led2 = 3;
int Led4 = 4;
int Led8 = 5;
int Led16 = 6;
int Led32 = 7;
int Led64 = 8;
*/
unsigned int integer=0;
byte count=0;
byte chRead;

boolean valueCompleted = false;


void blinkLED (void) {
   digitalWrite(ledPin, HIGH);
   delay(200);
   digitalWrite(ledPin, LOW);
}

void getBits (unsigned int number, char *stringBits) {
   for (int i=0; i<16; i++) {
      *(stringBits++) = ((number<<i) & 0x8000) ? '1' : '0';
   }
   *stringBits= '\0';
}

void setup()
{
  Serial.begin(9600);

  pinMode(ledPin, OUTPUT);

  for (int i = 0; i < 7; i++) {
    pinMode(pins[i], INPUT);
  }
}


void loop() {
char stringBits[17];
  
  if (Serial.available()) {
    chRead = Serial.read();
    
    if (chRead == '\n') {
       valueCompleted = true;
       count = 0;
    }
    else if (chRead >= '0' && chRead <= '9' && count < 4) {
       integer = integer*10 + chRead - '0'; 
       count++;
    }
    
  }   
  if (valueCompleted == true) {
    valueCompleted = false;
    
    blinkLED();
    
    Serial.print ("Original \"decimal\" number: ");
    Serial.println (integer);
    
    Serial.print ("Binary: ");
    getBits (integer, stringBits);
    Serial.println (stringBits);

    for(i = 9; i < 16; i++) {
       if(stringBits[i] == '1') {
          digitalWrite(pins[i-9], HIGH);
       }
       else {
          digitalWrite(pins[i-9], LOW);
       }
    }    
    integer = 0;
  }
}

Why do you complicate so much... Is there a reason you want to convert from string to int, then from int to string, to then split this string into bits?

void setup()
{
  Serial.begin( 9600 );

  char numStr[] = "100";
  uint8_t num = atoi( numStr );
  
  for ( int8_t i = 7; i >= 0; i-- )
  {
    Serial.println( (bool)(num & (1 << i)) );
  }
}

@guix: I think that the OP what to convert the input received by the serial in decimal to binary string.

Yes, and then he want to split each '0' and '1' of this binary string, to set the state of his LEDs:

"100" -> 100 -> "1100100" -> '1','1','0','0','1','0','0' -> 1,1,0,0,1,0,0

My code produce the same result, but with much less work:

"100" -> 100 -> 1,1,0,0,1,0,0

Yes, you are right.

Maybe because the hour, when I see "100" I think in binary.

My apologies.