SPI connection MCP23s17 and MCP3208

Hi everyone,

For an advanced remote control panel I have to connect 20 potentionometers, 10 switches and 8 LED’s to my UNO. I bought myself two MCP3208 ADS’s and a MCP23s17 I/O expander. I tried to use them all at he same time but it won’t work. All the 3 chips are using different pins connected to CS and share MISO,MOSI and CLK.

This is code I’m using: (it is a combination of two examples)

#include <SPI.h>              // We use this library, so it must be called here.
#include <MCP23S17.h>         // Here is the new class to make using the MCP23S17 easy.
#define SELPIN    9 //Selection Pin 
#define DATAOUT   11//MOSI 
#define DATAIN    12//MISO 
#define SPICLOCK  13//Clock 
 
int readvalue; 

MCP iochip(0);             // Instantiate an object called "iochip" on an MCP23S17 device at address 1

void setup(){ 
 
  //set pin modes 
 pinMode(SELPIN, OUTPUT); 
 pinMode(DATAOUT, OUTPUT); 
 pinMode(DATAIN, INPUT); 
 pinMode(SPICLOCK, OUTPUT); 
 
 //disable device to start with 
 digitalWrite(SELPIN,HIGH); 
 digitalWrite(DATAOUT,LOW); 
 digitalWrite(SPICLOCK,LOW); 
 iochip.byteWrite(IODIRB, 0x00); //Use byte-write to set all 8 bits of IO Direction register for portB to outputs
 Serial.begin(9600); 
} 

int read_adc(int channel){
  int adcvalue = 0;
  byte commandbits = B11000000; //command bits - start, mode, chn (3), dont care (3)

  //allow channel selection
  commandbits|=((channel-1)<<3);

  digitalWrite(SELPIN,LOW); //Select adc
  // setup bits to be written
  for (int i=7; i>=3; i--){
    digitalWrite(DATAOUT,commandbits&1<<i);
    //cycle clock
    digitalWrite(SPICLOCK,HIGH);
    digitalWrite(SPICLOCK,LOW);    
  }

  digitalWrite(SPICLOCK,HIGH);    //ignores 2 null bits
  digitalWrite(SPICLOCK,LOW);
  digitalWrite(SPICLOCK,HIGH);  
  digitalWrite(SPICLOCK,LOW);

  //read bits from adc
  for (int i=11; i>=0; i--){
    adcvalue+=digitalRead(DATAIN)<<i;
    //cycle clock
    digitalWrite(SPICLOCK,HIGH);
    digitalWrite(SPICLOCK,LOW);
  }
  digitalWrite(SELPIN, HIGH); //turn off device
  return adcvalue;
}


void loop() { 
  iochip.digitalWrite(9, HIGH);  
  iochip.digitalWrite(10, LOW); 
  iochip.digitalWrite(11, HIGH);
  iochip.digitalWrite(12, LOW); 
  iochip.digitalWrite(13, HIGH); 
  iochip.digitalWrite(14, LOW); 
  
  
 readvalue = read_adc(1); 
 Serial.println(readvalue,DEC); 
 readvalue = read_adc(2); 
 Serial.println(readvalue,DEC); 
 readvalue = read_adc(3); 
 Serial.println(readvalue,DEC); 
 readvalue = read_adc(4); 
 Serial.println(readvalue,DEC); 
 readvalue = read_adc(5); 
 Serial.println(readvalue,DEC); 
 readvalue = read_adc(6); 
 Serial.println(readvalue,DEC); 
 readvalue = read_adc(7); 
 Serial.println(readvalue,DEC); 
 readvalue = read_adc(8);
 Serial.println(readvalue,DEC); 
 Serial.println(" "); 
 delay(500); 
 
  iochip.digitalWrite(9, LOW);  
  iochip.digitalWrite(10, HIGH); 
  iochip.digitalWrite(11, LOW);
  iochip.digitalWrite(12, HIGH); 
  iochip.digitalWrite(13, LOW); 
  iochip.digitalWrite(14, HIGH); 

delay(500);
 
 
 
 
}

