SPI CN0391 question reflection on the MOSI, MISO line=?

Status
Not open for further replies.

Bastiaan

Well-known member
Dear tinkeres,

I have a problem of understanding of the following CN0391 evaluation board. I have it currently hooked up to the Teensy3.6
and I dont get a feedback from the AD7124 on the evaluation board(ADC). it produces jitter on the MOSI, MISO line.

I am greatly lacking in the SPI department, and looking for some help. I posted the Screenshot from the OScilloscope to check on the CLK, MOSI,MISO,CS as you can see.
also I get a -1 value on my serial Monitor.

I just dont have a clue where to look. ill start with the SPI commands in the setup and change those as given by the PJRC community.

the following code that is being used is:

Code:
#include <ad7124.h>

/* constants ================================================================ */
const int ledPin = 9;
const int ssPin = 10;

/* public variables ========================================================= */
Ad7124Chip adc;

/* internal public functions ================================================ */

// -----------------------------------------------------------------------------
void setup() {



  //Initialize serial and wait for port to open:
  Serial.begin (38400);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }

  // prints title with ending line break
  Serial.println ("AD7124 Voltmeter");

  // Initializes the AD7124 device, the pin /CS is pin 10 (/SS)
  adc.begin (ssPin);

  // Setting the configuration 0:
  // - use of the internal reference voltage 2.5V
  // - gain of 1 for a bipolar measurement +/- 2.5V
  adc.setConfig (0, Ad7124::RefInternal, Ad7124::Pga1, true);
  // Setting channel 0 using pins AIN1(+)/AIN0(-)
  adc.setChannel (0, 0, Ad7124::AIN1Input, Ad7124::AIN0Input);
  // Configuring ADC in Full Power Mode (Fastest)
  adc.setAdcControl (Ad7124::StandbyMode, Ad7124::FullPower, true);
}

// -----------------------------------------------------------------------------
void loop() {
  long value;
  double voltage;

  // Measuring Voltage on Channel 0 in Single Conversion Mode
  digitalWrite (ledPin, 10);
  value = adc.read (ssPin);
  Serial.print("value ");
  Serial.println(value);
  digitalWrite (ledPin, 10);

  if (value >= 0) {

    // If the measurement is successful, the value is converted into voltage
    voltage = Ad7124Chip::toVoltage (value, 1, 2.5, true);
    // Print result
    Serial.println (voltage, 3);
  }
  else {

    Serial.println ("FAIL");
  }
}
 

Attachments

  • IMG_2572.jpg
    IMG_2572.jpg
    136.4 KB · Views: 89
  • IMG_2573.jpg
    IMG_2573.jpg
    116.3 KB · Views: 69
Sorry, I am not sure how much help I can be here. I don't know your setup. Might help if you provided a little more information, like:
A link to your evaluation board and/or maybe better yet to document describing it.

Likewise maybe either include the library code you are using and/or link to it.

Also at times pictures of your setup helps. Sometimes it helps to see things like, if one is using a breadboard, and the pins are not soldered to the Teensy, or a bad solder joint. Or maybe wires long or not good contact... Or maybe missing a ground wire.

But things I would typically look at are:
a) Your device is it setup to work at 3.3v? Or does it require 5v? If it requires 5v what do the IO pins output. As the T3.6 can not handle 5v.
b) SPI - Do the signals have Pull Up resistors. Many boards have them, but maybe not or maybe not correct values
c) What is the range of valid speeds for SPI for this device?
d) What SPI Mode should you use with it. (Which edge leading or trailing, Polarity)...
e) Does this evaluation board and/or your setup have multiple devices or the like that are on the SPI pins? If so do they have their own CS pins? And if so are they all hooked up and setup such that only one devices CS pin asserted?

Again sorry I know I am just doing a shotgun answer, but maybe one of them might get you somewhere.
 
Hi Kurt,

Thanks for the fast reply. Excellent questions!

1 https://www.analog.com/en/design-ce...circuits-from-the-lab/cn0391.html#rd-overview
Has 3.3V input, and for the Spi a 5 to 3.3 V level shifter included.
2they were not so concise about that: https://en.m.wikipedia.org/wiki/Serial_Peripheral_Interface
3 They say at the website the following about the speed: https://ez.analog.com/data_converters/precision_adcs/f/q-a/23642/ad7124-4-spi-read-problem
4 external MCLK=2.45MHz, https://www.analog.com/media/en/technical-documentation/data-sheets/ad7124-8.pdf
Page 9 I am giving you the Pdf as well to make sure. They say the behind the external clock something ackward(internal divided by four)
5 I hope I am correct and found the communication driver: I don’t exactly if they a referring to a specific SPI mode, they are talking about the specific order of msb and lsb, https://github.com/analogdevicesinc...drivers/communication/generic/Communication.c.
6 on the same pins I would like to use a hx8357 Feather wing with a different CS pin8 MOSI miso and dc and clk are the same.

