#include <TFT_eSPI.h>
#include <SPI.h>       // this is needed for display
#include <Wire.h>      // this is needed for FT6206
#include <Adafruit_FT6206.h>
#include <WiFi.h>
#include <HTTPClient.h>
#include <Arduino_JSON.h>
#include "Free_Fonts.h" 

// The FT6206 uses hardware I2C (SCL/SDA)
Adafruit_FT6206 ctp = Adafruit_FT6206();

// The display also uses hardware SPI, plus #9 & #10
#define TFT_CS 15
#define TFT_DC 2
#define TFT_MOSI 23
#define TFT_SCLK 18
//Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC);
TFT_eSPI tft = TFT_eSPI(); // Invoke custom library with default width and height



#define WHITE       0xFFFF
#define BLACK       0x0000
#define BLUE        0x001F
#define RED         0xF800
#define GREEN       0x07E0
#define CYAN        0x07FF
#define MAGENTA     0xF81F
#define YELLOW      0xFFE0
#define GREY        0x2108 
#define SCALE0      0xC655                                                               // accent color for unused scale segments                                   
#define SCALE1      0x5DEE                                                               // accent color for unused scale segments
#define TEXT_COLOR  0xFFFF                                                               // is currently white 


#define RED2RED     0
#define GREEN2GREEN 1
#define BLUE2BLUE   2
#define BLUE2RED    3
#define GREEN2RED   4
#define RED2GREEN   5

#define DEG2RAD 0.0174532925                                                             // conversion factor degrees to radials
   
// data connection and acquisition variables
const char* ssid =            "Wokwi-GUEST";                               // network wifi credentials  
const char* password =        "";                                          // wifi network key
String openWeatherMapApiKey = "ab7f52a62676a8f0cc0fa5a5bc4dc32b";          // API Openweathermap account
String city =                 "Moscow";
String countryCode =          "ru";                                        // "NL" for The Netherlands
String jsonDocument (1024);                                                // memory allocation json string 

// timer internet access for server download
unsigned long lastTime = 0;                                                // testing purposes = 30 seconds
unsigned long timerDelay;                                                  // is set at 1 seconds in Setup and to 5 minutes in Loop  
                                                        
// joint variables
float temp_01=10;
float hum_01;
int   hum_02; 

// rainbow scale ring meter variables
uint32_t runTime = -99999;                                                               // time for next update
int   reading = 10;                                                                      // value to be displayed in circular scale
int   tesmod = 0;
int   rGaugePos_x = 0;                                                                   // these two variables govern the position
int   rGaugePos_y = 155;                                                                 // of the square + gauge on the display
int   ringmeterRadius = 65;                                                              // governs diameter of rainbow gauge
char* ringlabel[] = {(char *)"",(char *)"*C",(char *)"%",(char *)"mBar"};                                                // some custom labels
float tempRainbowgauge;  
int   t = 40;                                                                            // governs position of numerical output rainbow scale

// small needle meter 
int   j;
int   pivotNeedle_x = 165;                                                               // pivot coordinates needle of small gauge
int   pivotNeedle_y = 222;      
float center_x1 = 160;                                                                   // center x of edge markers circle left gauge 
float center_y1 = 228;                                                                   // center y of edge markers circle left gauge         
int   radius_s = 65;                                                                     // for scale markers
int   needleLength = 45;                                                                 // gauge needle length
int   edgemarkerLength = 5;                                                              // edge marker length               
float edge_x1, edge_y1, edge_x1_out, edge_y1_out;   
float angleNeedle = 0;
float needle_x, needle_y;                                                                        
float needle_x_old, needle_y_old;
float angleCircle = 0;
int   pivot_x = 165;                                                                     // pivot coordinates needle of small gauge
int   pivot_y = 222;  

// circle segment 'pie chart' meter variables
byte inc = 0;
unsigned int col = 0;
float pivotHumcircle__x = 198;
float pivotHumcircle__y = 274;  
float startAngle = 0;
float subAngle;                                                                          // subtended angle
int   r = 34;                                                                            // circle radius 

