Using multiple potentiometers - problems with pin A2

I am using 4 10k pots on A0,A1,A2,A3, an i2c-display and digital pots with spi.
the pots on A0, A1 and A3 work fine. The pot on A2 is interfering with the pot on A1. That means A2 has not an independent value with analogread().

The multimeter gives the right voltage for all four pins, but confusing as it is for me, the printed value for A2 with analogread() is wrong. I tried two different Nanos (same result).

// include the SPI library:
#include <SPI.h>
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27,20,4);  // set the LCD address to 0x27 for a 16 chars and 2 line display

/*
R1:     B00010001 17
R2:     B00010010 18
R1+R2:  B00010011 19
*/
 
// set pin 10 as the slave select for the digital pot:
const int slave_Select_Pin  = 10;

int       level1            = 0;
int       level2            = 0;
int       level3            = 0;
int       level4            = 0;

int potPin1 = A0;
int potPin2 = A1;
int potPin3 = A2;
int potPin4 = A3;


 
void setup() {
     lcd.init();                      // initialize the lcd 
  	 lcd.backlight();
  	 lcd.setCursor(0,0);
     
     
     // set the slaveSelectPin as an output:
     pinMode (slave_Select_Pin, OUTPUT);
     Serial.begin(9600);
 
     // initialize SPI:
     SPI.setClockDivider(SPI_CLOCK_DIV16);
     SPI.begin();
     
     //Set Volume to 0 for all DigiPots
     MSP42010PotWrite(slave_Select_Pin, 1, level1);
     MSP42010PotWrite(slave_Select_Pin, 2, level2);
     MSP42010PotWrite(slave_Select_Pin, 3, level3);
     MSP42010PotWrite(slave_Select_Pin, 4, level4);
    
     pinMode(potPin1, INPUT);
	 pinMode(potPin2, INPUT);
	 pinMode(potPin3, INPUT);
	 pinMode(potPin4, INPUT);
}
 
void loop() {
  	 PotRead(1);
  	 PotRead(2);
  	 PotRead(3);
  	 PotRead(4);
}

void PotRead(int Pot) {
	int PotValue;

	switch (Pot) {
	case 1:        
     	lcd.setCursor(0,0);     
  		lcd.print ("Pot1 ");
  		PotValue = analogRead(potPin1);
    	break;  	
  	case 2:
     	lcd.setCursor(0,1);     
  		lcd.print ("Pot2 ");
  		PotValue = analogRead(potPin2);
    	break;
	case 3:
        lcd.setCursor(0,2);     
  		lcd.print ("Pot3 ");
  		PotValue = analogRead(potPin3);
    	break;  	
    case 4:
        lcd.setCursor(0,3);     
  		lcd.print ("Pot4 ");
  		PotValue = analogRead(potPin4);
    	break;    
    }
    lcd.print (PotValue);
    MSP42010PotWrite(slave_Select_Pin, Pot, PotValue/4);
}

 
void MSP42010PotWrite(int slaveSelectPin, int potSelect , int value) {
    // take the SS pin low to select the chip:
    digitalWrite(slaveSelectPin,LOW);
    switch (potSelect) {
	case 1:
        SPI.transfer(17);
     	SPI.transfer(value);
    	break;  	
  	case 2:
     	SPI.transfer(18);
     	SPI.transfer(value);
    	break;
	case 3:
        SPI.transfer(17);
        SPI.transfer(value);
        SPI.transfer(0); // Pot 2
        SPI.transfer(0); // Pot 2  
    	break;
    case 4:
        SPI.transfer(18);
        SPI.transfer(value);
        SPI.transfer(0); // Pot 2
        SPI.transfer(0); // Pot 2  
    	break;    	
    }
     // take the SS pin high to de-select the chip:
     digitalWrite(slaveSelectPin,HIGH);
}

The Nano has only got one ADC which is switched between input pins by the processor as required. This sometimes means that if successive readings are taken quickly from different analogue pins then the ADC does not have time to settle between readings

One way to ameliorate this effect is to take 2 readings in succession from the same pin and ignore the first one on each occasion. Give this a try and report the results

If UKHeliBod's response does not solve your problem which I think it will post a schematic as you have it wired.

Thanks for your answers. The problem is solved. It was a soldering problem. The pot on A2 wasn't connected. this seems to be obvious, but I was irritated, because measuring on A2 gave the right pot-voltage (why?). For that reason I looked in the wrong direction (took me hours).

Because of the chip's internal multiplexer that connects to the single ADC that @UKHeliBob mentioned. Under control of your code, the multiplexer connects the ADC to A1 and samples the voltage there. Next it connects the ADC to A2, where your meter is connected. The residual voltage that the ADC picked up from A1 can now be read, through the multiplexer, by your meter.

Your code is very long and repetitive, you could fix this by using arrays. For example

int       level1            = 0;
int       level2            = 0;
int       level3            = 0;
int       level4            = 0;

int potPin1 = A0;
int potPin2 = A1;
int potPin3 = A2;
int potPin4 = A3;

becomes

int level[4] = {0, 0, 0, 0};

const byte potPin[4] = {A0, A1, A2, A3};

Then, you can shorten your code like

void loop() {
  for(byte p=0; p<4; p++) {
    PotRead(p);
  }
}

and

void PotRead(int Pot) {
  int PotValue;

  lcd.setCursor(0,Pot);     
  lcd.print ("Pot");
  lcd.print (Pot+1);
  lcd.print (" ");
  PotValue = analogRead(potPin[Pot]);
  lcd.print (PotValue);
  MSP42010PotWrite(slave_Select_Pin, Pot, PotValue/4);
}

Theoretically, the unsigned int x = analogRead(A0); function accomplishes the following tasks. If so, there should not be any interference?
1. Slect analog channel and Vref.
2. Start conversion
3. Wait until conversion is complete by monitoring the ADIF flag.
4. Bring the contents of the <ADCH, ADCL> registers into variable x.

Look at the internals in the datasheet. There is one capacitor that is fed from the multiplexer and read by the ADC. That capacitor needs charging / discharging time to get to the input voltage.

If the analogRead(A0) command does not accomodate that discharging time of the "Hold Capacitor (Fig-1 CS/H)", then for sure we have to wait between successive acquisitions of the analog channels.
shCapa
Figure-1:

Thanks for all the answers. I now understand the reason for my wrong analysis.
I will fix my coding (arrays are a good recommendation).

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