#include "U8glib.h"
#define ENCODER_CLK 2
#define ENCODER_DT 3
U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_DEV_0 | U8G_I2C_OPT_NO_ACK | U8G_I2C_OPT_FAST);
int progress = 0;
int potentiometer_value = 0;
char buffer[20];
int string_width;
float pixel_x = 0;
float pixel_y = 0;
float line_x = 0;
float line_y = 0;
float text_x = 0;
float text_y = 0;
int center_x = 64;
int center_y = 108;
int radius_pixel = 92;
int radius_line = 87;
int radius_small_line = 91;
int radius_text = 75;
int angle;
int tick_value;
unsigned long millis_time;
unsigned long millis_time_last;
int fps;
int lastClk = HIGH;
int count =0;
const float DEG2RAD = PI / 180.0f; //https://forum.arduino.cc/t/calculating-angles/589533
void setup() {
// put your setup code here, to run once:
u8g.setFont(u8g_font_tpssb);
u8g.setColorIndex(1);
Serial.begin(115200);
pinMode(ENCODER_CLK, INPUT);
pinMode(ENCODER_DT, INPUT);
}
void loop() {
// put your main code here, to run repeatedly:
u8g.firstPage();
do{
u8g.setFont(u8g_font_tpssb);
u8g.setColorIndex(1); //set color to white
//Draw tickmarks
for(int i=-48; i<48; i=i+3){
angle = i + ((count/*potentiometer_value*/*3)/1) % 3;
tick_value = round((count/*potentiometer_value*//1.0) + angle/3.0);
pixel_x = sin(radians(angle))*radius_pixel + center_x;
pixel_y = -cos(radians(angle))*radius_pixel + center_y;
if(pixel_x > 0 && pixel_x <128 && pixel_y > 0 && pixel_y <64)
{
if(tick_value % 10 == 0){ //draw large tick marks
line_x = sin(radians(angle))*radius_line + center_x;
line_y = -cos(radians(angle))*radius_line + center_y;
u8g.drawLine(pixel_x, pixel_y, line_x, line_y);
text_x = sin(radians(angle))*radius_text + center_x;
text_y = -cos(radians(angle))*radius_text + center_y;
itoa(tick_value, buffer, 10);
string_width = u8g.getStrWidth(buffer);
u8g.drawStr(text_x-string_width/2, text_y, buffer);
}
else { //small tickmark
line_x = sin(radians(angle))*radius_small_line + center_x;
line_y = -cos(radians(angle))*radius_small_line + center_y;
//u8g.drawPixel(pixel_x, pixel_y);
u8g.drawLine(pixel_x, pixel_y, line_x, line_y);
}
}
}
// draw value and box at top
u8g.setFont(u8g_font_8x13r);
dtostrf(count/*potentiometer_value*/ /1.0, 1,1,buffer); //float to string
sprintf(buffer, "%s%s", buffer, "%"); //add % sign at end
string_width = u8g.getStrWidth(buffer);
u8g.setColorIndex(1); //set color to white
u8g.drawRBox(64-(string_width+4)/2, 0, string_width+4, 11, 2); //draw background round rectangle
u8g.drawTriangle(64-3, 11, 64+3 , 11, 64, 15); //draw small arrow below the rectangle
u8g.setColorIndex(0); //set color to black
u8g.drawStr(64-string_width/2,10,buffer);
//time it takes to update screen
u8g.setColorIndex(1); //set color to white
u8g.setFont(u8g_font_5x7r);
itoa(fps, buffer, 10);
u8g.drawStr(0,10,buffer);
}while (u8g.nextPage());
//potentiometer_value = map(analogRead(A0),0, 1023, 1000, 0);
potentiometer_value = map(analogRead(A0),0, 1023, 100, 0); //read the potentionmeter value
millis_time_last = millis_time;
millis_time = millis();
fps = round(1000.0/ (millis_time*1.0-millis_time_last));
/*do{
u8g.drawStr(25, 50, "Progress Bar");
u8g.drawFrame(0, 10,128, 20);
u8g.drawBox(10,15, progress, 10);
}while (u8g.nextPage());
if (progress < 108){
progress++;
}
else{
progress = 0;
}*/
//Rotary Encoder Code
int newClk = digitalRead(ENCODER_CLK);
if (newClk != lastClk) {
// There was a change on the CLK pin
lastClk = newClk;
int dtValue = digitalRead(ENCODER_DT);
if (newClk == LOW && dtValue == HIGH) {
Serial.println("Rotated clockwise ⏩");
count++;
}
if (newClk == LOW && dtValue == LOW) {
Serial.println("Rotated counterclockwise ⏪");
count--;
}
}
count=count+1;
//fillArc2(64, 11, 0, 120, 94, 94, 5, 1);
drawLine(0,0,0,0);
}
//https://forum.arduino.cc/t/adafruit_gfx-fillarc/397741/6
// #########################################################################
// Draw a circular or elliptical arc with a defined thickness
// #########################################################################
// x,y == coords of centre of arc
// start_angle = 0 - 359
// seg_count = number of 3 degree segments to draw (120 => 360 degree arc)
// rx = x axis radius
// yx = y axis radius
// w = width (thickness) of arc in pixels
// colour = 16 bit colour value
// Note if rx and ry are the same then an arc of a circle is drawn
int fillArc2(int x, int y, int start_angle, int seg_count, int rx, int ry, int w, uint8_t color)
{
uint8_t org_color = u8g.getColorIndex();
u8g.setColorIndex(color); //set color
byte seg = 3; // Segments are 3 degrees wide = 120 segments for 360 degrees
byte inc = 3; // Draw segments every 3 degrees, increase to 6 for segmented ring
// Calculate first pair of coordinates for segment start
float sx = cos(radians(start_angle - 90));
float sy = sin(radians(start_angle - 90));
uint16_t x0 = sx * (rx - w) + x;
uint16_t y0 = sy * (ry - w) + y;
uint16_t x1 = sx * rx + x;
uint16_t y1 = sy * ry + y;
// Draw colour blocks every inc degrees
for (int i = start_angle; i < start_angle + seg * seg_count; i += inc) {
// Calculate pair of coordinates for segment end
float sx2 = cos((i + seg - 90) * DEG2RAD);
float sy2 = sin((i + seg - 90) * DEG2RAD);
int x2 = sx2 * (rx - w) + x;
int y2 = sy2 * (ry - w) + y;
int x3 = sx2 * rx + x;
int y3 = sy2 * ry + y;
u8g.drawTriangle(x0, y0, x1, y1, x2, y2);
u8g.drawTriangle(x1, y1, x2, y2, x3, y3);
// Copy segment end to sgement start for next segment
x0 = x2;
y0 = y2;
x1 = x3;
y1 = y3;
u8g.setColorIndex(org_color);
}
}
//-- Dial pointer ---------------------------------------------------------------
void drawLine(int x1, int y1, int x2, int y2) {
int DP_len = 64; // Length of Dial pointer
int DP_width = 1; // Width of Dial pointer
int DP_pos = 12; // Position of Dial pointer
int D_height = 64;
int D_center = 128/2;
//-- Dial pointer ---------------------------------------------------------------
int ypt = D_height + DP_pos - DP_len;
if (ypt < 0) ypt = 0;
for (int xg = D_center - (DP_width - 1); xg <= D_center + (DP_width - 1); xg++) {
for (int yg = (D_height + DP_pos); yg < ypt; yg++) {
u8g.setColorIndex(1);
u8g.drawPixel(xg, yg);
}
}
}