// compass wind direction pointer
float compassPivot_x = 158;
float compassPivot_y = 65;
float c_x1, c_x2,c_x3, c_x4;
float c_y1, c_y2,c_y3, c_y4;
float c_x1_old,c_x2_old,c_x3_old, c_x4_old;
float c_y1_old,c_y2_old,c_y3_old, c_y4_old; 
   
float windDir_01;
float compassAngle;
int   compass_r = 22;
char* sector [] = {(char *)"N", (char *)"NE", (char *)"E", (char *)"SE", (char *)"S", (char *)"SW", (char *)"W", (char *)"NW", (char *)"N"};                     // wind sector labels
int   h;            



void setup(void) {
  Serial.begin(115200);

  tft.begin();

  if (!ctp.begin(40)) {  // pass in 'sensitivity' coefficient
    Serial.println("Couldn't start FT6206 touchscreen controller");
    while (1);
  }
   tft.fillScreen (TFT_BLACK);
   tft.setTextSize (2);
  
   tft.println ("network ");
   tft.println ("connecting");
 
   WiFi.begin (ssid, password);
   Serial.println ("connecting");
     while(WiFi.status() != WL_CONNECTED) {
     delay (500);
     Serial.print (".");
     tft.print ("."); 
   }
  Serial.println ();
    Serial.print ("Connected to WiFi network ");
    tft.println ("connected to ");  
    tft.println ();
    Serial.print (ssid);
    tft.println (ssid); 
    delay(1000);
    tft.fillScreen (TFT_BLACK);
     
    Serial.print (" - IP adress: ");
    Serial.println (WiFi.localIP());
    Serial.println ("timer set to 30 seconds (timerDelay variable) - it will take 30 seconds before publishing the first reading.");

   drawAllWindowFrames ();                    // instructions moved to subroutine
   tft.setTextColor (TFT_YELLOW,BLACK);
 
   tft.setFreeFont(FF1);
   
   tft.setTextSize (1);
   tft.setCursor (21,20);
   tft.print ("OpenWeather MSK");

   tft.setCursor (9,45);
   tft.print ("temp");
   tft.setCursor (10,67);
   tft.print ("baro");
   tft.setCursor (10,89);
   tft.print ("hum");
   tft.setCursor (10,111);
   tft.print ("wind");
   tft.setCursor (10,133);
   tft.print ("from:");

   tft.setFreeFont(FF0);                      // note - units in Free Font 0 = text size 1
   tft.setCursor (133,37);
   tft.print (char(247));                     // degree character
   tft.print ("C");  
   tft.setCursor (133,59);
   tft.print ("mm");
   tft.setCursor (133,81);
   tft.print ("%");
   tft.setCursor (133,102);
   tft.print ("m/s"); 
   
   tft.setCursor (10,160);  
   tft.print ("temp");                        // in rainbow scale 

   tft.setCursor (125,160);                   // left upper corner = anchoring point of rainbow gauge scale
   tft.print (char(247));                     // degree character
   tft.setTextSize (2);
   tft.print ("C");   
   tft.setTextSize (1); 

   tft.setCursor (55,290);                    // 0  is bottom rainbow scale temperature 
   tft.print ("0");
   tft.setCursor (98,290);                    // 50 is top rainbow scale temperature 
   tft.print ("50");
                                              


   tft.setCursor (220,160);                   // display percent sign in  small gauge scale
   tft.print ("%");

   drawSaleSmallGauge ();
   tft.fillCircle (pivot_x, pivot_y, 2, MAGENTA);    // pivot needle middle small gauge                                                                         // arbitrary seeding temp - avoids drawing black line from position 0.0
   needleMeter ();                                   // calculate position and draw the needle
   tft.drawRoundRect (158,150,80,80,4, GREEN);       // correction right middle small frame from buildup needle
   tft.setCursor (216,217);                        
   tft.setTextSize (1);  
   tft.print ("40");                           // scale starts with 40% and ends with 100%
   tft.setCursor (164,169);   
   tft.print ("100");    
   tft.setTextSize (2);

// wind sector window on top of compass
   tft.setCursor (171, 51);
   tft.setTextSize (1);  
   tft.print ("wind:");

   tft.setCursor (170,33);
   tft.setTextSize (1); 
   tft.setTextColor (TFT_GREEN);  
   tft.print ("v1.0 - FGW");
tft.setTextColor (TFT_WHITE);  

   timerDelay = 1000;      // this is for fast initial query OpenWeather server for json string
   doTheHardWork ();       // run this here - in void loop the timerDelay refreshes every 5 minutes 

   drawAllWindowFrames (); // drawover to correct for all drawing errors caused by needles and markers  
   rainbowScaleMeter ();   // prepare the rainbow scale meter
   needleMeter ();         // prepare the middle right, small meter with the needle
   circleSegmentMeter ();  // prepare the circle segment pie meter
   compassGauge ();        // prepare the wind compass meter
   compassPointer ();      // add pointer to the wind compass meter
   windSectorReporter ();  




}

