How to receive temperature from MAX6675 (SPI) with ESP32 with ESP-IDF?

0

Sorry English is not my native language. I try to take the temperature from the MAX6675 module with a thermocouple.

Max6675 datasheet
Espressif api-reference spi_master
spi_common.h
spi_master.h

I try to merge this Espressif example with this example
UPD1: I use VScode + Espressive-IDF v1.0.1 + ESP-IDF Release v3.3.5 + Win10.
UPD2: If u want to save yourself from drowning then swim.

just one more example from Espressif forum
and one more from Reddit

This is my code with new(b)est-printf-debug-system.

0.1) First my includes.

#include "esp_err.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "driver/spi_master.h"
#include "driver/gpio.h"
#include "esp_log.h"

0.2) Next let's define defines.
Chose IO_MUX pins or you own.
Look The IO_MUX pins for SPI buses.

#define VSPI 1

//SPI2
#ifdef HSPI 
#define PIN_HSPI_MISO 12
#define PIN_HSPI_MOSI 13
#define PIN_HSPI_CLK  14
#define PIN_HSPI_CS0  15

#define PIN_NUM_MOSI -1
#define PIN_NUM_MISO PIN_HSPI_MISO
#define PIN_NUM_CLK  PIN_HSPI_CLK
#define PIN_NUM_CS   PIN_HSPI_CS0
#define MAX7765_HOST HSPI_HOST

//SPI3
#elif VSPI
#define PIN_VSPI_MISO 19
#define PIN_VSPI_MOSI 23
#define PIN_VSPI_CLK  18
#define PIN_VSPI_CS0  5

#define PIN_NUM_MOSI -1
#define PIN_NUM_MISO PIN_VSPI_MISO
#define PIN_NUM_CLK  PIN_VSPI_CLK
#define PIN_NUM_CS   PIN_VSPI_CS0
#define MAX7765_HOST VSPI_HOST //spi_types.h
#endif

#define DMA_CHAN     1

about DMA_CHAN
I take error with DMA_CHAN 0.

Open instruction.

  1. Initialize an SPI bus by calling the function spi_bus_initialize(). Make sure to set the correct I/O pins in the struct spi_bus_config_t. Set the signals that are not needed to -1.
esp_err_t ret; //esp_err.h

/*All of spi_bla_bla_function return some value
 *         - ESP_ERR_INVALID_ARG   if parameter is invalid
 *         - ESP_ERR_NOT_FOUND     if host doesn't have any free CS slots
 *         - ESP_ERR_NO_MEM        if out of memory
 *         - ESP_OK                on success
*/ 
//configure SPI bus for our ESP32 chip
spi_bus_config_t esp32_bus_config=     //spi_common.h
   { 
   .miso_io_num=PIN_NUM_MISO,
   .mosi_io_num=PIN_NUM_MOSI,
   .sclk_io_num=PIN_NUM_CLK,
   .quadwp_io_num=-1,
   .quadhd_io_num=-1,
   .max_transfer_sz=16 
   };
printf("1.Initialize the SPI bus\n");
ret=spi_bus_initialize(MAX7765_HOST, &esp32_bus_config, DMA_CHAN); //spi_common.h
  1. Register a Device connected to the bus with the driver by calling the function spi_bus_add_device(). Make sure to configure any timing requirements the device might need with the parameter dev_config. You should now have obtained the Device’s handle which will be used when sending a transaction to it.

Next look at the MAX6675 datasheet. (And swim a couple of hours on the web.)

enter image description here

If I understand right I must Use SPI mode 1.
CPOL=0 Because Max6675 datasheet=>figure 1.a=>CLK diagram.
CPHA=1 Read the 16 output bits on the falling edge of the clock.

spi_device_interface_config_t max6675_config; //configure struct for MAX6675 (spi_master.h)
  max6675_config.address_bits = 0;
  max6675_config.command_bits = 0;
//max6675_config.dummy_bits = 0;
  max6675_config.mode = 1;                              
//max6675_config.duty_cycle_pos = 0;
//max6675_config.cs_ena_posttrans = 0;
//max6675_config.cs_ena_pretrans = 0;
  max6675_config.clock_speed_hz = 43*1000*1000/10; //Serial Clock Frequency fSCL 4.3 MHz (MAX6675 datasheet)
  max6675_config.spics_io_num = PIN_NUM_CS;
