#include "SPI.h"
#include "Adafruit_GFX.h"
#include "Adafruit_ILI9341.h"
#define TFT_DC 9
#define TFT_CS 10
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC);
//--------------- I/O ----------------
int UpButton = 2;
int DownButton = 3;
int Led1 =4;
int SensorValue = A0;
//------------------------------------
//=============== Gauge =============
int GaugeCenter_Y = 100;
int GaugeStartPoint = 150;
int GaugeOffSet = 0;
float GaugeRange = 0.2346; // 250(Deg) / 1023(Bit)
float GaugeMaxPSI = 0;
float GaugeMinPSI = 0;
float PSI = 0.0782; // 80(Max Pressuer) / 1023(Bits)
//===================================
float angle2, angle3;
float X1, X2, X3, X4, X5;
float Y1, Y2, Y3, Y4, Y5;
float oX1, oX2, oX3;
float oY1, oY2, oY3;
float Rad = 0;
int ScanCycle = 50; //Program scan rate (50ms)
int TimerForMaxMin = 4000 / ScanCycle; //wait 5 sec to display Max Min
int MaxPSI = 0;
int MinPSI = 1023 * GaugeRange; //
int NeedlePosition = 0;
int NeedleAngle = 0;
int count = 0;
int StepToMove = 0;
// 320 x 240
const int ScreenHeight = 239;
const int ScreenLenght = 319;
const int PlotScale = 2; //Half Scale
const int PlotLenght = 200;
const int PlotHeight = 80 / PlotScale;
const float PlotRatio = 0.078125; // 80PSI scale devide by 1024 Bits
const int PlotScanRate = 250; // 0.5 Sec Scan Rate
const int PlotResalotion = 2; // Resalotion of scan
int MaxText_X_Position = ScreenLenght - 50;
int MaxText_Y_Position = 0;
int MinText_X_Position = 0;
int MinText_Y_Position = 0;
int GaugeCenter_X = (ScreenLenght / 2);
int PlotXLocation = (ScreenLenght / 2) - (PlotLenght / 2);
int PlotYLocation = (ScreenHeight - 4);
int GaugeRadis = (ScreenHeight - PlotHeight) / 3;
int PlotX = 0;
int PlotY = 0;
int PlotY1 = 0;
int PlotCounter = 0;
int PlotOldValue = 0;
int PlotValue = 0;
int PlotScanCounter = 0;
int PlotColor = 0;
void setup()
{
pinMode(UpButton, INPUT);
pinMode(DownButton, INPUT);
pinMode(Led1, OUTPUT);
tft.begin();
tft.setRotation(45);
Serial.begin(115200);
//------------ Drawing the smaller Lines ---------------------
for (int Count = 0; Count < 251; Count = Count + 15)
{
Rad = (Count + GaugeStartPoint) / 57.29958; // 1 Rad = 57.2958 deg
X1 = ((GaugeRadis + 10) * cos(Rad) + GaugeCenter_X);
Y1 = ((GaugeRadis + 10) * sin(Rad) + GaugeCenter_Y);
tft.drawLine (GaugeCenter_X, GaugeCenter_Y, X1, Y1, ILI9341_WHITE);
}
tft.fillCircle(GaugeCenter_X, GaugeCenter_Y, GaugeRadis - 10, ILI9341_BLACK);
//-----------------------------------------------------------
//----------------- Max and Min -----------------------------
Call_Text_Display (ILI9341_RED, 2, MaxText_X_Position, MaxText_Y_Position, "max" );
Call_Text_Display (ILI9341_RED, 2, MinText_X_Position, MinText_Y_Position, "min" );
Call_Text_Display (ILI9341_WHITE, 2, 115, (GaugeCenter_Y + GaugeRadis), "Fuel psi" );
//-----------------------------------------------------------
//---------------- Number on Gauge --------------------------
Call_Gauge_Text ( 0, (GaugeCenter_X -12), (GaugeCenter_Y - 9), 20, "0" );
Call_Gauge_Text ( 30, (GaugeCenter_X -12), (GaugeCenter_Y - 7), 25, "10" );
Call_Gauge_Text ( 60, (GaugeCenter_X - 20), (GaugeCenter_Y - 9), 19, "20" );
Call_Gauge_Text ( 90, (GaugeCenter_X - 10), (GaugeCenter_Y - 12), 17, "30" );
Call_Gauge_Text ( 120, (GaugeCenter_X - 9), (GaugeCenter_Y -17), 10, "40" );
Call_Gauge_Text ( 150, (GaugeCenter_X - 7 ), (GaugeCenter_Y - 19), 10, "50" );
Call_Gauge_Text ( 180, (GaugeCenter_X + 7), (GaugeCenter_Y - 9), 10, "60" );
Call_Gauge_Text ( 210, (GaugeCenter_X + 7), (GaugeCenter_Y - 7), 10, "70" );
Call_Gauge_Text ( 240, (GaugeCenter_X + 7), (GaugeCenter_Y - 5), 10, "80" );
//-----------------------------------------------------------
Call_Gauge_Needle (0, (GaugeRadis * 0.9), GaugeCenter_X, GaugeCenter_Y, GaugeStartPoint, ILI9341_RED);
/*
for (int i=0; i<240;){ i=i+5;
Call_Gauge_Needle (i, (GaugeRadis * 0.9), GaugeCenter_X, GaugeCenter_Y, GaugeStartPoint, ILI9341_RED);
}
for (int i=240; i>0;){ i=i-5;
Call_Gauge_Needle (i, (GaugeRadis * 0.9), GaugeCenter_X, GaugeCenter_Y, GaugeStartPoint, ILI9341_RED);
}
delay(1000);
*/
//tft.fillCircle(GaugeCenter_X, GaugeCenter_Y, 9, ILI9341_RED);
//delay(5000);
}
void loop()
{
NeedleAngle = (analogRead(SensorValue) * GaugeRange);
Call_Plotting();
if (NeedleAngle > NeedlePosition)
{
StepToMove = NeedleAngle - NeedlePosition;
if (StepToMove > 10) {count = 10;} else {count = 1;}
}
if (NeedleAngle < NeedlePosition)
{
StepToMove = NeedlePosition - NeedleAngle;
if (StepToMove > 10) {count = -10;} else {count = -1;}
}
if (NeedleAngle != NeedlePosition)
{
NeedlePosition = NeedlePosition + count;
Call_Gauge_Needle (NeedlePosition, (GaugeRadis * 0.9), GaugeCenter_X, GaugeCenter_Y, GaugeStartPoint, ILI9341_RED);
Call_Min_and_Max();
}
//----- Delay timer for displaying the Max and Min PSI
if (TimerForMaxMin > 0) { TimerForMaxMin = TimerForMaxMin - 1; }
else {digitalWrite(Led1,HIGH);}
delay(ScanCycle);
//tft.drawLine(0, 0, ScreenLenght, 0, ILI9341_RED);
//tft.drawLine(0, 0, 0, ScreenHeight, ILI9341_RED);
//tft.drawLine(0, ScreenHeight, ScreenLenght, ScreenHeight, ILI9341_RED);
//tft.drawLine(ScreenLenght, 0, ScreenLenght, ScreenHeight, ILI9341_RED);
//tft.drawLine(ScreenLenght / 2, 0, ScreenLenght / 2, ScreenHeight, ILI9341_RED);
/* //testing center
tft.drawLine(22,0,22,255,ILI9341_BLUE);
tft.drawLine(297,0,297,255,ILI9341_BLUE);
tft.drawLine(0,0,0,319,ILI9341_WHITE);
tft.drawLine(319,0,319,239,ILI9341_RED);
tft.drawLine(0,0,319,0,ILI9341_YELLOW);
tft.drawLine(0,239,319,239,ILI9341_GREEN);
tft.drawLine(0,0,319,239,ILI9341_WHITE);
tft.drawLine(319,0,0,239,ILI9341_WHITE);
tft.drawLine(159,0,159,239,ILI9341_WHITE);
tft.drawLine(110,0,110,255,ILI9341_BLUE);
tft.drawLine(209,0,209,255,ILI9341_BLUE);
*/
}
//------------------ Subroutines ---------------------
void Call_Gauge_Needle (float angle, float radis, float centerPointx, float centerPointy, float StartPoint, int Color)
{
Rad = (angle + StartPoint) / 57.29958; // 1 Rad = 57.2958 deg
X1 = (radis * cos(Rad) + centerPointx);
Y1 = (radis * sin(Rad) + centerPointy);
if (angle > 270) { angle2 = angle - 90; }
else { angle2 = angle + 90; }
Rad = (angle2 + StartPoint) / 57.29958;
X2 = ((radis * 0.1) * cos(Rad) + centerPointx );
Y2 = ((radis * 0.1) * sin(Rad) + centerPointy );
if (angle2 > 180) { angle3 = angle2 - 180; }
else { angle3 = angle2 + 180; }
Rad = (angle3 + StartPoint) / 57.29958;
X3 = ((radis * 0.1) * cos(Rad) + centerPointx );
Y3 = ((radis * 0.1) * sin(Rad) + centerPointy );
// Clear needle on the way up
Rad = (angle - 20 + StartPoint) / 57.29958;
X5 = ((radis + 6) * cos(Rad) + centerPointx );
Y5 = ((radis + 6) * sin(Rad) + centerPointy );
tft.fillTriangle(X5, Y5, X3, Y3, X1, Y1, ILI9341_BLACK);
// Clear needle on the way down
Rad = (angle + 20 + StartPoint) / 57.29958;
X5 = ((radis + 6) * cos(Rad) + centerPointx );
Y5 = ((radis + 6) * sin(Rad) + centerPointy );
tft.fillTriangle(X5, Y5, X1, Y1, X2, Y2, ILI9341_BLACK);
tft.fillTriangle(X1, Y1, X2, Y2, X3, Y3, Color);
tft.fillCircle(GaugeCenter_X, GaugeCenter_Y, 13, ILI9341_WHITE);
oX1 = X1; oY1 = Y1;
oX2 = X2; oY2 = Y2;
oX3 = X3; oY3 = Y3;
}
void Call_Text_Display (int COLOR, int SIZE, int X, int Y, char TEXT[] )
{
tft.setTextColor(COLOR); tft.setTextSize(SIZE);
tft.setCursor(X, Y); tft.print(TEXT);
}
void Call_Number_Display (int COLOR, int SIZE, int X, int Y, float TEXT )
{
tft.setTextColor(COLOR); tft.setTextSize(SIZE);
tft.setCursor(X, Y); tft.print((float)TEXT,1);
}
void Call_Gauge_Text (int Position, float centerPointx, float centerPointy, float StartPoint, char Text[])
{
Rad = (Position + GaugeStartPoint) / 57.29958; // 1 Rad = 57.2958 deg
X1 = ((GaugeRadis + StartPoint) * cos(Rad) + centerPointx);
Y1 = ((GaugeRadis + StartPoint) * sin(Rad) + centerPointy);
Call_Text_Display(ILI9341_WHITE, 2, X1, Y1, Text);
}
void Call_Min_and_Max()
{
if (TimerForMaxMin < 1)
{
if (MaxPSI < NeedleAngle) {MaxPSI = NeedleAngle;}
if (MinPSI > NeedleAngle) {MinPSI = NeedleAngle;}
tft.fillRect(MaxText_X_Position, MaxText_Y_Position, 60, 15, ILI9341_BLACK);
Call_Number_Display (ILI9341_RED, 2, MaxText_X_Position, MaxText_Y_Position, ((MaxPSI / GaugeRange) * PSI));
tft.fillRect(MinText_X_Position, MinText_Y_Position, 60, 15, ILI9341_BLACK);
Call_Number_Display (ILI9341_RED, 2, MinText_X_Position, MinText_Y_Position, ((MinPSI / GaugeRange) * PSI));
}
}
void Call_Plotting()
{
if (PlotScanCounter >= (PlotScanRate / ScanCycle))
{
if (PlotCounter > PlotLenght) { PlotCounter = 0; PlotColor = !PlotColor; }
PlotValue = (analogRead(SensorValue) * PlotRatio / PlotScale);
tft.drawRect(PlotXLocation - 1, PlotYLocation + 3, PlotLenght + 5, - PlotHeight - 3, ILI9341_BLUE);
PlotX = PlotXLocation + PlotCounter; PlotY = - PlotHeight;
tft.fillRect(PlotX, PlotYLocation, PlotResalotion, PlotY, ILI9341_BLACK); //Block to clear
if (PlotX > PlotXLocation)
{
PlotX = PlotXLocation + PlotCounter; PlotY = PlotYLocation - PlotOldValue;
PlotY1 = PlotYLocation - PlotValue;
if (PlotColor) { tft.drawLine(PlotX - PlotResalotion , PlotY, PlotX, PlotY1, ILI9341_WHITE); }
else { tft.drawLine(PlotX - PlotResalotion , PlotY, PlotX, PlotY1, ILI9341_RED); }
}
PlotCounter = PlotCounter + PlotResalotion;
PlotOldValue = PlotValue;
PlotScanCounter = 0;
}
else {PlotScanCounter = PlotScanCounter + 1;}
}
uno:A5.2
uno:A4.2
uno:AREF
uno:GND.1
uno:13
uno:12
uno:11
uno:10
uno:9
uno:8
uno:7
uno:6
uno:5
uno:4
uno:3
uno:2
uno:1
uno:0
uno:IOREF
uno:RESET
uno:3.3V
uno:5V
uno:GND.2
uno:GND.3
uno:VIN
uno:A0
uno:A1
uno:A2
uno:A3
uno:A4
uno:A5
lcd1:VCC
lcd1:GND
lcd1:CS
lcd1:RST
lcd1:D/C
lcd1:MOSI
lcd1:SCK
lcd1:LED
lcd1:MISO
pot1:GND
pot1:SIG
pot1:VCC
led1:A
led1:C