7 so for my understanding I have a lot of things to do. Get the ad7124 to work at slower speed, use the provide library ad7124, send commands to the appropriate registers, starting with a clear reset for all the registers AD7124. (Just to make sure).
8 By using the SPI.transfer command write to a register followed by a binary number 0b00000001(for example) ( this I don’t exactly understand from the ad7124 pdf)

I am having a gap of understanding
what my goal is is to read 4 TC signals in continious Mode and the data from the cold junction from the 4 rtds on the board to the microprocessor. Put them on screen and almost simultaneously put those values in Brett breaugards PID to drive pololu 18V25 Hbridges for water cooling. The difficulty is for me is the cn0391 and later the adding of the GFX library

Thanks for reading and asking good questions and help.
 
Pictures for the cn0391 wiring and measurement
 

Attachments

  • BA379482-65AB-45AB-AF37-6C64B3904A26.jpeg
    BA379482-65AB-45AB-AF37-6C64B3904A26.jpeg
    136.1 KB · Views: 53
  • 1A90B4FF-3526-4D5B-8260-01D167A6391A.jpeg
    1A90B4FF-3526-4D5B-8260-01D167A6391A.jpeg
    120.2 KB · Views: 54
cn0391 update

ok, so I tested it with a teensy3.6 the AD7124 Full Test Continious program works, IOREF 3.3V external (needed!)

Output Serial Monitor:

`AD7124 Full Test


Setting up 4 channels with 4setup
Config0(0x19) = 0x9F0

Channel0(0x9) = 0x31

Config1(0x1A) = 0x9F0

Channel1(0xA) = 0x1071

Config2(0x1B) = 0x9F0

Channel2(0xB) = 0x20B1

Config3(0x1C) = 0x9F0

Channel3(0xC) = 0x30F1


Setting up ADC

(|(0x1) = 0x1188


Calibration

Offset0(0x29) = 0x800000

Gain0(0x31) = 0x554E8A

Offset1(0x2A) = 0x800000

Gain1(0x32) = 0x554E8A

Offset2(0x2B) = 0x800000

Gain2(0x33) = 0x554E8A

Offset3(0x2C) = 0x800000

Gain3(0x34) = 0x554E8A


V0 V1 V2 V3

-0.000 -0.000 -0.000 -0.000
-0.000 -0.000 -0.000 -0.000
-0.000 -0.000 -0.000 -0.000
-0.000 -0.000 -0.000 -0.000
-0.000 -0.000 -0.000 -0.000`

if I run the cn0391.ino
the MISO has quirks. sometimes it works and then I have a Timeout... I resoldered the pins from the AD7124 just to make sure. I connected the IOREF to the 3.3V from the Teensy 3.3V/250mA and connected this also to the power supply from the featherwing 3.5inch (HX8357). with the featherwing similar problems occur. so is it wise to hook up a 10k/10K voltage divider from 3.3V so that this line is pulled up?

i connected the following pins to the tftscreen as well: (pins are correctly given on the PJRC Post)

HTML:
https://forum.pjrc.com/threads/54982-TEENSY-3-6-ADAFRUIT-3-5-quot-TFT-touch-controller-issue
pins on the teensy3.6 for the TFT
SCLK, MISO,MOSI,CS,DC
13, 11 , 12 ,8, 9,

pins on the Teensy3.6 used for the
HTML:
https://wiki.analog.com/resources/eval/user-guides/arduino-uno/reference_designs/demo_cn0391
SCLK, MISO,MOSI,CS,
13, 11, 12, 10,

Anyway I tried this but the screen flashes on and off.

what would be the best approach in accessing and terminating the CN0391 code?
can I simply use Slave select and pull it high as given in this example?

Code:
#include <SPI.h>
#include "CN0391.h"
#include "Communication.h"
#include "Adafruit_GFX.h"
#include "Adafruit_HX8357.h"
#define TFT_CS 8
#define TFT_DC 9



Adafruit_HX8357 tft = Adafruit_HX8357(TFT_CS, TFT_DC);
unsigned long later_time = 0;