void loop() {
   timerDelay = 60000;  // 600000 connect to OpenWeather and refresh every ten minutes
   doTheHardWork ();
// --------------------------Testing proc-------------------------------




}

void doTheHardWork (){
// Send an HTTP GET request
  if ((millis () - lastTime) > timerDelay) 
      {
      // Check WiFi connection status
      if(WiFi.status ()== WL_CONNECTED)
         {
         String serverPath = "http://api.openweathermap.org/data/2.5/weather?q=" + city + "," + countryCode + "&APPID=" + openWeatherMapApiKey;    
         jsonDocument = httpGETRequest(serverPath.c_str ());
         JSONVar myObject = JSON.parse (jsonDocument);  // JSON.typeof(jsonVar) can be used to get the type of the var
         double temp_01 = (myObject ["main"]["temp"]); 
         double hum_01  = (myObject ["main"]["humidity"]); 
         double press_01 = (myObject ["main"] ["pressure"]);
  
      if (JSON.typeof (myObject) == "undefined")
         {
         Serial.println ("Parsing input failed!");
         return;
         }
         
   Serial.println ("*******************************************");  
   Serial.print ("JSON object = ");
   Serial.println (myObject);
   Serial.println ("*******************************************");  
   
   Serial.println ("extracted from JSON object:");        
   Serial.print ("Temperature:    ");    
   Serial.print (myObject["main"]["temp"]);
   Serial.println (" *Kelvin");       
   Serial.print ("Pressure:       ");
   Serial.print (myObject["main"]["pressure"]);
   Serial.println (" mB"); 
   Serial.print ("Humidity:       ");
   Serial.print(myObject["main"]["humidity"]);
   Serial.println (" %");  
   Serial.print ("Wind Speed:     ");
   Serial.print (myObject["wind"]["speed"]);
   Serial.println (" m/s");  
   Serial.print("Wind Direction: ");
   Serial.print (myObject["wind"]["deg"]);
   Serial.println (" degrees"); 

   double windDir = (myObject ["wind"]["deg"]);
   windDir_01 = windDir; 

   compassGauge ();
   compassPointer ();
   windSectorReporter ();
   
  // print some json data in upper window of the display 
  
   temp_01 = temp_01-273;                      // convert temp from Kelvin to Celsius
   tempRainbowgauge = temp_01;
   hum_02 = hum_01;
   press_01 = press_01 * 0.75; // conver mB to mmH ----- 0,750063755419211;

   Serial.print ("Wind from:      ");
   Serial.println (sector[h]);   

   Serial.print ("Rainbowgauge:   ");
   Serial.print (tempRainbowgauge,1);
   Serial.println (" *C");
   Serial.println ("");
   
   tft.setFreeFont (FF1);                     // start display data representation 

   tft.fillRect (60,35,70,15,BLACK);
   tft.setCursor (72,45);
   tft.print (temp_01,1);

   tft.fillRect (60,55,70,15,BLACK);
   tft.setCursor (67,67);
   //tft.print (myObject["main"]["pressure"]);
   tft.print (press_01,1);

   tft.fillRect (60,77,70,15,BLACK); 
   tft.setCursor (75,89);
   tft.print (myObject["main"]["humidity"]);
   
   tft.fillRect (60,99,70,15,BLACK);
   tft.setCursor (69,110);
   tft.print (myObject["wind"]["speed"]);   

   tft.fillRect (65,121,40,15,BLACK); 
   tft.setCursor (78,133); 
   tft.print (sector[h]);                      // wind sector

   tft.setFreeFont(FF0);                       // end display numerical data representation 
 
   rainbowScaleMeter ();
   needleMeter ();                             // calculate needle position middle right, small meter
   circleSegmentMeter ();                      // calculate and display the pie chart
    }
    else {
      Serial.println( "WiFi Disconnected");
    }
    lastTime = millis ();
  }  
}


void drawAllWindowFrames (){ 

   tft.drawRoundRect  (  4,   2, 234, 25, 2, GREEN);   // title frame 
   tft.drawRoundRect  (  4,  28, 150,118, 2, GREEN);   // left upper numerical window   
   tft.drawRoundRect  (  4, 150, 150,165, 2, GREEN);   // left lower (big) frame for rainbow scale gauge
   tft.drawRoundRect  (158, 150,  80, 80, 2, GREEN);   // right middle small frame - needle meter
   tft.drawRoundRect  (158, 235,  80, 80, 2, GREEN);
   tft.drawRoundRect  (158,  65,  80, 81, 2, GREEN);   // compass frame
   tft.drawRoundRect  (158,  47,  80, 16, 2, GREEN);   // wind sector indicator frame 
   tft.drawRoundRect  (158,  28,  80, 16, 2, GREEN);   // version window        
}



String httpGETRequest(const char* serverName) {

  HTTPClient http;
  http.begin(serverName);                              // your IP address with path or Domain name with URL path 
  int httpResponseCode = http.GET();                   // send HTTP POST request
  String payload = "{}"; 
  if (httpResponseCode>0)
     {
     Serial.print ("HTTP Response code: ");
     Serial.println (httpResponseCode);
     payload = http.getString ();
     }
  else {
    Serial.print( "Error code: ");
    Serial.println (httpResponseCode);
  }
  http.end ();                                         // free microcontroller resources
  return payload;
}



void  rainbowScaleMeter (){
   
   if (millis () - runTime >= 100)                     // originally 500 = delay                                       
     {                                    
      runTime = millis ();
      if( tesmod==0)
        {
         reading =  99;
        }
      if( tesmod==1)
        {
         reading = tempRainbowgauge*2;                 // important: here ring is seeded with value      
        } 
 
     int xpos = 10, ypos = 240, gap = 100;             // position of upper ring and proportion
     
     ringMeter (reading,0,100, (rGaugePos_x+15),(rGaugePos_y+17),ringmeterRadius,ringlabel[0],GREEN2RED);    
     tesmod = 1;
     }
}



