32 Channel Strain Sensor DAQ

Hi guys,

Lovely community here. So i got into the bandwagon of the ESP32. I am planning to build an entire data acquisition built around the ESP32. Would really appreciate it much if i were to get help from all of you. It would be a learning experience for all of us. So basically here are my project details and list of components being used.

A 32 Channel Data acquisition system with 30 sensors measuring strain (momentarily using a metal gage strain sensor of 120Ohm being fed to a quarter bridge circuit) and 2 temperature sensors(PT100). I would like an acquisition speed of atleast 1000Samples/Sec per channel. So here is my idea as of now.

32 Sensors connected to its each wheatstones bridge. The amplifier is done using the XR18910/XR10910, which is a 16:1 bridge Mux interface with selectable gain. I have attached link https://www.exar.com/content/document.a … rt=XR10910

The XR18911 can be controlled via I2C link. it does all the amplification necessary. I will need to use 2 XR10910 or 4 XR18911(8:1 sensor interface). And then finally controlled by our LEGENDARY ESP32 which converts the analog data to digital. and with the help of wifi to transmit it to a computer where it can be collected in an excel file along with time of capture.

Could you guys kindly help me out on how i am to proceed with programming of the ESP32. I would really prefer to use Arduino IDE guys, as that seems to simplify things. Also if there is any improvements that could be added to the circuit. Kindly let me know. Please let me know if you need more details(Picture attached). Thank you :slight_smile:

“A 32 Channel Data acquisition system with 30 sensors measuring strain (momentarily using a metal gage strain sensor of 120Ohm being fed to a quarter bridge circuit) and 2 temperature sensors(PT100). I would like an acquisition speed of atleast 1000Samples/Sec per channel. So here is my idea as of now.”

Why are you trying to use a D/A for an A/D? the part referenced is not an A/D!

You should probably start by looking at how fast you can actually read A SINGLE channel with the proposed amplifier. Not just read the datasheets and presume you can read it quickly and fast. 1000 samples a second at 32 channels implies 32,000+ samples per second. That’s roughly 33 microseconds per sample – without any handshaking between the A/D or wifi…

Load cells can be operating in a noisy environment - you often solve that noise problem by taking multiple readings - then averaging and reporting that one reading out. It doesn’t sound like you’ve made any provision for that. And then there is the question of skewing between channels… scan them sequentially, or one channel first - multiple times and average, one are you really trying to accomplish,

Perhaps you want to use a faster arduino (DUE) have multiple independent A/D’s operating and pick up the results and forward with an 8266…

I re-read the spec sheet for the amplifier - I see what you’re doing - but I think you’d still run into a speed problem. I presume you’d be using the sending values to the D/A to adjust for the offset for the bridge during the initial setup. You may want to simply try to see how fast you can read the basic setup with an ordinary Arduino Uno… without the wifi and you can get the speed you want - then try the wifi. Or you may consider a couple of Uno’s with the EPS32 assembling one packet that has the 32 readings in it and sending it out using a MQTT library.

D_Heidner:
I re-read the spec sheet for the amplifier - I see what you’re doing - but I think you’d still run into a speed problem. I presume you’d be using the sending values to the D/A to adjust for the offset for the bridge during the initial setup. You may want to simply try to see how fast you can read the basic setup with an ordinary Arduino Uno… without the wifi and you can get the speed you want - then try the wifi. Or you may consider a couple of Uno’s with the EPS32 assembling one packet that has the 32 readings in it and sending it out using a MQTT library.

Thank you kindly for the reply Heidner. I have respeced my design. Instead of having 32 channels at once. I divided acquisition into blocks. Each block acquires 8 channels of strain with the help of the XR18910 amplifier. It is similiar to the XR10910( but the XR18910 has 8 channels instead of 16). I have tried using the ADC of the ESP32 but it seems to be very slow. Sampling 8 channels at about 80 samples per second. So i replaced it with the Teensy 3.6, and i am getting about 3000 Samples for 8 channels. which is more than my requirement of 1000Samples/Sec. Although i am having difficulties with controlling the DAC. As controlling the DAC of 1 channel seems to affect the other channels as well. I have attached the code below. It’s quite a simple control. Also i find that i get a lot of noise at the input. Do you have advice for controlling noise for analog circuits?