The problem is that the ADC just outputs only zeros, when I upload the original example for the ADC,
without hardware changes, it displays the correct values on the serial monitor.

I hope someone can help me with this.

Hi panapro

Can you please post the ADC example that does work? Have you tried connecting the second ADC and port expander hardware while still running just the ADC example?

But something to try first is that you don’t seem to have set up the other two CS pins. I guess the one for the MCP23S17 is handled by the library, but it’s not clear how that relates to this:

MCP iochip(0);             // Instantiate an object called "iochip" on an MCP23S17 device at address 1

Since you are handling the ADCs directly in your code, you need to add a pinMode statement for pin 8 and make sure it is set to HIGH while reading from the other ADC.

Regards

Ray

Hello Ray,

Actually I haven’t connected the 2nd ADC yet.
This is the code which is working:

#define SELPIN 9 //Selection Pin 
#define DATAOUT 11//MOSI 
#define DATAIN  12//MISO 
#define SPICLOCK  13//Clock 
int readvalue; 

void setup(){ 
 //set pin modes 
 pinMode(SELPIN, OUTPUT); 
 pinMode(DATAOUT, OUTPUT); 
 pinMode(DATAIN, INPUT); 
 pinMode(SPICLOCK, OUTPUT); 
 //disable device to start with 
 digitalWrite(SELPIN,HIGH); 
 digitalWrite(DATAOUT,LOW); 
 digitalWrite(SPICLOCK,LOW); 

 Serial.begin(9600); 
} 

int read_adc(int channel){
  int adcvalue = 0;
  byte commandbits = B11000000; //command bits - start, mode, chn (3), dont care (3)

  //allow channel selection
  commandbits|=((channel-1)<<3);

  digitalWrite(SELPIN,LOW); //Select adc
  // setup bits to be written
  for (int i=7; i>=3; i--){
    digitalWrite(DATAOUT,commandbits&1<<i);
    //cycle clock
    digitalWrite(SPICLOCK,HIGH);
    digitalWrite(SPICLOCK,LOW);    
  }

  digitalWrite(SPICLOCK,HIGH);    //ignores 2 null bits
  digitalWrite(SPICLOCK,LOW);
  digitalWrite(SPICLOCK,HIGH);  
  digitalWrite(SPICLOCK,LOW);

  //read bits from adc
  for (int i=11; i>=0; i--){
    adcvalue+=digitalRead(DATAIN)<<i;
    //cycle clock
    digitalWrite(SPICLOCK,HIGH);
    digitalWrite(SPICLOCK,LOW);
  }
  digitalWrite(SELPIN, HIGH); //turn off device
  return adcvalue;
}


void loop() { 
 readvalue = read_adc(1); 
 Serial.println(readvalue,DEC); 
 readvalue = read_adc(2); 
 Serial.println(readvalue,DEC); 
 readvalue = read_adc(3); 
 Serial.println(readvalue,DEC); 
 readvalue = read_adc(4); 
 Serial.println(readvalue,DEC); 
 readvalue = read_adc(5); 
 Serial.println(readvalue,DEC); 
 readvalue = read_adc(6); 
 Serial.println(readvalue,DEC); 
 readvalue = read_adc(7); 
 Serial.println(readvalue,DEC); 
 readvalue = read_adc(8);
 Serial.println(readvalue,DEC); 
 Serial.println(" "); 
 delay(100); 
}

This example is working fine with the first ADC and the port expander connected. When I upload the other code, the ADC ‘serialprint’ starts displaying just zero’s. It looks like the port expander is working fine. (leds are flashing).

The following code is included in the MCP23S17.cpp-file, I guess these lines will tell the program that my mcp23s17 cs is connected to pin 10 of my arduino.

#define    CLOCK_DIVIDER (2)           // SPI bus speed to be 1/2 of the processor clock speed - 8MHz on most Arduinos
#define    SS            (10)          // SPI bus slave select output to pin 10 - READ ARDUINO SPI DOCS BEFORE CHANGING!!!

Is it possible that this clock-devider is messing things up?