Page 1 of 1

ESP32 SPI issue (voltage levels)

Posted: Wed Jan 24, 2024 6:56 pm
by jacob@mattiq.com
I have (technically had because it smoked) a PCB board with an ESP32 Dev Board plugged in. I had 4 external ADCs. ADC 1 and 2 were on hspi and ADC 3 and 4 were on vspi (doesn't matter if hspi/vspi are switched). When I run the code with the ESP32 powered via my USB everything works fine. When I remove the power and rely solely on [L7805CV](https://www.digikey.com/en/products/det ... 5CV/585964) to supply 5V to the ESP's 5V pin ADC 3 and 4 stop working. I cut my USB cable off and touched the 5V on the USB directly to the 5V on the ESP32 and ADC pin 3 and 4 came alive. This makes me think the issue is with the supply voltage level.

As far as the hardware/wiring is concerned I had everything connected to the same ground. The L7805CV was nowhere near its current rating (was only slightly warm) but I did notice that the voltage on the L7805CV was only 4.97V while the voltage from the USB was 5.01V. Could this be causing the issue? I need to redesign my board and I'm trying to understand why I was seeing this issue.

Here is the code I used to read the 4 channels. I tried really long delays before and after setting the pins high and low and didn't make a difference. The highlights (I think) are the pins I used (SPI1_SCK = 14; SPI1_MISO = 12; ADC_CS_1 = 15; ADC_CS_2 = 21; SPI2_SCK = 18; SPI2_MISO = 19; ADC_CS_3 = 25; ADC_CS_4 = 26;)

Code: Select all

#include <Arduino.h>
#include <SPI.h>
#include <HardwareSerial.h>

const int SPI1_SCK = 14;
const int SPI1_MISO = 12;
const int ADC_CS_1 = 15;
const int ADC_CS_2 = 21;

const int SPI2_SCK = 18;
const int SPI2_MISO = 19;
const int ADC_CS_3 = 25;
const int ADC_CS_4 = 26;


unsigned char upper_byte;
unsigned char middle_byte;
unsigned char lower_byte;
unsigned int data;

//uninitalised pointers to SPI objects
SPIClass vspi(VSPI);
SPIClass hspi(HSPI);

// function declarations
int readData(SPIClass*, unsigned int);

// RS485 properties
HardwareSerial SerialPort(2); //UART2 on ESP32 module
const int RXpin = 16; //pin 16 recommended for RXD
const int TXpin = 17; //pin 17 recommended for TXD
const int slave_address = 102; //address must be hard coded (will not auto generate)

int regs[256]; //register array available to master
bool debug_read_esp = false;
bool debug_read_all = false; // only will read data coming to ESP32, good to determine if communication exists
bool debug_write = false;

const unsigned int numSamples = 40; // number of samples to take for each channel

void setup() {

  Serial.begin(9600);
  // Set up the first SPI interface
  pinMode(ADC_CS_1, OUTPUT);
  digitalWrite(ADC_CS_1, HIGH);
  hspi.begin(SPI1_SCK, SPI1_MISO, -1, ADC_CS_1);

  pinMode(ADC_CS_2, OUTPUT);
  digitalWrite(ADC_CS_2, HIGH);
  hspi.begin(SPI1_SCK, SPI1_MISO, -1, ADC_CS_2);

  hspi.setClockDivider(SPI_CLOCK_DIV64); // ESP32 has SPI clock speed of 240MHz / 64 = 3.75MHz
  hspi.setDataMode(SPI_MODE2); // CPOL = 1, CPHA = 0 (clock is high in idle state, data sampled on rising edge)

  // Set up the second SPI interface
  pinMode(ADC_CS_3, OUTPUT);
  digitalWrite(ADC_CS_3, HIGH);
  vspi.begin(SPI2_SCK, SPI2_MISO, -1, ADC_CS_3);

  pinMode(ADC_CS_4, OUTPUT);
  digitalWrite(ADC_CS_4, HIGH);
  vspi.begin(SPI2_SCK, SPI2_MISO, -1, ADC_CS_4);

  vspi.setClockDivider(SPI_CLOCK_DIV64); // ESP32 has SPI clock speed of 240MHz / 64 = 3.75MHz
  vspi.setDataMode(SPI_MODE2); // CPOL = 1, CPHA = 0 (clock is high in idle state, data sampled on rising edge)

  SerialPort.begin(9600, SERIAL_8N1, RXpin, TXpin); //UART: baud rate, serial config., rxd pin, txd pin

  delay(2000);
  SerialPort.flush();
  Serial.flush();

}

void loop() {
  
  unsigned int data_total_0 = 0;
  unsigned int data_total_1 = 0;
  unsigned int data_total_2 = 0;
  unsigned int data_total_3 = 0;

  //read the data into the registers
  for (int i = 0; i < numSamples; i++){
    data_total_0 += readData(&hspi, ADC_CS_1); // read data from channel 1
    data_total_1 += readData(&hspi, ADC_CS_2); // read data from channel 2
    data_total_2 += readData(&vspi, ADC_CS_3); // read data from channel 3
    data_total_3 += readData(&vspi, ADC_CS_4); // read data from channel 4
  }

  regs[0] = data_total_0 / numSamples;
  regs[1] = data_total_1 / numSamples;
  regs[2] = data_total_2 / numSamples;
  regs[3] = data_total_3 / numSamples;

  // check for a modbus command over the serial port
  if (SerialPort.available() > 7){
    decode();
  }
}

int readData(SPIClass* spi, unsigned int cs_pin) {
  //Format is 0000UUUU MMMMMMMM LLLL0000
  // returns 16 bit data
  digitalWrite(cs_pin, LOW);
  delay(1);
  upper_byte = spi->transfer(0x00);
  middle_byte = spi->transfer(0x00);
  lower_byte = spi->transfer(0x00);
  data = ((upper_byte << 12) | (middle_byte << 4) | (lower_byte >> 4));
  digitalWrite(cs_pin, HIGH);
  return data;
}

Re: ESP32 SPI issue (voltage levels)

Posted: Thu Jan 25, 2024 4:11 am
by mikemoy
need to supply a little more to the story.
What voltage are you supplying the L7805CV ?
Did you put filter caps on the input and output, and if so what are they.