1
\$\begingroup\$

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();
}
\$\endgroup\$
6
  • 1
    \$\begingroup\$ Remove the quotes from "0b00000000" the the like: you are treating an binary integer as a string. \$\endgroup\$ Commented Apr 9, 2013 at 20:56
  • 1
    \$\begingroup\$ If 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 declared bits as a char array, then tried to assign it to a char. \$\endgroup\$ Commented Apr 9, 2013 at 22:15
  • 2
    \$\begingroup\$ @alextoombs For future reference. When you have embedded systems problems, try to describe your setup. In case of this question, the important things would be: model of the DAC, model of the PIC, development environment. It doesn't hurt to post the schematic either. \$\endgroup\$ Commented Apr 9, 2013 at 23:40
  • \$\begingroup\$ Thanks @NickAlexeev, I modified my post to include more helpful information, including part numbers and a crude schematic. Hopefully it will help more. \$\endgroup\$
    – alextoombs
    Commented Apr 14, 2013 at 20:55
  • \$\begingroup\$ Are you sure the address of the DAC is correct? And are you getting the ACK back from the DAC? Why not check for that in your SendI2C3 function? \$\endgroup\$
    – fm_andreas
    Commented Apr 14, 2013 at 21:17

3 Answers 3

1
\$\begingroup\$

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...

\$\endgroup\$
2
  • \$\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
    Commented 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
    Commented Apr 14, 2013 at 21:54
0
\$\begingroup\$

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

\$\endgroup\$
2
  • 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\$ Commented 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
    Commented Apr 14, 2013 at 20:57
0
\$\begingroup\$

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;
    }
}
\$\endgroup\$
2
  • \$\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
    Commented 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
    Commented Apr 15, 2013 at 1:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.