#define TS_MINX 3800
#define TS_MAXX 100
#define TS_MINY 100
#define TS_MAXY 3750

void setup() {
  Serial.begin(9600);
  delay(1000);
  SPI.begin();
  pinMode(CS_PIN, OUTPUT);
  pinMode(8, OUTPUT);
   CN0391_init();

     tft.begin();


#if(USE_RTD_CALIBRATION == YES)
   CN0391_calibration(RTD_CHANNEL);
   Serial.println(F("RTD channel calibration completed!"));
#else
   Serial.println(F("Calibration for RTD channel is disabled."));
#endif

#if(USE_TH_CALIBRATION == YES)
   CN0391_calibration(TH_CHANNEL);
   Serial.println(F("TC channel calibration completed!"));
#else
   Serial.println(F("Calibration for TC channel is disabled."));
#endif

}

void loop() 
{
        unsigned long currentMillis= millis();
        digitalWrite(10,LOW);
        CN0391_set_data();
        Serial.println("test");
        CN0391_display_data();
        later_time=millis()-currentMillis;
        Serial.print(later_time);
        Serial.println("  ms execution time 4 Channels differential with Cold Junction: ");
        digitalWrite(10,HIGH);
        digitalWrite(8,LOW);

        //do something here with the display
       tft.fillScreen(HX8357_BLACK);
  unsigned long start = micros();
  tft.setCursor(0, 0);
  tft.setTextColor(HX8357_WHITE);  tft.setTextSize(1);
  tft.println("Hello World!");

//tft finished
digitalWrite(8,HIGH); //wait for AD7124 if it is ready (298ms) conversion time 4 channels
digitalWrite(SSpin,LOW);


}

}

i probably have also to set SPISettings for the HX8357 as given in the SPI example on the teensy website correct?

many thanks

Bastiaantftandcn0391 connected.pngsecondrun.jpg
 
Last edited:
Sorry I did not take a full look through your code, so may miss a few things, but some of the things I think,
you may need is:

a) if you have multiple devices on the same SPI buss, than you need to only have one of their CS pins active (low) at a time. So for example if you leave their pin floating or connected but not set, the value could be randomly changing and causing issues. Also not everything is shown here...

That is you have:
Code:
  pinMode(CS_PIN, OUTPUT);
  pinMode(8, OUTPUT);
   CN0391_init();
My guess is this will have CS pin asserted as you did set it's state either high or low, but I believe defaults to LOW, which is asserted.

But what is the state of TFT_CS pin at this point?

If I have multiple devices like this, I will typically at the start of setup do something like:
Code:
pinMode(TFT_CS, OUTPUT);
digitalWrite(TFT_CS, HIGH);  // make sure unasserted
And do it for all CS pins I know of. Note: if you actually use one of our display drivers we may convert the SPI CS pin for the display to a Hardware CS pin... But that will be during the init stuff.

b) I don't see any call to: tft.begin(); in your code to initialize the display. Maybe I missed it somewhere.

c) Some displays and maybe some other devices don't have a properly setup tri-state like MISO pin (SDO) - They assume they are always driving the signal. My guess that this is not it as the only one I have found sells the HX8357 display is Adafruit, who usually handle this. Note: we do have a sped up version of driver for this display that is not part of the Teensduino releases. I believe the current github master for this is up at: https://github.com/mjs513/HX8357_t3n
 
Hi Kurt,

a Ok ill set both CS(TFT,CN0391) pins to the HIGH in the Init, that is something I have probably a misunderstanding in. for each time accessing the init in void setup (pseudo code)

Code:
void Setup()
{

digitalWrite(TFTSSpin,LOW);
tft.begin();
digitalWrite(TFTSSPin,HIGH);
digitalWrite(SSpin,LOW);

CN0391_init();
digitalWrite(SSpin,HIGH);

}
b I put TFT.begin() in the Setup ( one of the misunderstandings with the SPI stuff).
c ok ill have a look at this. so it technically shouldnt matter if I create a SPIsettingsADC and SPISETTINGSTFT on the same bus but with different CS pins due to the CLK? techically the HX8357 can run faster.
 
something like this, but I have a feeling that the code from theCN0391 doesnt want to cooperate with the TFT.
I tried switching the MOSI,MISO Pins from the tft.

ok nevermind up to next week.

Code:
#include <SPI.h>
#include "CN0391.h"
#include "Communication.h"
#include "Adafruit_GFX.h"
#include "Adafruit_HX8357.h"
#define TFT_CS 8
#define TFT_DC 9



