The code run on NodeMCU-32S (ESP32 in Arduino framework) capture analog input in background base on timer interrupt, display on SPI ILI9341 screen graphically.
#include "SPI.h"
#include "TFT_eSPI.h"
#define TFT_GREY 0x7BEF
TFT_eSPI myGLCD = TFT_eSPI();
#define FRAME_TOPX 10
#define FRAME_TOPY 5
#define FRAME_WIDTH 300
#define FRAME_HEIGHT 200
#define FRAME_BOTTOMY FRAME_TOPY + FRAME_HEIGHT
#define LAMP_PLOTTING_X FRAME_TOPX+290
#define LAMP_PLOTTING_Y FRAME_BOTTOMY+10
#define LAMP_PLOTTING_R 5
#define NO_OF_BFR_PAGE 2
#define NO_OF_BFR_ELE 300
unsigned int bfr[NO_OF_BFR_PAGE][NO_OF_BFR_ELE];
volatile int bfr_page;
volatile int bfr_idx;
volatile bool bfr_filled;
volatile int bfr_filled_page;
volatile bool bfr_run = false;
volatile int updateDot = -1;
volatile unsigned long prvSamplingTime;
#define PrgressDot_X FRAME_TOPX
#define PrgressDot_Y FRAME_BOTTOMY+4
#define PinAnalogIn 36
unsigned long previousTime = 0;
hw_timer_t * timer = NULL;
volatile SemaphoreHandle_t timerSemaphore;
void IRAM_ATTR onTimer(){
toFillBfr();
// Give a semaphore that we can check in the loop
xSemaphoreGiveFromISR(timerSemaphore, NULL);
}
void setup() {
Serial.begin(115200);
myGLCD.init();
myGLCD.setRotation(1);
myGLCD.fillScreen(TFT_BLACK);
delay(500);
myGLCD.fillRect(FRAME_TOPX-1, FRAME_TOPY-1,
FRAME_WIDTH+2, FRAME_HEIGHT+2, TFT_WHITE);
myGLCD.fillRect(FRAME_TOPX, FRAME_TOPY,
FRAME_WIDTH, FRAME_HEIGHT, TFT_GREY);
myGLCD.setTextColor(TFT_WHITE,TFT_BLACK);
myGLCD.drawString("Double Buffer", FRAME_TOPX, FRAME_BOTTOMY+20);
// prepare bfr
bfr_run = false;
bfr_filled = false;
bfr_page = 0;
bfr_idx = 0;
bfr_run = true;
// --- Prepare Timer Intrrupt ---
// Create semaphore to inform us when the timer has fired
timerSemaphore = xSemaphoreCreateBinary();
// Use 1st timer of 4 (counted from zero).
// Set 80 divider for prescaler (see ESP32 Technical Reference Manual for more
// info).
timer = timerBegin(0, 80, true);
// Attach onTimer function to our timer.
timerAttachInterrupt(timer, &onTimer, true);
// Set alarm to call onTimer function every second (value in microseconds).
// Repeat the alarm (third parameter)
timerAlarmWrite(timer, 10000, true); //10ms
//timerAlarmWrite(timer, 1000, true); //1ms
// Start an alarm
timerAlarmEnable(timer);
prvSamplingTime = micros();
// --- End of Prepare Timer Intrrupt ---
Serial.println("\n --- Start ---\n");
Serial.println("CPU Frequency (Mhz): " + String(getCpuFrequencyMhz()));
}
void handle_screen(){
if(bfr_filled){
//unsigned long beforeScreen = micros();
bfr_filled = false;
myGLCD.fillCircle(LAMP_PLOTTING_X, LAMP_PLOTTING_Y, LAMP_PLOTTING_R, TFT_RED);
myGLCD.fillRect(FRAME_TOPX, FRAME_TOPY,
FRAME_WIDTH, FRAME_HEIGHT, TFT_GREY);
int yPrv = bfr[bfr_filled_page][0];
for(int i=1; i<NO_OF_BFR_ELE; i++){
int yCur = bfr[bfr_filled_page][i];
myGLCD.drawLine(FRAME_TOPX+i-1, FRAME_BOTTOMY-yPrv,
FRAME_TOPX+i, FRAME_BOTTOMY-yCur,
TFT_WHITE);
yPrv = yCur;
}
myGLCD.fillCircle(LAMP_PLOTTING_X, LAMP_PLOTTING_Y, LAMP_PLOTTING_R, TFT_GREEN);
myGLCD.drawLine(PrgressDot_X, PrgressDot_Y, PrgressDot_X+299, PrgressDot_Y, TFT_BLACK);
//Serial.println("Fil duration: " + String(micros()-beforeScreen) + " (microsecond)");
}
//to draw alblue line under the graph for indicate the sample progress
if(int x=updateDot){
updateDot = -1;
myGLCD.drawPixel(PrgressDot_X+x, PrgressDot_Y, TFT_BLUE);
}
}
void loop() {
if (xSemaphoreTake(timerSemaphore, 0) == pdTRUE){
handle_screen();
}
}
void toFillBfr(){
//unsigned long beforeFill = micros();
unsigned long int curSamplingTime = micros();
if(bfr_run){
bfr[bfr_page][bfr_idx] = map(analogRead(PinAnalogIn),0, 4096, 0, 200);
updateDot = bfr_idx;
bfr_idx++;
if(bfr_idx >= NO_OF_BFR_ELE){
bfr_filled_page = bfr_page;
bfr_idx=0;
if(bfr_page==0){
bfr_page = 1;
}else{
bfr_page = 0;
}
bfr_filled = true;
}
}
//Send sampling interval to Serial Monitor for evaluation only,
//remove it before finalize.
Serial.println(curSamplingTime - prvSamplingTime);
prvSamplingTime = curSamplingTime;
//Serial.println("Fil duration: " + String(micros()-beforeFill) + " (microsecond)");
}
To setup TFT_eSPI using SPI ILI9342 for ESP32, read the post "ESP32 + 2.4" 320X240 Display (SPI ILI9341), using TFT_eSPI, prepare user setup file".