// simple project using Arduino UNO and 128x128 SD1107 OLED Display to show static image of compass
// created by upir, 2023
// youtube channel: https://www.youtube.com/upir_upir
// YOUTUBE VIDEO: https://youtu.be/G1C09eoJ07c
// YOUTUBE VIDEO CLOCK: https://youtu.be/srgsBWHSNSQ
// links from the video:
// 128x128 SH1107 OLED Display: https://s.click.aliexpress.com/e/_DdOCQHj
// 128x64 SSD1306 OLED Display: https://s.click.aliexpress.com/e/_DCKdvnh
// Arduino UNO: https://s.click.aliexpress.com/e/_AXDw1h
// Arduino breadboard prototyping shield: https://s.click.aliexpress.com/e/_ApbCwx
// Photopea (online Photoshop-like tool): https://www.photopea.com/
// u8g2 documentation: https://github.com/olikraus/u8g2/wiki/u8gvsu8g2
// Image2cpp (convert array to image): https://javl.github.io/image2cpp/
// Related videos:
// Arduino OLED Clock Project: https://youtu.be/srgsBWHSNSQ
// Arduino Parking Sensor - https://youtu.be/sEWw087KOj0
// Turbo pressure gauge with Arduino and OLED display - https://youtu.be/JXmw1xOlBdk
// Arduino Car Cluster with OLED Display - https://youtu.be/El5SJelwV_0
// Knob over OLED Display - https://youtu.be/SmbcNx7tbX8
// Arduino + OLED = 3D ? - https://youtu.be/kBAcaA7NAlA
// Arduino OLED Gauge - https://youtu.be/xI6dXTA02UQ
// Smaller & Faster Arduino - https://youtu.be/4GfPQoIRqW8
// Para la conversion XBMP utilizar la pagina:
// https://javl.github.io/image2cpp/
// Y con la libreria U6g2, marcar swap bits in byte , al final.
#include <Arduino.h>
#include <U8g2lib.h> // u8g2 library for drawing on OLED display - needs to be installed in Arduino IDE first
#include <Wire.h> // wire library for IIC communication with the OLED display
#include "brujula.h" // image generated using the image2cpp tool is stored in a separate header file
//#include "cursor.h" // image generated using the image2cpp tool is stored in a separate header file
// if you see the image offset on the display, try uncommenting the "PIMORONI" version of the display, see video for more details
//U8G2_SH1107_128X128_1_HW_I2C u8g2(U8G2_R0); // final display, 128x128px [page buffer, size = 128 bytes], HW IIC connection
U8G2_SH1107_128X128_2_HW_I2C u8g2(U8G2_R0); // final display, 128x128px [page buffer, size = 256 bytes], HW IIC connection
//U8G2_SH1107_PIMORONI_128X128_2_HW_I2C u8g2(U8G2_R0); //[page buffer, size = 256 bytes], HW IIC connection
//U8G2_SH1106_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE); // 64x128px OLED 1,3 i2c display, [full
// IIC connection of the OLED display and Arduino UNO
// +5V > +5V
// GND > GND
// SCL (serial clock) > A5 or SCL
// SDA (serial data) > A4 or SDA
#define DEG2RAD 0.0174532925
long unsigned int startMillis;
short unsigned int iter = 0; // used to calculate the frames per second (FPS)
int angle = 0;
int grados = 0;
int center_x = 64; // display x center, 64px for the 128x128px display
int center_y = 64; // display y center, 64px for the 128x128px display
int hand_dot_size = 3; // tamaño del circulo detras de la aguja
void setup(void) { // Arduino setup
u8g2.begin(); // begin the u8g2 library
u8g2.setContrast(255); // set display contrast/brightness
pinMode(A0, INPUT); // set the analog input pin A0 as input
}
void loop(void) { // main Arduino loop
grados = map(analogRead(A0), 0, 1023, 0, 360); // use the potentiometer to set the degrees between 0-360°
u8g2.firstPage(); // select the first page of the display (page is 128x8px), since we are using the page drawing method of the u8g2 library
do { // draw
u8g2.drawXBMP(0, 0, 128, 128, epd_bitmap_brujula); // draw fullscreen 128x128px image (drawn in Photopea, generated using image2cpp)
draw_hand_thin(grados -1, 60, 24); // second hand
} while ( u8g2.nextPage() ); // go over all the pages until the whole display is updated
}
// draw thin hand = Dibujar cursor de la Brujula
void draw_hand_thin (int hand_angle, int hand_lenght_long, int hand_legth_short) {
float xpos;
float ypos;
float xpos2;
float ypos2;
float tri_xoff;
float tri_yoff;
// calculate starting and ending position of the second hand
xpos = round(center_x + sin(radians(hand_angle)) * hand_lenght_long); // calculate x pos based on angle and radius
ypos = round(center_y - cos(radians(hand_angle)) * hand_lenght_long); // calculate y pos based on angle and radius
xpos2 = round(center_x + sin(radians(hand_angle + 180)) * hand_legth_short); // calculate x pos based on angle and radius
ypos2 = round(center_y - cos(radians(hand_angle + 180)) * hand_legth_short); // calculate y pos based on angle and radius
tri_xoff = round( sin(radians(hand_angle + 90)) * hand_dot_size); // Puntos para crear un triangulo X
tri_yoff = round(-cos(radians(hand_angle + 90)) * hand_dot_size); // Puntos para crear un triangulo Y
u8g2.drawTriangle(xpos2 + tri_xoff, ypos2 +tri_yoff, xpos2 - tri_xoff, ypos2 - tri_yoff, xpos, ypos); // dibujar punta flecha
u8g2.drawLine(xpos, ypos, xpos2, ypos2); // draw the main line
u8g2.setDrawColor(0); // black color
//u8g2.drawDisc(xpos2, ypos2, 3); // draw small filled black circle
u8g2.drawDisc(center_x, center_y, 3); // draw small filled black circle
u8g2.setDrawColor(1); // white color
//u8g2.drawCircle(xpos2, ypos2, 3, U8G2_DRAW_ALL); // draw small outline white circle
u8g2.drawCircle(center_x, center_y, 3, U8G2_DRAW_ALL); // draw small outline white circle
//u8g2.setFont(u8g2_font_ncenB14_tr);
u8g2.setFont(u8g2_font_ncenB10_tn);
u8g2.setCursor(48, 50);
u8g2.print(grados);
}