int ringMeter(int value,int vmin,int vmax,int x,int y,int r, char *units, byte scheme){
  // Minimum value of r is about 52 before value text intrudes on ring
  // drawing the text first is an option
 
   x += r; y += r;                                     // calculate coordinates of center of ring
   int w = r / 3;                                      // width of outer ring is 1/4 of radius
   int angle = 150;                                    // half the sweep angle of the meter (300 degrees)
   int v = map (value, vmin, vmax, -angle, angle);     // map the value to an angle v
   byte seg = 3;                                       // segments are 3 degrees wide = 100 segments for 300 degrees
   byte inc = 6;                                       // draw segments every 3 degrees, increase to 6 for segmented ring
   int colour = BLUE;                                  // variable to save "value" text color from scheme and set default
 
 
   for (int i = -angle+inc/2; i < angle-inc/2; i += inc)    // draw color blocks every increment degrees
     {           
      float sx = cos((i - 90) * DEG2RAD);                   // calculate pair of coordinates for segment start
      float sy = sin((i - 90) * DEG2RAD);
      uint16_t x0 = sx * (r - w) + x;
      uint16_t y0 = sy * (r - w) + y;
      uint16_t x1 = sx * r + x;
      uint16_t y1 = sy * r + y;
    
      float sx2 = cos((i + seg - 90) * DEG2RAD);            // calculate pair of coordinates for segment end
      float sy2 = sin((i + seg - 90) * DEG2RAD);
      int x2 = sx2 * (r - w) + x;
      int y2 = sy2 * (r - w) + y;
      int x3 = sx2 * r + x;
      int y3 = sy2 * r + y;

      if (i < v) 
         {                                                  // fill in coloured segments with 2 triangles
          switch (scheme)
             {
              case 0: colour = RED; break;                  // fixed color
              case 1: colour = GREEN; break;                // fixed color
              case 2: colour = BLUE; break;                 // fixed colour
              case 3: colour = rainbow(map(i, -angle, angle, 0, 127)); break;      // full spectrum blue to red
              case 4: colour = rainbow(map(i, -angle, angle, 70, 127)); break;     // green to red (high temperature etc)
              case 5: colour = rainbow(map(i, -angle, angle, 127, 63)); break;     // red to green (low battery etc)
              default: colour = BLUE; break;                                       // fixed color
             }
              tft.fillTriangle(x0, y0, x1, y1, x2, y2, colour);
              tft.fillTriangle(x1, y1, x2, y2, x3, y3, colour);
             }
      else                                                   // fill in blank segments
             {
              tft.fillTriangle(x0, y0, x1, y1, x2, y2, SCALE1);  // color of the unoccupied ring scale 
              tft.fillTriangle(x1, y1, x2, y2, x3, y3, SCALE0);  // color of the unoccupied ring scale
             }
             }

   tft.fillRect (t,y,72,15,BLACK);
   tft.setTextSize (2);
   if (tempRainbowgauge<-9.9) t = 33;
   if (tempRainbowgauge>-9.9) t = 38; 
   if (tempRainbowgauge > 0 ) t = 50;
   if (tempRainbowgauge >9.9) t = 42;
   tft.setCursor (t+15,y);  
   tft.setTextColor (GREEN);     
   tft.print (tempRainbowgauge,1);
   return 0;
}

unsigned int rainbow (byte value) {                  // value is expected to be in range 0-127
                                                     // value is converted to a spectrum color from 0 = blue through to 127 = red
   byte red = 0;                                     // red is the top 5 bits of a 16 bit colour value
   byte green = 0;                                   // green is the middle 6 bits
   byte blue = 0;                                    // blue is the bottom 5 bits
   byte quadrant = value / 32;

   if (quadrant == 0)
     {
      blue = 31;
      green = 2 * (value % 32);
      red = 0;
     }
   if (quadrant == 1)
     {
      blue = 31 - (value % 32);
      green = 63;
      red = 0;
     }
   if (quadrant == 2)
     {
      blue = 0;
      green = 63;
      red = value % 32;
     }
   if (quadrant == 3)
     {
      blue = 0;
      green = 63 - 2 * (value % 32);
      red = 31;
     }
   return (red << 11) + (green << 5) + blue;
}


float sineWave(int phase) {
  
   return sin(phase * 0.0174532925);
}


