@@ -13,8 +13,10 @@ Arduino Library for X9C10X series digital potentiometer.
1313
1414## Description
1515
16- This ** experimental** library provides a X9C base class, a X9C10X class and
17- four derived classes for specific digital potentiometer.
16+ This ** experimental** library provides
17+ - a minimal X9C base class,
18+ - an elaborated X9C10X class and
19+ - four derived classes for specific digital potentiometer.
1820
1921| class | resistance | tested | notes |
2022| :------:| :----------:| :-------:| :-------------|
@@ -29,22 +31,25 @@ four derived classes for specific digital potentiometer.
2931_ Note: Ω Ohm sign = ALT-234_
3032
3133The X9C10X object keeps track of the position of the potentiometer,
32- but the user should set it with ** setPosition(pos , true);**
34+ but the user should set it with ** setPosition(position , true);**
3335Otherwise the library and device will probably not be in sync.
3436
35- Since 0.2.0 the library has a minimal X9C class. See below.
37+ Since 0.2.1 the library also supports ** restoreInternalPosition(position)**
38+ to set the internal position with the value from the latest ** store()** call.
39+ See the examples.
3640
3741
3842### Multiple devices
3943
4044Multiple devices can be controlled by assigning them an unique selectPin (CS).
4145This behaviour is similar to the SPI select pin.
4246
43- It should be possible to share the U/D and INC lines (not tested) when controlling multiple X9C devices.
47+ It should be possible to share the U/D and INC lines (not tested) when controlling
48+ multiple X9C devices.
4449
4550Note: one should select one device at a time.
4651Sharing a CS pin or sending pulses to multiple devices at the same time will
47- cause the library and devices get oout of sync.
52+ cause the library and devices get out of sync.
4853
4954
5055### PINOUT
@@ -79,13 +84,14 @@ quality can become an issue. (not investigated further)
7984
8085## Interface
8186
87+ ``` cpp
88+ #include " X9C10X.h"
89+ ```
8290
8391## X9C base class
8492
8593This is the most minimalistic base class.
86- It does not provide position information but that is sometimes enough.
87-
88- Use ** \# include "X9C10X.h"**
94+ It does not provide position information but sometimes that is just enough.
8995
9096- ** X9C()** Constructor.
9197- ** void begin(uint8_t pulsePin, uint8_t directionPin, uint8_t selectPin)**
@@ -95,45 +101,61 @@ Note: **begin()** has a hard coded 500uS delay so the device can wake up.
95101- ** void decr()** moves one position down (if possible).
96102- ** void store()** stores the current position in NV-RAM to be used at the next restart.
97103Does not return a value as the position cannot be read from the device.
98- So the user should keep track of the position if needed.
104+ So the user must keep track of the position if needed.
99105
100106
101107## X9C10X base class
102108
103- This class is derived from the X9C class but adds position, Ohm and type information.
104-
105- Use ** \# include "X9C10X.h"**
109+ This class is derived from the X9C class and adds position, Ohm and type information.
106110
107111- ** X9C10X(uint32_t Ohm = 10000)** Constructor, default initializes the resistance to 10000 Ω.
108112To calibrate one can fill in any other (measured) value e.g. 9950 Ω.
109113This can be useful e.g. if one sets a fixed resistor parallel over the X9C one.
110114- ** void begin(uint8_t pulsePin, uint8_t directionPin, uint8_t selectPin)**
111115sets the INC, UD and CS pins used by the device.
112116Note: ** begin()** has a hard coded 500uS delay so the device can wake up.
113- - ** void setPosition(uint8_t position, bool forced = false)** sets the wiper
117+ - ** uint8_t setPosition(uint8_t position, bool forced = false)** sets the wiper
114118to a position between 0 and 99.
115119The movement is relative to the current (internal) position.
116120If forced is set to true, the wiper will be moved to the closest "end" position
117121and from there moved to the requested position.
118- The internal position is replaced by the new position.
122+ The internal position is replaced by the new position.
123+ If the new position > 99 the new position is truncated to 99.
124+ Returns new position 0 .. 99.
119125- ** uint8_t getPosition()** returns the current (internal) position. 0..99
120126- ** bool incr()** moves one position up (if possible).
121127Returns true if moved and false if already at end position
122128according to internal position math.
123129- ** bool decr()** moves one position down (if possible).
124130Returns true if moved and false if already at begin position
125131according to internal position math.
126- - ** uint8_t store()** stores the current position in the NVRAM of the device,
127- and returns the current position so it can later be used as position parameter for ** setPosition()** .
128- Warning: use with care (not tested).
129- Note: ** store()** blocks for 20 milliseconds.
132+ - ** uint8_t store()** stores the current position in the NVRAM of the device.
133+ Returns the current position so it can later be used as position parameter
134+ for ** setPosition()** or ** restoreInternalPosition()** .
135+ - Warning: use with care (not tested).
136+ - Note: ** store()** blocks for 20 milliseconds.
137+ - ** uint8_t restoreInternalPosition(uint8_t position)** hard overwrite of the current
138+ (internal) position to initialize the library with the value returned by ** store()** .
139+ The potentiometer will not be moved() in this process, and the user is responsible
140+ to provide the right value.
141+ Returns new position 0 .. 99.
142+ This function allows users e.g. to save the position returned by ** store()** in EEPROM
143+ to initialize the library with this EEPROM value after a reboot.
144+ - Warning: use with care (not tested).
130145
131146Note: ** begin()** changed in 0.2.0 as the implicit parameter position
132147was removed for the explicit function call to ** setPosition()** .
133148If ** setPosition()** is not called, the device uses the last stored
134149value as position. Unfortunately the position cannot be read from the device.
135150This will result in a mismatch between the internal position and the
136- external one.
151+ external one.
152+
153+ Since 0.2.1 the function ** uint8_t restoreInternalPosition(uint8_t position)**
154+ gives some means to solve this, see examples.
155+ Be aware that if a system resets and the position has been changed since last
156+ ** store()** the restore and therefore the library will not be in sync with the device.
157+ To create a fool proof system additional hardware is needed, see Concept read position below.
158+
137159
138160
139161#### Ohm
@@ -165,7 +187,7 @@ These classes have the same interface as the X9C10X base class.
165187The only difference is that the type is set to a non zero value.
166188
167189
168- #### Performance
190+ ## Performance
169191
170192The table below is tested on a (relative slow) Arduino UNO 16 MHz with IDE 1.18.19.
171193Other processors might give similar or faster times. See performance example.
@@ -191,6 +213,8 @@ X9C10X_LIB_VERSION: 0.1.2
191213
192214Time per step is 780 / 99 = ~ 8 us per step on an UNO.
193215
216+ Note: no performance improvements since 0.1.2
217+
194218
195219## Operation
196220
@@ -206,9 +230,30 @@ A voltage of **3V3** would be **setPosition(66)**.
206230Note: check datasheet for the range of the max voltage and current allowed.
207231
208232
233+ #### Concept read position
234+
235+ If you need to make a robust system with X9C devices you can solder two devices "in parallel".
236+ One to control whatever you need to control, and the other to create a feedback loop through analogRead().
237+ Lets name them feedback device and control device.
238+ The two devices should share the select, direction and pulse pins in hardware.
239+ This way they will get the exact same pulses and signals and would therefore be in the exact same position
240+ after initialization.
241+
242+ The feedback device would be a voltage divider, splitting 5 Volts in 100 level.
243+ To read these levels you need at least an 8 bit ADC or better.
244+ This setup would allow you to read the position in the control device 100% of the time.
245+
246+ The price is at least twice as high in terms of hardware, the performance will be less at some times
247+ and the code will be slightly more complex
248+
249+ It might be possible to measure the voltage of the wiper of the control device.
250+ However that might not always be easy or possible, due to voltage used, etc.
251+
252+
209253## Future
210254
211255- update documentation
256+ - concept of ** read()** => put 2 X9C parallel and read one with analogRead().
212257- test different platforms
213258- add error codes ?
214259- add examples
@@ -225,5 +270,5 @@ Note: check datasheet for the range of the max voltage and current allowed.
225270 - ** getOhm()** ==> ** getValue()**
226271 - ** getMaxOhm()** ==> ** getMaxValue()**
227272 - think milliVolt, ohm, lux, speed, etc.
228- User can do this too with ** getPosition() * factor**
273+ User can do this too with ** getPosition() \ * factor**
229274
0 commit comments