Pages: [1] 2   Go Down
Author Topic: Convert Dec to BCD  (Read 6023 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 27
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi,

I am trying to convert a decimal value to the corresponding BCD code. However, this seems not to be working at all, because only gives the 'tens' part and the 'unit' is lost. Such as, 27 only return 2.
I want the result into a 8-bit array (the result will not be greater than 99)...

Code:
byte decToBcd(byte val)
{
  return ( (val/10*8) + (val%10) );
}
« Last Edit: April 04, 2011, 08:27:16 am by SpcCode » Logged

Global Moderator
Boston area, metrowest
Offline Offline
Brattain Member
*****
Karma: 545
Posts: 27361
Author of "Arduino for Teens". Available for Design & Build services. Now with Unlimited Eagle board sizes!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

So you want 27 for example to come back as 0010 0111? (2 & 7)?

and 99 would be 1001 1001 (9 & 9)?

Logged

Designing & building electrical circuits for over 25 years. Check out the ATMega1284P based Bobuino and other '328P & '1284P creations & offerings at  www.crossroadsfencing.com/BobuinoRev17.
Arduino for Teens available at Amazon.com.

Offline Offline
Newbie
*
Karma: 0
Posts: 27
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

So you want 27 for example to come back as 0010 0111? (2 & 7)?

and 99 would be 1001 1001 (9 & 9)?

Correct.
Logged

Global Moderator
Boston area, metrowest
Offline Offline
Brattain Member
*****
Karma: 545
Posts: 27361
Author of "Arduino for Teens". Available for Design & Build services. Now with Unlimited Eagle board sizes!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

This is kinda crude, but could be a way to do it given the assumption above:

x = 0
stop = 0
while (x<10 and stop = 0){
value = value - x*10  // reduce by 10, keep count, stop when value is <10
  if (value < 10){
  upperbyte = x
  stop = 1}
  else {x=x+1}
}
lowerbyte = (value, HEX)

Logged

Designing & building electrical circuits for over 25 years. Check out the ATMega1284P based Bobuino and other '328P & '1284P creations & offerings at  www.crossroadsfencing.com/BobuinoRev17.
Arduino for Teens available at Amazon.com.

Global Moderator
Boston area, metrowest
Offline Offline
Brattain Member
*****
Karma: 545
Posts: 27361
Author of "Arduino for Teens". Available for Design & Build services. Now with Unlimited Eagle board sizes!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Thinking a little more, that doesn't quite do it.

maybe need this to put the two together

lowerbyte = value & 0x0F  // AND forces upper bits low, leaves hex value in lower nibble
upperbyte = x<<4  // moves the found nibble into the upper bits
newbyte = upperbyte | lowerbyte // OR them together
Logged

Designing & building electrical circuits for over 25 years. Check out the ATMega1284P based Bobuino and other '328P & '1284P creations & offerings at  www.crossroadsfencing.com/BobuinoRev17.
Arduino for Teens available at Amazon.com.

Offline Offline
Newbie
*
Karma: 0
Posts: 27
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

This is kinda crude, but could be a way to do it given the assumption above...

I added that code, but for some reason is not showing anything on the Serial Monitor?
Code:
      int x = 0;
      int sstop = 0;
      byte upperbyte;
      byte lowerbyte;
      byte newbyte;
      while (x<10 and sstop == 0)
      {
        DecResult = DecResult - x*10;  // reduce by 10, keep count, stop when value is <10
        if (DecResult < 10)
        {
          upperbyte = x;
          sstop = 1;
        }
        else
        {
          x=x+1;
        }
      }
      lowerbyte = DecResult & 0x0F;  // AND forces upper bits low, leaves hex value in lower nibble
      upperbyte = x<<4;  // moves the found nibble into the upper bits
      newbyte = upperbyte | lowerbyte; // OR them together
      Serial.print("Result: ");
      Serial.println(newbyte, BYTE);
« Last Edit: April 04, 2011, 12:00:21 am by SpcCode » Logged

Global Moderator
Boston area, metrowest
Offline Offline
Brattain Member
*****
Karma: 545
Posts: 27361
Author of "Arduino for Teens". Available for Design & Build services. Now with Unlimited Eagle board sizes!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

It could be creating non-printing characters.
Try using HEX instead of BYTE.
Logged

Designing & building electrical circuits for over 25 years. Check out the ATMega1284P based Bobuino and other '328P & '1284P creations & offerings at  www.crossroadsfencing.com/BobuinoRev17.
Arduino for Teens available at Amazon.com.

Offline Offline
Newbie
*
Karma: 0
Posts: 27
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

It could be creating non-printing characters.
Try using HEX instead of BYTE.

Thanks !

I am trying now to display the upperbyte but it says that is zero
Code:
      Serial.print("Lowerbyte: ");
      Serial.println(lowerbyte, HEX);
      Serial.print("Upperbyte: ");
      Serial.println(upperbyte, HEX);
Logged

Global Moderator
Boston area, metrowest
Offline Offline
Brattain Member
*****
Karma: 545
Posts: 27361
Author of "Arduino for Teens". Available for Design & Build services. Now with Unlimited Eagle board sizes!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I gotta get to bed.

Try putting some ()s in the while test:

while ((x<10) && (sstop == 0)){

Concept seems straight forward tho, yes? Keep playing with the code, you'll get there.

G'night.
Logged

Designing & building electrical circuits for over 25 years. Check out the ATMega1284P based Bobuino and other '328P & '1284P creations & offerings at  www.crossroadsfencing.com/BobuinoRev17.
Arduino for Teens available at Amazon.com.

SF Bay Area (USA)
Online Online
Tesla Member
***
Karma: 135
Posts: 6788
Strongly opinionated, but not official!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
byte decToBcd(byte val)
{
  return ( (val/10*8) + (val%10) );
}
I don't see much wrong with that other than that the "8" should be a "16", and maybe some more parens:
Code:
byte decToBcd(byte val)
{
  return ( (val/10)*16) + (val%10) );
}
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 27
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I gotta get to bed.
Try putting some ()s in the while test:
while ((x<10) && (sstop == 0)){
Concept seems straight forward tho, yes? Keep playing with the code, you'll get there.
G'night.

You give me the idea. I made this way and works perfect. I will improve it tomorrow.
Code:
      int upint = 0;
      int lowint = 0;
      int upbits[4] = {0,0,0,0};
      int lowbits[4] = {0,0,0,0};
     
      upint = DecResult/10;
      lowint = DecResult%10;
     
      //Converting Decimal to Binary
      for (int i=3; i >= 0; i--)
      {
        upbits[i] = upint % 2;
        upint = upint/2;
       
        lowbits[i] = lowint % 2;
        lowint = lowint/2;
      }
     
      byte Result[8] = {0,0,0,0,0,0,0,0};
     
      // Reorganizing the bits
      Result[0] = lowbits[3];
      Result[1] = lowbits[2];
      Result[2] = lowbits[1];
      Result[3] = lowbits[0];
      Result[4] = upbits[3];
      Result[5] = upbits[2];
      Result[6] = upbits[1];
      Result[7] = upbits[0];
Logged

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 223
Posts: 13878
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
I want the result into a 8-bit array (the result will be greater than 99)...

Code:
byte decToBcd(byte val)
{
  return ( (val/10)*16) + (val%10) );
}

// macro version
#define DEC2BCD(dec) (((dec / 10) << 4) + (dec % 10))

works for values 0..99,  how for bigger values 100-255?
Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 309
Posts: 26495
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
how for bigger values 100-255?
I don't understand the question - you can't fit three BCD digits in a byte.
Logged

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 223
Posts: 13878
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

@AWOL
The input of the function can ....
Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

0
Offline Offline
Newbie
*
Karma: 0
Posts: 41
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Not sure I understand the question. Do you mean your decimal interpretation of a value in a register? ie does "15" =0x0F?  isn't the example "27" stored internally as  0x1B? if so then what you want is Binary to BCD. Here is my take on using the ADD3 algorithm for converting binary to BCD. I only needed two BCD digits but it can be easily expanded.
Code:
//-------------- binary to BCD using add3 algorithm -----------
byte binaryToBcd(byte binSource){
  byte bcdResult=0;

  byte tempA=0;
  byte tempB=0;
  byte tempC=0;

  for (int y=0;y<8;y++){
    tempC=binSource & B10000000;
    binSource=binSource<<1;
    bcdResult=bcdResult<<1;
    if(tempC>0){
      bcdResult=bcdResult | B00000001;
    }

    if (y<7){                             //don't check or do add 3 on last shift
      tempA=bcdResult & B00001111;        //check lo nibble
      if (tempA >= 5) { 
        bcdResult=bcdResult+3;
      }

      tempB=bcdResult&B11110000;
      tempB=tempB>>4;                     // check hi nibble
      if(tempB>=5) {
        tempB=tempB+3;
      }

      tempB=tempB<<4;
      tempA=bcdResult & B00001111;
      bcdResult= tempB | tempA ;          // reassemble nibbles
    }
  }
  return   bcdResult;
Logged

Pages: [1] 2   Go Up
Jump to: