/*
 * VoltBar.ino ver. 1.18.21
 * ------------------------
 * This program provides bar graph (vertical orientations) and measure Volt from 0 - 15 Volt on Port A15
 * -----------------------------------------------------------------------------------------------------
 *
 * It requires and Arduino Mega (or UNO) and an Adafruit 3.5" TFT 240x320 + Touchscreen Breakout Board
 * https://learn.adafruit.com/adafruit-2-4-color-tft-touchscreen-breakout?view=all
 * 
 * Adafruit libraries
 * https://github.com/adafruit/Adafruit_HX8357_Library/archive/master.zip
 * https://github.com/adafruit/Adafruit-GFX-Library/archive/master.zip
 *
 * Optional touch screen libraries (Touch-Screen is not in use in this program)
 * https://github.com/adafruit/Touch-Screen-Library/archive/master.zip
 *
 ******************************************************************************
 * All the mcufriend.com UNO shields have the same pinout.
 * i.e. control pins A0-A4.  Data D2-D9.  microSD D10-D13.
 * Touchscreens are normally A1, A2, D7, D6 but the order varies
 *
 * This demo should work with most Adafruit TFT libraries
 * If you are not using a shield,  use a full Adafruit constructor()
 * e.g. Adafruit_TFTLCD tft(LCD_CS, LCD_CD, LCD_WR, LCD_RD, LCD_RESET);
 ******************************************************************************
 *
 * Revisions
 * rev     date        author          description
 * 1       12-19-2015  kasprzak        initial creation
 * 2       21-01-2018  OZ6YM, Palle    Special edition (Volt-BAR)
 * 
 * This pin setting will also operate the SD card
 * Pin settings
 *
 * Arduino   device
 * 5V        Vin
 * GND       GND
 * A0
 * A1
 * A2         Y+ (for touch screen use)
 * A3         X- (for touch screen use)
 * A4
 * A5
 * 1
 * 2
 * 3
 * 4         CCS (42 for mega)
 * 5
 * 6
 * 7         Y- (44 for mega)
 * 8         X+ (46 for mega)
 * 9         DC (48 on mega * change define)
 * 10        CS (53 for mega * change define)
 * 11        MOSI (51 for mega)
 * 12        MISO  (50 for mega)
 * 13        CLK (SCK) (52 for mega)
 * 44        Y- (for touch screen only)
 * 46        X+ (for touch screen only)
 * 48        DC
 * A15       READS the voltage on A15 ( MEGA2560 ) but could use A0 on UNO
 * SDA
 * SLC
 */
