Open ziatajo opened 5 years ago
No need to self-deprecate! Let me make sure I understand your problem. You were able to successfully use the example code. Then you changed the loop function to something like:
void loop() {
long voltage1 = adc.readADC1(pos_pin1,neg_pin1);
long voltage2 = adc.readADC2(pos_pin2,neg_pin2);
Serial.print(voltage1);
Serial.print(", ");
Serial.println(voltage2); // send voltage through serial
delay(1000); // wait 1 second
}
and now you are only getting 0 and -1. Is that correct?
Exactly, both sensor values are only 0 or -1 now. I'm using an Adafruit Feather ESP32 if that helps. Let me know if you need something else. Thank you for your help.
Are you using 3.3V on DVDD and 5V on AVDD? The esp32 is not 5V tolerant, so the ads126x digital side needs to be run at 3.3V (or use level shifters). The ads126x analog side requires 5V to operate.
Try commenting out one of the voltage read lines, maybe there was an introduced change that messed with the reading.
I do not have an ads126x readily available, but I had problems with it when uploading new code to a microcontroller. Try uploading the code, disconnecting all power to your circuit for a few seconds, then power it back on.
That is a good point. I have a Step-Up for the 5V, but connected DVDD and AVDD to 5V now I changed that DVDD is on the 3.3V. Unfortunately it didn't change the result and it's still the same. My code at the moment is:
#include <ADS126X.h>
ADS126X adc1; // start the class
int chip_select1 = 4; // Arduino pin connected to CS on ADS126X
long voltage1 = 0;
long voltage2 = 0;
int pos_pin1 = 0; // ADS126X pin AIN0, for positive input
int neg_pin1 = 1; // ADS126X pin AIN1, for negative input
int pos_pin2 = 2;
int neg_pin2 = 3;
void setup() {
Serial.begin(115200);
adc1.begin(chip_select1); // setup with chip select pin0.
adc1.startADC1(); // start conversion on ADC1
Serial.println("Reading Voltages:");
}
void loop() {
voltage1 = adc1.readADC1(pos_pin1,neg_pin1); // read the voltage
Serial.print(voltage1); // send voltage through serial
delay(100);
Serial.print(" , ");
voltage2 = adc1.readADC1(pos_pin2,neg_pin2); // read the voltage
Serial.println(voltage2); // send voltage through serial
delay(100);
}
I only get 0 and -1 (don't know when it is changing between the two). When I comment out one of the "voltagex=adc1.readADC1...." lines the still active sensor works. (it works for both sensors) I also changed the delays but longer or shorter didn't help too.
EDIT: I just tried it with a Teensy 3.2 instead of the ESP32. I get the same "error". One sensor works, two sensors don't.
I think I know what the problem is. As a quick test, could you try reading each voltage twice? So:
void loop() {
adc1.readADC1(pos_pin1,neg_pin1);
voltage1 = adc1.readADC1(pos_pin1,neg_pin1); // read the voltage
Serial.print(voltage1); // send voltage through serial
delay(100);
Serial.print(" , ");
adc1.readADC1(pos_pin2,neg_pin2);
voltage2 = adc1.readADC1(pos_pin2,neg_pin2); // read the voltage
Serial.println(voltage2); // send voltage through serial
delay(100);
}
We have exactly the same issue. We also tried you code from last comment and also only recieved "0,0". A fix would be great. Reading just one of the sensors works perfectly well. Btw, thanks for the library :)
I let the ADS1262 in my office over the weekend, thats why I could test it not before now. As SammyRamone state, also with the double reading it doesn't work. However there is a small difference. With reading each voltage twice, I always only get "0 , 0", as soon as I read it only once it will change between 0 or -1 (no pattern).
Do you get the same problem with both of ContinuousMode and PulseMode?
How do I change that? :)
You can go to README.md and find setContinuousMode()
or setPulseMode()
And pls also try to use this func void setDelay(uint8_t del)
to see if it can solve something!
I changed it like the following. In two steps, first only the PulseMode(), than with delay. Both doesn't change anything. adc1.setContinuousMode(); + delay doesn't help too.
void setup() {
Serial.begin(115200);
adc1.begin(chip_select1); // setup with chip select pin0.
adc1.setDelay(ADS126X_DELAY_8_8);
adc1.setPulseMode();
adc1.startADC1(); // start conversion on ADC1
Serial.println("Reading Voltages:");
}
With the PulseMode, then can you try something like this?
void loop() {
adc1.startADC1();
voltage1 = adc1.readADC1(pos_pin1,neg_pin1); // read the voltage
Serial.print(voltage1); // send voltage through serial
adc1.stopADC1();
delay(1000);
Serial.print(" , ");
adc1.startADC1();
voltage2 = adc1.readADC1(pos_pin2,neg_pin2); // read the voltage
Serial.println(voltage2); // send voltage through serial
adc1.stopADC1();
delay(1000);
}
(The purpose is just to figure out the problem we are encountering by using some different ways to read)
With this I get the same output as at the start:
Reading Voltages: 0 , -1 0 , 0 0 , -1 -1 , -1 -1 , 0 -1 , 0 -1 , 0 -1 , -1 0 , -1 -1 , 0 0 , -1 -1 , 0 -1 , 0 0 , -1 -1 , 0 -1 , -1
Hi, Do you have any other ideas, how I could solve this?
Thank you.
Hi @ziatajo
I think we should try with single-ended mode to see :)
Instead of wiring your sensor1 to pos_pin1
and neg_pin1
, now you just connect the positive side of sensor1 to pos_pin1
, and the negative side you connect to GND of the board.
Do the same thing with your sensor2.
Then in the code, you change to something like this:
adc1.readADC1(pos_pin1, ADS126X_DIGITAL);
...
adc1.readADC1(pos_pin2, ADS126X_DIGITAL);
(I think that you should test single-ended mode with one sensor first, then test with two sensors later to see if the single-ended working well or not)
Hi @q-bird
I changed my code to your suggestion. If I read just one sensor it works, if I try to read two I get the same result as before (0 or -1)
Currently, the delay between two sensors is 1s. What will happen if you change to 10s or 20s (jst for testing)?
--> delay(10000);
(change both lines)
void loop() {
voltage1 = adc1.readADC1(pos_pin1,ADS126X_DIGITAL); // read the voltage
Serial.print(voltage1); // send voltage through seria
delay(10000);
Serial.print(" , ");
voltage2 = adc1.readADC1(pos_pin2,ADS126X_DIGITAL); // read the voltage
Serial.println(voltage2); // send voltage through serial
delay(10000);
}
This code, still the same.
OK, so please try this one
...
#define N 10
...
void loop() {
for(int i = 0; i < N; i++) {
voltage1 = adc1.readADC1(pos_pin1,ADS126X_DIGITAL); // read the voltage
delay(100);
}
Serial.print(voltage1); // send voltage through seria
delay(10000);
Serial.print(" , ");
for(int i = 0; i < N; i++) {
voltage2 = adc1.readADC1(pos_pin2,ADS126X_DIGITAL); // read the voltage
delay(100);
}
Serial.println(voltage2); // send voltage through serial
delay(10000);
}
Ok, it looks better :) The values are positive when i press my FSR resistive sensor.
Reading Voltages: -255463651 , -255539036 -255456798 , -255571295 2130455999 , -255822856 -253952042 , -252904811 -253789455 , 2118578383 357117345 , -242835174 -242840129 , -243950477 -247262989 , -246449838 -247997117 , -246418198
Ok, so I did some more tests. It seems that the double read would work, but we had to little delay. (sorry for that failed test before) It works now for N>=2 and d >= 52. This is the current code:
#include <ADS126X.h>
ADS126X adc1; // start the class
#define N 2
#define d 52
int chip_select1 = 10; // Arduino pin connected to CS on ADS126X
long voltage1 = 0;
long voltage2 = 0;
int pos_pin1 = 0; // ADS126X pin AIN0, for positive inpu
int pos_pin2 = 1;
void setup() {
Serial.begin(115200);
adc1.begin(chip_select1); // setup with chip select pin0.
adc1.startADC1(); // start conversion on ADC1
Serial.println("Reading Voltages:");
}
void loop() {
for(int i = 0; i < N; i++) {
voltage1 = adc1.readADC1(pos_pin1,ADS126X_DIGITAL); // read the voltage
delay(d);
}
Serial.print(voltage1); // send voltage through serial
Serial.print(" , ");
for(int i = 0; i < N; i++) {
voltage2 = adc1.readADC1(pos_pin2,ADS126X_DIGITAL); // read the voltage
delay(d);
}
Serial.println(voltage2); // send voltage through serial
}
EDIT:
I tried it know also with:
adc1.begin(chip_select1); // setup with chip select pin0.
adc1.setRate(ADS126X_RATE_38400);
adc1.startADC1(); // start conversion on ADC1
now I can reduce the delay to 170 Microseconds. Later I would need reading 4 differential sensors with at least 1kHz. Would that be possible somehow?
Good to hear! Now I think you can change back to read from pos_pins and neg_pins. f = 1kHz -> T = 1ms = 1000us And in order to know how long your reading will take, we will try to do something like:
...
unsigned long us = 0;
...
void loop() {
us = micros(); // micro seconds
/* Reading code */
// Your reading code here
/* End of reading code */
// Printing the time of reading code
Serial.print("T = ");
Serial.print(micros() - us);
Serial.println("us");
}
If you see the value printed is less than 1000us meaning it matches with your requirement! if not, let's try to change N
and d
and the setRate
to have the best results
Thanks for finding the problem, hopefully I will have time to push a fix this week.
The problem is it needs to restart a conversion when changing pins, so you need to do one dummy read to change the pin, delay for at least one conversion cycle, then save the next read. The necessary delay is dependent on the sampling rate (the setRate()
function). It defaults to 20 SPS, so a delay of at least 50 milliseconds (I would do 51 to be on the safe side). You can also check for when the DRDY pin is pulled low if you need precise timing.
@q-bird yes I took some more measurements, with reading every sensor twice (as it has to be now) and some Serialprinting I can reach something about 970us. So if @Molorius can solve the problem of necessary double readings, I can probably read 4 sensors within 1kHZ.
But I don't totally understand it. The samling rate of 38400 would mean 1 reading every 26 us. Is the read command taking that much longer, so that 170us is the minimum I can get?
Also, do you know what how I can do differential reading to the 2.5V internal reference? Would that be one of these?: ADS126X_TEMP | Temperature sensor monitor positive/negative 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)
If I need to measure 6 sensors, would it be possible to differential read all to the same "Neg-PIN"?
Any updates to this? Would be nice to have a real fix without the double readings
An update would really be great, I just made some further tests. I'm using now 5 full bridge load cells. So I'm always reading between Pos and Neg Pins. I now had to increase N to 4 compared to 2 before. I cannot explain why, but it makes the hole process alot slower. I also printed the 4 read values of one Sensor, and the first three are zero or -1 and the 4th has the corret value. Thank you very much.
#include <ADS126X.h>
ADS126X adc1; // start the class
#define N 4
int d=30;
int chip_select1 = 4; // Arduino pin connected to CS on ADS126X
long voltage1 = 0;
long voltage2 = 0;
long voltage3 = 0;
long voltage4 = 0;
long voltage5 = 0;
int pos_pin1 = 0; // ADS126X pin AIN0, for positive inpu
int neg_pin1 = 1;
int pos_pin2 = 2;
int neg_pin2 = 3;
int pos_pin3 = 4;
int neg_pin3 = 5;
int pos_pin4 = 6;
int neg_pin4 = 7;
int pos_pin5 = 8;
int neg_pin5 = 9;
int neg_pinInt = ADS126X_REF_POS_INT;
unsigned long us = 0;
unsigned long diff = 0;
void setup() {
Serial.begin(2000000);
adc1.begin(chip_select1); // setup with chip select pin0.
adc1.setRate(ADS126X_RATE_38400);
adc1.setGain(ADS126X_GAIN_32);
adc1.startADC1(); // start conversion on ADC1
Serial.println("Reading Voltages:");
}
void loop() {
// us = micros();
for(int i = 0; i < N; i++) {
voltage1 = adc1.readADC1(pos_pin1,neg_pin1); // read the voltage
voltage1 =voltage1>>16;
delayMicroseconds(d);
}
Serial.print(voltage1); // send voltage through serial
Serial.print(",");
for(int i = 0; i < N; i++) {
voltage2 = adc1.readADC1(pos_pin2,neg_pin2); // read the voltage
voltage2 =voltage2>>16;
delayMicroseconds(d);
}
Serial.print(voltage2); // send voltage through serial.
Serial.print(",");
for(int i = 0; i < N; i++) {
voltage3 = adc1.readADC1(pos_pin3,neg_pin3); // read the voltage
voltage3 =voltage3>>16;
delayMicroseconds(d);
}
Serial.print(voltage3); // send voltage through serial
Serial.print(",");
for(int i = 0; i < N; i++) {
voltage4 = adc1.readADC1(pos_pin4,neg_pin4); // read the voltage
voltage4 =voltage4>>16;
delayMicroseconds(d);
}
Serial.print(voltage4); // send voltage through serial
Serial.print(",");
for(int i = 0; i < N; i++) {
voltage5 = adc1.readADC1(pos_pin5,neg_pin5); // read the voltage
voltage5 =voltage5>>16;
delayMicroseconds(d);
}
Serial.println(voltage5); // send voltage through serial
// Serial.print(",");
// diff=micros() - us;
// Serial.println(diff);
}
Sorry for being annoying, but it would still be great to have a fix for this :)
It's not annoying, they're helpful reminders. I keep trying to find my ADS1262, but I can't seem to find it for testing. I will set up a branch for this so someone else can test before I put it in the main. I'll post here when I have tests to be done, but I am pretty busy at the moment so it may take a while. In the meantime, just use the DRDY pin to verify when the conversion is complete.
Hi, it's me again.
I'm still using the ADS1262. The last project I could ignore the "lower" measurement frequency. Now we have a new project where we would like to get the data of 8 sensors with ~1kHz. Therefore it would be great if this problem can be solved. I'm not a pro in programming,... But I invested quite some time now to investigate this problem. I try to describe my findings and hope you can use them to upgrade the library.
You start the
int32_t ADS126X::readADC1(uint8_t pos_pin,uint8_t neg_pin)
with
if(cs_used) _ads126x_write_pin_low(cs_pin);
However, as soon as the pos/neg - pins are changed, you call ADS126X::writeRegister(ADS126X_INPMUX);
this function calls
void ADS126X::writeRegisters(uint8_t start_reg,uint8_t num)
which also set the CS_Pin low at the start and low at the end.
There fore the CS_Pin is already HIGH when doing the rest of the readADC1 function. To try that out, just moved the
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 }
at the start of the function just before
if(cs_used) _ads126x_write_pin_low(cs_pin);
Until now it worked by waiting some time after each readADC1 and reading the same pins multiple times.
To test this, I added
#include <Arduino.h>
and a Microsecond delay after writing the registers:
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
delayMicroseconds(200);
}
The higher I make this delay, the less measurements with readADC1 I have to make. The minimal delay to only read twice depends on the samplingRate (here 38400) and probably the SPI Rate (here 80000000).
Writing new data to certain registers results in restart of conversions that are in progress.The registers that result in conversion restart(either ADC1or ADC2)are shown in the ADC Restart column in Table38. The device drives the DRDY output high when ADC1 restarts. Additionally, data can be written as a block to multiple registers using a single command. If data are written as a block,the data of certain registers take effect immediately as the data are shifted in, while the data of other registers are buffered and take effect when the command is fully completed.The registers that update as a group are identified in the Group Update column in Table 38. The group update registers that pertain to ADC1 operation are labeled Group1. The group update registers that pertain to ADC2 operation are labeled Group2. Update registers as a groupt o minimize the ADC recovery time after a configuration change.If the write command is terminated before completion,the data of group registers are not saved.
Could it be a problem that you only write the INPMUX register and not all registers of Group1? I tried to implement that into the library, but couldn't get a good result.
void ADS126X::writeRegisters(uint8_t start_reg, uint8_t num) { // page 87
if (cs_used) _ads126x_write_pin_low(cs_pin);
if (start_reg == ADS126X_INPMUX) {
uint8_t buff[50] = { 0 }; // plenty of room, all zeros
buff[0] = ADS126X_MODE0 | ADS126X_WREG; // first byte is starting register with write command
buff[1] = 7 - 1; // tell how many registers to write, see datasheet
buff[2] = REGISTER_ARRAY[ADS126X_MODE0];
buff[3] = REGISTER_ARRAY[ADS126X_MODE1];
buff[4] = REGISTER_ARRAY[ADS126X_MODE2];
buff[5] = REGISTER_ARRAY[ADS126X_INPMUX];
buff[6] = REGISTER_ARRAY[ADS126X_IDACMUX];
buff[7] = REGISTER_ARRAY[ADS126X_IDACMAG];
buff[8] = REGISTER_ARRAY[ADS126X_REFMUX];// put the desired register values in buffer
/*for (uint8_t i = 0; i < num; i++) {
buff[i + 2] = REGISTER_ARRAY[i + start_reg];
}*/
// have the microcontroller send the amounts, plus the commands
_ads126x_spi_rw(buff, 7 + 2);
}
else{
uint8_t buff[50] = { 0 }; // plenty of room, all zeros
buff[0] = start_reg | ADS126X_WREG; // first byte is starting register with write command
buff[1] = num - 1; // tell how many registers to write, see datasheet
// put the desired register values in buffer
for (uint8_t i = 0; i < num; i++) {
buff[i + 2] = REGISTER_ARRAY[i + start_reg];
}
// have the microcontroller send the amounts, plus the commands
_ads126x_spi_rw(buff, num + 2);
}
if(cs_used) _ads126x_write_pin_high(cs_pin);
}
Does this help? Do you have any ideas? I can test things if you need to! If necessary I could also send you an ADS1262..
Thank you.
Hi, Any solution for using more than 1 Channel or sensor on ads1262. Thanks in advance. Ravi
Hi Friends, Finally I think Got the Solution. I am Testing it...
Hi Friends, Finally I think Got the Solution. I am Testing it...
We would also still be interested in a solution, so please tell us when you found something :)
Hi, Pl Try This Program..
// DATE: 09 06 2020 AT 20:23 // R K ENTERPRISES // RAVI N //ravirke@gmail.com /*Wiring to your Arduino 32BITRKE.ino ads1262_Reg_Write(INPMUX, 0x01); // SELECTING CH0 & CH1 ads1262_Reg_Write(INPMUX, 0x23); // SELECTING CH2 & CH3 ads1262_Reg_Write(INPMUX, 0x45); // SELECTING CH4 & CH5 ads1262_Reg_Write(INPMUX, 0x67); // SELECTING CH6 & CH7 ads1262_Reg_Write(INPMUX, 0x89); // SELECTING CH8 & CH9
ads1262 pin label | Pin Function | Arduino Connection |
---|---|---|
DRDY | Data ready Output pin | D6 |
MISO | Slave Out | D12 |
MOSI | Slave In | D11 |
SCLK | Serial Clock | D13 |
CS | Chip Select | D7 |
START | Start Conversion | D5 |
PWDN | Power Down/Reset | D4 |
DVDD | Digital VDD | +5V |
DGND | Digital Gnd | Gnd |
AN0-AN9 | Analog Input | Analog Input |
AINCOM | Analog input common | |
AVDD | Analog VDD | - |
AGND | Analog Gnd | - |
*/
int CONFIG_SPI_MASTER_DUMMY = 0xFF;
//Pins used for the connection with the sensor, the other you need are controlled by the SPI library): const int ADS1262_DRDY_PIN = 6; const int ADS1262_CS_PIN = 7; const int ADS1262_START_PIN = 5; const int ADS1262_PWDN_PIN = 4; //Register address
float volt_V=0; float volt_mV=0; volatile int i, data; volatile char SPI_RX_Buff[10]; volatile long ads1262_rx_Data[10]; volatile static int SPI_RX_Buff_Count = 0; volatile char *SPI_RX_Buff_Ptr; volatile int Responsebyte = false; volatile signed long sads1262Count = 0; volatile signed long uads1262Count=0; double resolution;
void setup() { // initalize the data ready and chip select pins: pinMode(ADS1262_DRDY_PIN, INPUT); //Data ready input line pinMode(ADS1262_CS_PIN, OUTPUT); //Chip enable output line pinMode(ADS1262_START_PIN, OUTPUT); //Start pinMode(ADS1262_PWDN_PIN, OUTPUT); //Power down output
digitalWrite(ADS1262_START_PIN, LOW); //Manter o pino LOW e controlar comunicação via código SPI digitalWrite(ADS1262_CS_PIN, LOW); //Manter o pino LOW para manter comunicação sempre possível
Serial.begin(115200); //inicia comunicação serial SPI.begin(); // start the SPI library: SPI.beginTransaction(SPISettings(20000000, MSBFIRST, SPI_MODE1)); ads1262_Init(); // initialise ads1262 slave
}
void loop() {
// FOR SINGLE ENDED OPERATION CONNECT PIN NUM 3 ( AINCOM ) TO GND
ads1262_Reg_Write(INPMUX, 0x0A);
delay(10);
RKEADC();
Serial.print(" ");
ads1262_Reg_Write(INPMUX, 0x1A);
delay(10);
RKEADC();
Serial.print(" ");
ads1262_Reg_Write(INPMUX, 0x2A);
delay(10);
RKEADC();
Serial.print(" ");
ads1262_Reg_Write(INPMUX, 0x3A);
delay(10);
RKEADC();
Serial.print(" ");
ads1262_Reg_Write(INPMUX, 0x4A);
delay(10);
RKEADC();
Serial.print(" ");
ads1262_Reg_Write(INPMUX, 0x5A);
delay(10);
RKEADC();
Serial.print(" ");
ads1262_Reg_Write(INPMUX, 0x6A);
delay(10);
RKEADC();
Serial.print(" ");
ads1262_Reg_Write(INPMUX, 0x7A);
delay(10);
RKEADC();
delay(3000);
Serial.println(" ");
}
//**
void RKEADC() {
while (digitalRead(ADS1262_DRDY_PIN) == HIGH){ }
SPI_RX_Buff_Ptr = ads1262_Read_Data(); //6Bytes <STATUS|DATA1|DATA2|DATA3|DATA4|CHECKSUM>
for(i = 0; i <5; i++) //Remove STATUS byte?
{
SPI_RX_Buff[SPI_RX_Buff_Count++] = *(SPI_RX_Buff_Ptr + i);
}
if(SPI_RX_Buff_Count >= 5) { ads1262_rx_Data[0]= (unsigned char)SPI_RX_Buff[1]; // read 4 bytes adc count ads1262_rx_Data[1]= (unsigned char)SPI_RX_Buff[2]; ads1262_rx_Data[2]= (unsigned char)SPI_RX_Buff[3]; ads1262_rx_Data[3]= (unsigned char)SPI_RX_Buff[4]; uads1262Count = (signed long) (((unsigned long)ads1262_rx_Data[0]<<24)|((unsigned long)ads1262_rx_Data[1]<<16)|(ads1262_rx_Data[2]<<8)|ads1262_rx_Data[3]);//get the raw 32-bit adc count out by shifting
sads1262Count = (signed long) (uads1262Count); // get signed value
resolution = (double)((double)VREF/pow(2,31)); //resolution= Vref/(2^n-1) , Vref=2.5, n=no of bits
volt_V = (resolution)*(float)(sads1262Count); // voltage = resolution * adc count
volt_mV = volt_V*1000; // voltage in mV
//Serial.print(volt_mV);
//Serial.print(" , ");
//Serial.print(" Volt ");
Serial.print(volt_V,4);
Serial.print(" ");
//Serial.println(" mV");
//delay(10000);
}
SPI_RX_Buff_Count = 0;
}
//*****
//float mapfloat(float x, float in_min, float in_max, float out_min, float out_max) //{ // return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; //}
void ads1262_Init()
{
ads1262_Reset(); delay(100);
ads1262_Reg_Write(POWER, 0x11);delay(10); //11h (default) internal ref enabled
ads1262_Reg_Write(INTERFACE, 0x05);delay(10); //0D RAVI//05h (default) Status byte enabled, Checksum enablade
ads1262_Reg_Write(MODE0, 0x00);delay(10); //00h (default) Continuous Conv Mode | 0x40 Pulse conversion mode (one shot conversion)
ads1262_Reg_Write(MODE1, 0x00);delay(10); //80h (default) FIR Filter | 00h sinc1 | 60h sinc4
ads1262_Reg_Write(MODE2, 0x06);delay(10); // 5DRAVI //04h (default) PGA enabled 1V/V 20sps| 5Ch 32V/V 7200sps | 5Fh 32V/V 38400sps
//ads1262_Reg_Write(INPMUX, 0x01);delay(10); //01h (default) Multiplexer, AIN0 e AIN1 | 23h AIN2 e AIN3
ads1262_Reg_Write(OFCAL0, 0x00);delay(10); //00h (default) Offset Calibration Registers
ads1262_Reg_Write(OFCAL1, 0x00);delay(10); //00h (default) Offset Calibration Registers
ads1262_Reg_Write(OFCAL2, 0x00);delay(10); //00h (default) Offset Calibration Registers
ads1262_Reg_Write(FSCAL0, 0x00);delay(10); //00h (default) Full-Scale Calibration Registers
ads1262_Reg_Write(FSCAL1, 0x00);delay(10); //00h (default) Full-Scale Calibration Registers
ads1262_Reg_Write(FSCAL2, 0x40);delay(10); //40h (default) Full-Scale Calibration Registers
ads1262_Reg_Write(IDACMUX, 0xBB);delay(10); //BBh (default) Output Multiplexer, no connection, no connection
ads1262_Reg_Write(IDACMAG, 0x00);delay(10); //00h (default) Current magnitude, off
ads1262_Reg_Write(REFMUX, 0x00);delay(10); //00h (default) Reference Multiplexer, 2.5V, 2.5V
ads1262_Reg_Write(TDACP, 0x00);delay(10);//00h (default) TDACP, no connection
ads1262_Reg_Write(TDACN, 0x00);delay(10); //00h (default) TDACN, no connection
ads1262_Reg_Write(GPIOCON, 0x00);delay(10); //00h (default) GPIO not connected
ads1262_Reg_Write(GPIODIR, 0x00);delay(10); //00h (default) GPIO output
ads1262_Reg_Write(GPIODAT, 0x00);delay(10); //00h (default) GPIO low
ads1262_Reg_Write(ADC2CFG, 0x00);delay(10); //00h (default) ADC2
ads1262_Reg_Write(ADC2MUX, 0x01);delay(10); //01h (default)
ads1262_Reg_Write(ADC2OFC0, 0x00);delay(10); //00h (default)
ads1262_Reg_Write(ADC2OFC1, 0x00);delay(10); //00h (default)
ads1262_Reg_Write(ADC2FSC0, 0x00);delay(10); //00h (default)
ads1262_Reg_Write(ADC2FSC1, 0x40);delay(10); //40h (default)
SPI.transfer(START); //Inicia a conversão via código 08h
}
char* ads1262_Read_Data() { SPI.transfer(RDATA); static char SPI_Dummy_Buff[6]; for (int i = 0; i < 6; ++i) { SPI_Dummy_Buff[i] = SPI.transfer(CONFIG_SPI_MASTER_DUMMY); //CONFIG_SPI_MASTER_DUMMY - FFh } return SPI_Dummy_Buff; // 6Bytes <STATUS|DATA1|DATA2|DATA3|DATA4|CHECKSUM> }
void ads1262_Reset() //PWDN_PIN MUST BE HIGH FOR OPERATION { digitalWrite(ADS1262_PWDN_PIN, HIGH); delay(100); digitalWrite(ADS1262_PWDN_PIN, LOW); delay(100); digitalWrite(ADS1262_PWDN_PIN, HIGH); delay(100); }
void ads1262_Reg_Write (unsigned char READ_WRITE_ADDRESS, unsigned char DATA) { // now combine the register address and the command into one byte: byte dataToSend = READ_WRITE_ADDRESS | WREG;
// take the chip select low to select the device: SPI.transfer(dataToSend); //Send register location SPI.transfer(0x00); //number of register to wr SPI.transfer(DATA); //Send value to record into register delayMicroseconds(2); }
An update would really be great, I just made some further tests. I'm using now 5 full bridge load cells. So I'm always reading between Pos and Neg Pins. I now had to increase N to 4 compared to 2 before. I cannot explain why, but it makes the hole process alot slower. I also printed the 4 read values of one Sensor, and the first three are zero or -1 and the 4th has the corret value. Thank you very much.
#include <ADS126X.h> ADS126X adc1; // start the class #define N 4 int d=30; int chip_select1 = 4; // Arduino pin connected to CS on ADS126X long voltage1 = 0; long voltage2 = 0; long voltage3 = 0; long voltage4 = 0; long voltage5 = 0; int pos_pin1 = 0; // ADS126X pin AIN0, for positive inpu int neg_pin1 = 1; int pos_pin2 = 2; int neg_pin2 = 3; int pos_pin3 = 4; int neg_pin3 = 5; int pos_pin4 = 6; int neg_pin4 = 7; int pos_pin5 = 8; int neg_pin5 = 9; int neg_pinInt = ADS126X_REF_POS_INT; unsigned long us = 0; unsigned long diff = 0; void setup() { Serial.begin(2000000); adc1.begin(chip_select1); // setup with chip select pin0. adc1.setRate(ADS126X_RATE_38400); adc1.setGain(ADS126X_GAIN_32); adc1.startADC1(); // start conversion on ADC1 Serial.println("Reading Voltages:"); } void loop() { // us = micros(); for(int i = 0; i < N; i++) { voltage1 = adc1.readADC1(pos_pin1,neg_pin1); // read the voltage voltage1 =voltage1>>16; delayMicroseconds(d); } Serial.print(voltage1); // send voltage through serial Serial.print(","); for(int i = 0; i < N; i++) { voltage2 = adc1.readADC1(pos_pin2,neg_pin2); // read the voltage voltage2 =voltage2>>16; delayMicroseconds(d); } Serial.print(voltage2); // send voltage through serial. Serial.print(","); for(int i = 0; i < N; i++) { voltage3 = adc1.readADC1(pos_pin3,neg_pin3); // read the voltage voltage3 =voltage3>>16; delayMicroseconds(d); } Serial.print(voltage3); // send voltage through serial Serial.print(","); for(int i = 0; i < N; i++) { voltage4 = adc1.readADC1(pos_pin4,neg_pin4); // read the voltage voltage4 =voltage4>>16; delayMicroseconds(d); } Serial.print(voltage4); // send voltage through serial Serial.print(","); for(int i = 0; i < N; i++) { voltage5 = adc1.readADC1(pos_pin5,neg_pin5); // read the voltage voltage5 =voltage5>>16; delayMicroseconds(d); } Serial.println(voltage5); // send voltage through serial // Serial.print(","); // diff=micros() - us; // Serial.println(diff); }
hello friends. let me know where is the pin start connect to arduino
A short add here to ask if anyone has a neat solution to this problem yet? Any help will be appreciated. Thanks.
A short add here to ask if anyone has a neat solution to this problem yet? Any help will be appreciated. Thanks.
We are currently using it with a dummy read, then waiting 250us and doing the actual read. This works for us, but is obviously not optimal. You can see our code here https://github.com/bit-bots/bit_foot/blob/master/firmware/esp32_bit_foot/esp32_bit_foot.ino Hope that helps you
Thanks for the reference SR.
I encounter the same problem, and I solve this by using : while(!(voltage = adc.readADC1(1,2))); just wait ADC
I believe the problem may be related to the fact that the ADC should be stopped before writing to the registers.
In the readADC1()
method - when the input mux pins have changed, it attempts to write to the registers while the ADC is running (see https://github.com/Molorius/ADS126X/blob/master/src/ADS126X.cpp#L84-L88) . Based on sample code provided by TI in the reference design design, I have found a solution that works around the issue in the ADS126X library and seems to be a lot faster than the solutions above that wait for a successful conversion.
float readAdcV(int ainPos, int ainNeg)
{
adc.REGISTER.INPMUX.bit.MUXN = ainNeg;
adc.REGISTER.INPMUX.bit.MUXP = ainPos;
adc.writeRegister(ADS126X_INPMUX); // replace on ads126x
adc.startADC1();
while (digitalRead(esp32AdcRdyPin) == HIGH)
{
// wait
}
adc.stopADC1();
signed long int outputCode = adc.readADC1(ainPos, ainNeg);
float voltage = (float)((adcResolution) * (double)(outputCode));
Serial.print(" outputCode: " + String(outputCode));
return voltage;
}
where adc
is an instance of the ADS126X class. The key is that the ADS126X_INPMUX
register is set while the ADC is stopped. TI's sample code also stops the ADC before reading the last conversion -- i have followed that pattern here, though I'm not certain if that is required.
The ADS126X::readADC1
method could be patched to avoid this clunky workaround, but I'm not sure what the software alternative would be to polling the DRDY
pin.
Hi everyone, thank you for your patience and feedback. I have a potential fix, I would like help testing it before I clean up the timings and merge into mainline (I no longer have access to this ADC): https://github.com/Molorius/ADS126X/tree/pin-switch-fix
git clone -b pin-switch-fix https://github.com/Molorius/ADS126X.git
This uses the suggestion by @halmos to stop any adc conversions before switching pins. I also decoupled the pin switching from actually reading voltage measurements. You can still use the old syntax though.
If it appears completely broken, please also try either the example in the project for a single read or your own code. I'm pretty sure this code didn't break anything but I cannot test it.
Example 1 (uses old syntax):
#include <ADS126X.h>
ADS126X adc; // start the class
int chip_select = 5; // Arduino pin connected to CS on ADS126X
int pos_pin_first = 0; // ADS126X pin AIN0, for positive input
int neg_pin_first = 1; // ADS126X pin AIN1, for negative input
int pos_pin_second = 2;
int neg_pin_second = 3;
void setup() {
Serial.begin(115200);
adc.begin(chip_select); // setup with chip select pin
adc.startADC1(); // start conversion on ADC1
Serial.println("Reading Voltages:");
}
void loop() {
long voltage_first = adc.readADC1(pos_pin_first,neg_pin_first); // read the voltage for one set of pins
long voltage_second = adc.readADC1(pos_pin_second,neg_pin_second); // read the voltage for the other set
Serial.println(voltage_first);
Serial.println(voltage_second);
Serial.println("");
delay(1000); // wait 1 second
}
Example 2 (uses new syntax):
#include <ADS126X.h>
ADS126X adc; // start the class
int chip_select = 5; // Arduino pin connected to CS on ADS126X
int pos_pin_first = 0; // ADS126X pin AIN0, for positive input
int neg_pin_first = 1; // ADS126X pin AIN1, for negative input
int pos_pin_second = 2;
int neg_pin_second = 3;
void setup() {
Serial.begin(115200);
adc.begin(chip_select); // setup with chip select pin
adc.startADC1(); // start conversion on ADC1
Serial.println("Reading Voltages:");
}
void loop() {
adc.setInputMux1(pos_pin_first,neg_pin_first); // set pins to use for reads
long voltage_first = adc.readADC1(); // read the voltage
adc.setInputMux1(pos_pin_second,neg_pin_second); // switch reading to different pins
long voltage_second = adc.readADC1(); // read the voltage
Serial.println(voltage_first);
Serial.println(voltage_second);
Serial.println("");
delay(1000); // wait 1 second
}
Hi Molorius
Thx for you're library and time/effort to make them better :) I have tested you're examples, and got the following results.
Example 1, gives the result: Reading Voltages: 0 0
Reading Voltages: 0 0
-1 -1
-1 -1
-1 0
And so on, so the problem is still there.
Example 2, cant compile. The code cant read the following lines: adc.setInputMux1(pos_pin_first,neg_pin_first); // set pins to use for reads adc.setInputMux1(pos_pin_second,neg_pin_second); // switch reading to different pins
The setInputMux1, does not works.
Example 2, cant compile. The code cant read the following lines: adc.setInputMux1(pos_pin_first,neg_pin_first); // set pins to use for reads adc.setInputMux1(pos_pin_second,neg_pin_second); // switch reading to different pins
The setInputMux1, does not works.
Did you make sure that you are on the correct branch (pin-switch-fix). Looks a bit like you may just were on master.
I did some testing on the pin-switch-fix but I'm getting 0 readings every 2/3 readings on all channels (I'm working with a 1ms loop reading 4 of the 10 channels of the ADC). Also, that branch introduced delays when stopping or starting the ADC when the mux changes, which I need to happen 4 times on each main loop.
Using the workaround of reading each channel twice with a 250us delay in-between I get an effective loop period of 1.7 ms. On the other hand, using the pin-switch-fix branch I get an effective loop period of ~800ms !!! due to the delays introduced.
The best I've achieved for reading 4 sensors is using the double reading hack of @SammyRamone with a 140us delay and the 38400 rate config. I get a 1.3 ms period for all 4 sensors which is 770Hz
Hi everybody, I did more digging and I discovered some surprises about the ADS126X. In general, multiplexed ADCs introduce some delays when changing the multiplexor. Those delays are the reason why the double reading with an in-between delay hack works (it gives time to the multiplexor to change and generate a new reading).
The best way to take this into the account in the library from my perspective would be to use the DRDY (data ready) pin as follows:
IMPORTANT: however after reading some forums and the datasheet, if your application needs reading more than one channel on each application loop (which I think everyone buying an ADC with more than one channel would be doing...) you will have these multiplexor delays on every loop literally killing the sample rate. With one channel you might get the announced 38400 kSps but in these cases the better you can get is around 1~3 kSps. In conclusion, non-sense...
Hello all, Thanks @Molorius for this awesome library. Thanks @franz6ko for the coming up with the suggestion.
Below is my implementation for reading multiple channels. I have implemented a simple function which monitors the DRDY function. I needed to read the values twice from ADC for some reason.
@Molorius sir, I think it will be great if you can implement the DRDY Pin functionality internally in the library.
#include <ADS126X.h>
ADS126X adc; // start the class
int chip_select = 10; // Arduino pin connected to CS on ADS126X
int start_pin = 9;
int drdy_pin = 3;
int pos_pin = 0; // ADS126X pin AIN0, for positive input
//int pos_pin = ADS126X_AIN0;
int neg_pin = 1; // ADS126X pin AIN1, for negative input
//int neg_pin = ADS126X_AIN1;
float last_voltage;
float voltage0_1, voltage2_3;
int drdy_status = 1;
float readADCVal(int pospin, int negpin){
while(1)
{
last_voltage = adc.readADC1(pospin, negpin); // read the voltage
drdy_status = digitalRead(drdy_pin);
last_voltage = adc.readADC1(pospin, negpin); // read the voltage
if(drdy_status == 0) break;
}
return last_voltage;
}
void setup() {
Serial.begin(115200);
pinMode(drdy_pin, INPUT_PULLUP);
adc.setStartPin(start_pin);
adc.begin(chip_select); // setup with chip select pin
adc.setGain(ADS126X_GAIN_16);
adc.setRate(ADS126X_RATE_7200);
adc.startADC1(); // start conversion on ADC1
Serial.println();
Serial.println("Reading Voltages:");
}
void loop() {
voltage0_1 = readADCVal(0, 1);
voltage2_3 = readADCVal(2, 3);
// adc.lastChecksum();// Check last values error 0 means good
Serial.print(voltage0_1/100000); // send voltage through serial
Serial.print(" ");
Serial.println(voltage2_3/100000); // send voltage through serial
// delayMicroseconds(1000); // wait 1 second
delay(1);
}
https://www.waveshare.com/wiki/High-Precision_AD_HAT I have this ADS 1263 , I am trying to read the the signal using Arduino nano . But in the adc above there no start pin?
Thank you @Molorius @ziatajo @ziatajo @SammyRamone , for this nice communication , I was try with the code which @Molorius post for multi-channel reading, but the problem I am facing is when my sensor value is increasing in one channel , the value of other also changing , also when my sensor signal coming back to zero, the value in the adc is taking so much time to come back to the original value, ? anyone has a solution for this , or any methods for this problem? i want to read 5 channels at at time.
Looks like the library still lacks a consistent way to update ADS1262 settings.
I faced this issue when trying to switch back and forth reading the internal temperature of ADS1262 [adc.readADC1(ADS126X_TEMP, ADS126X_TEMP)] and reading strain gauge [adc.readADC1(ADS126X_AIN7 ,ADS126X_AIN6)].
Reading the temperature requires using internal reference and PGA=1. Reading strain gauge requires using external reference and PGA=16. So several settings need to be changed when switching.
I have tried the solutions given earlier in this thread but can't get them to work.
Is there any news about how get this to work?
ADS1262 data sheet seems to give instructions how to change the settings. Is it so that the library does not follow this workflow?
Hi, Maybe I'm just too stupid, but I cannot even manage to add a second sensor.
I used the example and successfully connected a full-bridge loadcell to AIN0-AIN1. Than I wanted to add a second full-bridge loadcell to AIN2-AIN3. I just copied the code: Defined additional POS-NEG pins, and read the value: voltage1 = adc1.readADC1(pos_pin1,neg_pin1); // read the voltage
voltage2 = adc1.readADC1(pos_pin2,neg_pin2); // read the voltage
However my data for both sensors is now just showing 0 or -1.
What am I doing wrong?
Thank you and best regards