The below code shows the control of 6 channels. As i am testing with 6 strain gauges at the moment. I am trying to also figure out a way to have the data which is in serial to be sent to a webserver. Preferably via arduino uno? is it possible to that another arduino device like the arduino Yun can receive serial data and transmit this information over wifi to a web server?

#include <Adafruit_MAX31865.h>
#include <TimeLib.h>

#include <TimeLib.h>
#include <WProgram.h>
//#include <Wire.h>
#include <i2c_t3.h>
#include <Filters.h>

Adafruit_MAX31865 max = Adafruit_MAX31865(10, 11, 12, 13); //Temperature
#define RREF 430.0                                         //Temperature

const unsigned long fiveSeconds = 5 * 1000UL;  // Counter for 5 seconds
static unsigned long lastSampleTime = 0 - fiveSeconds;  // initialize such that a reading is due the first time through loop()


int StrainInput1     = A0;

float strainValue1     = 0;  // variable to store the value coming from the sensor
float strainValue2     = 0;
float strainValue3     = 0;
float strainValue4     = 0;
float strainValue5     = 0;
float strainValue6     = 0;
//float strainValue7     = 0;
//float strainValue8     = 0;
float tempPT100        = 0;

float filterFrequency = 1000.0;  //filters out changes faster than 1000Hz
FilterOnePole lowpassFilter( LOWPASS, filterFrequency );   
 

float vd=3.345;
int res=8192;

String sensorOutput;

void strainOutput();
void strainOffset();
void strainGain();

void setup() {
  analogReadResolution(13);
  Wire.begin(I2C_MASTER, 0x00, I2C_PINS_18_19, I2C_PULLUP_EXT, 400000);
  Wire.setClock(400000L);    // Set i2C speed to 400Khz
  Serial.begin(2000000);     // open the serial port at 115200 bps

  Serial.println("CLEARDATA");
  Serial.println("LABEL,Current time,Strain 1,Strain 2,Strain 3,Strain 4,Strain 5,Strain 6");
  
  Wire.beginTransmission(0x66); 
  
  Wire.write(0x07);         // LDO register
  Wire.write(0x01);         // 2.65V

  Wire.endTransmission();

  strainGain();
  
  
  max.begin(MAX31865_4WIRE);  // set to 2WIRE or 4WIRE as necessary

  strainOffset();
}

void loop() {
  Wire.beginTransmission(0x66);
  Wire.send(0x10);         // Call Channel 1  
  Wire.endTransmission(); 
  strainValue1 = lowpassFilter.input( analogRead( StrainInput1) );
  //strainValue1 = analogRead(StrainInput1);

  Wire.beginTransmission(0x66);
  Wire.send(0x12);         // Call Channel 2
  Wire.endTransmission(); 
  strainValue2 = lowpassFilter.input( analogRead( StrainInput1) );
  //strainValue2 = analogRead(StrainInput1);

  Wire.beginTransmission(0x66);
  Wire.send(0x14);         // Call Channel 3
  Wire.endTransmission();
  strainValue3 = lowpassFilter.input( analogRead( StrainInput1) );
  //strainValue3 = analogRead(StrainInput1);

  Wire.beginTransmission(0x66);
  Wire.send(0x15);         // Call Channel 4
  Wire.endTransmission(); 
  strainValue4 = lowpassFilter.input( analogRead( StrainInput1) );
  //strainValue4 = analogRead(StrainInput1);
  
  Wire.beginTransmission(0x66);
  Wire.send(0x18);         // Call Channel 5
  Wire.endTransmission(); 
  strainValue5 = lowpassFilter.input( analogRead( StrainInput1) );
  //strainValue5 = analogRead(StrainInput1);
  
  Wire.beginTransmission(0x66);
  Wire.send(0x1A);         // Call Channel 6
  Wire.endTransmission();
  strainValue6 = lowpassFilter.input( analogRead( StrainInput1) );
  //strainValue6 = analogRead(StrainInput1);

//  Wire.beginTransmission(0x66);
//  Wire.send(0x1C);         // Call Channel 6
//  Wire.endTransmission();
//  strainValue7 = analogRead(StrainInput1);
//
//  Wire.beginTransmission(0x66);
//  Wire.send(0x1E);         // Call Channel 6
//  Wire.endTransmission();
//  strainValue8 = analogRead(StrainInput1);
//

unsigned long now = millis();
 
// if (now - lastSampleTime >= fiveSeconds)
// {
//    lastSampleTime += fiveSeconds;
//    temperatureCal();
//  
// }
 
  
  resToVolt();
  strainOutput(); 
    
 
}

