Waterfall graph speed

gcr100
Posts: 1
Joined: Sat Dec 02, 2023 5:15 pm

Waterfall graph speed

Postby gcr100 » Sat Dec 02, 2023 5:27 pm

Hello everyone, im new to the forum and still learning about the esp32.
Im using a esp32 wroom to make a simple vfo/panadapter for radios that i make, my goal is to create an opensource pcb for this purpose, however im running into a speed problem.
I'm runing a simple code for a waterfall graph which is done by reading an adc channel and computing the fft of the read values, then the esp32 displays the values on a tft display (spi ili9486 320x480) running at 80mhz but the update speed seems to be really slow like 7-10hz and that's just for the waterfall graph, i did something similar but without the waterfall for a previous project involving a stm32 and that ran a bit faster, https://github.com/gcrcien/STM32_VFO, im coding all this in the arduino IDE.
Has any of you guys done a similar project that can give hints on how to accelerate this project? I'm new to the esp32 but i have read that dma is a way to accelerate the spi lcd refresh rate, but im lost with this.

[Codebox]#include "arduinoFFT.h"
#include "SPI.h"
#include "TFT_eSPI.h"

TFT_eSPI tft = TFT_eSPI();

#define CHANNEL 34
#define TFT_WIDTH 480
#define TFT_HEIGHT 100
#define GRAPH_TOP_MARGIN 4
#define GRAPH_BOTTOM_MARGIN 4

#define BLACK 0x0000
#define GREEN 0x07E0

arduinoFFT FFT;

const uint16_t samples = 128;
const double samplingFrequency = 10000;
double vReal[samples];
double vImag[samples];

#define NUM_WATERFALL_ROWS 90
float waterfallData[NUM_WATERFALL_ROWS][128] = {0};

void performFFTAndDrawGraph(int xOffset, int yOffset);

void setup() {
//SPI.beginTransaction(SPISettings(20000000, MSBFIRST, SPI_MODE0));
tft.init();
tft.invertDisplay(0);
tft.fillScreen(BLACK);
tft.setRotation(1);
}

void loop() {
performFFTAndDrawGraph(0, 0);
}

void performFFTAndDrawGraph(int xOffset, int yOffset) {
// Capturar datos de entrada
for (int i = 0; i < samples; i++) {

vReal = analogRead(34);
vImag = 0;
}

// Realizar FFT
FFT = arduinoFFT(vReal, vImag, samples, samplingFrequency);
FFT.Windowing(FFT_WIN_TYP_RECTANGLE, FFT_FORWARD);
FFT.Compute(FFT_FORWARD);
FFT.ComplexToMagnitude();

// Solo mapear los datos de entrada antes de almacenarlos en el array waterfall
for (int col = 0; col < 128; ++col) {
int mappedValue = map(vReal[col], 0, 5000, 0, 128); // Solo mapear a un rango de 0 a 255
waterfallData[NUM_WATERFALL_ROWS - 1][col] = mappedValue;

}

// Actualizar datos de waterfall
for (int row = 0; row < NUM_WATERFALL_ROWS - 1; ++row) {
for (int col = 0; col < 128; ++col) {
waterfallData[row][col] = waterfallData[row + 1][col];
}
}

// Dibujar el waterfall en la pantalla
for (int row = 0; row < NUM_WATERFALL_ROWS; ++row) {
for (int col = 0; col < 128; ++col) {
int intensity = waterfallData[row][col];
int color = intensity; // El color ahora está en el rango de 0 a 255

tft.drawPixel(col + xOffset, TFT_HEIGHT - 1 - row + yOffset + 80, color);
}
}
}[/Codebox]

lbernstone
Posts: 829
Joined: Mon Jul 22, 2019 3:20 pm

Re: Waterfall graph speed

Postby lbernstone » Sun Dec 03, 2023 4:24 am

I'm not super math guy, so I don't know if it has the functions you need, but arduino-esp32 includes some xtensa optimized dsp routines.
It looks to me like you are sending one pixel at a time over the wire. TFT_eSPI uses the sprite concept as a framebuffer. Use that, write your whole graph out to memory (or at least a good sized page if you don't have psram) and then send that to the screen. This example should show you how to enable DMA transfers, as well as using sprites to pop data to screen.

Who is online

Users browsing this forum: No registered users and 133 guests