Giter Club home page Giter Club logo

ad520x's Introduction

Arduino CI Arduino-lint JSON check GitHub issues

License: MIT GitHub release PlatformIO Registry

AD520X

Arduino library for SPI AD5204 and AD5206 digital potentiometers.

Works with the AD840x series too (see PR #15)

Description

The library is experimental as not all functionality is tested (enough).

The AD5204 (4 channels) and AD5206 (6 channels) are SPI based digital potentiometers. This library consists of a base class AD520X that does the work.

The interface is straightforward, one can set a value per channels between 0..255.

type channels 1 kΩ 10 kΩ 50 kΩ 100 kΩ works
AD5204 4 V V V confirmed
AD5206 6 V V V confirmed
AD8400 1 V V V V confirmed
AD8402 2 V V V V
AD8403 4 V V V V confirmed

The library is not yet confirmed to work for AD8402 (2 channels). This device has a very similar interface (datasheet comparison) so it should work. If you can confirm the AD8402 works, please let me know.

0.5.0 Breaking change

Version 0.5.0 introduced a breaking change to improve handling the SPI dependency. The user has to call SPI.begin() or equivalent before calling AD520X.begin(). Optionally the user can provide parameters to the SPI.begin(...)

0.4.0 breaking change

The version 0.4.0 has breaking changes in the interface. The essence is removal of ESP32 specific code from the library. This makes it possible to support the ESP32-S3 and other processors in the future. Also it makes the library a bit simpler to maintain.

Related

Interface

#include "AD520X.h"

Constructors

  • AD520X(uint8_t select, uint8_t reset, uint8_t shutdown, SPIClassRP2040 * mySPI = &SPI) constructor HW SPI (RP2040 specific)
  • AD520X(uint8_t select, uint8_t reset, uint8_t shutdown, SPIClass * mySPI = &SPI) constructor HW SPI
  • AD520X(uint8_t select, uint8_t reset, uint8_t shutdown, uint8_t dataOut, uint8_t clock) constructor SW SPI Base class, not to be used directly.
  • AD5204(select, reset, shutdown, ...) has 4 channels. As above.
  • AD5206(select, reset, shutdown, ...) has 6 channels. As above.
  • AD8400(select, reset, shutdown, ...) has 1 channel. As above.
  • AD8402(select, reset, shutdown, ...) has 2 channels. As above.
  • AD8403(select, reset, shutdown, ...) has 4 channels. As above.

Note:

  • hardware SPI is 10+ times faster on an UNO than software SPI.
  • software SPI on ESP32 is about equally fast than hardware SPI.

Base

Since 0.2.0 the functions have more default parameters. Potentiometer is default pot 0 and value is default the AD520X_MIDDLE_VALUE of 128.

  • void begin(uint8_t value = 128) value is the initial value of all potentiometer.
  • void reset(uint8_t value = 128) resets the device and sets all potentiometers to value, default 128.

Value

  • bool setValue(uint8_t pm = 0, uint8_t value = 128) set a potentiometer to a value. Default value is middle value.
    Returns true if successful, false if not.
  • bool setValue(uint8_t pmA, uint8_t pmB, uint8_t value) set two potentiometers to same value. Note, no default value! Returns true if successful, false if not.
  • void setAll(uint8_t value = 128) set all potentiometers to the same value e.g. 0 or max or mid value. Can typically be used for mute.
  • uint8_t getValue(uint8_t pm = 0) returns the last set value of a specific potentiometer.
  • setGroupValue(mask, value) bit mask to set 0..8 channels in one call.

The library has defined #define AD520X_MIDDLE_VALUE 128

Percentage

  • bool setPercentage(uint8_t pm = 0, float percentage = 50) similar to setValue, percentage from 0..100%, default potmeter 0 and 50%. Returns true when successful, false if not.
  • bool setPercentage(uint8_t pmA, uint8_t pmB, float percentage) similar to setValue, percentage from 0..100%. Note, no default value. Returns true when successful, false if not.
  • float getPercentage(uint8_t pm = 0) return the value of potentiometer pm as percentage.
  • setGroupPercentage(mask, value) bit mask to set 0..8 channels in one call.

Hardware SPI

To be used only if one needs a specific speed for hardware SPI.
Has no effect on software SPI.

  • void setSPIspeed(uint32_t speed) set SPI transfer rate.
  • uint32_t getSPIspeed() returns SPI transfer rate.

Misc

  • uint8_t pmCount() returns the number of internal potentiometers.
  • void powerOn() switches the module on.
  • void powerOff() switches the module off.
  • bool isPowerOn() returns true if on (default) or false if off.

Debugging

  • bool usesHWSPI() returns true / false depending on constructor.

Future

Must

  • improve documentation

Should

  • extend unit tests
  • extent examples

Could (only if requested.)

  • AD520X_MIDDLE_VALUE 127 ? (0.4.0?)
  • setSWSPIdelay(uint8_t del = 0) to tune software SPI?
    • bit delay / not byte delay
    • unit microseconds
    • if (_del) delayMicroseconds(_del/2); // pre and post pulse.
  • void setInvert(uint8_t pm) invert flag per potentiometer.
    • 0..255 -> 255..0
    • 1 uint8_t can hold 8 flags
    • will slow performance
    • how does this work with stereo functions.
    • at what level should invert work.
  • bool getInvert(uint8_t pm)

Wont

  • void setGamma(uint8_t pm, float gamma)
  • void follow(pm_B, pm_A, float percentage = 100)
    • makes pm_B follow pm_A unless pm_B is addressed explicitly
    • e.g. to be used for stereo channels.
    • array cascade = 0xFF or pm_A.
    • It will follow pm_A for certain percentage default 100.

Support

If you appreciate my libraries, you can support the development and maintenance. Improve the quality of the libraries by providing issues and Pull Requests, or donate through PayPal or GitHub sponsors.

Thank you,

ad520x's People

Contributors

ale11re avatar robtillaart avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

ad520x's Issues

Wrong SPI_MODE for AD8403

Hi,
I noticed that using pot.setValue(0, x) and pot.setValue(1, x) has effect on potentiometer 1 both in half scale.
Similarly, using pot.setValue(2, x) and pot.setValue(3, x) has effect on potentiometer 2.
Could not find effect on potentiometer 3 and 4.

Not an issue. Letting you know I used it on an ad8400 and it works fine.

I do have a couple of questions as I am trying to use it with a circuitpython project and there is no library for it. I looked through your library and I'm a newb with libraries. Is the baudrate 16000000?
Do you set the mode and the phase?
What is the format of the data sent to the chip?
I'm close to having it work but it's hit or miss if the chip reacts to the command or not

Thanks!!

VSPI not declared in this scope

I'm trying to use this code for an adafruit ESP32-S2 board using the 2.0.0 release of the arduino IDE and I get the following error:

`c:\Users\aerejb\Documents\Arduino\libraries\AD520X\AD520X.cpp: In member function 'void AD520X::begin(uint8_t)':
c:\Users\aerejb\Documents\Arduino\libraries\AD520X\AD520X.cpp:61:28: error: 'VSPI' was not declared in this scope
mySPI = new SPIClass(VSPI);
^~~~
c:\Users\aerejb\Documents\Arduino\libraries\AD520X\AD520X.cpp:61:28: note: suggested alternative: 'SPI'
mySPI = new SPIClass(VSPI);
^~~~
SPI

Compilation error: exit status 1`

My sketch is as follows:

#include "AD520X.h"

uint32_t start, stop;
// select, reset, shutdown, data, clock
AD8400 pot(10, 255, 255, 11, 13);  // SW SPI

// define inputs
const byte right_turn_input = A1;
const byte left_turn_input = 5;
const byte on_off_input = A3;
const byte speed_input = A2;

// define outputs
const byte right_turn_output = 2;
const byte left_turn_output = 4;
const byte on_off_output = 6;
const byte speed_output = 3;

// define variables

int speed_value = 0;
int satelite_count = 0;

bool motor_state = false;

float motor_offset_angle = 0;
float magnetic_declination = 0;
float boat_heading = 0;
float desired_heading = 0;

double actual_lattitude = 0;
double actual_longitude = 0;
double desired_lattitude = 0;
double desired_longitude = 0;





void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  Serial.println("Begin program");

  pot.begin(0); // set initial potentiometer value to zero (this gives you the wiper resistance 50-100 ohms)

  // define pin inputs
  pinMode(right_turn_input, INPUT);
  pinMode(left_turn_input, INPUT);
  pinMode(on_off_input, INPUT);
  pinMode(speed_input, INPUT);

  // define pin outputs
  pinMode(right_turn_output, OUTPUT);
  pinMode(left_turn_output, OUTPUT);
  pinMode(on_off_output, OUTPUT);
  pinMode(speed_output, OUTPUT);

}

