Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 10 of 10

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

  1. #1
    Senior Member
    Join Date
    Sep 2016
    Posts
    105

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

    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");
      }
    }
    Attached Thumbnails Attached Thumbnails Click image for larger version. 

Name:	IMG_2572.jpg 
Views:	8 
Size:	136.4 KB 
ID:	20887   Click image for larger version. 

Name:	IMG_2573.jpg 
Views:	9 
Size:	116.3 KB 
ID:	20888  


  2. #2
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    7,418
    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.

  3. #3
    Senior Member
    Join Date
    Sep 2016
    Posts
    105
    Hi Kurt,

    Thanks for the fast reply. Excellent questions!

    1 https://www.analog.com/en/design-cen...ml#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/Seri...eral_Interface
    3 They say at the website the following about the speed: https://ez.analog.com/data_converter...i-read-problem
    4 external MCLK=2.45MHz, https://www.analog.com/media/en/tech...s/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/...ommunication.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.

  4. #4
    Senior Member
    Join Date
    Sep 2016
    Posts
    105
    Pictures for the cn0391 wiring and measurement
    Attached Thumbnails Attached Thumbnails Click image for larger version. 

Name:	BA379482-65AB-45AB-AF37-6C64B3904A26.jpeg 
Views:	3 
Size:	136.1 KB 
ID:	20899   Click image for larger version. 

Name:	1A90B4FF-3526-4D5B-8260-01D167A6391A.jpeg 
Views:	4 
Size:	120.2 KB 
ID:	20900  


  5. #5
    Senior Member
    Join Date
    Sep 2016
    Posts
    105

    Lightbulb 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 Code:
    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 Code:
    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

    BastiaanClick image for larger version. 

Name:	tftandcn0391 connected.png 
Views:	2 
Size:	500.9 KB 
ID:	20916Click image for larger version. 

Name:	secondrun.jpg 
Views:	2 
Size:	74.2 KB 
ID:	20915
    Last edited by Bastiaan; 07-10-2020 at 12:26 PM.

  6. #6
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    7,418
    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

  7. #7
    Senior Member
    Join Date
    Sep 2016
    Posts
    105
    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.

  8. #8
    Senior Member
    Join Date
    Sep 2016
    Posts
    105
    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!");
    
    
    }

  9. #9
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    7,418
    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/projecthub...793-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
    
    #define CN0391_CS 10
    #define CN0391_SPI_SPEED 2000000 // 2mhz? 
    
    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(CN0391_CS, OUTPUT);
      pinMode(TFT_CS, OUTPUT);
    
    
      
       digitalWrite(CN0391_CS,LOW);
       SPI.beginTransaction(SPISettings(CN0391_SPI_SPEED , MSBFIRST, SPI_MODE0));
    
       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
      SPI.endTransaction();
      digitalWrite(CN0391_CS,HIGH);
    
      tft.begin();
    }
    
    void loop() 
    {
          
            unsigned long currentMillis= millis();
    
      // 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));
          
            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: ");
      SPI.endTransaction();
      digitalWrite(CN0391_CS,HIGH);
          
    
    
    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.

  10. #10
    Senior Member
    Join Date
    Sep 2016
    Posts
    105

    Wink

    ok connected to this large library with all its functions is given here:
    HTML Code:
    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 Code:
    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!

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •