14Bit SPI Data

I have another noob question.

I am using the max31855 Thermocouple decoder that communicates over SPI with the FEZ panda ii. The total packet is 32 bits but the thermocouple reading is only the first 14 bits and the cold junction the lowest 12 bits. I have tried a number of different bit shifts to try and get at the 14 bits of data. Below is a basic scheme.

  1. readwrite to spi port, data goes into byte array
  2. take 1st byte and cast to short
  3. take 2nd byte and cast to short while shifting bit left 8 positions
  4. take short and shift it back 2 positions to the right

I have tried this numerous times and I am getting crazy readings on the VFD display. Is it a problem with endianness?

Here is the max31855 datasheet link:

And my code:

using System;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using GHIElectronics.NETMF.Hardware;
using GHIElectronics.NETMF.FEZ;
using System.Text;

namespace VFD
{
    public class Program
    {
        public static void Main()
        {
            // Set SPI port settings for VFD
            SPI.Configuration myVFDPortSettings = new SPI.Configuration((Cpu.Pin)FEZ_Pin.Digital.Di1, false, 0, 0, true, true, 2000, SPI.SPI_module.SPI1);

            // Open SPI port for MAX31855
            SPI.Configuration myMAXPortSettings = new SPI.Configuration((Cpu.Pin)FEZ_Pin.Digital.Di34, false, 0, 0, false, false, 2000, SPI.SPI_module.SPI2);
 
            
            // Create SPI VFD port
            SPI myVFDPort = new SPI(myVFDPortSettings);

            // Create SPI MAX31855 Port
            SPI myMAXPort = new SPI(myMAXPortSettings);


            // Create byte array for temp data and read in 32bits
            byte[] myTempsOut = new byte[4] { 0x00 ,0x00, 0x00, 0x00 };
            byte[] myTempsIn = new byte[4];
                        
            
                  
            
            // Initialize VFD
            byte[] myVFDInitialize = new byte[] { 0xF8, 0x38 };
            myVFDPort.Write(myVFDInitialize);
            Thread.Sleep(6);
            byte[] myVFDAddress = new byte[] { 0xF8, 0x00 };
            byte[] myVFDClear = new byte[] { 0xF8, 0x01 };
            byte[] myVFDMessageStart = new byte[] { 0xFA };
            byte[] myVFDOn = new byte[] { 0xF8, 0xC };

            while (true)
            {

                Thread.Sleep(1000);
                myVFDPort.Write(myVFDClear);
                myMAXPort.WriteRead(myTempsOut, myTempsIn);
                Thread.Sleep(10);

                short temp = (short)(myTempsIn[0]);
                temp |= (short)(myTempsIn[1] <<6);
                temp = (short)(temp >> 2);
                //temp = (short)(temp >> 6);


                double temperature = ((temp * 0.25) * 9 / 5) + 32;

                string displaytemp = temperature.ToString();
                // Set DDRAM address for text
                
                myVFDPort.Write(myVFDAddress);
                Thread.Sleep(10);

                // Write to display
               
                byte[] buffer = System.Text.UTF8Encoding.UTF8.GetBytes(displaytemp);
                byte[] sendstring = new byte[myVFDMessageStart.Length + buffer.Length];

                myVFDMessageStart.CopyTo(sendstring, 0);
                buffer.CopyTo(sendstring, myVFDMessageStart.Length);

                myVFDPort.Write(sendstring);
                Thread.Sleep(6);
                temp = 0;
                temperature = 0;

                // Turn on display
                
                myVFDPort.Write(myVFDOn);
                Thread.Sleep(6);
            }
        }

    }
}

I am not sure because I don’t know your master/slave config but follow that code, the first byte u got:


short temp = (short)(myTempsIn[0]);

I think myTempsIn[0] is always 0. Try to take myTempsIn[1] and myTempsIn[2]. There are some configurations but normally the first byte is returned by slave is zero.

It might be in myTempsIn[2] and myTempsIn[3]. :slight_smile:

The first thing you should do is use the debugger to see what data you get back. You can
then verify which bytes contains the data and whether you are bigendian or littleendian.

You said “take 2nd byte and cast to short while shifting bit left 8 positions” but in your code you shifted left 6.

Also if you shift right two positions most likely you will lose the two low order bits.

@ Mike -

The first thing you should do is use the debugger to see what data you get back. => Correct :))

I just realized something as I looked at the datasheet timing diagram. I have been looking at the data backwards… what a noob!!!

The datasheet shows that the first 3 bits out are error bits. I will AND these to determine the error code. The next bit is reserved and then bit 4 through bit 15 is the signed cold junction temp. Bit 16 is the another error bit and bit 17 is reserved. Finally bits 18-31 are the signed temperature bit.

I was reading the datasheet timing backwards going from left to right it shows bits 31-0 but I am reading the data bits in from right to left.

That is really embarrassing…

Thanks Mike and Dat I will use the debugger to watch the values next time!

Nate did you get this to work? If so could you please post the code?