Hi Everyone,
I would like to to setup ESP32 as SPI master and 24-bit ADS1256 as slave for data collection. I will use 6 out of 8 ADC channels on the ADS1256.
I have the following questions hopefully you could help me.
1. The ADS1256 has DRDY pin which we could use to trigger the hardware interrupt of the ESP32 to begin the SPI transaction. Should I create a DRDY hardware interrupt ISR which will call the SPI transaction on the ESP32 or does ESP32 have a built-in SPI function to setup the hardware interrupt with this DRDY pin?
2. I don't fully understand the purpose of pre_cb and post_cb callback. When do we use them?
3. The ADS1256 will sample data at the rate of 6kHz, and I would like not to miss the data. Is interrupt better or polling better in this case?
Thanks,
Khoi
ADS1256 with ESP32 idf
Re: ADS1256 with ESP32 idf
This is an additional functionality.2. I don't fully understand the purpose of pre_cb and post_cb callback. When do we use them?
For example, you have LCD with SPI interface. This LCD has 1 input: "0" - spi transfer data, "1" spi transfer command.
So you can use pre_cb to set this pin.
Try the interrupt or polling.3. The ADS1256 will sample data at the rate of 6kHz, and I would like not to miss the data. Is interrupt better or polling better in this case?
I use both SPI at 18 MHz in self-develop board and it works
Re: ADS1256 with ESP32 idf
Sorry for the late reply and thank you very much for the reply.
I was able to make ADS1256 to work with my ESP32 but I the latency between SPI transactions is very large. The below is my code:
For example, the time delay between the following two transactions
takes 13us.
How would I be able to make the latency smaller? My SPI speed is 2.5MHz, the maximum acceptable speed for ADS1256 is 3.45MHz.
Thanks
I was able to make ADS1256 to work with my ESP32 but I the latency between SPI transactions is very large. The below is my code:
Code: Select all
// Works with all 4 channels, make sure to tie CS LOW properly
#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 "soc/gpio_struct.h"
#include "driver/gpio.h"
#include "rom/ets_sys.h"
#include <time.h>
#define PIN_NUM_MISO 19
#define PIN_NUM_MOSI 23
#define PIN_NUM_CLK 18
#define PIN_NUM_CS 5
#define PIN_NUM_DRDY 27
#define PIN_NUM_RST 13
#define PIN_NUM_LED 25
void ADS1256_cmd(spi_device_handle_t spi, const uint8_t cmd) {
esp_err_t ret;
spi_transaction_t t;
memset(&t, 0, sizeof(t)); //Zero out the transaction
t.length=8; //Command is 8 bits
t.tx_buffer=&cmd; //The data is the cmd itself
ret=spi_device_polling_transmit(spi, &t); //Transmit!
assert(ret==ESP_OK); //Should have had no issues.
}
uint8_t ADS1256_read(spi_device_handle_t spi)
{
esp_err_t ret;
spi_transaction_t t;
memset(&t, 0, sizeof(t)); //Zero out the transaction
t.length=8;
t.rxlength=8; //Len is in bytes, transaction length is in bits.
t.flags = SPI_TRANS_USE_RXDATA;
ret = spi_device_polling_transmit(spi, &t); //Transmit!
assert(ret==ESP_OK); //Should have had no issues.
return *(uint8_t*)t.rx_data;
}
void ADS1256_REG(spi_device_handle_t spi, const uint8_t reg, const uint8_t cmd, const uint8_t data) {
esp_err_t ret;
spi_transaction_t t;
memset(&t, 0, sizeof(t));
t.length=24;
t.flags=SPI_TRANS_USE_TXDATA;
t.tx_data[0] = (0x50 | reg); // REGISTER
t.tx_data[1] = cmd; // 2nd command byte, write one register only
t.tx_data[2] = data; // Sending data to toggle register
ret=spi_device_polling_transmit(spi, &t); //Transmit!
assert(ret==ESP_OK); //Should have had no issues.
}
void ADS1256_init(spi_device_handle_t spi) {
uint8_t reg = 0, cmd = 0, data = 0;
// const lcd_init_cmd_t* lcd_init_cmds;
//Initialize non-SPI GPIOs
gpio_set_direction(PIN_NUM_RST, GPIO_MODE_OUTPUT);
gpio_set_direction(PIN_NUM_DRDY, GPIO_MODE_INPUT);
gpio_set_direction(PIN_NUM_LED, GPIO_MODE_OUTPUT);
// Set PULL UP for DRDY Pin
gpio_set_pull_mode(PIN_NUM_DRDY, GPIO_FLOATING);
// Hold reset level HIGH
gpio_set_level(PIN_NUM_RST, 1);
gpio_set_level(PIN_NUM_LED, 0);
vTaskDelay(1000 / portTICK_PERIOD_MS);
cmd = 0xFE; //Reset to Power-Up Values 0b11111110
ADS1256_cmd(spi, cmd);
vTaskDelay(10 / portTICK_PERIOD_MS);
reg = (0x50 | 0x00); cmd = 0x00; data = 0x01; // 01h => status: MSB First, Auto-Calibration Disabled, Analog Input Buffer Disabled
ADS1256_cmd(spi, reg); // Setup Status Register
ADS1256_cmd(spi, cmd);
ADS1256_cmd(spi, data);
vTaskDelay(10 / portTICK_PERIOD_MS);
reg = (0x50 | 0x02); cmd = 0x00; data = 0x01; // 01h => Clock Out = Off, Sensor Detect OFF, gain 2
// 0x02 = 0b10 // 0x00 = 0b00 // 0x01 = 0b01
ADS1256_cmd(spi, reg); // Setup A/D Control Register
ADS1256_cmd(spi, cmd);
ADS1256_cmd(spi, data);
vTaskDelay(10 / portTICK_PERIOD_MS);
reg = (0x50 | 0x03); cmd = 0x00; data = 0xF0; // F0h = 11110000 = 30,000SPS
// 0x02 = 0b11 // 0x00 = 0b00 // 0x01 = 0b01
ADS1256_cmd(spi, reg); // Setup A/D Data Rate
ADS1256_cmd(spi, cmd);
ADS1256_cmd(spi, data);
vTaskDelay(10 / portTICK_PERIOD_MS);
cmd = 0xF0; // Perform Offset and Gain Self-Calibration (F0h)
// 0xF0 = 0b11110000
ADS1256_cmd(spi, cmd);
}
void app_main()
{
uint8_t reg = 0, cmd = 0, data = 0;
uint16_t counter = 0;
uint32_t clock_millis;
esp_err_t ret;
spi_device_handle_t spi;
spi_bus_config_t buscfg={
.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=0,
};
spi_device_interface_config_t devcfg={
.clock_speed_hz=2800*1000, //Clock out at 10 MHz
.mode=1, //SPI mode 1
.spics_io_num=-1, //CS pin
.queue_size=7, //We want to be able to queue 7 transactions at a time
.pre_cb= NULL,
.post_cb = NULL,
};
//Initialize the SPI bus
ret=spi_bus_initialize(VSPI_HOST, &buscfg, 0); // 0 means DMA disabled
ESP_ERROR_CHECK(ret);
//Attach the ADS1256 to the SPI bus
ret=spi_bus_add_device(VSPI_HOST, &devcfg, &spi);
ESP_ERROR_CHECK(ret);
//Initialize the ADS1256
ADS1256_init(spi);
long adc_val[6] = {0,0,0,0,0,0}; // store readings in array
uint8_t mux[6] = {0x08,0x18,0x28,0x38,0x48,0x58};
uint8_t i = 0; uint8_t channel = 0;
vTaskDelay(100 / portTICK_PERIOD_MS);
setvbuf(stdout, NULL, _IONBF, 0);
printf("configured, starting\n");
printf("AIN0 AIN1 AIN2 AIN3 AIN4 AIN5\n");
while(1){
for (i=0; i <= 5; i++){ // read all 6 single ended channels AIN0, AIN1, AIN2, AIN3, AIN4, AIN5
channel = mux[i]; // analog in channels #
while (gpio_get_level(PIN_NUM_DRDY) == 1) {} ; // Wait until the data read pulls LOW
// Switching between channels
reg = 0x01; cmd = 0x00; data = channel; // 1st Command Byte: 0101 0001 0001 = MUX register address 01h
ADS1256_REG(spi, reg, cmd, data); // Data Byte(s): xxxx 1000 write the databyte to the register(s)
//SYNC command 1111 1100 (0xFC)
cmd = 0xFC;
ADS1256_cmd(spi, cmd);
//while (!digitalRead(rdy)) {} ;
//WAKEUP 0000 0000
cmd = 0x00;
ADS1256_cmd(spi, cmd);
// Read Data
cmd = 0x01;
ADS1256_cmd(spi, cmd); // Read Data 0000 0001 (01h) // ********** Step 3 **********
adc_val[i] = ADS1256_read(spi);
adc_val[i] <<= 8; //shift to left
adc_val[i] |= ADS1256_read(spi);
adc_val[i] <<= 8;
adc_val[i] |= ADS1256_read(spi);
//ets_delay_us(2);
if(adc_val[i] > 0x7fffff){ //if MSB == 1
adc_val[i] = adc_val[i]-16777216; //do 2's complement
}
}
/* for (i=0; i <= 5; i++){*/
/* */
/* printf("%ld",adc_val[i]); // Raw ADC integer value +/- 23 bits*/
/* printf(" ");*/
/* }*/
/* printf("\n");*/
vTaskDelay(5 / portTICK_PERIOD_MS);
counter = (counter+1)%1000;
if (counter == 999) {
clock_millis = (uint32_t) (clock() * 1000 / CLOCKS_PER_SEC);
printf("clock_millis: %d\n", clock_millis);
}
}
}
Code: Select all
ADS1256_REG(spi, reg, cmd, data); // Data Byte(s): xxxx 1000 write the databyte to the register(s)
//SYNC command 1111 1100 (0xFC)
cmd = 0xFC;
ADS1256_cmd(spi, cmd);
How would I be able to make the latency smaller? My SPI speed is 2.5MHz, the maximum acceptable speed for ADS1256 is 3.45MHz.
Thanks
Re: ADS1256 with ESP32 idf
Hi e2738729, can you please share your final code?
I'm also searching for ADS1256 ESP-IDF and found no solutions.
Thanks.
I'm also searching for ADS1256 ESP-IDF and found no solutions.
Thanks.
Who is online
Users browsing this forum: No registered users and 95 guests