From 9998b63739e53031b4a148f86938cb1dad0845a6 Mon Sep 17 00:00:00 2001 From: brendanmatkin Date: Mon, 30 Oct 2023 10:56:24 -0600 Subject: [PATCH 1/4] move pin mux to startADC + add us delay --- src/ADS126X.cpp | 47 +++++++++++++++++------------- src/ADS126X.h | 8 ++--- src/boards/arduino.cpp | 5 ++++ src/definitions/ADS126X_hardware.h | 3 ++ 4 files changed, 38 insertions(+), 25 deletions(-) diff --git a/src/ADS126X.cpp b/src/ADS126X.cpp index f90bd2a..d5627fa 100755 --- a/src/ADS126X.cpp +++ b/src/ADS126X.cpp @@ -43,28 +43,47 @@ void ADS126X::reset() { ADS126X::readRegisters(0,ADS126X_REG_NUM); // read all the registers } -void ADS126X::startADC1() { +void ADS126X::startADC1(uint8_t pos_pin, uint8_t neg_pin) { + // NOTE: can take up to 50ms for VRef to settle after power on (and possibly after changing certain registers?) + // check if desired pins are different than old pins + if ((REGISTER.INPMUX.bit.MUXN != neg_pin) || (REGISTER.INPMUX.bit.MUXP != pos_pin)) { + REGISTER.INPMUX.bit.MUXN = neg_pin; + REGISTER.INPMUX.bit.MUXP = pos_pin; + ADS126X::writeRegister(ADS126X_INPMUX); // replace on ads126x + } if(start_used) { _ads126x_write_pin_low(start_pin); - _ads126x_delay(2); + _ads126x_delaymicro(2); // p.61 delay needs to be ~5.42534722e-7 seconds. so like 0.5us I think? _ads126x_write_pin_high(start_pin); + _ads126x_delaymicro(2); + _ads126x_write_pin_low(start_pin); + _ads126x_delaymicro(2); } else ADS126X::sendCommand(ADS126X_START1); } void ADS126X::stopADC1() { - ADS126X::sendCommand(ADS126X_STOP1); + if (start_used) { + _ads126x_write_pin_low(start_pin); + } + else ADS126X::sendCommand(ADS126X_STOP1); } -void ADS126X::startADC2() { - ADS126X::sendCommand(ADS126X_START2); +void ADS126X::startADC2(uint8_t pos_pin, uint8_t neg_pin) { + // check if desired pins are different than old pins + if ((REGISTER.ADC2MUX.bit.MUXN != neg_pin) || (REGISTER.ADC2MUX.bit.MUXP != pos_pin)) { + REGISTER.ADC2MUX.bit.MUXN = neg_pin; + REGISTER.ADC2MUX.bit.MUXP = pos_pin; + ADS126X::writeRegister(ADS126X_ADC2MUX); // replace on ads126x + } + else ADS126X::sendCommand(ADS126X_START2); } void ADS126X::stopADC2() { ADS126X::sendCommand(ADS126X_STOP2); } -int32_t ADS126X::readADC1(uint8_t pos_pin,uint8_t neg_pin) { +int32_t ADS126X::readADC1() { if(cs_used) _ads126x_write_pin_low(cs_pin); // create buffer to hold transmission @@ -81,13 +100,6 @@ int32_t ADS126X::readADC1(uint8_t pos_pin,uint8_t neg_pin) { } ADC_BYTES; ADC_BYTES.reg = 0; // clear the ram just in case - // check if desired pins are different than old pins - if((REGISTER.INPMUX.bit.MUXN != neg_pin) || (REGISTER.INPMUX.bit.MUXP != pos_pin)) { - REGISTER.INPMUX.bit.MUXN = neg_pin; - REGISTER.INPMUX.bit.MUXP = pos_pin; - ADS126X::writeRegister(ADS126X_INPMUX); // replace on ads126x - } - uint8_t i = 0; // current place in outgoing buffer buff[i] = ADS126X_RDATA1; // the read adc1 command i++; @@ -124,7 +136,7 @@ int32_t ADS126X::readADC1(uint8_t pos_pin,uint8_t neg_pin) { return ADC_BYTES.reg; } -int32_t ADS126X::readADC2(uint8_t pos_pin,uint8_t neg_pin) { +int32_t ADS126X::readADC2() { if(cs_used) _ads126x_write_pin_low(cs_pin); // create buffer to hold transmission @@ -141,13 +153,6 @@ int32_t ADS126X::readADC2(uint8_t pos_pin,uint8_t neg_pin) { } ADC_BYTES; ADC_BYTES.reg = 0; // clear so pad byte is 0 - // check if desired pins are different than old pins - if((REGISTER.ADC2MUX.bit.MUXN != neg_pin) || (REGISTER.ADC2MUX.bit.MUXP != pos_pin)) { - REGISTER.ADC2MUX.bit.MUXN = neg_pin; - REGISTER.ADC2MUX.bit.MUXP = pos_pin; - ADS126X::writeRegister(ADS126X_ADC2MUX); // replace on ads126x - } - uint8_t i = 0; // current place in outgoing buffer buff[i] = ADS126X_RDATA2; // the read adc2 command i++; diff --git a/src/ADS126X.h b/src/ADS126X.h index c8a4039..1d5d053 100755 --- a/src/ADS126X.h +++ b/src/ADS126X.h @@ -23,13 +23,13 @@ class ADS126X { //General Commands void noOperation(void); void reset(void); - void startADC1(void); + void startADC1(uint8_t pos_pin, uint8_t neg_pin); void stopADC1(void); - void startADC2(void); + void startADC2(uint8_t pos_pin, uint8_t neg_pin); void stopADC2(void); // Analog Read Functions - int32_t readADC1(uint8_t pos_pin,uint8_t neg_pin); - int32_t readADC2(uint8_t pos_pin,uint8_t neg_pin); + int32_t readADC1(void); + int32_t readADC2(void); // Calibration Functions void calibrateSysOffsetADC1(uint8_t shorted1,uint8_t shorted2); void calibrateGainADC1(uint8_t vcc_pin,uint8_t gnd_pin); diff --git a/src/boards/arduino.cpp b/src/boards/arduino.cpp index 682b31d..2473b60 100755 --- a/src/boards/arduino.cpp +++ b/src/boards/arduino.cpp @@ -53,4 +53,9 @@ void _ads126x_delay(uint16_t ms) { delay(ms); } +// wait for the desired microseconds +void _ads126x_delaymicro(uint16_t us) { + delayMicroseconds(us); +} + #endif // ifdef ARDUINO diff --git a/src/definitions/ADS126X_hardware.h b/src/definitions/ADS126X_hardware.h index 5e091a3..796a8a9 100755 --- a/src/definitions/ADS126X_hardware.h +++ b/src/definitions/ADS126X_hardware.h @@ -26,4 +26,7 @@ void _ads126x_spi_rw(uint8_t buff[],uint8_t len); // wait for the desired milliseconds void _ads126x_delay(uint16_t ms); +// wait for the desired microseconds +void _ads126x_delaymicro(uint16_t us); + #endif // define ADS126X_HARDWARE_H From 7483fcc2b403b6bb86b8bf9fe296deeb09f19315 Mon Sep 17 00:00:00 2001 From: brendanmatkin Date: Mon, 30 Oct 2023 10:57:01 -0600 Subject: [PATCH 2/4] getGain helper function --- src/ADS126X.cpp | 4 ++++ src/ADS126X.h | 1 + 2 files changed, 5 insertions(+) diff --git a/src/ADS126X.cpp b/src/ADS126X.cpp index d5627fa..7b8e39c 100755 --- a/src/ADS126X.cpp +++ b/src/ADS126X.cpp @@ -433,6 +433,10 @@ void ADS126X::setGain(uint8_t gain) { ADS126X::writeRegister(ADS126X_MODE2); } +uint8_t ADS126X::getGain() { + return REGISTER.MODE2.bit.GAIN; +} + void ADS126X::setRate(uint8_t rate) { REGISTER.MODE2.bit.DR = rate; ADS126X::writeRegister(ADS126X_MODE2); diff --git a/src/ADS126X.h b/src/ADS126X.h index 1d5d053..be5551a 100755 --- a/src/ADS126X.h +++ b/src/ADS126X.h @@ -87,6 +87,7 @@ class ADS126X { void enablePGA(void); void bypassPGA(void); void setGain(uint8_t gain); + uint8_t getGain(void); void setRate(uint8_t rate); void setReference(uint8_t negativeReference, uint8_t positiveReference); From 799da676c00a2e1925bbb44a1112cdbe80528165 Mon Sep 17 00:00:00 2001 From: brendanmatkin Date: Mon, 30 Oct 2023 10:57:34 -0600 Subject: [PATCH 3/4] add DRDY pin (data ready) + helpers --- src/ADS126X.cpp | 15 +++++++++++++++ src/ADS126X.h | 4 ++++ 2 files changed, 19 insertions(+) diff --git a/src/ADS126X.cpp b/src/ADS126X.cpp index 7b8e39c..f390b96 100755 --- a/src/ADS126X.cpp +++ b/src/ADS126X.cpp @@ -32,6 +32,12 @@ void ADS126X::setStartPin(uint8_t pin) { _ads126x_write_pin_low(start_pin); } +void ADS126X::setDrdyPin(uint8_t pin) { + drdy_used = true; + drdy_pin = pin; + _ads126x_setup_input(drdy_pin); +} + /*!< Regular ADC Commands */ void ADS126X::noOperation() { @@ -83,6 +89,15 @@ void ADS126X::stopADC2() { ADS126X::sendCommand(ADS126X_STOP2); } +// NOTE: only drdy_pin version is implemented! +bool ADS126X::dataReady() { + if (drdy_used) { + return !_ads126x_read_pin(drdy_pin); // LOW == data ready. + } else { + return true; // TODO: enable status byte and read ADC and check appropriate status bit + } +} + int32_t ADS126X::readADC1() { if(cs_used) _ads126x_write_pin_low(cs_pin); diff --git a/src/ADS126X.h b/src/ADS126X.h index be5551a..490cf51 100755 --- a/src/ADS126X.h +++ b/src/ADS126X.h @@ -18,6 +18,7 @@ class ADS126X { void begin(uint8_t chip_select); void begin(void); void setStartPin(uint8_t pin); // designate a pin connected to START + void setDrdyPin(uint8_t pin); // designate a pin connected to DRDY (Data Ready) // All ADC Commands. Page 85 //General Commands @@ -28,6 +29,7 @@ class ADS126X { void startADC2(uint8_t pos_pin, uint8_t neg_pin); void stopADC2(void); // Analog Read Functions + bool dataReady(void); int32_t readADC1(void); int32_t readADC2(void); // Calibration Functions @@ -112,6 +114,8 @@ class ADS126X { uint8_t cs_pin; // chip select pin bool start_used = false; uint8_t start_pin; // start pin + bool drdy_used = false; + uint8_t drdy_pin; // drdy pin (data ready) ADS126X_STATUS_Type STATUS; // save last status and checksum values uint8_t CHECKSUM; From 3d98f5eab4ac8a684b0d9fe611287b119403899d Mon Sep 17 00:00:00 2001 From: brendanmatkin Date: Mon, 30 Oct 2023 11:40:05 -0600 Subject: [PATCH 4/4] update basics.ino + docs --- README.md | 62 ++++++++++++++++++++++---------------- examples/basics/basics.ino | 4 +-- 2 files changed, 38 insertions(+), 28 deletions(-) diff --git a/README.md b/README.md index 06145ca..7f3fe52 100755 --- a/README.md +++ b/README.md @@ -110,6 +110,10 @@ void setStartPin(uint8_t pin) Optional. Designate an Arduino pin to start ADC1. If not used, a command will be sent instead. +void setDrdyPin(uint8_t pin) +----------------------------- +Optional. Designate an Arduino pin to watch for Data Ready. +If not used, calibrations will require a `waitTime` and dataReady() will always return true. General Commands ================ @@ -122,29 +126,9 @@ void reset() ------------ Resets the chip. -void startADC1() ----------------- -Starts conversion on ADC1. - -void stopADC1() ---------------- -Stops conversion on ADC1. - -void startADC2() +void startADC1(uint8_t pos_pin, uint8_t neg_pin) ---------------- -Starts conversion on ADC2. - -void stopADC2() ---------------- -Stops conversion on ADC2. - - -Analog Read Functions -===================== - -int32_t readADC1(uint8_t pos_pin,uint8_t neg_pin) -------------------------------------------------- -Reads the 32 bit voltage between the two pins `pos_pin` and `neg_pin`. +Starts conversion on ADC1 between the two pins `pos_pin` and `neg_pin`. These can be: | Option | Description | @@ -159,9 +143,13 @@ These can be: | `ADS126X_TDAC` | TDAC test signal positive/negative | | `ADS126X_FLOAT` | Float (open connection) | -int32_t readADC2(uint8_t pos_pin,uint8_t neg_pin) -------------------------------------------------- -Reads the 24 bit voltage between the two pins `pos_pin` and `neg_pin`. +void stopADC1() +--------------- +Stops conversion on ADC1. Uses `start_pin` if it was set (via `setStartPin`), sends a command if it wasn't. + +void startADC2(uint8_t pos_pin, uint8_t neg_pin) +---------------- +Starts conversion on ADC2 between the two pins `pos_pin` and `neg_pin`. These can be: | Option | Description | @@ -174,8 +162,26 @@ These can be: | `ADS126X_ANALOG` | Analog power supply monitor positive/negative | | `ADS126X_DIGITAL` | Digital power supply monitor positive/negative | | `ADS126X_TDAC` | TDAC test signal positive/negative | -| `ADS126X_FLOAT` | Float (open connection) | +| `ADS126X_FLOAT` | Float (open connection) | + +void stopADC2() +--------------- +Stops conversion on ADC2. + +Analog Read Functions +===================== +int32_t readADC1() +------------------------------------------------- +Reads the 32 bit voltage between the pins set in `startADC1`. + +int32_t readADC2(uint8_t pos_pin,uint8_t neg_pin) +------------------------------------------------- +Reads the 24 bit voltage between the pins set in `startADC2`. + +bool dataReady() +--------------- +If `setDrdyPin` was used, returns true when the adc's `DRDY` (data ready indicator) pin is `LOW`. If not pin was set, this always returns true. Useful for getting continuous conversions as quickly as possible. Almost certainly faster than command polling (especially if you attach this pin to an interrupt routine). Calibration Functions ===================== @@ -553,6 +559,10 @@ Selects the PGA gain | `ADS126X_GAIN_16` | 16 V/V | | `ADS126X_GAIN_32` | 32 V/V | +void getGain() +-------------- +Returns the value of the constant used in setGain (i.e. `ADS126X_GAIN_1` -> `0b000` which is int `0`). To get the corresponding actual voltage gain, do something like `uint8_t voltageGainValue = 1 << adc.getGain();` (`ADS126X_GAIN_1` would return `1`). + void setRate(uint8_t rate) -------------------------- Selects the ADC data rate. In FIR filter mode, the available data diff --git a/examples/basics/basics.ino b/examples/basics/basics.ino index 86f06a0..e37c15f 100755 --- a/examples/basics/basics.ino +++ b/examples/basics/basics.ino @@ -15,13 +15,13 @@ void setup() { Serial.begin(115200); adc.begin(chip_select); // setup with chip select pin - adc.startADC1(); // start conversion on ADC1 + adc.startADC1(pos_pin, neg_pin); // start conversion on ADC1 Serial.println("Reading Voltages:"); } void loop() { - long voltage = adc.readADC1(pos_pin,neg_pin); // read the voltage + long voltage = adc.readADC1(); // read the voltage Serial.println(voltage); // send voltage through serial delay(1000); // wait 1 second }