#include <MCUFRIEND_kbv.h>         // https://github.com/prenticedavid/MCUFRIEND_kbv
long INPUTPORT = A15;                   // In use of a MEGA2560 
//
// COLOR-PICKER is all possible colors om MCUFRIEND-Display
//---------------------------------------------------------
// http://www.barth-dev.de/online/rgb565-color-picker/
#define LTBLUE    0xB6DF
#define LTTEAL    0xBF5F
#define LTGREEN   0xBFF7
#define LTCYAN    0xC7FF
#define LTRED     0xFD34
#define LTMAGENTA 0xFD5F
#define LTYELLOW  0xFFF8
#define LTORANGE  0xFE73
#define LTPINK    0xFDDF
#define LTPURPLE  0xCCFF
#define LTGREY    0xE71C
#define BLUE      0x001F
#define TEAL      0x0438
#define GREEN     0x07E0
#define CYAN      0x07FF
#define RED       0xF800
#define MAGENTA   0xF81F
#define YELLOW    0xFFE0
#define ORANGE    0xFD20
#define PINK      0xF81F
#define PURPLE    0x801F
#define GREY      0xC618
#define WHITE     0xFFFF
#define BLACK     0x0000
#define DKBLUE    0x000D
#define DKTEAL    0x020C
#define DKGREEN   0x03E0
#define DKCYAN    0x03EF
#define DKRED     0x6000
#define DKMAGENTA 0x8008
#define DKYELLOW  0x8400
#define DKORANGE  0x8200
#define DKPINK    0x9009
#define DKPURPLE  0x4010
#define DKGREY    0x4A49
int BACKGND = DKGREY;           // Default Background color
int MyBar = BLUE;
double volts;
double bvolts;
boolean graph_1 = true;
boolean graph_2 = true;
boolean graph_3 = true;
boolean graph_4 = true;
boolean graph_5 = true;
boolean graph_6 = true;
boolean graph_7 = true;
uint16_t g_identifier;
// NOT all variables is in use or this program
// -------------------------------------------
struct grafix {         // Graph structure declaration
  int x;                // upper left coordinate horizontal
  int y;                // upper left coordinate vertical
  int w;                // width of graph
  int h;                // height of graph
  float minX;           // minimum X graph value, can be negative
  float maxX;           // maximum X graph value
  float minY;           // minimum Y
  float maxY;           // maximum Y
  float xInc;           // scale division between lo and hi
  float yInc;           // y increment
  float currentValue;   // Current value
  int digitTotal;       // total digits displayed, not counting decimal point
  int decimals;         // digits after decimal point
  int barColor;         // Color for bar
  int voidColor;        // Background color in bar chart
  int backBar;          // Background bar color
  int border;           // Border color
  int textColor;        // Color for text
  int backFill;         // Background color for entire graph
  char label[30];       // Label text
} myG;                  // NOT IN USE
MCUFRIEND_kbv tft;      // Defining tft
int flag;
/*************************************************/
void DrawBarChartV( double x , double y , double w, double h , double loval , double hival , double inc , double curval ,  int dig , int dec, unsigned int barcolor, unsigned int voidcolor, unsigned int bordercolor, unsigned int textcolor, unsigned int backcolor, String label, boolean & redraw);
/*************************************************/
void setup(void) {
//  Serial.begin(9600);
  g_identifier = tft.readID();    // Get TFT ID  3.2" = 0x9341
  tft.begin(g_identifier);
  Serial.print("TFT ID "); Serial.println(g_identifier, HEX);
  
  tft.begin(g_identifier);
  tft.fillScreen(BACKGND);
  tft.setRotation(1);
  pinMode(INPUTPORT, INPUT);
}
//*******************************************************************************************************
void loop() 
{
  bvolts = analogRead(INPUTPORT);
  DrawBarChartV( 305,  40, 10, 190, 0, 1500 , 100, bvolts , 4 , 0, BLUE, DKGREEN, BLUE, WHITE, BLACK, "Volt", graph_1);
}
/********************************************************************************************************
  This method will draw a vertical bar graph for single input
  it has a rather large arguement list and is as follows
  x = position of bar graph (lower left of bar)
  y = position of bar (lower left of bar
  w = width of bar graph
  h =  height of bar graph (does not need to be the same as the max scale)
  loval = lower value of the scale (can be negative)
  hival = upper value of the scale
  inc = scale division between loval and hival
  curval = date to graph (must be between loval and hival)
  dig = format control to set number of digits to display (not includeing the decimal)
  dec = format control to set number of decimals to display (not includeing the decimal)
  barcolor = color of bar graph
  voidcolor = color of bar graph background
  bordercolor = color of the border of the graph
  textcolor = color of the text
  backcolor = color of the bar graph's background
  label = bottom lable text for the graph
  redraw = flag to redraw display only on first pass (to reduce flickering)
******************************************************************************************/
void DrawBarChartV( double x , double y , double w, double h , double loval , double hival , double inc , double curval ,  int dig , int dec, unsigned int barcolor, unsigned int voidcolor, unsigned int bordercolor, unsigned int textcolor, unsigned int backcolor, String label, boolean & redraw)
{
  double stepval, range;
  double my, level;
  double i, data;
  
  // draw the border, scale, and label once
  // avoid doing this on every update to minimize flicker
  if (redraw == true) {
    redraw = false;
    tft.drawRect(x , y , w , h , bordercolor);
    // step val basically scales the hival and low val to the height
    // deducting a small value to eliminate round off errors
    // this val may need to be adjusted
    stepval = ( inc) * (double (h) / (double (hival - loval))) - .001;
//*********************************************************************
    tft.setTextSize(1);
    tft.setTextColor(textcolor, BACKGND);
        
    for (i = 0; i <= h; i += stepval) {
      my =  y + h + i -190;
      tft.drawFastHLine(x-5, my,  5, textcolor);
      // draw vertical skala-labels
      //----------------------------
      tft.setCursor(x + w -40, my - 3 );
      data = (hival - ( i * (inc / stepval)))/100;
      tft.println(Format(data, dig, dec));    //Skala lodret
      } //******* END of for ******************************************
    } //********* END of if  ******************************************
  // compute level of bar graph that is scaled to the  height and the hi and low vals
  // this is needed to accompdate for +/- range
  level = map( bvolts, 0, 1023, 0, 188 );
  if ( level < 102 ) { MyBar = ORANGE; } // level < 6,65 volt 
  if ( level > 102 ) { MyBar = BLUE;   } // level OK!
  if ( level < 88  ) { MyBar = RED;    } // level < 8,00 volt
  // draw the bar graph
  // write a upper and lower bar to minimize flicker cause by blanking out bar and redraw on update
  tft.fillRect(x, y, w, h - level, GREEN);
  tft.fillRect(x, y + 190 - level, w, level, MyBar);
  // write the current value
  tft.setTextColor(textcolor, BACKGND);
  tft.setTextSize(2);
  tft.setCursor(x +30 , y - h - 23);
  tft.println(Format(curval, dig, dec));   // talrække lodret
} // ******************** END of DrawBarChartV ******************
//
/****************************************************************
  Purpose: To format any double number.
****************************************************************/
String Format(double val, int dec, int dig )
{
  int addpad = 0;
  char sbuf[20];
  String condata = (dtostrf(val, dec, dig, sbuf));
  int slen = condata.length();
  
  for ( addpad = 1; addpad <= dec + dig - slen; addpad++)
  {
    condata = " " + condata;
  }
  return (condata);
} // ****************** END of Format **************************
//
// ******************** END of Program VoltBar *****************
//