void drawSaleSmallGauge (){
 
   j = 270;                                          // start point of cirle segment
   do {
       angleCircle = (j* DEG2RAD);                   // angle expressed in radians - 1 degree = 0,01745331 radians      

       edge_x1 = (center_x1+4 + (radius_s*cos (angleCircle)));   // scale - note the 4 pixels offset in x      
       edge_y1 = (center_y1 + (radius_s*sin (angleCircle)));     // scale
         
       edge_x1_out = (center_x1+4 + ((radius_s+edgemarkerLength)*cos (angleCircle)));   // scale - note the 4 pixels offset in x   
       edge_y1_out = (center_y1 + ((radius_s+edgemarkerLength)*sin (angleCircle)));     // scale
        
       tft.drawLine (edge_x1, edge_y1, edge_x1_out, edge_y1_out,MAGENTA); 
 
       j = j+6; 
   } 
   while (j<356);                                     // end of circle segment
}


void needleMeter (){                                                                         

   tft.drawLine (pivotNeedle_x, pivotNeedle_y, needle_x_old, needle_y_old, 0);   // remove old needle by overwritig in white
  
 // if (101 > hum_02 < 0) { 
   angleNeedle = (420*DEG2RAD - 1.5*hum_02*DEG2RAD);                             // contains a 1.5 stretch factor to expand 60 percentage points over 90 degrees of scale

   if (angleNeedle > 6.28) angleNeedle = 6.28;                                   // prevents the needle from ducking below horizontal    
   needle_x = (pivotNeedle_x + ((needleLength)*cos (angleNeedle)));              // calculate x coordinate needle point
   needle_y = (pivotNeedle_y + ((needleLength)*sin (angleNeedle)));              // calculate y coordinate needle point
   needle_x_old = needle_x;                                                      // remember previous needle position
   needle_y_old = needle_y;

   tft.drawLine (pivotNeedle_x, pivotNeedle_y, needle_x, needle_y,MAGENTA); 
 // }
  
   Serial.println("-----------------------------");
   Serial.println(pivotNeedle_x);
   Serial.println(pivotNeedle_y);
   Serial.println(needle_x);
   Serial.println(needle_y);
   Serial.println(hum_01);
   Serial.println(hum_02);

   tft.fillCircle (pivotNeedle_x, pivotNeedle_y, 2, MAGENTA);                    // restore needle pivot
}



 void circleSegmentMeter (){

   tft.fillCircle (pivotHumcircle__x, pivotHumcircle__y,34,BLACK);       
   fillSegment (pivotHumcircle__x, pivotHumcircle__y, 0, (360*hum_02/100), 34, TFT_RED);    // draw pie chart segment
   tft.drawCircle (pivotHumcircle__x, pivotHumcircle__y,35,YELLOW);                         // correct for faulty pixels circle edge
 
   tft.setCursor (pivotHumcircle__x+10, pivotHumcircle__y-5); 
   tft.setTextColor (TFT_YELLOW);
   tft.setTextSize (1);
   tft.print ("hum");
   tft.setCursor (pivotHumcircle__x+10, pivotHumcircle__y+5);  
   tft.print (hum_02);
   tft.print ("%");  
   tft.setTextSize (2);
}


// ######################################################################################
// #  circle segment meter - draw segments                                              #
// ######################################################################################

// x,y == coords of centre of circle
// startAngle = 0 - 359
// subAngle   = 0 - 360 = subtended angle
// r = radius
// colour = 16 bit colour value

int fillSegment (int x, int y, int startAngle, int subAngle, int r, unsigned int colour)
{
  float sx = cos((startAngle - 90) * DEG2RAD);                                              // calculate first pair of coordinates for segment start
  float sy = sin((startAngle - 90) * DEG2RAD);
  uint16_t x1 = sx * r + x;
  uint16_t y1 = sy * r + y;

  for (int i = startAngle; i < startAngle + subAngle; i++)                                  // draw color blocks every inc degrees 
     {    
     int x2 = cos((i + 1 - 90) * DEG2RAD) * r + x;                                          // calculate pair of coordinates for segment end
     int y2 = sin((i + 1 - 90) * DEG2RAD) * r + y;
     tft.fillTriangle(x1, y1, x2, y2, x, y, colour);
     x1 = x2;                                                                               // copy segment end to segment start for next segment
     y1 = y2;
     }
     return 0;
}


