Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added support for MCP4725’s power-down mode #9

Open
wants to merge 5 commits into
base: master
Choose a base branch
from

Conversation

mitchyboy9
Copy link

@mitchyboy9 mitchyboy9 commented Mar 6, 2017

My personal motivation for implementing the power-down functionality was that I needed to be able to set 0V in my project. I didn't actually care about saving power while the MCP4725 sleeps. The offset error in the MCP4725 meant that with setVoltage(0, false), I had 2.6mV on the output pin, which was too high for my purposes.

The only thing I'm not 100% happy with is the names of the constants used to set the power-down output impedance (MCP4725_OUTPUT_LOAD_RESISTANCE_1K etc). They seem a bit long and hard to remember, but we obviously need them to be unique enough that there wouldn't be clashes out in the field and descriptive enough so as to make it clear what their purpose is.

In case you're wondering why I didn't just set the value of those constants to the appropriate bit masks, then directly use that in the powerDown function (instead of using the switch statement), it's because that would give client code the potential to invoke undesired behaviour on the MCP4725 if an incorrect value was passed in. At present, the worst that could happen is that they could fail to invoke power-down mode, but who knows what the future holds and what those two extra bits either side of the power-down bits might be used for.

Testing
I have tested this change on an Arduino Duemilanove.
I ran the triangle sample and my new powerdown sample and verified that the output was as expected using both a multimeter as a failsafe sanity check and an analogue input pin on the Arduino to plot the output voltages using the Arduino IDE's plotter function.
I tested the power down modes by attaching an ohmmeter between the out and gnd pins and checking that the power-down output impedance was as expected.
I also tested passing in true to both setVoltage and powerDown, each time, cycling power to the MCP4725 and verifying that the output state when power returned was as expected.

* Added the powerDown method to put the MCP4725 into power-down mode.
I defaulted the pull-down resistance to 500k Ohm in the case where an invalid value
for loadResistance is passed to the method.  It seemed safer to default to a high
impedance rather than a low.
* Created an example sketch to show how the powerDown method is used
* Added #include guard to Adafruit_MCP4725.h to avoid problems of double inclusion, which I experienced when trying to use the library in Sloeber
The current `setVoltage` method is badly named, because the caller is not actually setting a voltage, they’re setting a DAC input code.  Since the library has already been released, we can’t now change the name of this method or we’ll lose backwards compatibility, so I have had to name the new method `setNearestActualVoltage`.  It would have been clearer to have e.g. `setDacInputCode` and `setNearestVoltage`.

I suspect that a lot (most?) users of this library will want to be able to set an actual voltage, rather than have to calculate the input code required to generate the voltage they want.  For those that do want to set a voltage, this new method makes client code a lot cleaner.  Clearly, in order to do this, we need to know the reference voltage, so this is passed in to the new method.

`setNearestActualVoltage` returns a `float` which represents the nominal output voltage that is nearest to the requested value.
If you want to use more than two MCP4725s on the same I2C bus, you might run into the problem that you don’t have enough unique addresses for your MCP4725s.  It’s technically possible to have 8 unique addresses for the MCP4725, but most of the readily available ones will have the same two addresses.  The data sheet states: 
“The choice of A2 and A1 bits are provided by the customer as part of the ordering process. These bits are then programmed (hard-wired) during manufacturing”

So that leaves us with A0 to play with.  This address can be altered by pulling the address pin high/low.

By using one of the Arduino’s digital pins per MCP4725, essentially as a chip select pin, you can have as many MCP4725s as you have spare digital pins.  That is what the changes in this commit provide.

To use this feature, each MCP4725 should be constructed with the Arduino pin used as the chip select and the begin() method should be called with the address that corresponds to the A0 pin being pulled high
e.g.

Adafruit_MCP4725 dac1(2); // Digital pin 2 used as chip select
Adafruit_MCP4725 dac2(3); // Digital pin 3 used as chip select

void setup(void) {
  dac1.begin(0x61); // This is the address of the chip when A0 is pulled high
  dac2.begin(0x61);
}

void loop() {
  dac1.setNearestActualVoltage(1000, 5000, false);
  dac2.setNearestActualVoltage(3000, 5000, false);

  delay(2000);

  dac1.setNearestActualVoltage(2000, 5000, false);
  dac2.setNearestActualVoltage(4000, 5000, false);

  delay(2000);
}
(and updated comments in examples to reflect new file extensions)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants