#include <Arduino.h>
#include <driver/i2s.h>
#include <driver/adc.h>
#include <soc/syscon_reg.h>
#include <SPI.h>
#include <TFT_eSPI.h>
#include "esp_adc_cal.h"
#include "filters.h"
//#define DEBUG_SERIAL
//#define DEBUG_BUFF
#define DELAY 1000
// Width and height of sprite
#define WIDTH 320 //240
#define HEIGHT 240 //280
#define ADC_CHANNEL ADC1_CHANNEL_5 // GPIO33
#define DMA_BUFFER_LEN 1000 // number of samples
#define I2S_NUM (0)
#define BUFF_SIZE 50000
#define B_MULT BUFF_SIZE / DMA_BUFFER_LEN
#define BUTTON_Ok 32
#define BUTTON_Plus 25
#define BUTTON_Minus 35
//#define BUTTON_Back 25
#define BUTTON_Up 34
#define BUTTON_Down 26
TFT_eSPI tft = TFT_eSPI(); // Declare object "tft"
TFT_eSprite spr = TFT_eSprite(&tft); // Declare Sprite object "spr" with pointer to "tft" object
const int potPin = 13; // ADC2 pin 13
int potValue = 0;
const int voltagePin = 14; // ADC2 pin 14
int voltageValue = 0;
float vot_charge;
int triger = 0;
esp_adc_cal_characteristics_t adc_chars;
TaskHandle_t task_menu;
TaskHandle_t task_adc;
float v_div = 825;
float s_div = 10;
float offset = 0;
float toffset = 0;
uint8_t current_filter = 1;
//options handler
enum Option {
None,
Autoscale,
Vdiv,
Sdiv,
Offset,
TOffset,
Filter,
Stop,
Mode,
Single,
Clear,
Reset,
Probe,
UpdateF,
Cursor1,
Cursor2
};
int8_t volts_index = 0;
int8_t tscale_index = 0;
uint8_t opt = None;
bool menu = false;
bool info = true;
bool set_value = false;
float SAMPLING_FREQ = 1000; //in ksps --> 1000 = 1Msps
bool auto_scale = false;
bool full_pix = true;
bool stop = false;
bool stop_change = false;
uint16_t i2s_buff[BUFF_SIZE];
bool single_trigger = false;
bool data_trigger = false;
bool updating_screen = false;
bool new_data = false;
bool menu_action = false;
uint8_t digital_wave_option = 0; //0-auto | 1-analog | 2-digital data (SERIAL/SPI/I2C/etc)
int btnok, btnpl, btnmn, btnbk, btnu, btndn;
void IRAM_ATTR btok() {
btnok = 1;
}
void IRAM_ATTR btplus() {
btnpl = 1;
}
void IRAM_ATTR btminus() {
btnmn = 1;
}
//void IRAM_ATTR btback() {
// btnbk = 1;
//}
void IRAM_ATTR btup() {
btnu = 1;
}
void IRAM_ATTR btdown() {
btndn = 1;
}
void setup() {
Serial.begin(115200);
configure_i2s(1000000);
setup_screen();
pinMode(BUTTON_Ok, INPUT);
pinMode(BUTTON_Plus, INPUT);
pinMode(BUTTON_Minus, INPUT);
//pinMode(BUTTON_Back, INPUT);
pinMode(BUTTON_Up, INPUT);
pinMode(BUTTON_Down, INPUT);
attachInterrupt(BUTTON_Ok, btok, RISING);
attachInterrupt(BUTTON_Plus, btplus, RISING);
attachInterrupt(BUTTON_Minus, btminus, RISING);
//attachInterrupt(BUTTON_Back, btback, RISING);
attachInterrupt(BUTTON_Up, btup, RISING);
attachInterrupt(BUTTON_Down, btdown, RISING);
characterize_adc();
#ifdef DEBUG_BUFF
debug_buffer();
#endif
xTaskCreatePinnedToCore(
core0_task,
"menu_handle",
10000, /* Размер стека в словах */
NULL, /* Входной параметр задачи */
0, /* Приоритет задачи */
&task_menu, /* Дескриптор задачи. */
0); /* Ядро, где должна выполняться задача */
xTaskCreatePinnedToCore(
core1_task,
"adc_handle",
10000, /* Stack size in words */
NULL, /* Task input parameter */
3, /* Priority of the task */
&task_adc, /* Task handle. */
1); /* Core where the task should run */
}
void core0_task(void* pvParameters) {
(void)pvParameters;
for (;;) {
potValue = analogRead(potPin);
voltageValue = analogRead(voltagePin);
if (potValue >= 2500) {
triger = 1;
} else {
triger = 0;
}
if (triger == 0) {
menu_handler();
if (new_data || menu_action) {
new_data = false;
menu_action = false;
updating_screen = true;
spr.drawString(String(int(voltageValue)) + " div", 10, 115);
update_screen(i2s_buff, SAMPLING_FREQ);
updating_screen = false;
vTaskDelay(pdMS_TO_TICKS(10));
//Serial.println("CORE0");
}
vTaskDelay(pdMS_TO_TICKS(10));
} else {
//spr.drawString(String(int(voltageValue)) + " div", 10, 115);
//spr.pushSprite(0, 0); // Вытолкнуть нарисованный спрайт за оси
//yield(); // Остановить сброс сторожевого таймера
//draw_battery(40, 80); // Рисуем анимацию батареи
}
}
}
void core1_task(void* pvParameters) {
(void)pvParameters;
for (;;) {
if (triger == 0) {
if (!single_trigger) {
while (updating_screen) {
vTaskDelay(pdMS_TO_TICKS(1));
}
if (!stop) {
if (stop_change) {
i2s_adc_enable(I2S_NUM_0);
stop_change = false;
}
ADC_Sampling(i2s_buff);
new_data = true;
} else {
if (!stop_change) {
i2s_adc_disable(I2S_NUM_0);
i2s_zero_dma_buffer(I2S_NUM_0);
stop_change = true;
}
}
//Serial.println("CORE1");
vTaskDelay(pdMS_TO_TICKS(300));
} else {
float old_mean = 0;
while (single_trigger) {
stop = true;
ADC_Sampling(i2s_buff);
float mean = 0;
float max_v, min_v;
peak_mean(i2s_buff, BUFF_SIZE, &max_v, &min_v, &mean);
//signal captured (pp > 0.4V || changing mean > 0.2V) -> DATA ANALYSIS
if ((old_mean != 0 && fabs(mean - old_mean) > 0.2) || to_voltage(max_v) - to_voltage(min_v) > 0.05) {
float freq = 0;
float period = 0;
uint32_t trigger0 = 0;
uint32_t trigger1 = 0;
//if analog mode OR auto mode and wave recognized as analog
bool digital_data = !false;
if (digital_wave_option == 1) {
trigger_freq_analog(i2s_buff, SAMPLING_FREQ, mean, max_v, min_v, &freq, &period, &trigger0, &trigger1);
} else if (digital_wave_option == 0) {
digital_data = digital_analog(i2s_buff, max_v, min_v);
if (!digital_data) {
trigger_freq_analog(i2s_buff, SAMPLING_FREQ, mean, max_v, min_v, &freq, &period, &trigger0, &trigger1);
} else {
trigger_freq_digital(i2s_buff, SAMPLING_FREQ, mean, max_v, min_v, &freq, &period, &trigger0);
}
} else {
trigger_freq_digital(i2s_buff, SAMPLING_FREQ, mean, max_v, min_v, &freq, &period, &trigger0);
}
single_trigger = false;
new_data = true;
Serial.println("Single GOT");
//return to normal execution in stop mode
}
vTaskDelay(pdMS_TO_TICKS(1)); //time for the other task to start (low priorit)
}
vTaskDelay(pdMS_TO_TICKS(300));
}
}
}
}
void loop() {
}