Decimal to Binary conversion (0-1023) printed to LED

So...
We got an Arduino board from school and I'm trying to figure out how to convert an decimal number to binary.

The decimal number is read from a potentiometer and gives a value between 0 och 1023. The input number should then print the corresponding binary number to 10 LEDs.

How do I do this?
It seems that I cant use more than 8 bits so my code doesn't work on the ninth and tenth LED. The program prints the decimal and the binary number to the serial monitor without any problem and I can almost write it to the LED.

Can I use the modulus operand and if so, how? My code doesn't work on digitalWrite(10 xxxx) and digitalWrite(11 xxxx).

void setup() {                   
  
pinMode(2, OUTPUT);
pinMode(3, OUTPUT);
pinMode(4, OUTPUT);
pinMode(5, OUTPUT);
pinMode(6, OUTPUT);
pinMode(7, OUTPUT);
pinMode(8, OUTPUT);
pinMode(9, OUTPUT);
pinMode(10, OUTPUT);
pinMode(11, OUTPUT);

Serial.begin(9600); 



}

void loop() {                 
  int sensorValue=analogRead(A0);


  Serial.print("Decimalt = ");
  Serial.print(sensorValue);         
  Serial.print("\t Binaert = ");      
  Serial.println(sensorValue, BIN);
  digitalWrite(13, HIGH);             

  
if(sensorValue >=0 && sensorValue <=1023) {
  digitalWrite(2, (sensorValue & 1));
  digitalWrite(3, (sensorValue & 2));
  digitalWrite(4, (sensorValue & 4));
  digitalWrite(5, (sensorValue & 8));
  digitalWrite(6, (sensorValue & 16));
  digitalWrite(7, (sensorValue & 32));
  digitalWrite(8, (sensorValue & 64));
  digitalWrite(9, (sensorValue & 128));


  
  digitalWrite(10, (sensorValue &256));
  digitalWrite(11, (sensorValue &512));
  
  
}
 
delay(500);                       
 
}

yes you can use modulo.

sensorValue % 100

so when on between 0 and 99you get 0
so when on between 100 and 199 you get 1
so when on between 200 and 299 you get 2
so when on between 300 and 399 you get 3

and if you use arrays you can realy easy code this with a for loop

My code doesn't work on digitalWrite(10 xxxx) and digitalWrite(11 xxxx).

How do you know?

I don't see a problem with what you have posted. Explain what goes wrong.

jremington:
How do you know?

I don't see a problem with what you have posted. Explain what goes wrong.

I have connected all the LEDs and the pontentiometer but LED 9 and 10 doesn't light up when I turn the potentiometer up all the way. It stops at 8 LED.

According to our teacher I can't get this code to work with more than 8 bits.

spirit:
yes you can use modulo.

sensorValue % 100

so when on between 0 and 99you get 0
so when on between 100 and 199 you get 1
so when on between 200 and 299 you get 2
so when on between 300 and 399 you get 3

and if you use arrays you can realy easy code this with a for loop

I'm a total beginner when it comes to programming and this is the first assignment.
Do I put the sensorValue % 100 in digitalWrite(10)? So it'll be digitalWrite(10, (sensorValue%100))?

