C++ SPI for Max 31855 Thermocouple Amp
Re: C++ SPI for Max 31855 Thermocouple Amp
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
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
Re: C++ SPI for Max 31855 Thermocouple Amp
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.
Re: C++ SPI for Max 31855 Thermocouple Amp
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
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
Re: C++ SPI for Max 31855 Thermocouple Amp
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
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
Re: C++ SPI for Max 31855 Thermocouple Amp
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 .
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 .
Re: C++ SPI for Max 31855 Thermocouple Amp
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
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
Re: C++ SPI for Max 31855 Thermocouple Amp
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();
}
Re: C++ SPI for Max 31855 Thermocouple Amp
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.
As the documentation says the total data length is in bits, I expect the total data length received is also in bits.
Re: C++ SPI for Max 31855 Thermocouple Amp
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
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
Re: C++ SPI for Max 31855 Thermocouple Amp
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.
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.
Who is online
Users browsing this forum: No registered users and 293 guests