void loop() {
  // put your main code here, to run repeatedly:
  delay(10);
  on_off();
  
  if (motor_state == true) {
    speed_calculation();
    steering_calculation();
  }
  //Serial.println(" ");
}

void speed_calculation() {
  // figure out what the speed value is
  
  speed_value = analogRead(speed_input) / 4;
  if (speed_value > 256) { speed_value = 256; }
  if (speed_value < 20) { speed_value = 0; }
  pot.setValue(0,speed_value);  // Set digital potentiometer value for the motor to read
  //analogWrite(speed_output, speed_value);
  Serial.print("Output speed value = "); Serial.print(speed_value); Serial.print(", ");
}

void steering_calculation() {
  // figure out what the steering should change
  if (digitalRead(right_turn_input) == 1) {
    digitalWrite(left_turn_output, 0);
    digitalWrite(right_turn_output, 1);
    Serial.print("Turn Right,  ");
  }
  delay(5);
  
  if (digitalRead(right_turn_input) == 0) {
    digitalWrite(right_turn_output, 0);
    Serial.print("deactivate right turn,  ");
  }
  delay(5);
  
  if (digitalRead(left_turn_input) == 1) {
    digitalWrite(right_turn_output, 0);
    digitalWrite(left_turn_output, 1);
    Serial.print("Turn Left,  ");
  }
  delay(5);
  
  if (digitalRead(left_turn_input) == 0) {
    digitalWrite(left_turn_output, 0);
    Serial.print("deactivate left turn,  ");
  }
  delay(5);
}

void on_off() {
  motor_state = digitalRead(on_off_input);
  digitalWrite(on_off_output, motor_state);
  
  if (motor_state == true) {
    Serial.println(", Motor on");
  }
  else {
    Serial.println(", Motor off");
  }
}

Inverted Logic on AD8403

Hi,
I was playing around with the AD8403 chip and I noticed that Shutdown and Reset logic are inverted.
They're both active LOW. In fact, if shutdown is LOW, the output is disabled. Looking deep into the library source it's exactly the opposite. Cannot understand how it works with AD5204 as it shares the same logic principle.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.