Clarifying my question a bit. We're using a PIC32 board with an MCP4706 8-bit DAC, controlled over I2C. If we write a binary value (e.g. 0b00000100) to the DAC, it outputs as expected. However, we're trying to incrementally change the voltage output by the DAC, which goes into a voltage follower controlling a MOSFET that allows current to flow from a high-current source into a battery.
Here's a schematic of all that. It's not perfect, but it gets out point across.
enter image description here
An analog pin measures the value output by a current sensor in-line with the battery, which controls the current flow, essentially. Currently, our conversion between voltage and current is done arbitrarily, which is okay. I'm looking to get steadily increasing values from the DAC, but I'm reading 0.00V at all time from the output unless I manually set the DAC value. I'm adding some different code here:
// Control voltage sent to DAC as a function of Cvolt read from current sensor
void CurrentControl()
{
double current;
// Gets values for Cvolt and Bvolt
getAnalog();
// ARBITRARY CONVERSION, NEED TO CHANGE
current = Cvolt*.0035;
// Current should be between 8A and 9A at all times for safety
if(current <= 8.0)
{
// if current is less than 8A, increase DAC value
shift = shift + 1;
// safety control; keep shift at 255 (max) if it tries to go higher
if(shift > 255)
shift = 255;
// write value to DAC Vout register
SendI2C3(DAC,0b00000000,shift);
}
else if(current >= 9.0)
{
// if current is more than 9A, decrease DAC value
shift = shift - 1;
// safety control; keep shift at 0 if it tries to go lower
if( shift < 0)
shift = 0;
// write value to DAC Vout register
SendI2C3(DAC,0b00000000,shift);
}
}
.
.
.
// Send data to I2C line at given address
void SendI2C3(char addrs,char regis, char data)
{
char ack;
I2C_start();
ack=I2C_write(addrs); //Address for LED is 0x50
ack=I2C_write(regis); //0xFE for LED
ack=I2C_write(data); //0x20to0x7F standard
I2C_stop();
}
3 Answers 3
Since "dec" is an int, it is already a binary value. You just need to ensure it is between 0 and 255 inclusive, and send it to the DAC - no need for any decimal to binary conversion (and your messing about with character arrays and strings is no use at all).
It might be useful to see how you set "dec" to the desired value...
-
\$\begingroup\$ I added some clarifying code. Right now I'm attempting to write the integer straight to the DAC, but I'm not seeing any output. I limit the range of the sent int to [0,255] manually. \$\endgroup\$alextoombs– alextoombs04/14/2013 20:54:43Commented Apr 14, 2013 at 20:54
-
\$\begingroup\$ So the reason I couldn't get it to work was that the DAC itself was bad. We soldered another in, and your solution works, so I'm marking it solved. The code I have in works just fine now. Thanks a lot for the help. \$\endgroup\$alextoombs– alextoombs04/14/2013 21:54:56Commented Apr 14, 2013 at 21:54
you need to define char bitsc; as a char pointer(char * bitsc;), then your statement bitsc = (char)bits; will have to change to bitsc = bits; so this way it makes sense to assign the pointer of the array bits to the the char pointer bitsc. which should take care of the error on your printf since now you are providing a char pointer for the argument related to the %8s switch. Im not completely sure but then I would try to char* high = "0b11111111"; and char* low = "0b00000000"; Finally in C you cannot return a string from a function however you can return a pointer to the string so your function definition would have to change to char* decToDAC(int dec) which should be just fine since now you will be returning char* pointer to the binary strings
-
2\$\begingroup\$ He just wants to send an 8 bit value to a DAC. Since he is starting with an int, there is no need to mess about with strings and char pointers. \$\endgroup\$Peter Bennett– Peter Bennett04/09/2013 23:03:10Commented Apr 9, 2013 at 23:03
-
\$\begingroup\$ I think @PeterBennett and others are right about maintaining integers the whole while, but thanks for the help regardless. \$\endgroup\$alextoombs– alextoombs04/14/2013 20:57:34Commented Apr 14, 2013 at 20:57
Because the value is already and integer you should be able to use code as below using putchar to directly output the value in binary.
I've included the return values you had in the original code, although I wouldn't recommend them because there's no way to tell the difference between a value less than zero and zero and the same for overrange numbers and 255.
char decToDAC(int dec) {
if (dec > 255)
return 0xFF;
else if (dec < 0)
return 0x00;
else {
putchar(dec);
return dec;
}
}
-
\$\begingroup\$ I tried using this code to output to the DAC, but I wasn't able to get it to output. I changed some of my code above-- I also output the char I tried to send (using your method) to PuTTY before it wrote to the DAC, and PuTTY would freeze upon trying to write it. \$\endgroup\$alextoombs– alextoombs04/14/2013 20:53:54Commented Apr 14, 2013 at 20:53
-
\$\begingroup\$ Some binary codes will freeze a terminal emulator like PuTTY, try a program called RealTerm it's better for viewing binary data and you can also display in hex and a few other formats. \$\endgroup\$PeterJ– PeterJ04/15/2013 01:42:16Commented Apr 15, 2013 at 1:42
"0b00000000"
the the like: you are treating an binary integer as a string. \$\endgroup\$dec
is an int, it is already binary, so no conversion is required - although you may want to check that it is less than 256, and set it to 255 if not. Also, you declaredbits
as a char array, then tried to assign it to a char. \$\endgroup\$