So here is my problem, my friend and I are writing a simple project for a electrical eng. teacher, who really doesn't know too much about programming c++. We were assigned to make a successive approximation ADC Look here in any coding language possible. I would have liked to make it in Java for Linux, but the professor insisted we make it for c++ and specifically for windows. (derp) I have limited c++ knowledge, but I tried my best and wrote a successful decimal to binary conversion loop. However, said friends code refuses to work for any bit value above 30 bits, as in, it crashes when it is entered.

I know it is not a problem with my function, but a problem with the equation. I need just a little help troubleshooting the problem.

Code:

# include <iostream>;
# include <cmath>;
# include <string>;
# include <cstring>;
# include <iomanip>;
#include <windows.h>;
#include <stdio.h>;


using namespace std;
//temp location for ereperation
HANDLE hCon;

//list of colors 1-15 to interface with the console
enum Color { DARKBLUE = 1, DARKGREEN, DARKTEAL, DARKRED, DARKPINK, DARKYELLOW, GRAY, DARKGRAY, BLUE, GREEN, TEAL, RED, PINK, YELLOW, WHITE };

//color function
void SetColor(Color c) //Color c is for the ereperation ^^^^
{
        if(hCon == NULL) //if there isn't a memory location
                hCon = GetStdHandle(STD_OUTPUT_HANDLE); //creates space in console buffer
        SetConsoleTextAttribute(hCon, c);	//sets color in console to selected color for that memory location
}

//main function
int main()
{
char answer;
do {
SetColor(DARKRED); cout << "*********************************************************************************";
SetColor(TEAL);cout << "              Welcome To the Analog to Digital Converter Program              ";SetColor(DARKRED); cout << "* ";
double n ; 
int d = 0;
double x, y;
int z, twotothen, j;
double an, bit, ref;
SetColor(WHITE); cout << " Enter Vref: ";  //All functions have defensive programming:
SetColor(YELLOW); 
std::cin >> std::setw(3) >> ref;
for (; ref < 0 ;)
{
	SetColor(WHITE); cout << " Vref Cannot be less than 0, Enter a new Vref: "; //Here
	SetColor(YELLOW); cin >>ref;
}
SetColor(WHITE); cout << "  Enter number of bits (1-32): ";
SetColor(YELLOW); cin >> bit;
for (;bit <= 0 || bit >= 33;)
{
	SetColor(WHITE); cout << "  Please enter a bit value between 1 and 32: "; //Here
	SetColor(YELLOW);cin >>bit;
}
SetColor(WHITE); cout << "  Please enter the analog voltage: ";
SetColor(YELLOW); cin >> an;
for(; an < 0 || an > ref;)
{
	SetColor(WHITE); cout << "  The analog voltage must be greater than zero and less than Vref, \nPlease enter new value: "; //And here
	SetColor(YELLOW); cin >> an;
}
y = ref/pow(2,bit); //Calculatng the step size
x = an/ref; //Used to calculate VR
SetColor(WHITE); cout << "  Step size is: ";
SetColor(YELLOW); cout << y << endl;
twotothen = pow(2, bit);
    //cout << x << endl; //Test if the control value is good
     z = .6 * pow(2, bit);
//cout<< z << endl; //test if VR is correct
int binary(z);
SetColor(GREEN); cout << "  Step               VR                  Binary Value                           "; //Header
cout << "  ____            _______                ____________                           ";

for( j = 1, n =1 ; d!= z; n++, j++ ) //Main loop
{
int k = pow(2, n);
double p;
d = abs(d); //make sure the VR is positive
d += twotothen/ k;
SetColor(WHITE); cout << setw( 5) << right << j << "             " << setw(7)  << setprecision(6) << abs(d * y)  << "                ";//Outputs The Step,VR
//Function for decimal to binary
string result;
int rep = d; // the number to convert to binary
                if (rep == 0) // if the input is 0, output 0
                   result = "0";

                while (rep != 0) 
				{
                      if (rep%2!=0) //if the number is divisible by 2, remainder = 1
					  {
							result += "1";//add 1 to the string
                      } 
					  else 
					  {
                            result += "0";//add 0 to the string
                      }

                       rep = rep/2;
				}

  //This is problamatic however, becuase it writes the string in reverse, so it has to get converted:

  string hold;//string to hold the converted value
  string::reverse_iterator rev; //calls string rev to beign reversing the data values
  for ( rev=result.rbegin() ; rev < result.rend(); rev++ ) //for loop; string rev = Returns the reverse of the beginning value, until reaching the end
  {
	cout << *rev; //points back to the result string for the next conversion
	hold += *rev; //add the converted value to be held (this value is truncated every time a new number is converted)
  }

cout << setw(bit) << endl;

if (d == z) //when conversion is complete
{
	cout << "  Final Bianry Conversion is: ";
    SetColor(YELLOW); cout << hold << endl;
}

if( abs(d) > abs(z))//else go to next conversion,
{
d-= twotothen/ k;
}
}

SetColor(WHITE); cout << "  Percent error is: ";
SetColor(YELLOW); cout << (1 - (d * y / an))*100;//the VR devided by the expected voltage
SetColor(WHITE); cout << " %" << endl;

cout << "  Convert Again?";
SetColor(RED); cout << "[Y/y] "; 
SetColor(YELLOW); cin >> answer;
system("cls");
}while ( answer =='y' || 'Y'); //if N or anything else, end the program
return 0;

}

