C++ SPI for Max 31855 Thermocouple Amp
C++ SPI for Max 31855 Thermocouple Amp
I have been struggling with implementing a C++ library I'm building with respect to a Maxim 31855 Thermocouple Amplifier, a part sold from Adafruit among others. This is a SPI device.
Implementations, such as Adafruit, using Arduino IDE are available, but as part of a larger library I am building, I need an actual C++ implementation.
I've searched N Kolban's library of cpp_utils, and this has helped, but he doesn't do an implementation for the Max31855. Other than Kolban's treatments, every other example I come across utilizes the Arduino core library.
I understand the concept of what the Max31855 is needing: it doesn't use MOSI (Master Out, Slave In), but generates a signal to be read via MISO (Master In, Slave Out) on transition from CS (chip select) transition to low.
My first stumbling block is associated with the CS transition. In using the HSPI built into the ESP32, CS is on pin 15, the CS has select the device by changing CS pin 15 from high to low. In the ESP32 API literature, it mentions that the first instance of the HSPI is associated with CS pin 15 (CS0), but any additional SPI slaves would need their own pin. This implies, to me, that the SPI functions are going to drive the CS0. In the case of the Max31855, there is no address sent out on MOSI, so the only action needed is to go low on CS0, then read MISO through the receive transaction.
My Questions:
- Does this read transaction drop CS0? Or do I need to manually drop it prior to the read transaction?
- What is the sequence necessary for reading data from MISO for the Max31855?
- Do you have any example C++ code (not Arduino Core based) that does this?
Thanks!
JavaBen
Implementations, such as Adafruit, using Arduino IDE are available, but as part of a larger library I am building, I need an actual C++ implementation.
I've searched N Kolban's library of cpp_utils, and this has helped, but he doesn't do an implementation for the Max31855. Other than Kolban's treatments, every other example I come across utilizes the Arduino core library.
I understand the concept of what the Max31855 is needing: it doesn't use MOSI (Master Out, Slave In), but generates a signal to be read via MISO (Master In, Slave Out) on transition from CS (chip select) transition to low.
My first stumbling block is associated with the CS transition. In using the HSPI built into the ESP32, CS is on pin 15, the CS has select the device by changing CS pin 15 from high to low. In the ESP32 API literature, it mentions that the first instance of the HSPI is associated with CS pin 15 (CS0), but any additional SPI slaves would need their own pin. This implies, to me, that the SPI functions are going to drive the CS0. In the case of the Max31855, there is no address sent out on MOSI, so the only action needed is to go low on CS0, then read MISO through the receive transaction.
My Questions:
- Does this read transaction drop CS0? Or do I need to manually drop it prior to the read transaction?
- What is the sequence necessary for reading data from MISO for the Max31855?
- Do you have any example C++ code (not Arduino Core based) that does this?
Thanks!
JavaBen
Re: C++ SPI for Max 31855 Thermocouple Amp
Howdy,
If I were in your shoes ... what I'd do is study the SPI documentation for ESP-IDF in detail. This will provide a good overview of the capabilities of SPI on the ESP32. See:
http://esp-idf.readthedocs.io/en/latest ... aster.html
Make sure that the above is as clear to you as it can be ... if anything isn't clear, research that and, if needed/desired, post questions to the forum to clarify your understanding of these APIs. Once you have a handle on how SPI works from a C interface, then we can turn to C++. At the highest level, the C APIs that you will read about can also be invoked directly from C++. This means that you can write your C++ apps directly to these native ESP-IDF APIs. If you wish to leverage C++, then you can create a C++ class that encapsulates these APIs to provide a more C++ oriented flavor to your logic (class encapsulation, class instances, exception handling, STL etc).
An illustrative C++ wrapper that I use can be found here:
https://github.com/nkolban/esp32-snippe ... tils/SPI.h
If I were in your shoes ... what I'd do is study the SPI documentation for ESP-IDF in detail. This will provide a good overview of the capabilities of SPI on the ESP32. See:
http://esp-idf.readthedocs.io/en/latest ... aster.html
Make sure that the above is as clear to you as it can be ... if anything isn't clear, research that and, if needed/desired, post questions to the forum to clarify your understanding of these APIs. Once you have a handle on how SPI works from a C interface, then we can turn to C++. At the highest level, the C APIs that you will read about can also be invoked directly from C++. This means that you can write your C++ apps directly to these native ESP-IDF APIs. If you wish to leverage C++, then you can create a C++ class that encapsulates these APIs to provide a more C++ oriented flavor to your logic (class encapsulation, class instances, exception handling, STL etc).
An illustrative C++ wrapper that I use can be found here:
https://github.com/nkolban/esp32-snippe ... tils/SPI.h
Free book on ESP32 available here: https://leanpub.com/kolban-ESP32
Re: C++ SPI for Max 31855 Thermocouple Amp
OK, thanks!
Re: C++ SPI for Max 31855 Thermocouple Amp
I suggest you consider the option of driving the chip select (CS) and serial clock (SCK) directly by your code and read the state of the serial data out (SO) after each falling edge of SCK. In other words consider using "bit banging". You may need to insert some delays to comply with the timing requirements of the chip.
Re: C++ SPI for Max 31855 Thermocouple Amp
Archibald, thank you very much for your reply!
I've been going through the Adafruit library for this chip, and their example (serial example - I'm away from my desktop right now and don't have access to the actual name), and that's exactly the way they are implementing it.
I intend to 'bang my head' against the chip's capabilities and see if I can't get it to work before I toss in my efforts and assume the approach you and Adafruit suggest.
Thanks, and I very much appreciate your comment!
I'm really surprised that I haven't been able to locate any ESP32 C++ (non-arduino) examples of reading from this chip though!
JavaBen
I've been going through the Adafruit library for this chip, and their example (serial example - I'm away from my desktop right now and don't have access to the actual name), and that's exactly the way they are implementing it.
I intend to 'bang my head' against the chip's capabilities and see if I can't get it to work before I toss in my efforts and assume the approach you and Adafruit suggest.
Thanks, and I very much appreciate your comment!
I'm really surprised that I haven't been able to locate any ESP32 C++ (non-arduino) examples of reading from this chip though!
JavaBen
Re: C++ SPI for Max 31855 Thermocouple Amp
Interestingly, it doesn't appear to me that Adafruit's serial example works for hardware using VSPI mode.
In Adafruit_MAX31855.cpp, the constructor Adafruit_MAX31855::Adafruit_MAX31855(int8_t _sclk, int8_t _cs, int8_t _miso), if provided with -1 for _sclk, makes use of SPI.begin(), which should utilize hardware VSPI. So, making this change to Adafruit's example serialthermocouple.ino, should allow me to make use of the hardware VSPI capabilities.
But.
Changing serialthermocouple.ino: setting to MAXCLK to -1, used by constructor Adafruit_MAX31855 thermocouple(MAXCLK, MAXCS, MAXD0), and wiring the breadboard to utilize VSPI SS 15, VSPI SCK 18 and VSPI MISO 19 (instead of MAXCLK 5, MAXCS 5, and MAXD0 3) results in the serial monitor displaying : "Something wrong with thermocouple!".
Interesting!
Has anyone been able to actually utilize the VSPI mode for MAX31588? Or for other SPI devices?
In Adafruit_MAX31855.cpp, the constructor Adafruit_MAX31855::Adafruit_MAX31855(int8_t _sclk, int8_t _cs, int8_t _miso), if provided with -1 for _sclk, makes use of SPI.begin(), which should utilize hardware VSPI. So, making this change to Adafruit's example serialthermocouple.ino, should allow me to make use of the hardware VSPI capabilities.
But.
Changing serialthermocouple.ino: setting to MAXCLK to -1, used by constructor Adafruit_MAX31855 thermocouple(MAXCLK, MAXCS, MAXD0), and wiring the breadboard to utilize VSPI SS 15, VSPI SCK 18 and VSPI MISO 19 (instead of MAXCLK 5, MAXCS 5, and MAXD0 3) results in the serial monitor displaying : "Something wrong with thermocouple!".
Interesting!
Has anyone been able to actually utilize the VSPI mode for MAX31588? Or for other SPI devices?
Re: C++ SPI for Max 31855 Thermocouple Amp
It appears Adafruit's serialthermocouple example is making use of Arduino-1.8.5 code, where begin() is declared and defined, even though it's listed as example code for the ESP32. This call (SPI.begin()) is invoked in the example serialthermocouple.ino if the clk is set to -1, in an attempt to utilize VSPI mode.
The Arduino/hardware/espressif ... SPI.h does not have a SPIClass.begin() call; instead, it has SPIClass.begin(sck=-1, miso, mosi, ss) call.
The Arduino/hardware/espressif ... SPI.h does not have a SPIClass.begin() call; instead, it has SPIClass.begin(sck=-1, miso, mosi, ss) call.
Re: C++ SPI for Max 31855 Thermocouple Amp
If we look at this line:
https://github.com/espressif/arduino-es ... /SPI.h#L55
we will find the code:
The way to interpret this declaration is that all the parameters are optional and, if not supplied, default to -1.
This would then mean that:
is a perfectly valid API call.
https://github.com/espressif/arduino-es ... /SPI.h#L55
we will find the code:
Code: Select all
void begin(int8_t sck=-1, int8_t miso=-1, int8_t mosi=-1, int8_t ss=-1);
This would then mean that:
Code: Select all
begin();
Free book on ESP32 available here: https://leanpub.com/kolban-ESP32
Re: C++ SPI for Max 31855 Thermocouple Amp
OK, thanks! Much appreciated!
Re: C++ SPI for Max 31855 Thermocouple Amp
I am intending to rewrite Adafruit MAX thermocouple code to proprietary esp32 one.
Ridiculously still fighting with setting sdk on my windows properly and still working with Arduino IDE...
Something gets overwritten by VStudio and VSCode and stuff won't compile.
I would use timer interrupts for SPI according to 31855 datasheet protocols/requirements.
Datasheet found here:
https://datasheets.maximintegrated.com/ ... X31855.pdf
Ridiculously still fighting with setting sdk on my windows properly and still working with Arduino IDE...
Something gets overwritten by VStudio and VSCode and stuff won't compile.
I would use timer interrupts for SPI according to 31855 datasheet protocols/requirements.
Datasheet found here:
https://datasheets.maximintegrated.com/ ... X31855.pdf
Who is online
Users browsing this forum: axellin and 116 guests