GY-63_MS5611/libraries/X9C10X/X9C10X.cpp

259 lines
4.3 KiB
C++
Raw Normal View History

2022-02-14 14:53:03 -05:00
//
// FILE: X9C10X.cpp
// AUTHOR: Rob Tillaart
2022-11-27 05:27:05 -05:00
// VERSION: 0.2.2
2022-02-14 14:53:03 -05:00
// PURPOSE: Arduino Library for X9C10X series digital potentiometer.
2022-02-23 09:57:01 -05:00
// URL: https://github.com/RobTillaart/X9C10X
2022-02-14 14:53:03 -05:00
#include "X9C10X.h"
2022-07-24 10:36:28 -04:00
2022-02-14 14:53:03 -05:00
// minimum pulse width CLOCK = ? us (datasheet);
// digitalWrite takes enough time on UNO / AVR so clock_delay == 0
// Note that if clock pulses are long enough the data pulses are too.
#ifdef __AVR__
2022-02-15 11:54:24 -05:00
#define X9C10X_DELAY_MICROS 0
2022-02-14 14:53:03 -05:00
#else
2022-02-15 11:54:24 -05:00
#define X9C10X_DELAY_MICROS 1
2022-02-14 14:53:03 -05:00
#endif
#define X9C10X_UP HIGH
#define X9C10X_DOWN LOW
2022-07-24 10:36:28 -04:00
#define X9C10X_MAXPOT 99
2022-02-14 14:53:03 -05:00
2022-07-15 06:26:27 -04:00
/////////////////////////////////////////////////////////
//
// MINIMALISTIC BASE CLASS
//
X9C::X9C()
2022-02-14 14:53:03 -05:00
{
}
2022-07-15 06:26:27 -04:00
void X9C::begin(uint8_t pulsePin, uint8_t directionPin, uint8_t selectPin)
2022-02-14 14:53:03 -05:00
{
_pulsePin = pulsePin;
_directionPin = directionPin;
_selectPin = selectPin;
2022-07-15 06:26:27 -04:00
// #7 order of the initialization does matter
// as it might introduce an unwanted STORE pulse.
// use of pull ups might be wise.
digitalWrite(_selectPin, HIGH);
2022-02-14 14:53:03 -05:00
digitalWrite(_pulsePin, HIGH);
digitalWrite(_directionPin, HIGH);
2022-07-15 06:26:27 -04:00
pinMode(_selectPin, OUTPUT);
pinMode(_pulsePin, OUTPUT);
pinMode(_directionPin, OUTPUT);
2022-02-14 14:53:03 -05:00
// wiper power up time. Page 5.
delayMicroseconds(500);
2022-07-15 06:26:27 -04:00
}
2022-02-14 14:53:03 -05:00
2022-07-15 06:26:27 -04:00
bool X9C::incr()
{
_move(X9C10X_UP);
return true;
}
bool X9C::decr()
{
_move(X9C10X_DOWN);
return true;
}
void X9C::store()
{
// _pulsePin starts default HIGH
digitalWrite(_selectPin, LOW);
#if X9C10X_DELAY_MICROS > 0
delayMicroseconds(X9C10X_DELAY_MICROS);
#endif
digitalWrite(_selectPin, HIGH);
delay(20); // Tcph page 5
}
/////////////////////////////////////////////////////////
//
// PROTECTED
//
void X9C::_move(uint8_t direction, uint8_t steps)
{
digitalWrite(_directionPin, direction);
delayMicroseconds(3); // Tdi (page 5)
// _pulsePin starts default HIGH
digitalWrite(_selectPin, LOW);
while (steps--)
{
digitalWrite(_pulsePin, HIGH);
#if X9C10X_DELAY_MICROS > 0
delayMicroseconds(X9C10X_DELAY_MICROS);
#endif
digitalWrite(_pulsePin, LOW);
#if X9C10X_DELAY_MICROS > 0
delayMicroseconds(X9C10X_DELAY_MICROS);
#endif
}
// _pulsePin == LOW, (No Store, page 7)
digitalWrite(_selectPin, HIGH);
// reset _pulsePin to default.
digitalWrite(_pulsePin, HIGH);
}
/////////////////////////////////////////////////////////
//
// X9C10X BASE CLASS
//
X9C10X::X9C10X(uint32_t maxOhm) : X9C()
{
_maxOhm = maxOhm;
2022-02-14 14:53:03 -05:00
}
2022-07-24 10:36:28 -04:00
uint8_t X9C10X::setPosition(uint8_t position, bool forced)
2022-02-14 14:53:03 -05:00
{
2022-07-24 10:36:28 -04:00
if (position > 99)
{
position = 99;
}
2022-02-23 09:57:01 -05:00
2022-07-24 10:36:28 -04:00
// force to nearest end position first to minimize number of steps.
2022-02-23 09:57:01 -05:00
if (forced)
{
if (position < 50)
{
_move(X9C10X_DOWN, 99);
_position = 0;
}
else
{
_move(X9C10X_UP, 99);
_position = 99;
}
}
2022-02-16 14:14:45 -05:00
if (position > _position)
{
_move(X9C10X_UP, position - _position);
}
if (position < _position)
{
_move(X9C10X_DOWN, _position - position);
}
2022-02-23 09:57:01 -05:00
2022-02-16 14:14:45 -05:00
_position = position;
2022-07-24 10:36:28 -04:00
return _position;
2022-02-14 14:53:03 -05:00
}
2022-11-27 05:27:05 -05:00
uint8_t X9C10X::getPosition()
{
return _position;
}
2022-02-23 09:57:01 -05:00
bool X9C10X::incr()
2022-02-14 14:53:03 -05:00
{
2022-02-23 09:57:01 -05:00
if (_position >= 99) return false;
2022-02-14 14:53:03 -05:00
_position++;
_move(X9C10X_UP);
2022-02-23 09:57:01 -05:00
return true;
2022-02-14 14:53:03 -05:00
}
2022-02-23 09:57:01 -05:00
bool X9C10X::decr()
2022-02-14 14:53:03 -05:00
{
2022-02-23 09:57:01 -05:00
if (_position == 0) return false;
2022-02-14 14:53:03 -05:00
_position--;
_move(X9C10X_DOWN);
2022-02-23 09:57:01 -05:00
return true;
2022-02-14 14:53:03 -05:00
}
uint8_t X9C10X::store()
{
2022-07-15 06:26:27 -04:00
X9C::store();
2022-02-14 14:53:03 -05:00
return _position;
}
2022-07-24 10:36:28 -04:00
uint8_t X9C10X::restoreInternalPosition(uint8_t position)
{
if (position > 99)
{
position = 99;
}
_position = position;
return _position;
}
2022-07-15 06:26:27 -04:00
// rounding needed!
uint32_t X9C10X::getOhm()
2022-02-14 14:53:03 -05:00
{
2022-07-15 06:26:27 -04:00
return (_maxOhm * _position + 49) / 99;
};
2022-02-14 14:53:03 -05:00
2022-02-15 11:54:24 -05:00
2022-07-15 06:26:27 -04:00
uint32_t X9C10X::getMaxOhm()
{
return _maxOhm;
};
// rounding needed!
uint8_t X9C10X::Ohm2Position(uint32_t value, bool invert)
{
if (value > _maxOhm) return 99;
uint8_t val = (99 * value + _maxOhm/2) / _maxOhm;
if (invert) return 99 - val;
return val;
2022-02-14 14:53:03 -05:00
}
2022-07-15 06:26:27 -04:00
uint16_t X9C10X::getType()
{
return _type;
};
2022-02-14 14:53:03 -05:00
/////////////////////////////////////////////////////////
//
2022-07-15 06:26:27 -04:00
// SPECIFIC DERIVED DEVICE CLASSES
2022-02-14 14:53:03 -05:00
//
X9C102::X9C102(uint32_t ohm) : X9C10X(ohm)
{
_type = 102;
}
X9C103::X9C103(uint32_t ohm) : X9C10X(ohm)
{
_type = 103;
}
X9C104::X9C104(uint32_t ohm) : X9C10X(ohm)
{
_type = 104;
}
X9C503::X9C503(uint32_t ohm) : X9C10X(ohm)
{
_type = 503;
}
// -- END OF FILE --