C++ SPI for Max 31855 Thermocouple Amp

User avatar
javaben
Posts: 35
Joined: Mon Mar 19, 2018 11:49 pm

Re: C++ SPI for Max 31855 Thermocouple Amp

Postby javaben » Fri May 11, 2018 6:37 pm

Kolban,

Again, thanks for the comment above.

You are correct with respect to
"Arduino/hardware/espressif/esp32/libraries/SPI/src/SPI.h "
containing
"void begin(int8_t sck=-1, int8_t miso=-1, int8_t mosi=-1, int8_t ss=-1);"

What I was pointing out, was that in using the Adafruit example for the serialthermocouple.ino, it uses a different SPI.h file.

The file "ArduinoApp/arduino-1.8.5/hardware/arduino/avr/libraries/SPI/src/SPI.h", which is what the Adafruit library is using, only contains "static void begin();"

So when passing a "-1" for the clock, which the example permits, causes the invocation of the Serial.begin() of a method that doesn't have these default values, and the Adafruit example code reports the thermocouple having a problem, while the use of non-hardware VSPI doesn't have this problem. So, to my understanding, there's a problem with the example code if I'm trying to use with VSPI, even after carefully switching the breadboard configuration to make use of the VSPI pins.

AT least that's my interpretation ;-) I'm new to C++, and to ESP32, so I could easily be misunderstanding something.

Thanks,

JavaBen

Archibald
Posts: 110
Joined: Mon Mar 05, 2018 12:44 am

Re: C++ SPI for Max 31855 Thermocouple Amp

Postby Archibald » Fri May 11, 2018 8:33 pm

If you use the hardware VSPI or HSPI interface, my understanding of the documentation here is that a "transaction" of one byte of data would take about 24μs. Your 14 bits of data should take less than 2μs longer (assuming the API can cope with 14 bits). In contrast, I am bit banging a byte of data within 3μs (transmitting to peripheral, excluding chip selection). I would expect to be able to receive 14 bits of data from a thermocouple within 6μs, including chip selection. My transmission code is just 6 short lines of Arduino code within a function.

User avatar
javaben
Posts: 35
Joined: Mon Mar 19, 2018 11:49 pm

Re: C++ SPI for Max 31855 Thermocouple Amp

Postby javaben » Fri May 11, 2018 8:41 pm

Hi Archibald!

Thanks for your help.

I wasn't so much trying to do this because of speed, but because the chip says it can support this, and thus I wanted to do it this way.

However, I can't find where anyone on the internet is using the chip directly, and the manuals are somewhat ambiguous on this as well....so if I can't find a solution within the next hour or two, I'm going to abandon the chip's capabilities and implement your suggestion.

Thanks again!

JavaBen

User avatar
javaben
Posts: 35
Joined: Mon Mar 19, 2018 11:49 pm

Re: C++ SPI for Max 31855 Thermocouple Amp

Postby javaben » Fri May 11, 2018 8:56 pm

Here's an example of something in the manual that is confusing me:

The MAX31588 is only addressed via the chip select line (CS); no addressing is necessary, and no commands are necessary to be sent to the device (no MOSI). So MOSI is set to -1 in the spi_bus_config_t.

I'm assuming I've got to cycle the CS from high (non-select), to low, delay a bit for settle, then read the 4 bytes (32 bits), then raise the CS and again delay a bit; repeat.

The manual presents the 'Command address phases', and presents it as though I've got to send a command and address in order to get a response in the rx_buffer. I don't see any other method that is directly reading the response after I do the CS low that would be placing it into the rx_buffer.

So, I'm confused about: The manual says I don't have to send address and command, but I can't find a way to get a response after dropping the CS (which is when the MAX31855 sends the data) using anything other than a sent transaction.

Thanks

JavaBen

Archibald
Posts: 110
Joined: Mon Mar 05, 2018 12:44 am

Re: C++ SPI for Max 31855 Thermocouple Amp

Postby Archibald » Fri May 11, 2018 9:29 pm

With regard to chip select, take a look at spicommon_cs_initialize and spics_io_num. I've not studied this API in detail but I don't think you should need to drive CS directly.

Of the five transaction phases, you should be able to skip straight to the read phase. The clock pulses from the ESP32 should then read data into rx_buffer.

Are you setting rxlength to 14?

I'm no expert at this :) .

User avatar
javaben
Posts: 35
Joined: Mon Mar 19, 2018 11:49 pm

Re: C++ SPI for Max 31855 Thermocouple Amp

Postby javaben » Fri May 11, 2018 10:35 pm

Hi Archibald!

Thanks so much for your assistance!

I was taking a break for a while, and will be heading out with my wife for the evening.

I'll try your suggestions tomorrow.

Regarding the size of 14; no, I was setting it to 4, as I understood I was specifying 'bytes' and the response from the MAX31855 is 32 bits.

Thanks again, looking forward to trying your suggestions.

JavaBen

User avatar
javaben
Posts: 35
Joined: Mon Mar 19, 2018 11:49 pm

