//#include <Arduino.h>
#include <U8g2lib.h>
#ifdef U8X8_HAVE_HW_SPI
#include <SPI.h>
#endif
#ifdef U8X8_HAVE_HW_I2C
#include <Wire.h>
#endif
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R1, /* reset=*/ U8X8_PIN_NONE, /* clock=*/ 8, /* data=*/ 9); // ESP32 Thing, HW I2C with pin remapping
int value_fuel;
int value_watertemp;
int value_rpm;
int value_rpm_gauge_angle;
int value_rpm_gauge_angle_rev;
const uint8_t helvR08[913] U8G2_FONT_SECTION("helvR08") =
"_\0\2\2\4\4\3\4\5\11\12\0\376\6\377\6\377\1#\2i\3t \5\0L\11!\7aE"
"\311H\1\42\7\63\335I\262\2#\12U\304Z\65T\65T\5$\13t\275j\34\31i\64b\4%"
"\13f\305\313\352R\31%\325\65&\14eE[\6)\203\250\222\231\4'\6!t\211\0(\7r\275"
"\231\352\14)\10r\275IL-\5*\7\63\325YZ\11+\13U\305jFq\310\214\42\0,\7\62"
"\64YR\0-\6\22\324\211\0.\6\21EI\0/\10r=Y\245Z\0\60\11d\305\232\212\316\244"
"\0\61\7b\306\332\352\0\62\12d\305\232\212\31\304r\4\63\11c\306\212\6\33\304\5\64\13d\305j"
"\6Q\215\230A\2\65\11c\306\312\210\32\304\5\66\13d\305\332\310`E\231\24\0\67\13d\305\312\310"
" \326 \203\10\70\13d\305\232\212IE\231\24\0\71\13d\305\232\212\62m\220\24\0:\6AEI"
"\14;\10b\64Y\206I\1<\11S\305j\252A\6\1=\7\63M\312\6\3>\11S\306J\6\31"
"\244\22\77\11S\306\212\6)\303\4@\17x\275\354\220\31\272b\222#erd\0A\14eEkF"
"\31\244\270\62\320 B\13dF\313\212#E\71\22\0C\14eE\333\312@\243\214\62H\13D\15e"
"E\313H\31h\240\201\6C\1E\13dF\313\320`e\220\301\10F\13d\306\312\320`e\220A\6"
"G\14eE\333\312(n\240AZ\0H\15eEK\6\32\34\31h\240A\0I\6aE\311\1J"
"\10cEjSU\0K\12dFKTI\256(\3L\7c\306J\354\34M\14e\306K\6k%"
"\225TR\5N\14eEK\6S%\225\344\6\1O\14eE\333\312@\3\15\64H\13P\13dF"
"\313\212r\244\14\62\0Q\17\205\65\333\312@\3\15\64H\33d\230\0R\12dF\313\212r\244(\3"
"S\13dF\333\310`\243\14F\2T\10cE\312\212]\0U\15eEK\6\32h\240\201\6i\1"
"V\10dFK\364\212\21W\15g\305K\214\62\312\312\254A\214\0X\12dFK\224I\252(\3Y"
"\14eE\213L\61\305\250AF\21Z\12dF\313\310 \266\301\10[\7r=\311\352\22\134\10r<"
"I*S\3]\7r<\211\352\32^\11\65\324j\6\251\6\1_\6\25\274\312\20`\6\42\364I\14"
"a\11TE\212FiU*b\13t\305J\6\31\254h\216\4c\10SE\332\254\201\0d\13t\305"
":\310 \215h\246\1e\10SEZ\65\64\20f\11s\305iJ+\266\0g\13d\275\332\210\62m"
"\220\24\0h\12t\305J\6\31\254\350\14i\7qEI\32\2j\11\222\64Y\6\251K\1k\11s"
"EJ\254\226J*l\6qE\311\21m\13UE\313H\225J*\251\2n\10T\305\312\212\316\0o"
"\11T\305\232\212fR\0p\11d\275\312\212\346H\31q\11d\275\332\210f\332 r\10S\305IZ"
"\261\4s\10SE\332\6r\1t\11s\305YL+\266\0u\10SEJr%\1v\10T\305J"
"t\305\10w\13UEKJ*\251\316\224\0x\11T\305J\224IE\31y\11d=J\64\223\254\1"
"z\10SE\312L\345\0{\11s<i\212I\326 |\6q=\311\21}\13s<I\6\61\252\230"
"\42\0~\7%U[T\12\0\0\0\4\377\377\0";
// small font from the u8g2 library, digits only
const u8g2_uint_t digit_small[145] U8G2_FONT_SECTION("digit_small") = {
0,4,4,0,4,5,0,0,0,0,45,57,0,9,0,5,
0,0,0,0,4,0,0,0,0,0,4,0,0,0,0,0,
4,0,0,3,5,5,4,0,4,96,160,160,160,192,3,5,
5,4,0,4,64,192,64,64,224,3,5,5,4,0,4,192,
32,64,128,224,3,5,5,4,0,4,224,32,64,32,192,3,
5,5,4,0,4,128,160,224,32,32,3,5,5,4,0,4,
224,128,224,32,192,3,5,5,4,0,4,64,128,192,160,224,
3,5,5,4,0,4,224,32,32,64,64,3,5,5,4,0,
4,96,160,64,160,192,3,5,5,4,0,4,224,160,96,32,
64};
/*
Fontname: Tahoma
Copyright:
Capital A Height: 0, '1' Height: 13
Calculated Max Values w= 7 h=13 x= 1 y=16 dx= 9 dy= 0 ascent=24 len=13
Font Bounding box w=11 h=12 x= 0 y=11
Calculated Min Values x= 0 y= 0 dx= 0 dy= 0
Pure Font ascent =13 descent= 0
X Font ascent =13 descent= 0
Max Font ascent =24 descent= 0
*/
const u8g2_uint_t tah[238] U8G2_FONT_SECTION("tah") = {
0,11,12,0,11,13,0,0,0,0,45,57,0,24,0,13,
0,3,1,1,4,0,16,224,1,1,1,2,0,11,128,3,
11,11,4,0,11,32,32,32,64,64,64,64,64,128,128,128,
7,13,13,9,0,11,56,68,130,130,130,130,130,130,130,130,
130,68,56,5,13,13,9,1,11,224,32,32,32,32,32,32,
32,32,32,32,32,248,7,13,13,9,0,11,56,68,130,130,
130,2,4,8,16,32,64,128,254,7,13,13,9,0,11,56,
68,130,130,2,4,56,4,2,130,130,68,56,7,13,13,9,
0,11,8,8,16,16,32,34,66,66,130,254,2,2,2,7,
13,13,9,0,11,252,128,128,128,128,248,4,2,130,130,130,
68,56,7,13,13,9,0,11,56,68,130,128,128,184,196,130,
130,130,130,68,56,6,13,13,9,1,11,252,4,8,8,8,
16,16,32,32,64,64,64,128,7,13,13,9,0,11,56,68,
130,130,130,68,56,68,130,130,130,68,56,7,13,13,9,0,
11,56,68,130,130,130,130,70,58,2,2,130,68,56};
const u8g2_uint_t rpm_gauge_piece_01[] U8X8_PROGMEM = {
B11111100, B00000000,
B11111110, B00000000,
B11111110, B00000000,
B11111110, B00000000,
B01111110, B00000000,
B01111111, B00000000,
B01111111, B00000000,
B01111111, B00000000,
B00111111, B10000000,
B00111111, B10000000,
B00111111, B11000000,
B00011111, B11100000,
B00011111, B11100000,
B00001111, B11110000,
B00000111, B11111000,
B00000111, B11111000,
B00000011, B11110000,
B00000001, B11100000,
B00000001, B11000000,
B00000000, B10000000
};
const u8g2_uint_t rpm_gauge_piece_02[] U8X8_PROGMEM = {
B00000000, B01000000,
B00000000, B11100000,
B00000001, B11110000,
B00000001, B11111000,
B00000011, B11111100,
B00000111, B11111100,
B00000111, B11111000,
B00001111, B11110000,
B00011111, B11100000,
B00011111, B11100000,
B00111111, B11000000,
B00111111, B10000000,
B00111111, B10000000,
B01111111, B00000000,
B01111111, B00000000,
B01111111, B00000000,
B01111110, B00000000,
B11111110, B00000000,
B11111110, B00000000,
B11111110, B00000000,
B11111100, B00000000,
B11111100, B00000000
};
const u8g2_uint_t rpm_gauge_piece_03[] U8X8_PROGMEM = {
B00000000, B00000011, B11000000,
B00000000, B00111111, B11000000,
B00000001, B11111111, B11000000,
B00000111, B11111111, B11000000,
B00001111, B11111111, B11000000,
B00111111, B11111111, B11000000,
B01111111, B11111111, B10000000,
B11111111, B11111000, B00000000,
B01111111, B11000000, B00000000,
B00111111, B00000000, B00000000,
B00011110, B00000000, B00000000,
B00001000, B00000000, B00000000
};
const u8g2_uint_t rpm_gauge_piece_04[] U8X8_PROGMEM = {
B11111000, B00000000, B00000000,
B11111111, B10000000, B00000000,
B11111111, B11110000, B00000000,
B11111111, B11111100, B00000000,
B11111111, B11111110, B00000000,
B11111111, B11111111, B10000000,
B00111111, B11111111, B11000000,
B00000011, B11111111, B11110000,
B00000000, B01111111, B11111000,
B00000000, B00011111, B11110000,
B00000000, B00001111, B11100000,
B00000000, B00000011, B11000000,
B00000000, B00000001, B10000000
};
const u8g2_uint_t rpm_gauge_piece_05[] U8X8_PROGMEM = {
B00001100, B00000000,
B00011100, B00000000,
B00111110, B00000000,
B01111111, B00000000,
B11111111, B00000000,
B01111111, B10000000,
B00111111, B11000000,
B00111111, B11000000,
B00011111, B11100000,
B00001111, B11100000,
B00001111, B11100000,
B00000111, B11110000,
B00000111, B11110000,
B00000111, B11110000,
B00000011, B11110000,
B00000011, B11111000,
B00000011, B11111000,
B00000011, B11111000,
B00000001, B11111000,
B00000001, B11111000
};
const u8g2_uint_t rpm_gauge_piece_06[] U8X8_PROGMEM = {
B00000001, B11111000,
B00000011, B11111000,
B00000011, B11111000,
B00000011, B11111000,
B00000011, B11110000,
B00000111, B11110000,
B00000111, B11110000,
B00000111, B11110000,
B00001111, B11100000,
B00001111, B11100000,
B00011111, B11100000,
B00111111, B11000000,
B00111111, B11000000,
B01111111, B10000000,
B11111111, B00000000,
B11111111, B00000000,
B01111110, B00000000,
B00111100, B00000000,
B00011100, B00000000,
B00001000, B00000000
};
const unsigned char mph_bits[] PROGMEM = {
0x00, 0xd1, 0x49, 0x00, 0x00, 0x5b, 0x4a, 0x00, 0x00, 0x55, 0x4a, 0x00, 0x00, 0xd1, 0x79, 0x00,
0x02, 0x51, 0x48, 0x20, 0x0c, 0x51, 0x48, 0x18, 0x70, 0x00, 0x00, 0x07, 0x80, 0x07, 0xf0, 0x00,
0x00, 0xf8, 0x0f, 0x00
};
long display_value = 65000;
float angle = 0;
int potentiometer_pin = 2;
int smooth_movement = 0;
void draw(void) {
// graphic commands to redraw the complete screen should be placed here
u8g2.setColorIndex(1); // white
//int ro = 3;
/*
// draw gauge from 6 pieces
if (angle >= 45 ) {
u8g2.drawXBMP( 3, 32, 2, 20, rpm_gauge_piece_01);
}
if (angle >= 90) {
u8g2.drawXBMP( 3, 10, 2, 22, rpm_gauge_piece_02);
}
if (angle >= 135) {
u8g2.drawXBMP(13, 3, 3, 12, rpm_gauge_piece_03);
}
if (angle >= 180) {
u8g2.drawXBMP(31, 3, 3, 13, rpm_gauge_piece_04);
}
if (angle >= 225) {
u8g2.drawXBMP(47,12, 2, 20, rpm_gauge_piece_05);
}
if (angle >= 270) {
u8g2.drawXBMP(47,32, 2, 20, rpm_gauge_piece_06);
}
*/
u8g2.setColorIndex(1); // black
// 2021 new version of triangle - calculated based on the needle position
int needle_left_x_center = 31;
int needle_left_y_center = 31;
float needle_left_x_start = -sin(angle * 3.141592654 / 180.0)*17;
float needle_left_y_start = cos(angle * 3.141592654 / 180.0)*17;
float needle_left_x_end = -sin(angle * 3.141592654 / 180.0)*32;
float needle_left_y_end = cos(angle * 3.141592654 / 180.0)*32;
needle_left_x_start += 31;
needle_left_y_start += 31;
needle_left_x_end += 31;
needle_left_y_end += 31;
needle_left_x_start = (int)(needle_left_x_start+0.5);
needle_left_y_start = (int)(needle_left_y_start+0.5);
needle_left_x_end = (int)(needle_left_x_end+0.5);
needle_left_y_end = (int)(needle_left_y_end+0.5);
//-------
float angle2 = (ceil((angle+1)/45)*45)+5;
float needle_left_x_end2 = -sin((angle2) * 3.141592654 / 180.0)*32;
float needle_left_y_end2 = cos((angle2) * 3.141592654 / 180.0)*32;
needle_left_x_end2 += 31;
needle_left_y_end2 += 31;
needle_left_x_end2 = (int)(needle_left_x_end2+0.5);
needle_left_y_end2 = (int)(needle_left_y_end2+0.5);
u8g2.drawTriangle(needle_left_x_center, needle_left_y_center, needle_left_x_end, needle_left_y_end, needle_left_x_end2, needle_left_y_end2);
// white
u8g2.setColorIndex(1);
// PIXEL dots around
u8g2.drawPixel( 11, 51);
u8g2.drawPixel( 7, 45);
u8g2.drawPixel( 4, 38);
u8g2.drawPixel( 3, 31);
u8g2.drawPixel( 4, 24);
u8g2.drawPixel( 7, 17);
u8g2.drawPixel( 11, 11);
u8g2.drawPixel(17, 7);
u8g2.drawPixel(24, 4);
u8g2.drawPixel(31, 3);
u8g2.drawPixel(38, 4);
u8g2.drawPixel(45, 7);
u8g2.drawPixel(51, 11);
u8g2.drawPixel(55, 17);
u8g2.drawPixel(58, 24);
u8g2.drawPixel(59, 31);
u8g2.drawPixel(58, 38);
u8g2.drawPixel(55, 45);
u8g2.drawPixel(51, 51);
u8g2.setColorIndex(1);
//u8g2.setFont(tah);
// get width of the displaye string
int speed_mph = map(angle, 45, 315, 0, 320);
speed_mph = (int)speed_mph;
String aStupidWasteOfResource = String(speed_mph);
char copy[5];
aStupidWasteOfResource.toCharArray(copy, 5);
int w = u8g2.getStrWidth(copy);
// center = 27, 32
// calculate left side of speed number
int speed_pos_x = 27-(w/2);
u8g2.setCursor(speed_pos_x+5, 37+11);
//u8g2.drawPixel(16, 37);
u8g2.print((int)speed_mph);
char mileage[20];
snprintf(mileage, sizeof(mileage), "%06ld", display_value);
int mileage_length = strlen(mileage); // get length of the mileage string
//digit_small
//u8g2.setFont(digit_small);
u8g2.setCursor(16+2+3, 37+9+2);
u8g2.print(mileage);
u8g2.setBitmapMode(false /* transparent */);
u8g2.drawBitmap(0, 0, 32, 9, mph_bits);
/*
u8g2.setFont(helvR08_font);
u8g2.setCursor(10, 60);
u8g2.print("SENSOR 1");
*/
//SECOND GAUGE////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
u8g2.setColorIndex(1); // white
int ro = 65;
/*
// draw gauge from 6 pieces
if (angle >= 45 ) {
u8g2.drawXBMP( 3, ro + 32, 2, 20, rpm_gauge_piece_01);
}
if (angle >= 90) {
u8g2.drawXBMP( 3, ro +10, 2, 22, rpm_gauge_piece_02);
}
if (angle >= 135) {
u8g2.drawXBMP(13, ro +3, 3, 12, rpm_gauge_piece_03);
}
if (angle >= 180) {
u8g2.drawXBMP(31, ro +3, 3, 13, rpm_gauge_piece_04);
}
if (angle >= 225) {
u8g2.drawXBMP(47,ro +12, 2, 20, rpm_gauge_piece_05);
}
if (angle >= 270) {
u8g2.drawXBMP(47,ro +32, 2, 20, rpm_gauge_piece_06);
}
*/
u8g2.setColorIndex(0); // black
// 2021 new version of triangle - calculated based on the needle position
needle_left_x_center = 31;
needle_left_y_center = ro +31;
needle_left_x_start = -sin(angle * 3.141592654 / 180.0)*17;
needle_left_y_start = cos(angle * 3.141592654 / 180.0)*17;
needle_left_x_end = -sin(angle * 3.141592654 / 180.0)*32;
needle_left_y_end = cos(angle * 3.141592654 / 180.0)*32;
needle_left_x_start += 31;
needle_left_y_start += ro +31;
needle_left_x_end += 31;
needle_left_y_end += ro +31;
needle_left_x_start = (int)(needle_left_x_start+0.5);
needle_left_y_start = (int)(needle_left_y_start+0.5);
needle_left_x_end = (int)(needle_left_x_end+0.5);
needle_left_y_end = (int)(needle_left_y_end+0.5);
//-------
angle2 = (ceil((angle+1)/45)*45)+5;
needle_left_x_end2 = -sin((angle2) * 3.141592654 / 180.0)*32;
needle_left_y_end2 = cos((angle2) * 3.141592654 / 180.0)*32;
needle_left_x_end2 += 31;
needle_left_y_end2 += ro + 31;
needle_left_x_end2 = (int)(needle_left_x_end2+0.5);
needle_left_y_end2 = (int)(needle_left_y_end2+0.5);
u8g2.drawTriangle(needle_left_x_center, needle_left_y_center, needle_left_x_end, needle_left_y_end, needle_left_x_end2, needle_left_y_end2);
// white
u8g2.setColorIndex(1);
// PIXEL dots around
u8g2.drawPixel( 11, ro + 51);
u8g2.drawPixel( 7, ro + 45);
u8g2.drawPixel( 4, ro + 38);
u8g2.drawPixel( 3, ro + 31);
u8g2.drawPixel( 4, ro + 24);
u8g2.drawPixel( 7, ro + 17);
u8g2.drawPixel( 11, ro + 11);
u8g2.drawPixel(17, ro + 7);
u8g2.drawPixel(24, ro + 4);
u8g2.drawPixel(31, ro + 3);
u8g2.drawPixel(38, ro +4);
u8g2.drawPixel(45, ro +7);
u8g2.drawPixel(51, ro +11);
u8g2.drawPixel(55, ro +17);
u8g2.drawPixel(58, ro +24);
u8g2.drawPixel(59, ro +31);
u8g2.drawPixel(58, ro +38);
u8g2.drawPixel(55, ro +45);
u8g2.drawPixel(51, ro +51);
u8g2.setColorIndex(1);
//u8g2.setFont(tah);
// get width of the displaye string
speed_mph = map(angle, 45, 315, 0, 320);
speed_mph = (int)speed_mph;
aStupidWasteOfResource = String(speed_mph);
//char copy[5];
aStupidWasteOfResource.toCharArray(copy, 5);
w = u8g2.getStrWidth(copy);
// center = 27, 32
// calculate left side of speed number
speed_pos_x = 27-(w/2);
u8g2.setCursor(speed_pos_x+5, ro +37+11);
//u8g2.drawPixel(16, 37);
u8g2.print((int)speed_mph);
//char mileage[20];
snprintf(mileage, sizeof(mileage), "%ld", display_value);
mileage_length = strlen(mileage); // get length of the mileage string
//digit_small
u8g2.setFont(helvR08);
u8g2.setCursor(16+2+3, ro +37+9+2);
u8g2.print(mileage);
u8g2.setColorIndex(1);
u8g2.setFont(helvR08);
u8g2.setCursor(10, 60);
u8g2.print("SENSOR 1");
u8g2.setCursor(10, 125);
u8g2.print("SENSOR 2");
}
void setup(void) {
u8g2.begin();
u8g2.setContrast(255); // set display contrast/brightness
analogReadResolution(12);
Serial.begin(115200);
}
void loop(void) {
unsigned long currentMillis = millis();
// picture loop
u8g2.firstPage();
do {
draw();
// u8g.nextPage();
} while( u8g2.nextPage() );
// rebuild the picture after some delay
//delay(1);
display_value++;
int sensorValue = analogRead(1);
sensorValue = constrain(sensorValue, 0, 4096);
//angle = constrain(sensorValue /2, 45, 315);
angle = map(sensorValue, 0, 4096, 45, 315); // remap the potentiometer value from 0-670 to 45-315°. It does not go all the way to 1024 because I´m only using 3.3V
value_fuel = map(sensorValue, 0, 4096, 0, 100); // fuel value, for now, take everything from one potentiometer
value_watertemp = map(sensorValue, 0, 4096, 0, 100); // water temperature value, for now, take everything from one potentiometer
value_rpm = map(sensorValue, 0, 4096, 0, 8000); // RPM value
value_rpm_gauge_angle = map(sensorValue, 0, 4096, 315, 45); // RPM gauge angle value
value_rpm_gauge_angle_rev = map(sensorValue, 0, 4096, 45, 315);
unsigned long finalMillis = millis() - currentMillis;
Serial.print("Done all task at = ");
Serial.println(finalMillis);
}