MCP3208 through MAX14850 (Digital Isolator)

I'm trying to connect a MCP3208 with a MAX14850ASE+ but can't get it to work.
Datasheet: MAX14850

The test code works without the MAX between the two:

#define SELPIN 10     //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); 
 Serial.println(" "); 
 delay(5000); 
}

Why don't you want to connect the MCP3208 directly to the Arduino? The MAX14850 is driven on both sides with the same 5V. Does that make sense to you?

This is a simplified schematic and breadboard test.
The soldered end product has 2 power supplies.

Why don't you use the SPI interface? I had a similar chip (MCP3202) which even had command/response change inside of one byte but it worked perfectly with the SPI hardware.

This might look like this (adapted from my code to match the datasheet of the MCP3208):

typedef union {
	uint16_t word;
	struct {
		uint8_t lo;
		uint8_t hi;
	} byte;
} byteword;

uint16_t read_adc(uint8_t channel) {
	digitalWrite(SELPIN, LOW);
	
	uint8_t cmd = 0xC0; // Start and Single Mode
	cmd |= channel << 3;
	byteword reading;
	SPI.beginTransaction(SPISettings()); // standard 4MHz, CPOL 0, CPHA 0
	SPI.transfer(cmd); // send command, reception is ignored including start null bit
	reading.byte.hi = SPI.transfer(0x00); // get first 8 bits
	reading.byte.lo = SPI.transfer(0x00); // get another 4 bits
	SPI.endTransaction();
	uint16_t result = reading.word >> 4; // correct to get actual value
	digitalWrite(SELPIN, HIGH);
	return result;
}

But the hardware MISO is D12 and MOSI is D11.

I guess in your code the edges are wrong. The chip does set the DO pin after the rising edge and clears it on the falling edge.

So my schematic is right and it is a coding thing?
Sorry but what do you mean by "Why don't you use the SPI interface"?
Isn't the MCP3208 a SPI chip and connected to the Atmegas SPI...?

So my schematic is right and it is a coding thing?

I haven't found an error in the schematic yet so I searched the code for stuff that might cause a failure.

Sorry but what do you mean by "Why don't you use the SPI interface"?

Although you used pins that are also used by the SPI interface your code doesn't use the hardware SPI but does bit-banging using the pins as GPIOs.

Isn't the MCP3208 a SPI chip and connected to the Atmegas SPI...?

It's not really an SPI chip but it has a SPI compatible interface. Your schematic connects to the same pin group you would use for the hardware SPI but you didn't connect in the correct order for hardware SPI. Your bit-banging code did use the pins you specified in the schematic but the code doesn't use the correct SPI mode (if I'm allowed to use that term for a software emulation).

Look at Din and Dout on the 3208... (swap them)

@weird_dave, your right. When I connect the MCP directly i had it right.
MISO < DOUT (12)
MOSI > DIN (11)

I hate it when they call it:
SIMO, SDO, DO, DOUT, SO, MTSR, SOMI, SDI, DI, DIN, SI, MRST, nCS, CS, CSB, CSN, nSS, STE, SYNC
always confusing...

But i already tried the swapping before without luck.
I also use now the Mega because if i remember right one of my Nano was fake and something was interchanged.

So now it is:

#define SPICLOCK 52  //Clock
#define DATAOUT 51   //MOSI 
#define DATAIN 50      //MISO 
#define SELPIN 53      //Selec Pin

But it does not work :frowning:

Did you check it with my code?

Changing the pins at the Arduino end isn't quite right, you need to change it at the 3208 end (or on the 3208 side of the isolator, you have output to output and input to input in the diagram).

Sorry for the delay.
@pylon, i don't understand your code.
Where do i place it? In "void loop" and the rest from my code i leave as it is?

It's a replacement for your read_adc() function. Just remove the function in your code and copy mine in in replace.