// **Project Link:** https://wokwi.com/projects/372034198045091841?gh=1
// Error message: Library not found: "TFT_eSPI@wokwi:e05dd5def8f952d3f56c5f0b6f6fcfffe80b6b01"
// #include "Adafruit_GFX.h"
#include "TFT_eSPI.h"
#include "Adafruit_ILI9341.h"
#include "SPI.h"
#include "Chewy_Regular_16.h"
#include "bitmap.h"
#define TFT_DC 2
#define TFT_CS 15
#define TFT_MOSI 23
#define TFT_SCLK 18
TFT_eSPI tft = TFT_eSPI();
TFT_eSprite sprite= TFT_eSprite(&tft);
#define background1 0x29CC
const String logo_menu_name[] = {
"input",
"sound",
"dsp",
"settings",
};
const int potPin = 34;
int potentiometer_value = 388; // value from the potentiometer
char buffer[20]; // helper buffer for converting values into C-style string (array of chars)
int string_width; // helper value for string widths
float pixel_x = 0; // x pos for pixel
float pixel_y = 0; // y pos for pixel
float line_x = 0; // x pos for line end
float line_y = 0; // y pos for line end
float text_x = 0; // x pos for text
float text_y = 0; // y pos for text
uint8_t offsetTriangle = 100;
int center_x = 120; //64; // x center of the knob
int center_y = 200; //108; // y center of the knob (outside of the screen)
int radius_pixel = 92; // radius for pixel tickmarks
int radius_line = 87; // radius for line end
int radius_text = 75; // radius for text
int angle; // angle for the individual tickmarks
int tick_value; // numeric value for the individual tickmarks
byte precalculated_x_radius_pixel[180]; // lookup table to prevent expensive sin/cos calculations
byte precalculated_y_radius_pixel[180]; // lookup table to prevent expensive sin/cos calculations
// Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC);
// void disp_text(uint8_t x, uint8_t y, bool wrap, uint32_t color, )
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
Serial.println("Hello, ESP32!");
// tft.begin();
// tft.setFont(&Chewy_Regular_16);
// tft.setCursor(10, 50);
// tft.setTextColor(ILI9341_WHITE);
// tft.setTextWrap(false);
// tft.print("POLYTRON asdfasdfa;sdkfjlk;asjdf");
tft.init();
// tft.setRotation(0);
// tft.setSwapBytes(true);
tft.fillScreen(background1);
// tft.pushImage(40, 40, 62, 62, music);
#if 0
// sprite.setColorDepth(8);
// ke kanan, ke bawah
sprite.createSprite(200, 200);
// sprite.setPivot(23,23);
sprite.setSwapBytes(true);
// sprite.drawXBitmap(0, 40, menuAudio, 240, 320, TFT_TRANSPARENT);
// sprite.fillSprite(TFT_TRANSPARENT);
sprite.pushImage(1, 1, 46, 46, first_menu[2]);
sprite.setTextSize(4);
sprite.drawString(logo_menu_name[0], 47, 9);
sprite.pushImage(1, 51, 46, 46, first_menu[2]);
sprite.drawString(logo_menu_name[1], 47, 59);
sprite.pushImage(1, 101, 46, 46, first_menu[2]);
sprite.drawString(logo_menu_name[2], 47, 109);
sprite.pushImage(1, 151, 46, 46, first_menu[2]);
sprite.drawString(logo_menu_name[3], 47, 159);
sprite.pushImage(1, 201, 46, 46, first_menu[2]);
sprite.drawString("asdf", 47, 209);
sprite.pushSprite(0, 50);
#else
for (int i = 0; i < 180; i++) { // pre-calculate x and y positions into the look-up tables
precalculated_x_radius_pixel[i] = sin(radians(i-90)) * radius_pixel + center_x;
precalculated_y_radius_pixel[i] = -cos(radians(i-90)) * radius_pixel + center_y;
}
// tft.fillRect(0, 0, 240, 40, TFT_RED);
// tft.fillRect(0, 40, 240, 40, TFT_ORANGE);
// tft.fillRect(0, 80, 240, 40, TFT_YELLOW);
// tft.fillRect(0, 120, 240, 40, TFT_GREEN);
// tft.fillRect(0, 160, 240, 40, TFT_BLUE);
// tft.fillRect(0, 200, 240, 40, TFT_SKYBLUE);
// tft.fillRect(0, 200, 240, 40, TFT_VIOLET);
// tft.setCursor(0, 0);
// tft.setTextColor(TFT_BLACK);
// tft.setTextSize(4);
// tft.println("test");
#endif
}
void loop() {
// put your main code here, to run repeatedly:
tft.fillRect(0, 0, 240, 240, TFT_WHITE);
// calculate tickmarks
for (int i=-90; i<=90; i=i+9) { // only try to calculate tickmarks that would end up be displayed
angle = i + ((potentiometer_value*9)/10) % 9; // final angle for the tickmark
tick_value = round((potentiometer_value/10.0) + angle/9.0); // get number value for each tickmark
//pixel_x = sin(radians(angle)) * radius_pixel + center_x; // calculate the tickmark pixel x value
//pixel_y = -cos(radians(angle)) * radius_pixel + center_y; // calculate the tickmark pixel y value
pixel_x = precalculated_x_radius_pixel[angle+90]; // get x value from lookup table
pixel_y = precalculated_y_radius_pixel[angle+90]; // get y value from lookup table
if (pixel_x > 0 && pixel_x < 240 && pixel_y > 0 && pixel_y < 240) { // only draw inside of the screen
if(tick_value >= 0 && tick_value <= 100) { // only draw tickmarks between values 0-100%, could be removed when using rotary controller
tft.setTextSize(1);
tft.setTextColor(TFT_BLACK);
if (tick_value % 10 == 0) { // draw big tickmark == lines + text
line_x = sin(radians(angle)) * radius_line + center_x; // calculate x pos for the line end
line_y = -cos(radians(angle)) * radius_line + center_y; // calculate y pos for the line end
tft.drawLine(pixel_x, pixel_y, line_x, line_y, TFT_BLACK); // draw the line
// drawLine(int32_t xs, int32_t ys, int32_t xe, int32_t ye, uint32_t color)
text_x = sin(radians(angle)) * radius_text + center_x; // calculate x pos for the text
text_y = -cos(radians(angle)) * radius_text + center_y; // calculate y pos for the text
itoa(tick_value, buffer, 10); // convert integer to string
// string_width = u8g.getStrWidth(buffer); // get string width
// u8g.drawStr(text_x - string_width/2, text_y, buffer); // draw text - tickmark value
string_width = tft.textWidth(buffer);
tft.drawString(buffer, text_x - string_width/2, text_y);
}
else { // draw small tickmark == pixel tickmark
tft.drawPixel(pixel_x, pixel_y, TFT_BLACK); // draw a single pixel
// drawPixel(int32_t x, int32_t y, uint32_t color, uint8_t alpha, uint32_t bg_color = 0x00FFFFFF);
}
}
}
}
dtostrf(potentiometer_value/10.0, 1, 1, buffer); // float to string, -- value, min. width, digits after decimal, buffer to store
sprintf(buffer, "%s%s", buffer, "%"); // add some random ending character
string_width = tft.textWidth(buffer); // calculate string width
// u8g.setColorIndex(1); // set color to white
// u8g.drawRBox(64-(string_width+4)/2, 0, string_width+4, 11, 2); // draw background rounded rectangle
// u8g.drawTriangle( 64-3, 11, 64+4, 11, 64, 15); // draw small arrow below the rectangle
// u8g.setColorIndex(0); // set color to black
// u8g.drawStr(64-string_width/2, 10, buffer); // draw the value on top of the display
tft.fillRect(120-(string_width+4)/2, offsetTriangle+0, string_width+4, 11, TFT_BLACK);
tft.fillTriangle(120-3, offsetTriangle+11, 120+4, offsetTriangle+11, 120, offsetTriangle+15, TFT_BLACK);
tft.drawString(buffer, 120-string_width/2, 10);
delay(10); // this speeds up the simulation
potentiometer_value = map(analogRead(potPin), 0, 1023, 1000, 0); // read the potentiometer value, remap it to 0-1000
}