-
Notifications
You must be signed in to change notification settings - Fork 22
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Problem adding multiple sensors #5
Problem adding multiple sensors #5
Comments
No need to self-deprecate! Let me make sure I understand your problem. 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. |
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.
I only get 0 and -1 (don't know when it is changing between the two). 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. |
I let the ADS1262 in my office over the weekend, thats why I could test it not before now. |
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 |
And pls also try to use this func |
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.
|
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: |
Hi, Thank you. |
Hi @ziatajo I think we should try with single-ended mode to see :) 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)? |
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 :) Reading Voltages: |
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)
EDIT: I tried it know also with:
now I can reduce the delay to 170 Microseconds. |
Good to hear! ...
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 |
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 |
@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? 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.
|
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.
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).
Could it be a problem that you only write the INPMUX register and not all registers of Group1?
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, |
Hi Friends, |
We would also still be interested in a solution, so please tell us when you found something :) |
Hi, // DATE: 09 06 2020 AT 20:23 this example gives differential voltage across the CHx And CHy in mV
|
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 | - |
*/
#include <SPI.h>
#include <math.h>
#define PGA 1 // Programmable Gain = 1
#define VREF 2.5 // 2.494v Internal reference of 2.048V
#define VFSR VREF/PGA //2.50/1 = 2.50
#define FSR (((long int)1<<23)-1)
int CONFIG_SPI_MASTER_DUMMY = 0xFF;
#define RREG 0x20
#define WREG 0x40
#define START 0x08
#define STOP 0x0A
#define RDATA 0x12
//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
#define POWER 0x01
#define INTERFACE 0x02
#define MODE0 0x03
#define MODE1 0x04
#define MODE2 0x05
#define INPMUX 0x06
#define OFCAL0 0x07
#define OFCAL1 0x08
#define OFCAL2 0x09
#define FSCAL0 0x0A
#define FSCAL1 0x0B
#define FSCAL2 0x0C
#define IDACMUX 0x0D
#define IDACMAG 0x0E
#define REFMUX 0x0F
#define TDACP 0x10
#define TDACN 0x11
#define GPIOCON 0x12
#define GPIODIR 0x13
#define GPIODAT 0x14
#define ADC2CFG 0x15
#define ADC2MUX 0x16
#define ADC2OFC0 0x17
#define ADC2OFC1 0x18
#define ADC2FSC0 0x19
#define ADC2FSC1 0x1A
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);
}
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? |
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. |
Thanks for the reference SR. |
I encounter the same problem, and I solve this by using : while(!(voltage = adc.readADC1(1,2))); |
I believe the problem may be related to the fact that the ADC should be stopped before writing to the registers. In the 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 The |
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
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 :) Example 1, gives the result: Reading Voltages: -1 -1 -1 -1
|
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, 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.
|
|
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. 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? |
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
The text was updated successfully, but these errors were encountered: