Issue with Binary Counter i.e. 3-4=0?

Hello,
I am trying to create a simple counter that will count down from 15 to 1 in binary with my arduino uno. As of right now I am making it print to the serial monitor but once I get the code worked out I wanted to make it light up LEDs to represent the bits.

Here is my code:

int new_Dop;                                               //this is the difference between the number and the power two
int old_Dop;                                               //this is to store the difference above
int prev_Dop;                                              //this is to store the old difference
int num;                                                   //this is the decimal number that will be converted 
int pwr;                                                   //this is the number that 2 will be raised to the power of

void setup(){
  Serial.begin (9600);
  Serial.println ("Binary converter 4.0");                 //this is my fourth time with this program every time slimming it down more and more
}

void loop (){
  for (num = 15; num >= 0; num--) {
    old_Dop=num;                                           //this is so the first time through the wow function the number in decimal will be in place
    Serial.println ("--");
    Serial.print ("the number is "); Serial.println (num);
    wow();
    Serial.println ("    "); 
  }
}

void wow(){
  for (pwr = 3; pwr >= 0; pwr--){                          //this allows the loop to be run 4 times and so there will be 4 bits ex: 1011 for 11
    new_Dop = old_Dop - pow(2,pwr);                        //this is the part that converts the decimal into binary one place at a time starting in the 8's
    prev_Dop = old_Dop;                                    //this stores the old difference to be used later if the new_Dop goes through the else statement 

    if (new_Dop >= 0){ 
      Serial.print ("1");
      old_Dop = new_Dop;                                   //this is here to run the next place in binary 
    }
    else{
      Serial.print ("0");
      old_Dop = prev_Dop;                                  //this is here to set it back so if it can run the next place in binary
    }
  }
}

Essentially the program is taking a number in base ten and converting it to base 2 using the "descending powers of 2 subtraction" Here is a link that describes that in detai:

The function "wow()" subtracts the Decimal number from 2^3 then checks if it is greater than or equal to 0 and prints a 1 or 0 accordingly then it does the process over again subtracting the remainder (or if it was less than zero the previous number) by 2^2 and so on.

However... when it comes to the numbers 11, 7, and 3 (1011, 0111, 0011 in binary respectively) it decides it wants to give me the binary numbers for 12, 8, and 4 (1100, 1000, 0100) respectively. I made another copy of this code that prints out basically every change in the variables so I could figure out why it was doing this, and the thing that I saw where there is something wrong was at 11 for the 4's place that 3-4=0... Then at 7 for the 8's place it is saying 7-8=0. Finally for 3 in the 4's place again it is saying 3-4=0.

I am not receiving errors when I run the sketch and I have looked at this too the point where I can't see what's wrong and I have a feeling a fresh pair of eyes will be able to find the problem in a matter of mere seconds!

Thank you for the help and sorry for the long windedness on something so (seemingly) simple, I'm just starting to learn Arduino and programing in general so its all a little tricky.

-pacodataco

How about this - assume your number is 0 to 255.

Then look at bit 0, decide to turn on LED or not.
Shift right one bit, look at bit 0, decide to turn on LED or not.
Shift right one bit, look at bit 0, decide to turn on LED or not.
Shift right one bit, look at bit 0, decide to turn on LED or not.
Shift right one bit, look at bit 0, decide to turn on LED or not.
Shift right one bit, look at bit 0, decide to turn on LED or not.
Shift right one bit, look at bit 0, decide to turn on LED or not.
Shift right one bit, look at bit 0, decide to turn on LED or not.

if ((0b00000001 & dataByte) ==1){"code to light bit 0";}
databyte = databyte >>1;
if ((0b00000001 & dataByte) ==1){light bit 1;}
databyte = databyte >>1;
if ((0b00000001 & dataByte) ==1){light bit 2;}
databyte = databyte >>1;
if ((0b00000001 & dataByte) ==1){light bit 3;}
databyte = databyte >>1;
if ((0b00000001 & dataByte) ==1){light bit 4;}
databyte = databyte >>1;
if ((0b00000001 & dataByte) ==1){light bit 5;}
databyte = databyte >>1;
if ((0b00000001 & dataByte) ==1){light bit 6;}
databyte = databyte >>1;
if ((0b00000001 & dataByte) ==1){light bit 7;}

Why not count down in decimal, then convert each result to binary? You can get the binary result by using bitRead() in a loop.
http://arduino.cc/en/Reference/BitRead

pow( ) is a float function with a float answer.

If the answer is 1.00000001, then 4 - 1.0000001 is 2.9999999 which , as an int, becomes 2. 4-1=2

It is stupid to use the pow() function to calculate 2 to the power of 1 or 2 or 3 or 4.

int powof2[] = { 1,2,4,8 } ;

for ( int pwr=0 ; pwr<4 ; pwr++ )
{
     int new_dop = old_dop - powof2[pwr] ;
}

cross roads is close to how I'd do it.

try

int k

setup()
{
  Serial.begin(15200)
  for(k=0; k<40; k++)
  {
    Serial.print(k,DEC); //default decimal
    Serial.print("\t");
    Serial.print(k,BIN);
    Serial.print("\t");
    Serial.print(  ((k&31)>>3)&1 );
    Serial.println();
  }
}

and see if you get any ideas.

Thank you for all the help and the quick responses!

CrossRoads:
I will try what you suggested in my next iteration of this! Since my main goal was to just start and try something what you suggested will be great to try!

Steinie44:
I will definetly look into what you suggested to!

Michinyon:
I think I will try your suggestion on this iteration!

Thanks again,
-pacodataco

Michinyon's reply got me to thinking. If the pow() function provides a float and in theory all the powers of two are whole numbers so why not just change all of the variables to floats that way if down the road I wish to scale this code up for counting between 0 and 256 like CrossRoads suggested I would only have to change a few numbers rather than add all of the numbers to the array. I tried it and funnily enough it worked! thanks again for all the suggestions that led to this solution!

In your case I think is better substitute this:

pow(2,pwr)

by some shift:

like:

1<<pwr

Explanation:

2? = 1 ... 1<<0 = 1 = 0001b
2¹ = 2 ... 1<<1 = 2 = 0010b
2² = 4 ... 1<<2 = 4 = 0100b
2³ = 8 ... 1<<3 = 8 = 1000b

Concluding: "there are only 10 type of people tows who binary a tows who don't." :slight_smile: