#include <Adafruit_GFX.h>
#include <Adafruit_ST7735.h>
#include <SPI.h>
#define TFT_CS 10
#define TFT_RST A1
#define TFT_DC A0
#define TFT_Mosi 11
#define TFT_Sclk 13
Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST);
// Кнопки
#define BTN_UP 2
#define BTN_DOWN 3
#define BTN_SEL 4
// Выход сигнала
#define SIGNAL_PIN 5
// Типы сигналов
enum WaveType {
SINE, // синус
SQUARE,
TRIANGLE,
SAW
};
WaveType currentWave = SINE;
int frequency = 1000;
int dutyCycle = 50;
bool menuMode = true;
int menuItem = 0;
unsigned long lastMicros = 0;
int phase = 0;
// Таблица синуса
const uint8_t sineTable[64] = {
128,140,153,165,177,188,199,209,
218,226,234,240,245,249,252,254,
255,254,252,249,245,240,234,226,
218,209,199,188,177,165,153,140,
128,115,102,90,78,67,56,46,
37,29,21,15,10,6,3,1,
0,1,3,6,10,15,21,29,
37,46,56,67,78,90,102,115
};
void setup() {
pinMode(BTN_UP, INPUT_PULLUP);
pinMode(BTN_DOWN, INPUT_PULLUP);
pinMode(BTN_SEL, INPUT_PULLUP);
pinMode(SIGNAL_PIN, OUTPUT);
tft.initR(INITR_BLACKTAB); // инициализация дисплея
tft.fillScreen(ST77XX_BLACK);
analogWrite(SIGNAL_PIN, 127);
drawUI();
}
void loop() {
handleButtons();
generateSignal();
drawOscilloscope();
}
void handleButtons() {
if (!digitalRead(BTN_UP)) {
delay(150);
if (menuItem == 0) {
currentWave = (WaveType)((currentWave + 1) % 4);
}
if (menuItem == 1) {
frequency += 100;
}
if (menuItem == 2) {
dutyCycle += 5;
if (dutyCycle > 95) dutyCycle = 95;
}
drawUI();
}
if (!digitalRead(BTN_DOWN)) {
delay(150);
if (menuItem == 0) {
currentWave = (WaveType)((currentWave + 3) % 4);
}
if (menuItem == 1) {
frequency -= 100;
if (frequency < 100) frequency = 100;
}
if (menuItem == 2) {
dutyCycle -= 5;
if (dutyCycle < 5) dutyCycle = 5;
}
drawUI();
}
if (!digitalRead(BTN_SEL)) {
delay(150);
menuItem++;
if (menuItem > 2) menuItem = 0;
drawUI();
}
}
void generateSignal() {
unsigned long period = 1000000UL / frequency;
if (micros() - lastMicros >= period / 64) {
lastMicros = micros();
uint8_t value = 0;
switch (currentWave) {
case SINE:
value = sineTable[phase];
break;
case SQUARE:
value = (phase < (64 * dutyCycle / 100)) ? 255 : 0;
break;
case TRIANGLE:
if (phase < 32)
value = phase * 8;
else
value = 255 - ((phase - 32) * 8);
break;
case SAW:
value = phase * 4;
break;
}
analogWrite(SIGNAL_PIN, value);
phase++;
if (phase >= 64) phase = 0;
}
}
void drawUI() {
tft.fillScreen(ST77XX_BLACK);
tft.setTextColor(ST77XX_GREEN);
tft.setTextSize(2);
tft.setCursor(5, 5);
tft.print(“GENERATOR”);
tft.setTextSize(1);
tft.setCursor(5, 40);
tft.print(menuItem == 0 ? “>” : " ");
tft.print("Wave: ");
switch(currentWave) {
case SINE: tft.print(“SINE”); break;
case SQUARE: tft.print(“SQUARE”); break;
case TRIANGLE: tft.print(“TRIANGLE”); break;
case SAW: tft.print(“SAW”); break;
}
tft.setCursor(5, 60);
tft.print(menuItem == 1 ? “>” : " ");
tft.print(“Freq: “);
tft.print(frequency);
tft.print(” Hz”);
tft.setCursor(5, 80);
tft.print(menuItem == 2 ? “>” : " ");
tft.print(“Duty: “);
tft.print(dutyCycle);
tft.print(”%”);
tft.drawRect(5, 105, 118, 50, ST77XX_WHITE);
}
void drawOscilloscope() {
static int x = 6;
tft.drawFastVLine(x, 106, 48, ST77XX_BLACK);
int y = 130;
switch(currentWave) {
case SINE:
y = 130 + sin(x * 0.2) * 15;
break;
case SQUARE:
y = (x % 20 < 10) ? 115 : 145;
break;
case TRIANGLE:
y = 115 + abs((x % 20) - 10) * 3;
break;
case SAW:
y = 145 - (x % 20) * 3;
break;
}
tft.drawPixel(x, y, ST77XX_YELLOW);
x++;
if (x > 120)
x = 6;
}
как в этом скетче развернуть изображение на 180 градусов