//max6675_config.flags = 0;
  max6675_config.queue_size = 1;
  max6675_config.pre_cb = NULL;
  max6675_config.post_cb = NULL;
    
  spi_device_handle_t handle;
  printf("2.Attach the MAX6675 to the SPI bus\n");
  ret=spi_bus_add_device(MAX7765_HOST, &max6675_config, &handle); //spi_master.h

Winter is coming...

  1. To interact with the Device, fill one or more spi_transaction_t structs with any transaction parameters required.
   printf("3.Configure Max6675 transaction\n");
   spi_transaction_t trans_from_max6675; //spi_master.h
   memset(&trans_from_max6675, 0, sizeof(trans_from_max6675));

     trans_from_max6675.length    = 16; 
     trans_from_max6675.rxlength  = 16;
     trans_from_max6675.flags     = SPI_TRANS_USE_RXDATA;
     trans_from_max6675.tx_buffer = 0;
     trans_from_max6675.user = (void*)1;        
  1. Then send the structs either using a polling transaction or an interrupt transaction...

Looking in the samples...

And all people use different methods

printf("4.SPI polling transmit\n");
ret = spi_device_polling_transmit(handle, &trans_from_max6675);
ESP_ERROR_CHECK(ret);
    
printf("5.SPI polling complete\n");
int hex_t_from_max = 0; 
hex_t_from_max = trans_from_max6675.rx_buffer;
uint32_t temp =0;

temp = SPI_SWAP_DATA_RX(hex_t_from_max,16);
printf("final");
printf("%d",temp);

And here is the result in the console

1.Initialize the SPI bus
2.Attach the MAX6675 to the SPI bus
3.Configure Max6675 transaction_t
4.SPI polling transmit
E (10306) task_wdt: Task watchdog got triggered. The following tasks did not reset the watchdog in time:
E (10306) task_wdt:  - IDLE (CPU 0)
E (10306) task_wdt: Tasks currently running:
E (10306) task_wdt: CPU 0: main
E (10306) task_wdt: CPU 1: IDLE
E (10306) task_wdt: Print CPU 0 (current core) backtrace

I'll be grateful if you correct the mistakes I'll be extremely grateful if you also explain what the mistakes are. And I'm ready to buy beer who will tell me where I can read how all this should work step by step.

P.S. Please, don't talk about Arduino.

UPD4**********************

Hi everyone.
I TAKE A NULL!
It still not that I try to find. But it better than nothing.
After some rest and reading about pointers, I clean my code a little.

#include "esp_err.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "driver/spi_master.h"
#include "driver/gpio.h"
#include "esp_log.h"



// Chose IO_MUX pins or you own
//Look at the IO_MUX pins for SPI buses
//https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/spi_master.html#gpio-matrix-and-io-mux

#define VSPI 1

//SPI2
#ifdef HSPI 
#define PIN_HSPI_MISO 12
#define PIN_HSPI_MOSI 13
#define PIN_HSPI_CLK  14
#define PIN_HSPI_CS0  15

#define PIN_NUM_MOSI -1
#define PIN_NUM_MISO PIN_HSPI_MISO
#define PIN_NUM_CLK  PIN_HSPI_CLK
#define PIN_NUM_CS   PIN_HSPI_CS0
#define MAX7765_HOST HSPI_HOST

//SPI3
#elif VSPI
#define PIN_VSPI_MISO 19
#define PIN_VSPI_MOSI 23
#define PIN_VSPI_CLK  18
#define PIN_VSPI_CS0  5

#define PIN_NUM_MOSI -1
#define PIN_NUM_MISO PIN_VSPI_MISO
#define PIN_NUM_CLK  PIN_VSPI_CLK
#define PIN_NUM_CS   PIN_VSPI_CS0
#define MAX7765_HOST VSPI_HOST //spi_types.h
#endif

#define DMA_CHAN     1
//#define GPIO_OUTPUT_PIN_SEL (1ULL << PIN_NUM_CS)
static const char *TAG = "MAX6675";


