├── .gitignore ├── Media ├── WiperTestBoard.jpg └── WiperSineTestXC104S.png ├── library.properties ├── README.md ├── keywords.txt ├── examples ├── RandomValue │ └── RandomValue.ino ├── MultiplePots │ └── MultiplePots.ino └── WiperTest │ └── WiperTest.ino ├── LICENSE └── src └── FastX9CXXX.h /.gitignore: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Media/WiperTestBoard.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GitMoDu/FastX9CXXX/HEAD/Media/WiperTestBoard.jpg -------------------------------------------------------------------------------- /Media/WiperSineTestXC104S.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GitMoDu/FastX9CXXX/HEAD/Media/WiperSineTestXC104S.png -------------------------------------------------------------------------------- /library.properties: -------------------------------------------------------------------------------- 1 | name=FastX9CXXX 2 | version=1.0 3 | author=GitMoDu 4 | maintainer=GitMoDu 5 | sentence=Arduino library for digital potentiometers X9C102, X9C103, X9C104 and X9C504. 6 | paragraph=Provides a simple way to set the desired resistance step and get the estimated resistance. 7 | category=Signal Input/Output 8 | url=https://github.com/GitMoDu/FastX9CXXX 9 | architectures=* 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # FastX9CXX 2 | 3 | Arduino library for digital potentiometers X9C102, X9C103, X9C104 and X9C504 4 | 5 | Provides a simple way to set the desired resistance step and get the estimated resistance. 6 | 7 | Compatible with all arduino boards, all you need is 3 digital pins. 8 | 9 | ## 10 | 11 | ![](https://raw.githubusercontent.com/GitMoDu/FastX9CXXX/master/Media/WiperTestBoard.jpg) 12 | 13 | ## Example WiperTest 14 | 15 | ![](https://raw.githubusercontent.com/GitMoDu/FastX9CXXX/master/Media/WiperSineTestXC104S.png) 16 | -------------------------------------------------------------------------------- /keywords.txt: -------------------------------------------------------------------------------- 1 | ####################################### 2 | # Syntax Coloring Map For FastX9CXXX 3 | ####################################### 4 | 5 | ####################################### 6 | # Datatypes (KEYWORD1) 7 | ####################################### 8 | 9 | ####################################### 10 | # Methods and Functions (KEYWORD2) 11 | ####################################### 12 | 13 | FastX9CXXX KEYWORD2 14 | 15 | 16 | ####################################### 17 | # Instances (KEYWORD2) 18 | ####################################### 19 | 20 | FastX9CXXX KEYWORD2 21 | 22 | ####################################### 23 | # Constants (LITERAL1) 24 | ####################################### 25 | 26 | -------------------------------------------------------------------------------- /examples/RandomValue/RandomValue.ino: -------------------------------------------------------------------------------- 1 | /// 2 | /// Example project to control a X9C102 digital potentiometer. 3 | /// 4 | 5 | #include 6 | 7 | #define X9_CS_PIN 3 8 | #define X9_UD_PIN 4 9 | #define X9_INC_PIN 5 10 | 11 | FastX9C102 Potentiometer; 12 | 13 | void setup() { 14 | Serial.begin(9600); 15 | Serial.println(); 16 | Serial.print(F("X9C102 Digital Potentiometer setup...")); 17 | 18 | Potentiometer.Setup(X9_CS_PIN, X9_UD_PIN, X9_INC_PIN); 19 | 20 | // Reset potentiometer to known position (Step == 0). 21 | Potentiometer.Reset(); 22 | 23 | Serial.println(F(" complete.")); 24 | } 25 | 26 | void loop() { 27 | Potentiometer.JumpToStep(random(X9CXXX::X9_STEPS)); 28 | Serial.print(F("Potentiometer current resistance: ")); 29 | Serial.print(Potentiometer.GetEstimatedResistance(), DEC); 30 | Serial.println(F(" Ohm")); 31 | delay(1000); // wait for a second 32 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 André 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /examples/MultiplePots/MultiplePots.ino: -------------------------------------------------------------------------------- 1 | /// 2 | /// Example project, using multiple X9CXXX digital potentiometers. 3 | /// 4 | 5 | #include 6 | 7 | #define X9_1_CS_PIN 3 8 | #define X9_1_UD_PIN 4 9 | #define X9_1_INC_PIN 5 10 | 11 | 12 | #define X9_2_CS_PIN 6 13 | #define X9_2_UD_PIN 7 14 | #define X9_2_INC_PIN 8 15 | 16 | FastX9C104 Potentiometer1(X9_1_CS_PIN, X9_1_UD_PIN, X9_1_INC_PIN); 17 | FastX9C503 Potentiometer2(X9_2_CS_PIN, X9_2_UD_PIN, X9_2_INC_PIN); 18 | 19 | 20 | void setup() { 21 | Serial.begin(9600); 22 | Serial.println(); 23 | 24 | Serial.print(F("X9C104 and X9C503 Digital Potentiometers setup...")); 25 | 26 | // Reset potentiometers to known position (Step == 0). 27 | Potentiometer1.Reset(); 28 | Potentiometer2.Reset(); 29 | 30 | Serial.println(F(" complete.")); 31 | } 32 | 33 | void loop() { 34 | Potentiometer1.JumpToStep(random(X9CXXX::X9_STEPS)); 35 | Potentiometer2.JumpToStep(random(X9CXXX::X9_STEPS)); 36 | Serial.print(F("Potentiometers current resistance: ")); 37 | Serial.print(Potentiometer1.GetEstimatedResistance(), DEC); 38 | Serial.print(F(" Ohm\t")); 39 | Serial.print(Potentiometer2.GetEstimatedResistance(), DEC); 40 | Serial.println(F(" Ohm")); 41 | delay(1000); // wait for a second 42 | } -------------------------------------------------------------------------------- /examples/WiperTest/WiperTest.ino: -------------------------------------------------------------------------------- 1 | /// 2 | /// Example project, using a X9CX104 digital potentiometer as a voltage divider 3 | /// and measuring the output with an analog pin. 4 | /// 5 | 6 | #include 7 | 8 | #define X9_CS_PIN 3 9 | #define X9_UD_PIN 4 10 | #define X9_INC_PIN 5 11 | 12 | #define WIPER_ANALOG_PIN A0 13 | 14 | #define STEP_DELAY_MILLIS 20 15 | 16 | FastX9C104 Potentiometer(X9_CS_PIN, X9_UD_PIN, X9_INC_PIN); 17 | 18 | uint16_t Angle = 0; 19 | 20 | void setup() { 21 | Serial.begin(9600); 22 | Serial.println(); 23 | 24 | //Serial.print(F("X9C104 Digital Potentiometer Sine Wave Test.")); 25 | 26 | // Setup output read, analog pin. 27 | pinMode(WIPER_ANALOG_PIN, INPUT); 28 | 29 | // Reset potentiometer to known position (Step == 0). 30 | Potentiometer.Reset(); 31 | 32 | // Plot Header. 33 | Serial.println(F("Step\tOutput")); 34 | } 35 | 36 | 37 | void loop() { 38 | // Step from sine wave, ranged to available steps. 39 | const uint8_t step = (0.5 * sin(Angle / 5.0) * X9CXXX::X9_STEPS) + (X9CXXX::X9_STEPS / 2); 40 | Potentiometer.JumpToStep(step); 41 | 42 | // Get the estimated step from the mapped output voltage. 43 | const uint8_t result = map(analogRead(WIPER_ANALOG_PIN), 0, 1023, 0, X9CXXX::X9_STEPS); 44 | 45 | // Plot the sample. 46 | Serial.print(step); 47 | Serial.print('\t'); 48 | Serial.print(result); 49 | Serial.print('\t'); 50 | Serial.println(); 51 | 52 | 53 | Angle++; 54 | 55 | delay(STEP_DELAY_MILLIS); // wait for a bit before stepping. 56 | } -------------------------------------------------------------------------------- /src/FastX9CXXX.h: -------------------------------------------------------------------------------- 1 | /// 2 | /// Created for personal use, use it at your own risk and benefit. 3 | /// https://github.com/GitMoDu/FastX9CXXX 4 | /// 5 | 6 | #ifndef _FASTX9CXXX_h 7 | #define _FASTX9CXXX_h 8 | 9 | #include 10 | 11 | class X9CXXX 12 | { 13 | public: 14 | static const uint8_t X9_STEPS = 100; //100 Wiper Tap Points 15 | 16 | static const uint32_t X9C102_RESISTANCE = 1000; //X9C102 = 1kOhm 17 | static const uint32_t X9C103_RESISTANCE = 10000; //X9C103 = 10kOhm 18 | static const uint32_t X9C503_RESISTANCE = 50000; //X9C503 = 50kOhm 19 | static const uint32_t X9C104_RESISTANCE = 100000; //X9C104 = 100kOhm 20 | }; 21 | 22 | template 23 | class FastX9CXXX 24 | { 25 | private: 26 | //In microseconds. 27 | const uint32_t NCS_TO_NINC_SETUP = 1; 28 | const uint32_t NINC_HIGH_TO_UND_CHANGE = 1; 29 | const uint32_t UND_TO_NINC_SETUP = 3; 30 | const uint32_t NINC_LOW_PERIOD = 1; 31 | const uint32_t NINC_HIGH_PERIOD = 1; 32 | const uint32_t NINC_INACTIVE_TO_NCS_INACTIVE = 1; 33 | const uint32_t NCS_DESELECT_TIME_STORE = 20000; 34 | const uint32_t NCS_DESELECT_TIME_NO_STORE = 1; 35 | const uint32_t NINC_TO_VWRW_CHANGE = 100; 36 | const uint32_t NINC_CYCLE_TIME = 2; 37 | const uint32_t POWER_UP_TO_WIPER_STABLE = 500; 38 | 39 | private: 40 | constexpr uint32_t GetResistanceStep() 41 | { 42 | return Resistance / X9CXXX::X9_STEPS; 43 | } 44 | 45 | private: 46 | uint8_t PinCS = UINT8_MAX; 47 | uint8_t PinUD = UINT8_MAX; 48 | uint8_t PinINC = UINT8_MAX; 49 | 50 | uint8_t CurrentStep = 0; 51 | const uint32_t ResistanceStep = GetResistanceStep(); 52 | 53 | public: 54 | uint32_t GetEstimatedResistance() 55 | { 56 | return CurrentStep * ResistanceStep; 57 | } 58 | 59 | FastX9CXXX() 60 | {} 61 | 62 | FastX9CXXX(const uint8_t csPin, const uint8_t udPin, const uint8_t incPin) 63 | { 64 | Setup(csPin, udPin, incPin); 65 | } 66 | 67 | const bool Setup(const uint8_t csPin, const uint8_t udPin, const uint8_t incPin) 68 | { 69 | PinCS = csPin; 70 | PinUD = udPin; 71 | PinINC = incPin; 72 | 73 | if (PinCS == UINT8_MAX || PinUD == UINT8_MAX || PinINC == UINT8_MAX) 74 | { 75 | return false; 76 | } 77 | 78 | pinMode(PinCS, OUTPUT); 79 | pinMode(PinUD, OUTPUT); 80 | pinMode(PinINC, OUTPUT); 81 | 82 | digitalWrite(PinCS, LOW); 83 | digitalWrite(PinUD, LOW); 84 | digitalWrite(PinINC, HIGH); 85 | 86 | return true; 87 | } 88 | 89 | // Resets the pot back to a known state. 90 | void Reset() 91 | { 92 | digitalWrite(PinCS, LOW); 93 | digitalWrite(PinUD, LOW); 94 | digitalWrite(PinINC, HIGH); 95 | 96 | for (uint8_t i = 0; i < X9CXXX::X9_STEPS; i++) 97 | { 98 | digitalWrite(PinINC, LOW); 99 | delayMicroseconds(NINC_HIGH_PERIOD); 100 | digitalWrite(PinINC, HIGH); 101 | delayMicroseconds(NINC_LOW_PERIOD); 102 | } 103 | digitalWrite(PinCS, HIGH); 104 | digitalWrite(PinUD, HIGH); 105 | 106 | CurrentStep = 0; 107 | } 108 | 109 | // Input step [0 ; X9_STEPS] 110 | void JumpToStep(const uint8_t step, const bool store = false) 111 | { 112 | if (step > X9CXXX::X9_STEPS - 1) 113 | { 114 | return;//Invalid step. 115 | } 116 | 117 | while (CurrentStep != step) 118 | { 119 | if (CurrentStep > step) 120 | { 121 | Down(false); 122 | } 123 | else 124 | { 125 | Up(false); 126 | } 127 | } 128 | 129 | if (store) 130 | { 131 | Store(); 132 | } 133 | } 134 | 135 | // Shifts the pot's wiper one step down. 136 | void Down(const bool store = false) 137 | { 138 | digitalWrite(PinINC, HIGH); 139 | digitalWrite(PinCS, LOW); 140 | digitalWrite(PinUD, LOW); 141 | 142 | delayMicroseconds(NINC_HIGH_TO_UND_CHANGE); 143 | digitalWrite(PinINC, LOW); 144 | 145 | if (store) 146 | { 147 | Store(); 148 | } 149 | 150 | if (CurrentStep > 0) 151 | { 152 | CurrentStep--; 153 | } 154 | } 155 | 156 | // Shifts the pot's wiper one step up. 157 | void Up(const bool store = false) 158 | { 159 | digitalWrite(PinINC, HIGH); 160 | digitalWrite(PinCS, LOW); 161 | digitalWrite(PinUD, HIGH); 162 | 163 | delayMicroseconds(NINC_HIGH_TO_UND_CHANGE); 164 | digitalWrite(PinINC, LOW); 165 | 166 | if (store) 167 | { 168 | Store(); 169 | } 170 | 171 | if (CurrentStep < X9CXXX::X9_STEPS) 172 | { 173 | CurrentStep++; 174 | } 175 | } 176 | 177 | const uint8_t GetStep() 178 | { 179 | return CurrentStep; 180 | } 181 | 182 | void Store() 183 | { 184 | digitalWrite(PinINC, HIGH); 185 | digitalWrite(PinCS, HIGH); 186 | delayMicroseconds(NCS_DESELECT_TIME_STORE);//This is way too long to wait for storage, better check elapsed outside if needed. 187 | digitalWrite(PinCS, LOW); 188 | } 189 | }; 190 | 191 | class FastX9C102 : public FastX9CXXX 192 | { 193 | public: 194 | FastX9C102() : 195 | FastX9CXXX() 196 | {} 197 | FastX9C102(const uint8_t csPin, const uint8_t udPin, const uint8_t incPin) : 198 | FastX9CXXX(csPin, udPin, incPin) 199 | {} 200 | }; 201 | 202 | class FastX9C103 : public FastX9CXXX 203 | { 204 | public: 205 | FastX9C103() : 206 | FastX9CXXX() 207 | {} 208 | FastX9C103(const uint8_t csPin, const uint8_t udPin, const uint8_t incPin) : 209 | FastX9CXXX(csPin, udPin, incPin) 210 | {} 211 | }; 212 | 213 | class FastX9C104 : public FastX9CXXX 214 | { 215 | public: 216 | FastX9C104() : 217 | FastX9CXXX() 218 | {} 219 | FastX9C104(const uint8_t csPin, const uint8_t udPin, const uint8_t incPin) : 220 | FastX9CXXX(csPin, udPin, incPin) 221 | {} 222 | }; 223 | 224 | class FastX9C503 : public FastX9CXXX 225 | { 226 | public: 227 | FastX9C503() : 228 | FastX9CXXX() 229 | {} 230 | FastX9C503(const uint8_t csPin, const uint8_t udPin, const uint8_t incPin) : 231 | FastX9CXXX(csPin, udPin, incPin) 232 | {} 233 | }; 234 | #endif 235 | --------------------------------------------------------------------------------