Re: C++ SPI for Max 31855 Thermocouple Amp

Postby javaben » Fri May 11, 2018 10:44 pm

This is what I currently have, but am unsure now how to proceed:

Code: Select all

#include <iostream>
#include <driver/spi_master.h>
#include <esp_err.h>

#define HSPI_MISO  12
#define HSPI_MOSI  -1  //pin 13 if used
#define HSPI_SCK   14
#define HSPI_SS    15

extern "C" {
    void app_main(void);
}

class BruteForce {
    public:
        BruteForce() {
                buscfg.mosi_io_num = HSPI_MOSI;
                buscfg.miso_io_num = HSPI_MISO;
                buscfg.sclk_io_num = HSPI_SCK;
                buscfg.quadwp_io_num = -1;
                buscfg.quadhd_io_num = -1;
                buscfg.max_transfer_sz = 4;  //4 BYTES???
                buscfg.flags = SPICOMMON_BUSFLAG_MASTER | SPICOMMON_BUSFLAG_MISO | SPICOMMON_BUSFLAG_SCLK;

                devcfg.command_bits = 0;
                devcfg.address_bits = 0;
                devcfg.dummy_bits = 0;      //note this; if dropping bits at start of cycle
                devcfg.mode = 0;           //0,1,2,3.  has to do with clock polarity, phase, and edge.  See wikipedia.org for spi mode numbers
                devcfg.duty_cycle_pos = 0; // setting to 0 defaults to 128, 50% duty cycle
                devcfg.cs_ena_pretrans = 0;  //amount of spi bit-cycles cs activated before transmission.
                devcfg.cs_ena_posttrans = 0;  //sim to pretrans, but trailing
                devcfg.clock_speed_hz = 10000; //10 khz; clock speed in hz
                devcfg.spics_io_num = -1;  //CS GPIO pin, -1 if not used
                devcfg.flags = SPICOMMON_BUSFLAG_MASTER | SPICOMMON_BUSFLAG_MISO | SPICOMMON_BUSFLAG_SCLK;  //spi_device_ flags
                devcfg.queue_size = 10; //queue depth.  0 will cause crash
                devcfg.pre_cb = NULL; //callback before trans ========not sure here
                devcfg.post_cb = NULL; //callback after trans ========not sure here
        }
        void init(void) {
            if(( err = spi_bus_initialize(HSPI_HOST, &buscfg, 0 )) != ESP_OK ) {
                std::cout << esp_err_to_name(err) << "\n";
            } else {
                std::cout << "init: initialize OK\n";
            }

            //Note: it crashes if queue_size = 0
            if(( err = spi_bus_add_device(HSPI_HOST, &devcfg, &devhandle) ) != ESP_OK ) {
                std::cout << esp_err_to_name(err) << "\n";
            } else {
                std::cout << "init: add_device OK\n";
            }
            
        };

    private:
        esp_err_t err;
        spi_bus_config_t buscfg;
        spi_device_interface_config_t devcfg;
        spi_device_handle_t devhandle;

};


void app_main(void) {
    BruteForce bf = BruteForce();

    bf.init();
}


Archibald
Posts: 110
Joined: Mon Mar 05, 2018 12:44 am

Re: C++ SPI for Max 31855 Thermocouple Amp

Postby Archibald » Fri May 11, 2018 10:51 pm

From the datasheet "A complete serial-interface read of the cold-junction compensated thermocouple temperature requires 14 clock cycles. Thirty-two clock cycles are required to read both the thermocouple and reference junction temperatures".

As the documentation says the total data length is in bits, I expect the total data length received is also in bits.

User avatar
javaben
Posts: 35
Joined: Mon Mar 19, 2018 11:49 pm

Re: C++ SPI for Max 31855 Thermocouple Amp

Postby javaben » Sat May 12, 2018 2:12 am

HI Archibald!

The clock should be running at 10KHz per devcfg.clock_speed_hz = 10000.

It's my understanding the clock pulses are being sent to the the Max31855 continualisly, but only read by the Max3 as long as the CS is held low, until all 32 bits were transferred, then it stops sending data until the next high/low CS cycle.

So I don't see that as a problem....but I don't really know! I don't have a protocol analyzer, so can't confirm this.

I'm wanting to do something to read the data from Max3, but I don't know what the function is that I need to invoke to do that, from the hardware SPI standpoint.

What do you think needs to be done?

Thanks for your time and interest.

JavaBen

chegewara
Posts: 2207
Joined: Wed Jun 14, 2017 9:00 pm

Re: C++ SPI for Max 31855 Thermocouple Amp

Postby chegewara » Sat May 12, 2018 3:21 am

There is a lot of libraries for MAX31855, just study it:
https://forums.ni.com/t5/LabVIEW-Interf ... -p/3392471

From this one i can see that you need to read data, then check if there is any error reported and if not then you need to convert data into temperature.

Image

Image

Who is online

Users browsing this forum: Pedro Hugo PSC and 149 guests