MSB is skipped when reading data from SPI slave

Hello,
I am trying to interface an Arduino Mega with DC682 (Demo board for LTC1859) which is a 16-bit analog-to-digital converter that uses SPI.

I wrote a simple program that sends the command byte, followed by a filler byte from the master (Arduino Mega) and to parallelly read two bytes (Which are the converted digital values of the analogue input provided to the ADC) from the Slave (DC682). The program is as shown below.

#include <SPI.h>

#define CONVST 53     //SS

byte lowerByte=0; byte upperByte=0;
word data=0;

void setup() {
  Serial.begin(9600);
  SPI.begin();
  SPI.setClockDivider(SPI_CLOCK_DIV2);    //8MHz clock for SPI
  SPI.setBitOrder(MSBFIRST);
  SPI.setDataMode(SPI_MODE0);

  pinMode(CONVST, OUTPUT);
  digitalWrite(CONVST, HIGH);    //Pull SS high initially
}

void loop() {
    digitalWrite(CONVST, LOW);      //pull SS low before the conversation

    upperByte=SPI.transfer(0b10000100);    //command byte for the ADC
    lowerByte=SPI.transfer(0b00000000);    //filler byte

    digitalWrite(CONVST, HIGH);    //pull SS high after the conversation

    data=word(upperByte,lowerByte);    //store ADC result as a word
    
    //printing the 16-bit digital value along with the leading 0s
    bool rawDataBit = 0;
    Serial.print("Raw:");
    for (int i=15; i>= 0; i--) {
        rawDataBit = (data>> i) & 1;
        Serial.print(rawDataBit, BIN);   
    }
    Serial.println();
}  

The input voltage provided is -6V. But the raw digital data outputed is not corresponding to -6V. But if I append a 1 as MSB, the conversion seems correct. I am getting the

0110001111100110

in the output but I should be getting (1 appended to the left)

1011000111110011

Just for comparision

Raw data.......: 0110001111100110
1 appended: 1011000111110011

The additional appending 1 is working for all the input voltages ranging from -5V to -10V. Rest of the range i.e. -5V to 0v to +10V is working fine without any appending needed.

I cannot figure out what exactly is wrong.
Please help me figure it out. Let me know if I am doing anything wrong.
Thanks.

What do you see if you print upperByte and lowerByte after reading them ?

For 0110001111100110 I get 01100011 and 11100110 as upper and lower bytes.
Just for comparison

01100011.11100110
01100011 11100110

Hey! I do not know how or why, but I tried to check the signal of the MISO pin on an oscillator. And from then on, the MSB bit was not getting skipped. Everything seems to be working fine now.
Is there a reason this happened? Any things I need to check or take care of, if I run into a similar situation ever again?

Try changing the command byte to 10000100 which selects the input range as -10V to +10V (Fig-1). Also check that your sketch does not define the variable rawData. Your command byte (10001100) selects the input range as 0V to 10V (Fig-1). Show the ADC value on Serial Monitor in bit form by including this code in your sketch: Serial.print(data, BIN).

rangeLT1859
commnadByteLTC1859
Figure-1:

Hello GolamMostafa,
Thank you for the reply and the suggestions. I am extremely sorry for the mistakes in the code that I posted here. I have been playing around with the code before posting it here. Did not check properly after posting. The rawData variable is actually the data variable. And the command byte is actually set to 10000100. Like I said I have been playing around with the code, so by the time I pasted it I was maybe testing the 0 to 10V range. Corrected both of them in the post.
Thank you so much for pointing them out.
Regarding the Serial.print(data, BIN), I could have done this, but this does not display the leading zeros. So wrote a simple loop to display all 16-bits of data, irrespective of the leading zeros or ones.

I do wish that printing with the BIN specifier would actually print the leading zeroes to avoid the need to do this. So much so that I wrote a function to do it for any data type and put it in a library file so that it could be #included in any sketch where it is required

Set input volatge at -6V or -5V and then show the ADC value on the Serial Monitor by executing the following code: Serial.print(data, HEX). Report the value. This must show MSB as 1. If not, we will investigate the issue. You can show all 16 bits in bit form along with leading zeros of data variable by executing the following codes:

for(int i=15; i >= 0; i--)
{
     Serial.print(bitRead(data, i), BIN);
}

Hello GolamMostafa and UKHeliBob,
Thank you so much for your suggestion and help. My issue got solved. I did not change anything in the program, nor in the hardware. I am not sure how or why it started working correctly all of a sudden.
Please let me know what caused this, so that it will be helpful when I face it again.

Oh yes you did !

Please, post your sketch that is working now. It could be that the program is working intermittently; so, you must try to reproduce the original fault. If it is a hobby project for learning, then you can start your next project; otherwise, you have to be serious to find the cause of the initial trouble.

Oh, sorry! What is this supposed to mean?

ADC_ReadSamples.ino (3.6 KB)
Here is the actual full program that I used.
This is the same one that did not give out proper result out. And this is the exact same program that started giving out the correct result out when I connected the CRO probes to SCK, MOSI and MISO.

I hope we find something so that it is helpful for the next time.

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