Timing issue with Arduino Uno board

Hello all,
I’m new to the world of Arduino, and I would like to submit the following simple issue.

The goal is to manage an SPI communication between Arduino Uno (16MHz) and an energy metering IC (MCP3909). Whit this in mind I have wrote the snippet of code attached in the end of the message.

Things work as they should, but with a DSO and digital probes I realized that signal level changes at the digital pins of Arduino are executed with relevant delay. For example, in correspondence of the series of instructions:

digitalWrite(mclr, HIGH); //Disable mclr for MCP3909
digitalWrite(cs, LOW); //Enable chip select

we can see cs line (pin 10) change after 5micro-second after the low-to-high transition of the mclr line (pin 9), although the two instructions are in sequence.

So, why there is such significant delay in the execution of signal level change in Arduino?
There is a way to make Arduino Uno more reactive to these instructions? For example inserting assembly instructions in the code?

In subsequent steps of the project timing will get critical so the more deterministic and reactive is the behavior of the board the easier would be to manage the system.

The screen shoots of the oscilloscope relevant to the initialization of MCP3909 are attached, and delays pointed out.

Thanks a lot for the help.

Regards,
Tommaso


#define dout 11 // Data out pin
#define din 12 // Data in pin
#define sclk 13 // SPI clock pin
#define cs 10 // Chip select pin
#define mclr 9 // MCLR of MCP3909

void setup() {

//Start serial USART communication
Serial.begin(9600);

pinMode(dout, OUTPUT);
pinMode(din, INPUT);
pinMode(sclk, OUTPUT);
pinMode(mclr, OUTPUT);
pinMode(cs, OUTPUT);

SPI.begin();

digitalWrite(mclr, LOW); // Hold cleared MCP3909
digitalWrite(cs, HIGH); // Disable slave device
delayMicroseconds(10);

//MSB transmitted first
SPI.setBitOrder(MSBFIRST);
//Set SPI clock to 16MHz/8
SPI.setClockDivider(SPI_CLOCK_DIV4);
//Set SPI_MODE1
SPI.setDataMode(SPI_MODE1);

delayMicroseconds(10);

digitalWrite(mclr, HIGH); //Disable mclr for MCP3909
digitalWrite(cs, LOW); //Enable chip select

//Load the Dual channel Pre-HPF operation mode directive
SPI.transfer(0b10100100);
digitalWrite(cs,HIGH); //Disable chip select
}

void loop() {

digitalWrite(cs, LOW); //Enable chip select
//Continue…

ImmaginiSPI.pdf (462 KB)

Hi,

First sorry for my bad English because i'm italian. i want to develope a similar project like yours with Arduino and MCP3909, but i have some problems with the MCP3909. i red the aplication note and the data sheet, but i still don't know how to connect the wires of the circuit of which i want to measure the electrical power consuption. have you got some schemes to explain me?

Instead of digitalWrite, you can use direct port manilulation to change the cs pin.

Say that you were using PortB bit 2 as the pin. Instead of this

digitalWrite(cs, LOW); // Enable slave device
digitalWrite(cs, HIGH); // Disable slave device

To make the pin low and not change the other pins in the port:
PORTB = PORTB & B11111011; // clear bit 2

To make the pin high and not change the other pins in the port:
PORTB = PORTB | B00000100; // set bit 2

I do this all the time with SPI.transfers for fast changes.

Others may use XOR & macros & stuff, I find my way much easier to follow, vs something that looks like this:
PORTB = _BV(<<1);
(which I’m sure is not correct)
or some uncommented C code shortcut that is hard to follow for non-coders who don’t use it on a regular basis.