Analog input to BCD

Hey guys,

i am very new to coding (i know the very basics of VB).

now we bought a arduino to tinker around a bit, but for the love of god there are some things i cant figure out...

for example, how can i convert a analog input (i.e. 0 - 1023) to a BCD code?
i found numerous topics about it, but since i'm so new to coding, i cant understand them XD

please help a newbie out? :x

Do you really want BCD or do you want binary?

well, in the end i will need both...

right now we are using a siemens PLC for a 7segment display, and we use a BCD to 7 segment IC for that.
thats why i need the BCD code..

but since a PLC is around 250€, if we can convert it to arduino, it would be alot cheaper...

Alright, to drive a single digit there is not difference between BCD and binary. And a little surprise, every variable on the Arduino is already binary, just use binary operators (or functions) on it :slight_smile:

we actually need 6 digits :smiley: (2 x 3 digits)

for now we are just tinkering with the arduino starter kit and the potentiometer included with it,
this only gives us a value of 0-1023.

but if i understand you correctly, if i read the value (analogvalue = analogRead(0)), and for example it is 800,

in the "analogvalue" will be a binary digit (i.e. 1100100000) so i can use a binary to BCD conversion?

Yup.

For more than one digit, it matters little what the bits in the source value look like. You have to do divisions by 10 to do the decimal conversion, and usually modulo (% operator in C) to isolate the digits. There is no bit level trickery that you can use.

Unless you pack the decimal digits more than one to a word or byte, you don't really have BCD in the sense it's normally used, you just have an array of decimal digits. Just terminology, though...

For example, a four digit BCD value fits into a 16 bit word, 4 bits for each decimal digit.

aarg:
For more than one digit, it matters little what the bits in the source value look like. You have to do divisions by 10 to do the decimal conversion, and usually modulo (% operator in C) to isolate the digits. There is no bit level trickery that you can use.

With a little jiggering K&R’s itoa() can be used:

void itoa(int n, char s[])
{
    int i, sign;
    if ((sign = n) < 0) /* record sign */
        n = -n; /* make n positive */
    i = 0;
    do { /* generate digits in reverse order */
        s[i++] = n % 10 + '0'; /* get next digit */
    } while ((n /= 10) > 0); /* delete it */
    if (sign < 0)
        s[i++] = '-';
    s[i] = '\0';
    reverse(s);
    return;
}

The RTC libraries all have BCD to DEC conversion functions and the reverse as well. Just copy from one of them.

thanks for the help so far guys, still a few issues to resolve..

when i use the code provided by Keith, i get an error: "reverse was not declared in this scope"
when i search google for examples of such code, i never see a declaration on "reverse"...

when calling up the function, i assume its just "analogBCD = itoa(analogBIN);" (where analogBIN is the value being read out)

as for the RTC libraries, i always get an error that my board is not compatible with that library (i try'd several RTC libraries, none of them work)

please dont shoot me for being dumb XD i'm really new to this and google isnt helpful when you dont know what to look for..

itoa() is already a normal C++ function so I don't know why the implementation of KeithRB.

DeathAspire:
when calling up the function, i assume its just "analogBCD = itoa(analogBIN);" (where analogBIN is the value being read out)

Nope, see the void? What's in front of the function name is the return type, aka, what comes out of the function when you call it. void mains nothing. It returns nothing. The function uses the array from the second parameter to build it.

Although many ways to Rome, I think using the BCD functions from the RCT library. Don't use the whole library, just open it and find the BCD fucntions and copy them to your project.

But just out of curiosity, which board do you use that it might not work?

this is the board info:

BN: Arduino/Genuino Uno
VID: 2341
PID: 0043
SN: 5563930303535190E101

the error i get:
WAARSCHUWING: bibliotheek RTCZero beweert te werken onder architectuur (samd) en kan incompatible zijn met uw huidige board dat werkt onder architectuur (avr).

English translation:
WARNING: library RTCZero claims to work under architecture (samd) and could be incompatible with your current board wich works under architecture (avr).

Why download RTCZero, which is obviously made for the Arduino Zero, and not just RTC? :wink: Don't make it to hard, the Uno is the most jellybean Arduino on the market.

DeathAspire:
for example, how can i convert a analog input (i.e. 0 - 1023) to a BCD code?

BCD stands for Binary Coded Decimal, so as a first step you need to have all the decimals you want, seperately.

1023 is four digits in decimal, so you have to convert 1023 into four decimals.

In Arduino there is an itoa() function, which can convert an integer into a null-terminated ASCII-string.

Use this as a reference for the itoa() function to create seperate decimals fom 1023 in a char array:
http://www.cplusplus.com/reference/cstdlib/itoa/

Once you have the four decimals in the first four bytes of an ASCII formatted string, it's easy to make a binary digit from an ASCII digit.

reverse() is given as another exercise in K&R. it is not a standard function. Besides, you don't need it since you can write to your BCD display in any order.

I supplied the source, because he does not need ASCII, once he has the base 10 digit he can convert it to BCD and display it - hence the "jiggering" remark.

septillion:
itoa() is already a normal C++ function

that is deprecated

Interesting. Why? When? And how can I look this up myself? :slight_smile:

Why not these functions?

uint8_t decToBcd( int val )
{
   return (uint8_t) ((val / 10 * 16) + (val % 10));
}

uint8_t bcdToDec( uint8_t val )
{
   return (uint8_t) ((val / 16 * 10) + (val % 16));
}

You just need to modify the casts and return types, no?