Verdris

AD7714 changes channels for literally no reason

Discussion created by Verdris on Jan 30, 2013
Latest reply on Mar 27, 2013 by ChrisD.Rama

Hi all,

 

I'm using an AD7714 to interface with three sensors, so I'm running in fully differential mode. The meat of my software looks like this:

 

                long singleONE = AD7714.SampleChannel(1);
                long intONE = AD7714.ReadChannel(1, 20);
                Debug.Print("CHANNEL ONE - Single reading = " + singleONE.ToString() + ", integrated reading = " + intONE.ToString());
                Thread.Sleep(1000);

                long singleTWO = AD7714.SampleChannel(2);
                long intTWO = AD7714.ReadChannel(2, 20);
                Debug.Print("CHANNEL TWO - Single reading = " + singleTWO.ToString() + ", integrated reading = " + intTWO.ToString());
                Thread.Sleep(1000);

                long singleTHREE = AD7714.SampleChannel(3);
                long intTHREE = AD7714.ReadChannel(3, 20);
                Debug.Print("CHANNEL THREE - Single reading = " + singleTHREE.ToString() + ", integrated reading = " + intTHREE.ToString());
                Thread.Sleep(1000);

 

The functions SampleChannel() and ReadChannel() are largely unimportant (though I'll paste the whole class below), since they work well on their own. That is, when I comment out lines 6-14, it reads the correct value for channel 1. Conversely, when I comment out lines 1-4 and 11-14, channel 2 is read correctly. Same for channel 3 on its own.

 

However, when I leave all lines uncommented and run the full program, the output from channel 1 is the voltage that appears on channel 3, the output from channel 2 is the voltage that appears on channel 1, and the output on channel 3 is the voltage that appears on channel 2. Here's my output:

 

CHANNEL ONE - Single reading = 240603, integrated reading = 240603 // this is the reading from channel 3
CHANNEL TWO - Single reading = 45822, integrated reading = 45822 // this is the reading from channel 1
CHANNEL THREE - Single reading = 1476135, integrated reading = 1476135 // this is the reading from channel 2

 

I'm using a STM32F405RG and the .NET micro framework to run the ADC. Here's the class I wrote:

 

public class AD7714
    {
        private static InputPort ADC_drdy = new InputPort(Pins.GPIO_PIN_D9, false, Port.ResistorMode.Disabled);
        private static OutputPort ADC_reset = new OutputPort(Pins.GPIO_PIN_D8, true); // reset pin for AD7714 is active high


        private static SPI.Configuration ADC = new SPI.Configuration(Pins.GPIO_PIN_D10, false, 0, 0, false, false, 8000, SPI_Devices.SPI1); // initializes ADC with CS/SS pin 10
        private static SPI ADCBus = new SPI(ADC);


        private static byte[] Channel_1 = new byte[3] { 0x14, 0x20, 0x5C }; /// Fully differential channels
        private static byte[] Channel_2 = new byte[3] { 0x15, 0x20, 0x5D };
        private static byte[] Channel_3 = new byte[3] { 0x16, 0x20, 0x5E };


        public static void Init()
        {
            RGB.Red();
            ADC_reset.Write(false);
            Thread.Sleep(200);
            ADC_reset.Write(true);
            byte[] ResetBuffer = new byte[6] { 0x27, 0xC0, 0x37, 0x13, 0x17, 0x20 };
            ADCBus.Write(ResetBuffer);
            Thread.Sleep(200);
            RGB.Off();
        }


        public static int SampleChannel(int Channel)
        {
            byte[] Empty = new byte[3] { 0, 0, 0 };
            byte[] Reading = new byte[3];
            while(ADC_drdy.Read());
            if (Channel == 1)
            {
                ADCBus.Write(Channel_1);
            }
            if (Channel == 2)
            {
                ADCBus.Write(Channel_2);
            }
            if (Channel == 3)
            {
                ADCBus.Write(Channel_3);
            }
            ADCBus.WriteRead(Empty, Reading);
            return ((Reading[0] << 16) + (Reading[1] << 8) + Reading[2]);
        }


        public static int ReadChannel(int Channel, int samples)
        {
            long total = 0;
            for (int i = 0; i < samples; i++)
            {
                total += SampleChannel(Channel);
            }
            return (int)(total / samples);
        }
    }

 

This isn't the first microcontroller I've had this issue with, the same problem appears with similar software being run on AtMega328P and the PIC32MX820F.

 

Message was edited to reflect that I can't properly poll pins.

Outcomes