Adafruit_HX8357 tft = Adafruit_HX8357(TFT_CS, TFT_DC);
unsigned long later_time = 0;

#define TS_MINX 3800
#define TS_MAXX 100
#define TS_MINY 100
#define TS_MAXY 3750

void setup() {
  
  Serial.begin(9600);
  delay(1000);
  SPI.begin();
  pinMode(CS_PIN, OUTPUT);
  pinMode(8, OUTPUT);


  
   digitalWrite(10,LOW);
   CN0391_init();

        

#if(USE_RTD_CALIBRATION == YES)
   CN0391_calibration(RTD_CHANNEL);
   Serial.println(F("RTD channel calibration completed!"));
#else
   Serial.println(F("Calibration for RTD channel is disabled."));
#endif

#if(USE_TH_CALIBRATION == YES)
   CN0391_calibration(TH_CHANNEL);
   Serial.println(F("TC channel calibration completed!"));
#else
   Serial.println(F("Calibration for TC channel is disabled."));
#endif
   digitalWrite(10,HIGH);
digitalWrite(8,LOW);
    tft.begin();
digitalWrite(8,HIGH);
}

void loop() 
{
      
        unsigned long currentMillis= millis();

        CN0391_set_data();
        Serial.println("test");
        CN0391_display_data();
        later_time=millis()-currentMillis;
        Serial.print(later_time);
        Serial.println("  ms execution time 4 Channels differential with Cold Junction: ");
      


tft.fillScreen(HX8357_BLACK);
  unsigned long start = micros();
  tft.setCursor(0, 0);
  tft.setTextColor(HX8357_WHITE);  tft.setTextSize(1);
  tft.println("Hello World!");
  tft.setTextColor(HX8357_YELLOW); tft.setTextSize(2);
  tft.println(1234.56);
  tft.setTextColor(HX8357_RED);    tft.setTextSize(3);
  tft.println(0xDEADBEEF, HEX);
  tft.println();
  tft.setTextColor(HX8357_GREEN);
  tft.setTextSize(5);
  tft.println("Groop");
  tft.setTextSize(2);
  tft.println("I implore thee,");
  tft.setTextSize(1);
  tft.println("my foonting turlingdromes.");
  tft.println("And hooptiously drangle me");
  tft.println("with crinkly bindlewurdles,");
  tft.println("Or I will rend thee");
  tft.println("in the gobberwarts");
  tft.println("with my blurglecruncheon,");
  tft.println("see if I don't!");


}
 
Again I don't see enough of your ADC code to have a real idea of what it does or assumes or...

There is some Arduino code I see up on another Arduino site: https://create.arduino.cc/projecthu...getting-the-best-out-of-the-ad7793-adc-cf01af

Which looks like it uses some adapted version of the communications code, which shows some stuff, but again I think it is really only setup to work by itself as far as SPI is concerned.

I am not sure how well the device itself cooperates... But the code is not setup to handle it well.

Again if it were me, I would have the code setup, where I would pass in the CS pin to it's init method.. Of course you can do it all yourself as wrapper around it. That is what you may need is something like: (Note I am assuming CS_PIN is your ADC CS pin??? or if that is your pin 10? )

Relooking I think something like:
Code:
#include <SPI.h>
#include "CN0391.h"
#include "Communication.h"
#include "Adafruit_GFX.h"
#include "Adafruit_HX8357.h"
#define TFT_CS 8
#define TFT_DC 9
[COLOR="#FF0000"]
#define CN0391_CS 10
#define CN0391_SPI_SPEED 2000000 // 2mhz? [/COLOR]

Adafruit_HX8357 tft = Adafruit_HX8357(TFT_CS, TFT_DC);
unsigned long later_time = 0;

#define TS_MINX 3800
#define TS_MAXX 100
#define TS_MINY 100
#define TS_MAXY 3750