He added the annotations after I programmed the decimal to binary converter. I am really at a loss for this one.
(Forgive the windows only code!)

Some equations:
Step size = Vref/Bits^2 = Vref / pow(2, bits)
VR= the equivalent voltage of the binary number

More can be seen at the link.

lines 1 thru 7: remove the semicolons at the end of those lines

The compiler vc++ 2010 express produces a lot of warnings about double to int and vice versa conversions. You should treat all those warnings as actual errors because they can often cause problems.

After making appropriate typecases and correcting line 130 (the while statement) I set bit to 32 and did not get program crash.

What values do we use for the three questions? I just put in some arbritrary numbers.

Edited 5 Years Ago by Ancient Dragon: n/a

What would you recommend in that case when doing conversions?
For example its hard divide or modulus ints.

Several observations:

1) remove the semi-colons after the include statements.
2) #include <cstdio> instead of <stdio.h> (in fact, I don't think you need it at all)
3) If you just removed the "feature" of outputting text in different colors, this program could run on Linux just as easily (removing the #include <windows.h>, of course).
4) Lines 40, 47, and 54, when you need a while-loop, use a while-loop.
5) If you are going to use the bits of the integer, use an "unsigned int" or, better, use fixed-length integer types, like uint64_t (from #include <stdint.h>) for a fixed-length 64bit unsigned integer type.
6) Don't use the pow() function for shifting bits. All calls like pow(2,bit); are equivalent to 1 << bit; using the bitshift operator, the latter is much better than pow().
7) don't use a string to store the result, it is just wasteful as hell.

Finally, your code is a bit too messy and un-indented that it is hard to reason about it. But, from the looks of it, you didn't implement a successive approximation ADC. My guess is that it doesn't work about 30 bits because you are using a signed integer which has at least one bit less than the unsigned integer (because it has to represent all negative numbers too!).

Working out great so far, however
d = __int64 abs(d);
Seems to still produce an error
error C2062: type '__int64' unexpected
Is this because of an uncalled library, or am I just calling it wrong?

You are calling it wrong (the __int64 should not be there). However, when dealing with higher numbers like this, you can't trust functions like abs(), they could very easily convert implicitly the operand to a lover type of int and then you loose everything. Don't use it. Use unsigned integers, not signed integers! You will avoid the use of this abs function altogether. There is no reason why a signed integer should appear anywhere in your code.

EDIT: I just tested your code. It doesn't work. It has huge percent errors at the end. And, it is also way, way longer than it needs to be (I rewrote it, and my implementation is less than 8 lines total, except for the I/O stuff).

Edited 5 Years Ago by mike_2000_17: n/a

Well this sucks, just finished wrapping it up and now its returning zero in the division functions, Any way to fix this?

y = ref / divide;
This always results in a zero

y, ref, and divide are all __int64

Should I force them to another type to do the division, like a float?

Well, from your comments, y is the step size and ref is the reference voltage, they both should be floating-point values, then, the integer division won't apply anymore, even if divide remains an __int64 (which I can't tell because I have no idea what "divide" is supposed to represent).

This article has been dead for over six months. Start a new discussion instead.