if(sensorValue >=0 && sensorValue <=1023) {

That is a useless test. The analogRead() function can not return a value that is outside that range.

According to our teacher I can't get this code to work with more than 8 bits.

You could, but not that way. Split the int into high and low bytes (using the highByte() and lowByte() functions or bit shifting.

Use the low order byte as you are for the first 8 pins. Use the high byte for the last two pins.

You have to know decimal, binary, hexadecimal, octal etc are just ways of representing numbers. But the number is still the same. It like languages, one, één, ein, une, uno, we all mean the same thing. And the copiler can understand all those different representations as long as you tell it which representation you use. But underneath the Arduino can only store 1's and 0's in bytes.

Okay, back to the problem. It lies in what digitalWrite() can accept. It's only designed to accept a 8-bit variable (a byte or a char or a uint8_t). All the upper bits are just ignored. To fix this you can cast it into a bool. That way every number not equal to 0 will result in a 1.

digitalWrite(10, (bool)(sensorValue & 256));
digitalWrite(11, (bool)(sensorValue & 512));

But better still, if I where you, I would read upon bit shift. And start using variable names for outputs. Now you can still remember what's connected to which output but it can become hard pretty quick. And for the leds I would suggest reading upon arrays :wink: This way works but you have to type a lot of code.

PaulS:

if(sensorValue >=0 && sensorValue <=1023) {

That is a useless test. The analogRead() function can not return a value that is outside that range.

Removed the test.

You could, but not that way. Split the int into high and low bytes (using the highByte() and lowByte() functions or bit shifting.

Use the low order byte as you are for the first 8 pins. Use the high byte for the last two pins.

How do I do this?

bitRead()?

PS. Written but not tested.

void setup() {
  // put your setup code here, to run once:
Serial.begin(9600);
}

void loop() {
int analog_value=552;

for (byte i=0; i<16;i++){        // for each bit in the 16 bits of the int called analog value....
  
  // read the bit in position 0 of the analog_value and set the pin High or Low depending on the result...repeat for each position up to 16.
  // start at pin 2 (i+2);
  
  digitalWrite(i+2,bitRead(analog_value,i));    

}
delay(500);
}

How do I do this?

int clueless = /* some value */;

byte lo = lowByte(clueless);
byte hi = highByte(clueless);

  digitalWrite(2, (lo & 1));
  digitalWrite(3, (lo & 2));
  digitalWrite(4, (lo & 4));
  digitalWrite(5, (lo & 8));
  digitalWrite(6, (lo & 16));
  digitalWrite(7, (lo & 32));
  digitalWrite(8, (lo & 64));
  digitalWrite(9, (lo & 128));

  digitalWrite(10, (hi & 1));
  digitalWrite(11, (hi & 2));

Life is a lot simpler if you don't reinvent the wheel.

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  Serial.println("Enter a decimal number:");
}

void loop() {
  char buffer[10];
  int charsRead;
  int val;

  if (Serial.available() > 0)
  {
    charsRead = Serial.readBytesUntil('\n', buffer, sizeof(buffer) - 1);
    buffer[charsRead] = '\0';
    val = atoi(buffer);
    itoa(val, buffer, 2);          // Part of the System V library for decades
    Serial.print("Decimal ");
    Serial.print(val);
    Serial.print(" is ");
    Serial.print(buffer);
    Serial.println(" in binary");
  }
}

septillion:
You have to know decimal, binary, hexadecimal, octal etc are just ways of representing numbers. But the number is still the same. It like languages, one, één, ein, une, uno, we all mean the same thing. And the copiler can understand all those different representations as long as you tell it which representation you use. But underneath the Arduino can only store 1's and 0's in bytes.

Okay, back to the problem. It lies in what digitalWrite() can accept. It's only designed to accept a 8-bit variable (a byte or a char or a uint8_t). All the upper bits are just ignored. To fix this you can cast it into a bool. That way every number not equal to 0 will result in a 1.

digitalWrite(10, (bool)(sensorValue & 256));

digitalWrite(11, (bool)(sensorValue & 512));




But better still, if I where you, I would read upon bit shift. And start using variable names for outputs. Now you can still remember what's connected to which output but it can become hard pretty quick. And for the leds I would suggest reading upon arrays ;) This way works but you have to type a lot of code.

Thank you! Now it works as it should.

There are many ways of doing this with some maybe better than others -

#define NUM_ENTRIES(ARRAY)      (sizeof(ARRAY) / sizeof(ARRAY[0]))

const uint8_t   LED_OFF     = LOW;
const uint8_t   LED_ON      = HIGH;

const uint8_t   pinsLEDS[]  = { 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };

const size_t    NUM_LEDS    = NUM_ENTRIES(pinsLEDS);

void setup()
{
    for ( size_t i = NUM_LEDS; i--; )
    {
        pinMode(pinsLEDS[i], OUTPUT);
    }

    Serial.begin(9600); 
}

void loop()
{
    int value   = analogRead(A0);

    Serial.print("Decimalt = ");
    Serial.print(value);         
    Serial.print("\t Binaert = ");      
    Serial.println(value, BIN);

    digitalWrite(13, HIGH);             

    for ( size_t i = 0; i < NUM_LEDS; value >>= 1, i++ )
    {
        digitalWrite(pinsLEDS[i], ((value & 1) ? LED_ON : LED_OFF));
    }

    delay(500);                       
}

@lloyddean
Good +1
You don't need:
? LED_ON : LED_OFF

Your code with some mods:

#define NUM_ENTRIES(ARRAY)      (sizeof(ARRAY) / sizeof(ARRAY[0]))

const uint8_t   LED_OFF     = LOW;
const uint8_t   LED_ON      = HIGH;

const uint8_t   pinsLEDS[]  = { 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };

const size_t    NUM_LEDS    = NUM_ENTRIES(pinsLEDS);

void setup()
{
    for ( size_t i = NUM_LEDS; i--; )
    {
        pinMode(pinsLEDS[i], OUTPUT);
    }

    Serial.begin(9600); 
}

void loop()
{
    int value   = analogRead(A0);

    Serial.print("Decimalt = ");
    Serial.print(value);   
   
    Serial.print("\t Binaert = ");      
//    Serial.println(value, BIN);

    digitalWrite(13, HIGH);             

    for ( size_t i = 0; i < NUM_LEDS; value >>= 1, i++ )
    {
        digitalWrite(pinsLEDS[i], value & 1);
        Serial.print(value & 1); //MSBits and LSBits are reversed
    }
    Serial.print("\n");   
    delay(500);                       
}

Need? Perhaps not.

It's a matter of opinion, and of style, as depending on the wiring of the LED's I need simply reverse the values of both these aliased constants and all the code falls in line.

Common cathode -

const uint8_t   LED_OFF     = LOW;
const uint8_t   LED_ON      = HIGH;

vs Common Anode -

const uint8_t   LED_OFF     = HIGH;
const uint8_t   LED_ON      = LOW;

where as your suggestion requires, search, replace, fail, debug, seach replace, fail, debug, argaaahhhhh ....

I should have said, in this line:
digitalWrite(pinsLEDS*, ((value & 1) ? LED_ON : LED_OFF));*
You don't need:
? LED_ON : LED_OFF

... and what I said stands!

... and what I said stands!

Who is saying otherwise? :wink:

hey, I have the same problem...
but I want to get an answer in 12 bit...
so a problem with my 12 and 13 nums led is not glowing.
please help..

void setup() {
pinMode(2, OUTPUT);
pinMode(3, OUTPUT);
pinMode(4, OUTPUT);
pinMode(5, OUTPUT);
pinMode(6, OUTPUT);
pinMode(7, OUTPUT);
pinMode(8, OUTPUT);
pinMode(9, OUTPUT);
pinMode(10, OUTPUT);
pinMode(11, OUTPUT);
pinMode(12, OUTPUT);
pinMode(13, OUTPUT);

Serial.begin(9600);
}

void loop() {
int sensorValue = analogRead(A0);
int freq = sensorValue;
sensorValue = map(sensorValue, 0, 2048, 0, 4095);
sensorValue = sensorValue>>2;
freq = map(freq,0,2048,0,4095);
Serial.print("Decimal = ");
Serial.print(sensorValue);
Serial.print("\t Binary = ");
Serial.println(sensorValue, BIN);

if (sensorValue > 0 && sensorValue <= 4095) {
digitalWrite(2, (sensorValue & 1));
digitalWrite(3, (sensorValue & 2));
digitalWrite(4, (sensorValue & 4));
digitalWrite(5, (sensorValue & 8));
digitalWrite(6, (sensorValue & 16));
digitalWrite(7, (sensorValue & 32));
digitalWrite(8, (sensorValue & 64));
digitalWrite(9, (sensorValue & 128));

digitalWrite(10, (bool)(sensorValue & 256));
digitalWrite(11, (bool)(sensorValue & 512));

digitalWrite(12, (bool)(sensorValue & 1024));
digitalWrite(13, (bool)(sensorValue & 2048));

}

delay(600);
}

hey, I have the same problem...
but I want to get an answer in 12 bit...
so a problem with my 12 and 13 nums led is not glowing.
please help..

void setup() {
pinMode(2, OUTPUT);
pinMode(3, OUTPUT);
pinMode(4, OUTPUT);
pinMode(5, OUTPUT);
pinMode(6, OUTPUT);
pinMode(7, OUTPUT);
pinMode(8, OUTPUT);
pinMode(9, OUTPUT);
pinMode(10, OUTPUT);
pinMode(11, OUTPUT);
pinMode(12, OUTPUT);
pinMode(13, OUTPUT);

Serial.begin(9600);
}

void loop() {
int sensorValue = analogRead(A0);
int freq = sensorValue;
sensorValue = map(sensorValue, 0, 2048, 0, 4095);
sensorValue = sensorValue>>2;
freq = map(freq,0,2048,0,4095);
Serial.print("Decimal = ");
Serial.print(sensorValue);
Serial.print("\t Binary = ");
Serial.println(sensorValue, BIN);

if (sensorValue > 0 && sensorValue <= 4095) {
digitalWrite(2, (sensorValue & 1));
digitalWrite(3, (sensorValue & 2));
digitalWrite(4, (sensorValue & 4));
digitalWrite(5, (sensorValue & 8));
digitalWrite(6, (sensorValue & 16));
digitalWrite(7, (sensorValue & 32));
digitalWrite(8, (sensorValue & 64));
digitalWrite(9, (sensorValue & 128));

digitalWrite(10, (bool)(sensorValue & 256));
digitalWrite(11, (bool)(sensorValue & 512));

digitalWrite(12, (bool)(sensorValue & 1024));
digitalWrite(13, (bool)(sensorValue & 2048));

}

delay(600);
}

septillion:
You have to know decimal, binary, hexadecimal, octal etc are just ways of representing numbers. But the number is still the same. It like languages, one, één, ein, une, uno, we all mean the same thing. And the copiler can understand all those different representations as long as you tell it which representation you use. But underneath the Arduino can only store 1's and 0's in bytes.

Okay, back to the problem. It lies in what digitalWrite() can accept. It's only designed to accept a 8-bit variable (a byte or a char or a uint8_t). All the upper bits are just ignored. To fix this you can cast it into a bool. That way every number not equal to 0 will result in a 1.

digitalWrite(10, (bool)(sensorValue & 256));

digitalWrite(11, (bool)(sensorValue & 512));




But better still, if I where you, I would read upon bit shift. And start using variable names for outputs. Now you can still remember what's connected to which output but it can become hard pretty quick. And for the leds I would suggest reading upon arrays ;) This way works but you have to type a lot of code.