void cs_low()
    {
    gpio_set_level(PIN_NUM_CS, 0);
    }


void cs_high()
    {
    gpio_set_level(PIN_NUM_CS, 1);
    }

uint16_t get_data(spi_device_handle_t spi)
    {
    void cs_low();

    spi_transaction_t t;
    memset(&t, 0, sizeof(t));
    t.length=8*2;
    t.flags = SPI_TRANS_USE_RXDATA;
    vTaskDelay(100 / portTICK_PERIOD_MS);
    esp_err_t ret = spi_device_polling_transmit(spi, &t);
    assert( ret == ESP_OK );
    void cs_high();
    
    return *(uint16_t*)t.rx_data;

    }

void app_main()
{
esp_err_t ret;

spi_device_handle_t spi;


//Set GPIO mode for chip select pin
gpio_config_t io_conf=
    {//gpio_types.h
    .intr_type    = GPIO_PIN_INTR_DISABLE,
    .mode         = GPIO_MODE_OUTPUT,
    .pin_bit_mask = PIN_NUM_CS,
    //.pin_bit_mask = GPIO_OUTPUT_PIN_SEL;
    .pull_down_en = 0,
    .pull_up_en   = 0
    };
gpio_config(&io_conf);

//Initialize the SPI bus
spi_bus_config_t esp32_bus_config=
    { //spi_common.h
    .miso_io_num=PIN_NUM_MISO,
    .mosi_io_num=-1,
    .sclk_io_num=-1,
    .quadwp_io_num=-1,
    .quadhd_io_num=-1,
    .max_transfer_sz=16 
    };
ret=spi_bus_initialize(MAX7765_HOST, &esp32_bus_config, DMA_CHAN);
ESP_ERROR_CHECK(ret);
    
//Attach the MAX to the SPI bus
spi_device_interface_config_t maxcfg = 
    {//spi_master.h
    .address_bits = 0,
    .command_bits = 0,
    .clock_speed_hz=300000,
    .mode=0,
    .spics_io_num=0,
    .queue_size=7,
    .pre_cb=0
    };
ret=spi_bus_add_device(MAX7765_HOST, &maxcfg, &spi);
ESP_ERROR_CHECK(ret);
   
uint16_t temp;

for ( uint8_t i = 0; i < 5; i++)
    {
    temp =get_data(spi);
    
    printf ("temp = %d\n", temp);
    vTaskDelay(1000 / portTICK_PERIOD_MS);
    ESP_LOGI(TAG, "temp = 0x%08x\n", temp);
    }
}

And here is the result in the console

//some logs
I (0) cpu_start: Starting scheduler on APP CPU.
I (307) gpio: GPIO[0]| InputEn: 0| OutputEn: 1| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0 
I (317) gpio: GPIO[2]| InputEn: 0| OutputEn: 1| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0 
temp = 0
I (1427) MAX6675: temp = 0x00000000
// temp=0 five more times

Last instruction what I find.

microcontroller
esp32
spi
asked on Stack Overflow Mar 28, 2021 by Dmitrii_Argon • edited Apr 19, 2021 by Dmitrii_Argon

1 Answer

0

I find the solution finally!!

stm32 Nucleo f070rb + mbed.com + 10min

#include "mbed.h"
#include "max6675.h"
DigitalOut led(LED1);

max6675 sensor(D12,D13,D10);  //miso, sclk, cs
Serial pc(USBTX,USBRX);

int main()
{
    pc.baud(115200);
    pc.printf("\033[0m\033[2J\033[HMAX6675 Thermocouple!\r\n\n\n");

    int cf = 0; // 0 Centigrade, 1 Fahrenheit
    
    while(1) {
        float temp = sensor.gettemp(cf);
        if (cf) {
        printf(" Temp: %4.2f%cF \n\033[2K\033[1A",temp,176);
        } else {
        printf(" Temp: %4.2f%cC \n\033[2K\033[1A",temp,176);
        }
        //wait_ms(250);   // requires 250mS for temperature conversion process
    }
}

Thank you, everyone. Die hard, ESP32

answered on Stack Overflow May 10, 2021 by Dmitrii_Argon

User contributions licensed under CC BY-SA 3.0