void resToVolt()
{   
    strainValue1 = strainValue1/res*vd;               //Stable readings at 2.42V
    strainValue2 = strainValue2/res*vd;               //Stable readings at 2.28V         
    strainValue3 = strainValue3/res*vd;               //Stable readings at 2.31V
    strainValue4 = strainValue4/res*vd;               //Stable readings at 2.84V
    strainValue5 = strainValue5/res*vd;               //Stable readings at 2.63V
    strainValue6 = strainValue6/res*vd;               //Stable readings at 2.79V
//    strainValue7 = strainValue7/res*vd;               //Stable readings at 2.79V
//    strainValue8 = strainValue8/res*vd;               //Stable readings at 2.79V


}
void strainOutput()
{
  sensorOutput  ="";
  //sensorOutput +="DATA,TIME,";
  sensorOutput +=strainValue1;
  sensorOutput +=',';
  sensorOutput +=strainValue2;
  sensorOutput +=',';
  sensorOutput +=strainValue3;
  sensorOutput +=',';
  sensorOutput +=strainValue4;
  sensorOutput +=',';
  sensorOutput +=strainValue5;
  sensorOutput +=',';
  sensorOutput +=strainValue6;
  //sensorOutput +=',';
//  sensorOutput +=strainValue7;
//  sensorOutput +=',';
//  sensorOutput +=strainValue8;
//  sensorOutput +=',';
  //sensorOutput +=tempPT100;
  Serial.println(sensorOutput);
}

void strainGain()
{ 
  Wire.beginTransmission(0x66);
  Wire.send(0x06);           // Gain Select
 //Wire.send(0x00);           // Gain Choice 2
  Wire.send(0x04);         // Gain Choice 150
  Wire.endTransmission();
}

void strainOffset()
{
  Wire.beginTransmission(0x66);
  Wire.send(0x20);        // Access Offset correction register Channel 1       
  Wire.send(0x00);
  Wire.send(0x00);
  Wire.endTransmission();

  
  Wire.beginTransmission(0x66);
  Wire.send(0x22);        // Access Offset correction register Channel 2       
  Wire.send(0x00);
  Wire.send(0x00);
  Wire.endTransmission();

  
  Wire.beginTransmission(0x66);
  Wire.send(0x24);        // Access Offset correction register Channel 3      
  Wire.send(0x07);
  Wire.send(0xFF);
  Wire.endTransmission();

  Wire.beginTransmission(0x66);
  Wire.send(0x25);        // Access Offset correction register Channel 4      
  Wire.send(0x00);
  Wire.send(0x00);
  Wire.endTransmission();

  Wire.beginTransmission(0x66);
  Wire.send(0x28);        // Access Offset correction register Channel 5      
  Wire.send(0x00);
  Wire.send(0x00);
  Wire.endTransmission();

  Wire.beginTransmission(0x66);
  Wire.send(0x2A);        // Access Offset correction register Channel 6      
  Wire.send(0x00);
  Wire.send(0x00);
  Wire.endTransmission();

}

void temperatureCal()
{
  uint16_t rtd = max.readRTD();

  //Serial.print("RTD value: "); Serial.println(rtd);
  //float ratio = rtd;
  //ratio /= 32768;
  //Serial.print("Ratio = "); Serial.println(ratio,8);
  //Serial.print("Resistance = "); Serial.println(RREF*ratio,8);
  //Serial.print("Temperature = "); Serial.println(max.temperature(100, RREF));
  
  tempPT100 = max.temperature(100,RREF);
}