#include #include TFT_eSPI tft = TFT_eSPI(); TFT_eSprite ds = TFT_eSprite(&tft); #define INPUT_PIN 35 #define BL_PIN 27 #define SAMPLES 1024 uint16_t raw_buffer[SAMPLES]; uint16_t clean_buffer[SAMPLES / 2]; uint32_t delays[] = {1, 2, 4, 8, 16, 32}; const char* labels[] = {"MAX", "x2", "x4", "x8", "x16", "x32"}; int mode = 0; void setup_i2s() { i2s_config_t i2s_config = { .mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_RX | I2S_MODE_ADC_BUILT_IN), .sample_rate = 150000, .bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT, .channel_format = I2S_CHANNEL_FMT_ONLY_RIGHT, .communication_format = I2S_COMM_FORMAT_I2S_MSB, .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1, .dma_buf_count = 2, .dma_buf_len = SAMPLES, .use_apll = false }; i2s_driver_install(I2S_NUM_0, &i2s_config, 0, NULL); i2s_set_adc_mode(ADC_UNIT_1, ADC1_CHANNEL_7); i2s_adc_enable(I2S_NUM_0); } // ВАША ОРИГИНАЛЬНАЯ КАЛИБРОВКА С МАССИВОМ void touch_calibrate() { uint16_t calData[5]; tft.fillScreen(TFT_BLACK); tft.setCursor(20, 0); tft.setTextColor(TFT_WHITE); tft.setTextSize(1); tft.println("Нажми на углы, как показано"); tft.calibrateTouch(calData, TFT_MAGENTA, TFT_BLACK, 15); tft.fillScreen(TFT_BLACK); } void setup() { pinMode(BL_PIN, OUTPUT); digitalWrite(BL_PIN, HIGH); pinMode(21, OUTPUT); digitalWrite(21, HIGH); tft.init(); tft.setRotation(1); tft.invertDisplay(false); touch_calibrate(); // Запуск вашей калибровки ds.setColorDepth(8); ds.createSprite(320, 160); setup_i2s(); drawButtons(); } void drawButtons() { tft.fillRect(0, 190, 320, 50, TFT_BLACK); tft.setTextSize(1); for (int i = 0; i < 6; i++) { uint16_t btnColor = (i == mode) ? TFT_YELLOW : 0x7BEF; tft.drawRect(i * 53, 195, 52, 44, btnColor); tft.setTextColor(TFT_WHITE, TFT_BLACK); tft.setCursor(i * 53 + 5, 215); tft.print(labels[i]); } } void loop() { uint16_t tx, ty; if (tft.getTouch(&tx, &ty)) { if (ty > 190) { int new_mode = tx / 53; if (new_mode < 6 && new_mode != mode) { mode = new_mode; drawButtons(); delay(150); } } } size_t read_len; i2s_read(I2S_NUM_0, (void*)raw_buffer, SAMPLES * 2, &read_len, portMAX_DELAY); int clean_count = 0; int v_max = 0, v_min = 4096; for (int i = 0; i < SAMPLES; i += 2) { clean_buffer[clean_count] = raw_buffer[i] & 0x0FFF; if (clean_buffer[clean_count] > v_max) v_max = clean_buffer[clean_count]; if (clean_buffer[clean_count] < v_min) v_min = clean_buffer[clean_count]; clean_count++; } int mid = (v_max + v_min) / 2; int hyst = (v_max - v_min) / 10; if (hyst < 15) hyst = 15; int trig = 0; for (int i = 1; i < clean_count / 2; i++) { if (clean_buffer[i-1] < mid - hyst && clean_buffer[i] > mid) { trig = i; break; } } int crossings = 0; bool state = false; for (int i = 0; i < clean_count; i++) { if (!state && clean_buffer[i] > mid + hyst) { crossings++; state = true; } else if (state && clean_buffer[i] < mid - hyst) { state = false; } } float freq = (crossings * 150000.0) / 1024.0; ds.fillSprite(TFT_BLACK); for(int x=0; x<320; x+=40) ds.drawFastVLine(x, 0, 160, 0x2104); for(int y=0; y<160; y+=40) ds.drawFastHLine(0, y, 320, 0x2104); ds.drawFastHLine(0, 80, 320, 0x7BEF); int range = clean_count / delays[mode]; for (int i = 1; i < 320; i++) { int idx1 = trig + map(i - 1, 0, 319, 0, range - 1); int idx2 = trig + map(i, 0, 319, 0, range - 1); if (idx2 >= clean_count) break; int y1 = map(clean_buffer[idx1], 0, 4095, 155, 5); int y2 = map(clean_buffer[idx2], 0, 4095, 155, 5); ds.drawLine(i-1, y1, i, y2, TFT_GREEN); } ds.pushSprite(0, 30); float vpp = ((v_max - v_min) * 3.3) / 4095.0; tft.fillRect(0, 0, 320, 30, TFT_BLACK); // ЧИСТИМ МЕСТО ПОД ТЕКСТ tft.setCursor(5, 5); tft.setTextColor(TFT_YELLOW, TFT_BLACK); if (vpp > 0.4) { if (freq > 999) tft.printf("Upp:%.2fV F:%.2fkHz", vpp, freq / 1000.0); else tft.printf("Upp:%.2fV F:%.0fHz", vpp, freq); } else { tft.printf("Upp:%.2fV F:0Hz", vpp); } }