void setup() {
  
  Serial.begin(9600);
  delay(1000);
  SPI.begin();
[COLOR="#FF0000"]  pinMode(CN0391_CS, OUTPUT);
  pinMode(TFT_CS, OUTPUT);
[/COLOR]

  
 [COLOR="#FF0000"]  digitalWrite(CN0391_CS,LOW);
   SPI.beginTransaction(SPISettings(CN0391_SPI_SPEED , MSBFIRST, SPI_MODE0));[/COLOR]

   CN0391_init();

        

#if(USE_RTD_CALIBRATION == YES)
   CN0391_calibration(RTD_CHANNEL);
   Serial.println(F("RTD channel calibration completed!"));
#else
   Serial.println(F("Calibration for RTD channel is disabled."));
#endif

#if(USE_TH_CALIBRATION == YES)
   CN0391_calibration(TH_CHANNEL);
   Serial.println(F("TC channel calibration completed!"));
#else
   Serial.println(F("Calibration for TC channel is disabled."));
#endif
 [COLOR="#FF0000"] SPI.endTransaction();
  digitalWrite(CN0391_CS,HIGH);
[/COLOR]
  tft.begin();
}

void loop() 
{
      
        unsigned long currentMillis= millis();

  [COLOR="#FF0000"]// Sorry I don't know the code inside here...
  // But assume this only talks to your ADC device
  // This sets up the communications again to talk to your device at the device speed and settings.      
   digitalWrite(CN0391_CS,LOW);
   SPI.beginTransaction(SPISettings(CN0391_SPI_SPEED , MSBFIRST, SPI_MODE0));
      [/COLOR]
        CN0391_set_data();
        Serial.println("test");
        CN0391_display_data();
        later_time=millis()-currentMillis;
        Serial.print(later_time);
        Serial.println("  ms execution time 4 Channels differential with Cold Junction: ");
 [COLOR="#FF0000"] SPI.endTransaction();
  digitalWrite(CN0391_CS,HIGH);[/COLOR]
      


tft.fillScreen(HX8357_BLACK);
  unsigned long start = micros();
  tft.setCursor(0, 0);
  tft.setTextColor(HX8357_WHITE);  tft.setTextSize(1);
  tft.println("Hello World!");
  tft.setTextColor(HX8357_YELLOW); tft.setTextSize(2);
  tft.println(1234.56);
  tft.setTextColor(HX8357_RED);    tft.setTextSize(3);
  tft.println(0xDEADBEEF, HEX);
  tft.println();
  tft.setTextColor(HX8357_GREEN);
  tft.setTextSize(5);
  tft.println("Groop");
  tft.setTextSize(2);
  tft.println("I implore thee,");
  tft.setTextSize(1);
  tft.println("my foonting turlingdromes.");
  tft.println("And hooptiously drangle me");
  tft.println("with crinkly bindlewurdles,");
  tft.println("Or I will rend thee");
  tft.println("in the gobberwarts");
  tft.println("with my blurglecruncheon,");
  tft.println("see if I don't!");


}

But again I don't see what you are doing inside some of your functions, and if the begin/end transaction and assert/deassert of CS can be done there instead of loop, but...

Note: The display code typically knows and does stuff to properly handle CS and Transaction stuff. You only need to configure part of it up front like I did as nothing is initialized by the functions yet, so you want to get things in a reasonably known state before you talk to the device libraries.
 
ok connected to this large library with all its functions is given here:
HTML:
https://github.com/analogdevicesinc/arduino/tree/master/Arduino%20Uno%20R3/examples/CN0391_example
s

For my understanding ill write how the cpp and h files are accessed in the Setup.

The drivers AD7124.h cpp gives a name to the AD7124 registers, bits and so on. to access the ad7124 communication.h and cpp are asked and provide the information from the AD7124 accordingly. The data from the AD7124 is then processed in the CN0391.cpp and h files by the appropriate functions it accesses the various registers writes values to it and attains the variables, voltages, offsets accordingly.(see serial monitor in the previous post)

furthermore the data that is changed from the cn0391.cpp and h files is "filtered" by thermocouple.h rtd.h which is written in the progrmem? technically no spi is needed here.

the link you posted with the arduino code has the same approach
HTML:
https://wiki.analog.com/_detail/resources/tools-software/uc-drivers/renesas/spi_architecture.png?id=resources%3Atools-software%3Auc-drivers%3Arenesas%3Aad7793

if I am off with my understanding, I am here to learn so let me know.
-----
i have to find my way in this jungle.
yeah I have to use two SPI settings = SPISETTINGSADC, and SPISETTINGSTFT in combination with the DigitalWrite to get a clear separation on how to access the SPI Bus. yeah the AD7124 is quite arrogant claiming the bus. lets see what happens,
i also thought about just to use the ad7124 and copy paste the registers to access the various channels, stripping the code and get the values from the thermocouples accordingly.

but thats up for next week.


thanks Kurt!
 
Status
Not open for further replies.
Back
Top