void compassGauge (){

   tft.drawCircle ((compassPivot_x+40), (compassPivot_y+40), compass_r+11, BLUE);           // outer circle compass 
   tft.drawCircle ((compassPivot_x+40), (compassPivot_y+40), compass_r+2, CYAN);            // inner circle compass - pointer fits in here
   tft.setTextSize (1);
   tft.setCursor (compassPivot_x+38, compassPivot_y+4);
   tft.setTextColor (WHITE, BLACK);
   tft.print ("N");
   tft.setCursor (compassPivot_x+38, compassPivot_y+69);
   tft.print ("S");
   tft.setCursor (compassPivot_x+71, compassPivot_y+35);
   tft.print ("E");
   tft.setCursor (compassPivot_x+5,  compassPivot_y+35);
   tft.print ("W");  
}



void compassPointer (){                                                                         
  
   tft.fillTriangle (c_x1_old,c_y1_old,c_x2_old,c_y2_old,c_x4_old,c_y4_old,BLACK);          // remove old compass pointer by overwritig in white
   tft.fillTriangle (c_x1_old,c_y1_old,c_x3_old,c_y3_old,c_x4_old,c_y4_old,BLACK);          // remove old compass pointer by overwritig in white
  
   compassAngle = ((windDir_01-90)*DEG2RAD);                                        

   c_x1 = ((compassPivot_x+40) + (compass_r * cos (compassAngle)));                         // calculate coordinates compass pointer tip 
   c_y1 = ((compassPivot_y+40) + (compass_r * sin (compassAngle)));                       

   c_x2 = ((compassPivot_x+40) + (compass_r * cos (compassAngle + 163*DEG2RAD)));           // calculate coordinates compass pointer base point
   c_y2 = ((compassPivot_y+40) + (compass_r * sin (compassAngle + 163*DEG2RAD)));                       

   c_x3 = ((compassPivot_x+40) + (compass_r * cos (compassAngle - 163*DEG2RAD)));           // calculate coordinates compass pointer base point
   c_y3 = ((compassPivot_y+40) + (compass_r * sin (compassAngle - 163*DEG2RAD)));                       

   c_x4 = ((compassPivot_x+40) + ((compass_r-4) * cos (compassAngle - 180*DEG2RAD)));       // calculate coordinates compass pointer base point
   c_y4 = ((compassPivot_y+40) + ((compass_r-4) * sin (compassAngle - 180*DEG2RAD)));                 

   c_x1_old = c_x1; c_x2_old = c_x2; c_x3_old = c_x3;   c_x4_old = c_x4;
   c_y1_old = c_y1; c_y2_old = c_y2; c_y3_old = c_y3;   c_y4_old = c_y4;
   
   tft.fillTriangle (c_x1, c_y1,c_x3, c_y3, c_x4, c_y4, 0x3A72);                            // print the new pointer to display                              
   tft.fillTriangle (c_x1, c_y1,c_x2, c_y2, c_x4, c_y4, BLUE);                              // print the new pointer to display
}


void windSectorReporter (){

   h = 0;
   if (windDir_01 <22.5) h = 0;
   if (windDir_01> 22.5) h = 1; 
   if (windDir_01> 67.5) h = 2;
   if (windDir_01>112.5) h = 3;
   if (windDir_01>157.5) h = 4;  
   if (windDir_01>202.5) h = 5;
   if (windDir_01>247.5) h = 6;
   if (windDir_01>292.5) h = 7; 
   if (windDir_01>337.5) h = 8;

   tft.fillRect (208,51,16,8,BLACK);
 
   tft.setCursor (210,51); 
   tft.print (sector[h]);    
}