Problem with messuring capacity with 50 Arduinos connected by I2C

I have a problem and hope someone here can help me.

I want to measure changes in capacity over time. One Arduino is used per capacity sensor. There is one anode per Arduino and a total of one common cahode. (See picture)

With four Arduinos connected in series via I2C master-slave connection, successful results were obtained. With more than four Arduinos all measurement results were 0, because no voltage is measured at the input pin anymore. I then lowered the reference voltage for analogRead. So 10 Arduinos in series were possible. However, the measured values are clearly lower. However, no absolute values are to be measured, but eun difference in the capacity is sufficient. Finally 50 Arduinos should be used. I have thought of the following possibilities

reduce the reference voltage further, but this may reduce the measurement results further, so that no deflection is measured.
increase the output voltage at the Arduino via an operational amplifier to compensate the voltage drop.

Does anyone have another idea how I could proceed to get a usable result with all 50 Arduinos? The code I used is to be found below.

Many thanks in advance

Greetings Imogdia

Master

const int OUT_PIN = A0;
const int IN_PIN = A2;

//Capacitance between IN_PIN and Ground
//Stray capacitance is always present. Extra capacitance can be added to
//allow higher capacitance to be measured.
const float IN_STRAY_CAP_TO_GND = 30.00;
const float IN_EXTRA_CAP_TO_GND = 0.0;
const float IN_CAP_TO_GND  = IN_STRAY_CAP_TO_GND + IN_EXTRA_CAP_TO_GND;
const int MAX_ADC_VALUE = 1023;

#include <Wire.h>

#define nodeMax 10
#define nodeStart 2

union u_capacitance
{
  struct
  {
    float capa_slave;
  };
  byte bytes[10];
};

u_capacitance capacitanceSlave;


void setup()
{
 analogReference(EXTERNAL);
 Wire.begin(); // join i2c bus (address optional for master)

 pinMode(OUT_PIN, OUTPUT);
 pinMode(IN_PIN, OUTPUT);

 Serial.begin(9600);
}

void loop() {
  //Capacitor under test between OUT_PIN and IN_PIN
  //Rising high edge on OUT_PIN
  pinMode(IN_PIN, INPUT);
  digitalWrite(OUT_PIN, HIGH);
  int val = analogRead(IN_PIN);

  //Clear everything for next measurement
  digitalWrite(OUT_PIN, LOW);
  pinMode(IN_PIN, OUTPUT);
  //digitalWrite(IN_PIN, LOW);

  //Calculate and print result

  float capacitance = (float)val * IN_CAP_TO_GND / (float)(MAX_ADC_VALUE - val);

  Serial.print(capacitance, 2);
  Serial.print(",");
  Serial.print(val);
  Serial.print(",");

  delay(10);

  for( int node = nodeStart; node <= nodeMax; node++){
    Wire.requestFrom(node, sizeof(capacitanceSlave));
    
    for (unsigned int i = 0; i < sizeof(capacitanceSlave); i++){
      capacitanceSlave.bytes[i] = Wire.read();
      }
    Serial.print(capacitanceSlave.capa_slave);
    Serial.print(",");

    delay(10);
  }
  Serial.println();
  delay(50);
}

Slave

const int OUT_PIN = A0;
const int IN_PIN = A2;

//Capacitance between IN_PIN and Ground
//Stray capacitance is always present. Extra capacitance can be added to
//allow higher capacitance to be measured.
const float IN_STRAY_CAP_TO_GND = 30.00;
const float IN_EXTRA_CAP_TO_GND = 0.0;
const float IN_CAP_TO_GND  = IN_STRAY_CAP_TO_GND + IN_EXTRA_CAP_TO_GND;
const int MAX_ADC_VALUE = 1023;

#include <Wire.h>

#define node 10

union u_capacitance
{
  struct
  {
    float capa_slave;
  };
  byte bytes[10];
};

u_capacitance capacitanceSlave;

