Looking for an Arduino board which would help in converting 12 bit binary input to decimal equivalent

brute force approach would be something like this

const byte adcPins[] = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}; // 12 pins for the 12 bits from LSb tto MSb

uint16_t adcRead() {
  uint16_t value = 0;
  for (byte i = 0; i < sizeof adcPins; i++)
    if (digitalRead(adcPins[i]) == HIGH) bitSet(value, i); // set the bit that needs to be 1
  return value;
}

void setup() {
  Serial.begin(115200); Serial.println();
  for (auto & aPin : adcPins) pinMode(aPin, INPUT); // set all the pins as input
}

void loop() {
  uint16_t sample = adcRead();
  Serial.print(F("sample = 0b"));
  Serial.print(sample, BIN);
  Serial.print(F(" or in decimal : "));
  Serial.println(sample);
  delay(1000);
}
  • you list your 12 pins (from Least Significant bit to Most Significant bit) in an array
  • you configure those pins as input
  • you have a function that reads the pins status in order and if a pin is HIGH then you put a 1 in the corresponding bit of your sample value (if it's LOW we already have a 0 in that bit position since we initialized the value to 0)

side note: digitalRead() is not super fast. So it would be faster and more "in sync" if you were to use PORT register : choose pins carefully so that they are in the order of the PORT and with 2 quick registers reads you get the value of 8 bits of the PORT in one go. Mask what you don't need (the top 4 bits of the MSB) and then combine the LSB and masked MSB into your uint16_t

1 Like

Can you please explain this Jack?

Port registers allow for lower-level and faster manipulation of the i/o pins of the microcontroller on an Arduino board. The chip used on the Arduino UNO board (328P) has three "ports":

PORT D (digital pins 0 to 7)
PORT B (digital pin 8 to 13)
PORT C (analog input pins)

Each port is controlled by three registers, which are also defined variables in the arduino language. The DDR register, determines whether the pin is an INPUT or OUTPUT. The PORT register controls whether the pin is HIGH or LOW, and the PIN register reads the state of INPUT pins set to input with pinMode() (or can flip bits if you are an advanced user :slight_smile: )

➜ You should read articles about I/O port registers

a few random hits from a google search

https://create.arduino.cc/projecthub/Hack-star-Arduino/learn-arduino-port-manipulation-2022-wokwi-systems-simulat-10f9af

PS/ (my name is not Jack)

1 Like

Thank you so much for your help.

byte myDigit[4];
int i = 0;
void setup()
{
  Serial.begin(9600);
  unsigned int y = 0x0FFF;//0b111111111111; //0x0FFF
  do
  {
    myDigit[i] = y % 10;
    y = y / 10;
    i++;
  }
  while (y != 0);
  unsigned int bcdNum = myDigit[i-1]<<12|myDigit[1-2]<<8
  |myDigit[i-3]<<4|myDigit[i-4];  //0100 0000 1001 0101 (4095 BCD format)
  Serial.println(bcdNum, HEX); //shows: 4095
}

void loop() 
{
 
}

I don't think there was an ask for a BCD format, was there ?

void setup()
{
  Serial.begin(115200);
  unsigned int y = 0x0FFF;//0b111111111111; //0x0FFF
  Serial.println(y); // That's all folks
}

void loop() {}

Actually, 12 bit binary is decimal :smiley:

Binary, hex and decimal are text representations of a number.

If someone asks for the decimal number of this appearance 4095 for the hex number 0x0FFF, then is he not asking for this pattern 0100 0000 1001 0101 which is undoubtedly a BCD format? BCD format is an excellent representation to show digits on 7-segment display devices and Text LCD when print() command is not available.

And that's undoubtedly a string e.g. "4095". And this conversion is made by print() automatically.

The OP is saying:

4095 can be stored in memory in the following two formats; but, OP has not said what format he wants; so, I have chosen the BCD format - can I choose like this?

1. 0000 1111 1111 11111 (0FFFF, natural binary format)
2. 0100 0000 1001 0101 (4095, bcd format)

"4095" is equivalent to {0x34, 0x30, 0x39, 0x35, 0x00}; so, the print() method is essentially extracting BCD digits from the given binary number 0x0FFFF using % and / operators or by using Horner Rule.

OP does not have 0xFFF, he has 12 pins which can be HIGH or LOW and wanted to build up 0b111111111111 (if all were HIGH) and print that value in decimal on a screen

See the whole discussion

As Mike explained in #2, the OP does not just want to "convert to decimal", but display it.

To the extent that it be converted into digit representation such as BCD, that is nothing more than an intermediate step in the process which will - for each digit separately - be immediately followed by conversion into a graphic pattern or 7-segment code. So it will never appear in the computation as BCD.

What does OP say below -- is he not asking for conversion? He is asking for 4095 which can be represented in memory either as:

0100 0000 1001 0101 (BCD format; good for human) or 
0000 1111 1111 1111 (natural binary format, good for machine)

Op is talking about the state of the 12 pins of his ADC

That is because the OP does not have the vocabulary or the knowledge to ask for what he actually needs.

He has got hold of some crap code written by some idiot who doesn't know how computers work. This person's idea of displaying a number, is to convert the number into a BCD string variable and then print that string. How you can get to doing that without knowing you can simply ask the LCD library to print a number God only knows.

Objection!

OP says that he wants to see decimal 4095 against the binary value of 1111 1111 1111. Now, I give a 4-digit cc-type 7-segment display unit and the given binary 12-bit number. You, please, present your method of processing the input binary number in order to show 4095 on the display unit.

@GolamMostafa you jump into the discussion at post #25 and it seems like you have completely ignored the discussion that happened in the first 24 posts.

Your input - whatever its technical merit - is just not adding value to the conversation and solving OP's needs. it's irrelevant...

➜ That was an XY problem and OP started with a wrong description of his needs.
➜ if you read further down the thread, you'll see the real question is as follow:

so that's the ask:

and the answer is something like this

const byte adcPins[] = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}; // 12 pins for the 12 bits from LSb tto MSb, as INPUT

uint16_t adcRead() {
  uint16_t value = 0;
  for (byte i = 0; i < sizeof adcPins; i++)
    if (digitalRead(adcPins[i]) == HIGH) bitSet(value, i); // set the bit that needs to be 1
  return value;
}

the value you get from a call to this adcRead() function is what you just print() to the OLED screen. There is NO need for any change of representation.

1 Like

@nithinpalanisamy way back in post #7 I suggested some code. Did you try it yet?

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.