I'd like to add in a 'getVoltage' type function that either maps to the getDifferentials (e.g. getVoltage0xGND, or is a general getVoltage using whatever that last mux and gain setting was). Would this be acceptable to put into the ADS classes?
A couple of very fast replies to establish my reputation, and now here I am taking four days to get back to you. :-p Sorry about that.
First, let me preface this by saying I will in no way be miffed if you want to fork the project and customize/specialize it in a way that doesn't quite fit with what I had in mind. I don't mean to say that this is the case here, but if you feel like it is, know that it's always an option. It is very open source, after all.
I'm in the process of creating a sort of "stub" sample device class that people can use as a basis for writing their own classes to fit with the I2Cdevlib conventions as easily as possible, but that isn't quite done There will also be a "Contribute" page created on the i2cdevlib.com website with some more instructions, published at the same time as I finish the stub class. In the mean time, let me try to summarize what I'm hoping for here.
First, adding the kind of functions you mention should be totally fine, and I'd readily welcome those kinds of changes into the master branch if you write them and submit a pull request. As long as the functionality is likely to be valuable to the majority of people who are going to be using the device class, then it should be a good fit. If it's a "helper" or "convenience" function that they
might end up using in some special case, and it isn't functionality specifically explained in the datasheet or other documentation, then leave it out.
Being able to get digital voltage difference from an A/D converter transparently without needing to calculate a scale factor is definitely valuable. In the ITG-3200 gyroscope, for example, you could add a getRotationDegrees() method or set of methods that would preemptively divide the axis measurements by 14.375, which is the scale factor to convert to degrees/sec according to the datasheet. I didn't do that, but I'd be fine with that. I'm currently in the process of adding some DMP-related convenience functions to the MPU-6050 class because I know they will be valuable, even though they aren't discussed in the datasheet (shame on InvenSense for that, ha!).
In order of decreasing importance, this is the functionality I'd like to see for any given device class:
- get*/set* style methods to read and write all specifically documented device registers, according to the register map
- initialize() and testConnection() methods to establish uniform functionality across the whole I2Cdevlib project
- Helpful Doxygen-style comments for those methods
- Convenience methods that most people are likely to need or want to use
I don't know if this is helpful enough, but hopefully it is. Let me know if not and I'll be happy to clarify anything I can.
As for the functionality of the initialize() method, I'd vote to keep things as simple as possible and still produce reliable results. Your example case is unlikely for production code; the chip will most likely always be run with the same code. But it could certainly happen during development and debugging. However, it does make sense that you would expect a function called "initialize" to actually set everything to a known, predicable state. Especially if some of the functionality of any convenience methods depend on knowing, for example, which MUX value is selected and what the gain is, then it's important to be very specific about the initial state. I'd say setting registers to the known default values shown in the datasheet is acceptable for the initialize() method.
Sometimes, too, a device has a single "reset" bit in one of the registers that will do it all for you. A lot of the motion sensors I've been messing with have that. I think the ADS1115 doesn't have one, but it's something to keep in mind for other devices.
Good questions!