void setup()
{
  analogReference(EXTERNAL);
  Wire.begin(node);                // join i2c bus with address node
  Wire.onRequest(requestEvent); // register event
  Serial.begin(9600);           // start serial for output

  pinMode(OUT_PIN, OUTPUT);
  pinMode(IN_PIN, OUTPUT);
}

void loop()
{
}

// function that executes whenever data is received from master
// this function is registered as an event, see setup()
void requestEvent()
{
  //Capacitor under test between OUT_PIN and IN_PIN
  //Rising high edge on OUT_PIN
  pinMode(IN_PIN, INPUT);
  digitalWrite(OUT_PIN, HIGH);
  int val = analogRead(IN_PIN);

  //Clear everything for next measurement
  digitalWrite(OUT_PIN, LOW);
  pinMode(IN_PIN, OUTPUT);
  //digitalWrite(IN_PIN, LOW);

  //Calculate and print result

  float capacitance = (float)val * IN_CAP_TO_GND / (float)(MAX_ADC_VALUE - val);

  capacitanceSlave.capa_slave = capacitance;
  
  Wire.write(capacitanceSlave.bytes, sizeof(capacitanceSlave));
  //Serial.println(capacitance, 3);
}

I notice no pull up resistors on the I2C lines. You should have one set somewhere on the bus.

Why connect 50 Arduinos together in the first place? Often this is done by beginners who don't know much about coding or adding port expansion chips.

The I2C bus is only good for a couple of feet anyway.

What is wrong with using capacitor sensing chips?

Yes, why, when each Arduino has 6 analog pins you could use?

The wiring diagram doesn't show anything connected to the 'REF' pin (which I assume is the 'AREF' pin?). You seem to be selecting a floating pin as an analog reference. That won't get good results.

I have to use one arduino per Sensor because in previouse scientific works two sensors interferre on one Arduino and the results are bad.

How does the Arduino know that it should give a bad measurement result?

A medium flows over the sensors and each deflection of a sensor is to be compared with a location of the MEdium. With two sensors on one Arduino this location is no longer correct.

So the answer to if you have pull up resistors is a no then. I can't see any on that photograph. You do seem to have two 1K resistors connected to to Vin and Gnd and then going off to the I2C lines though.

Can you please explain what you mean by this?

A simple fact to consider - many, many Arduino systems make accurate analog measurements on multiple input ports. So, it's extremely likely that this problem is self-made.

The sensors are used to detect a flow front of a liquid

Dragging information out of a reluctant poster makes it very difficult to help them.
Two questions spring to mind.

  1. What is this liquid? So we know if it conducts.
  2. Are the capacitive sensors you are using electrically insulated from this liquid.

It is difficult to see how correctly set up sensors can work on separate Arduinos but not on the same Arduino. There are many ways to measure capacitance and some ways use high impedance inputs. It could be that if we knew more we coud help more.

In the mean time are you defending the mistake I see with the I2C lines, or do you just think I am making an error. Maybe if you moved that brown wire getting in the way of those two 10K resistors that look to me are in parallel things would look different. But the definitive way to see would be to look at the I2C signals on an oscilloscope.

Hello imogdia
If you want to build a serious measurement system, all Adruinos used must be synchronised in time to get time-correlated measuring results.

Have a nice day and enjoy programming in C++ and learning.
Дайте миру шанс!

the liquid flows between the capacitor, so the capacitance changes. This is what I want to measure.
I am very sorry but I have neither Arduino nor POrgramming experience. This is the first part of my thesis and the code is from a former student.

Could you please comment on this. (last time of asking or I leave this thread)

The brown cable is the ground for the shielded cables of the sensor

OK so you do not want to discuss the wiring after asking you three times.
It is so frustrating when a poster will not cooperate, we only know what you tell us. And so I am out of here. I will put this thread on ignore so I wont receive any updates, so don't bother to reply to me.

I see what Mike is talking about. It appears that one of the pull up resistors leads is inserted in the wrong proto board pin socket.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.