#include <WiFi.h>
#include <HTTPClient.h>
#include <ESP32Servo.h>
#include <LilStepper.h>
#include <Adafruit_NeoPixel.h>
#include <ArduinoJson.h>

static const int servoPin = 1;
static const int pixelPin = 2;
//static const int stepperPin1 = 5;
//static const int stepperPin2 = 6;
//static const int stepperPin3 = 7;
//static const int stepperPin4 = 8;
//static const int limitPin1 = 3;

const int stepsPerRevolution = 200;  // change this to fit the number of steps per revolution
// for your motor

// initialize the stepper library on pins 5 through 8:
LilStepper stepper(stepsPerRevolution, 5, 6, 7, 8);


/*--------Déclaration NeoPixels--------*/
//#define PIN 2
#define NUMPIXELS 10
Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUMPIXELS, pixelPin, NEO_GRB + NEO_KHZ800);

/*--------Déclaration Stepper Motor--------*/
//Stepper stepper(stepperPin1,stepperPin2,stepperPin4,stepperPin3);        // IN1 --> D5, IN2 --> D6, IN3 --> D8, IN4 --> D7
int motorSpeed = 1;                       // motor gets slower as this number increases
int motorSteps_360_degres_int = 4180;     // 4150 is approx 360 degrees (4076 normally)
float motorSteps_360_degres = 4.180;      // 4150 divided by 100 because too large for calculation, will be multiply by 100 after in the code when needed
int Steps_from_switch_to_longitute_0 = motorSteps_360_degres_int/2;
int motorSteps_Correction = 70;           // Correction due to the switch position not exactly at -179°

int Position_Longitude_Laser;             // Actual longitude position of the laser

/*--------Déclaration Servo--------*/
Servo Servo_Latitude;                     // Servo function for Angle range of {0°;120°}: MicroSecond = 10,849 * Angle + 810 . Examples MicroSecond/Angle :1461us=60° (middle range); 2150us=120° (max); 810us=0° (min)
int MicroSecond;             
int Min_MicroSecond = 897;                // The microsecond to send to the servo to hit the Min_Latitude_ISS (-52°)
int Max_MicroSecond = 2025;               // The microsecond to send to the servo to hit the Max_Latitude_ISS (52°)
int Correctif_Latitude = 11;              // To correct the latitude calibration of the laser latitude

int Position_Latitude_Laser;              // Actual latitude position of the laser

/*--------Déclaration Butée--------*/
const int Switch_Buttee = 3;// Careful, D3 is an Input --> 3,3V max --> D3 have an intern pull-up resistance (link D3 to the ground)
int Etat_Buttee;

/*--------Déclaration Paramètre Connexion du D1 Mini--------*/
const char* ssid     = "XXX";       // SSID
const char* password = "XXX";  // Password
const char* host = "xxx.xxx.xxx.xxx";     // IP serveur - Server IP
const int   port = 8080;                  // Port serveur - Server Port

/*--------Déclaration ISS Low & High Latitude and Longitude--------*/
int Min_Latitude_ISS = -52;               // The minimal Latitude of the ISS is -52°
int Max_Latitude_ISS = 52;                // The maximun Latitude of the ISS is 52°

int Latitude_ISS;
int Longitude_ISS;
int nb_move = 0;
  
/*--------Déclaration Unix Time on Greenwhich Meridian--------*/
int UnixTime_int;
int Hour_UTC;
int Minute_UTC;
int Second_UTC;

/*--------Déclaration Request for router location-------*/
String Request;
int latitude_Lamp;
int longitude_Lamp;

void setup() {
  strip.begin();
  strip.show();

/*turn off all neopixels*/ 
  for(int i=0; i<NUMPIXELS; i++){
  strip.setPixelColor(i, strip.Color(0,0,0)); //white color
  strip.show(); // This sends the updated pixel color to the hardware.
  }
                 
  stepper.setStepDuration(motorSpeed);
  Servo_Latitude.attach(servoPin);
  pinMode(Switch_Buttee, INPUT_PULLUP);   //link D3 to the ground
  
  Serial.begin(115200);
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("WiFi connected");  
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
  Serial.println("IP address_router: ");
  Serial.println(WiFi.gatewayIP());

/*Init. Servo to latitude 0°)*/ 
  pinMode(servoPin, OUTPUT);                    // Attach the Servo
  Servo_Latitude.writeMicroseconds(1461); // 1461 Microsecond pulse corresponding to 60° for the Servo, corresponding to 0° Latitude
  delay(500);
  pinMode(servoPin, INPUT);                     // Detach the servo (to avoid the servo jittering)
  Position_Latitude_Laser = 0;

/*turn on all neopixels*/ 
  for(int i=0; i<NUMPIXELS; i++){
   strip.setPixelColor(i, strip.Color(255,255,255)); //white color
   strip.show(); // This sends the updated pixel color to the hardware.
   }
   
/*Init. Stepper to longitude -180°)*/
  stepper.step(motorSteps_Correction);    //on décale le stepper s'il se trouve à l'arrêt entre -179° et -180
  
  for(int s=0; s<motorSteps_360_degres_int; s++){
    Etat_Buttee = digitalRead(Switch_Buttee);
    if (Etat_Buttee == LOW){
      break;
    }
     stepper.step(-10);
  }
  stepper.step(-motorSteps_Correction); 
  Position_Longitude_Laser = -180;
   
/*Move to the Lamp location to inform where we are*/
  Get_Public_IP();          //Getting Public IP of the router
  Get_Lamp_location();      //Getting the Latitude and Longitude of the lamp 
  move_Longitude_Laser_Angle(longitude_Lamp + 6);
  move_Latitude_Laser_Angle(latitude_Lamp); 
  delay(800);
  
  /*turn off all neopixels*/ 
  for(int i=0; i<NUMPIXELS; i++){
  strip.setPixelColor(i, strip.Color(0,0,0)); //white color
  strip.show(); // This sends the updated pixel color to the hardware.
  }

}

void loop() {

Get_Longitude_Latitude_Hour_Minute();       // Requesting the time, latitude and longitude to the server
Sun_Position_NeoPixels(Hour_UTC);           // Displaying the Neopixels to represent the sun location on the surface of the Earth          
move_Longitude_Laser_Angle(Longitude_ISS);  // Moving the stepper motor to the ISS Longitude
move_Latitude_Laser_Angle(Latitude_ISS);    // Moving the servo motor to the ISS Latitude

delay(2500);                                // Wait 2,5 seconds in order to reduce the waiting time if the switchLED just turn ON
Sun_Position_NeoPixels(Hour_UTC);           // Displaying again the Neopixels if the switchLED just turn ON
delay(2500);                                // Wait an other 2,5 seconds to have a final delay of 5 seconds between each request to the API server

}

/*------------------------------------------------------------------------------------------------------------*/
void Get_Longitude_Latitude_Hour_Minute() {
  
  /* Sending the request to the API which locates the ISS */
  if (WiFi.status() == WL_CONNECTED) {      //Check WiFi connection status
    HTTPClient http;                        //Declare an object of class HTTPClient
    http.begin("http://api.open-notify.org/iss-now.json");  //Specify request destination asking for the ISS data (only use http sites, and not https sites)
    int httpCode = http.GET();              //Send the request
    
  /* Getting the JSON data from the API and Parse data*/
    if (httpCode > 0) {                     //Check the returning code
      String payload = http.getString();    //Get the request response payload
      Serial.println(payload);

  /* Parse the payload to get Time, Latitude and Longitude */
      const size_t capacity = JSON_OBJECT_SIZE(2) + JSON_OBJECT_SIZE(3) + 200;
      DynamicJsonDocument doc(capacity);
      
      deserializeJson(doc, http.getString());
      
      const char* message = doc["message"];                             // in the example it will be "success"
      long timestamp = doc["timestamp"];                                // in the example it will be "1553413828"
      
      float iss_position_latitude = doc["iss_position"]["latitude"];    // in the example it will be "-51.0835"
      float iss_position_longitude = doc["iss_position"]["longitude"];  // in the example it will be "-157.1986"

  /* Isolate the longitude, latitude and Unix Time data */
  //Converting the float latitude into Int latitude
      Latitude_ISS = (int) iss_position_latitude;
      Serial.print("Latitude ISS : ");
      Serial.println(Latitude_ISS);

  //Converting the float longitude into Int longitude
      Longitude_ISS = (int) iss_position_longitude;
      Serial.print("Longitude ISS : ");
      Serial.println(Longitude_ISS);
         
  //Converting the Unix Time data into Int Unix Time      
      UnixTime_int = (int) timestamp;                                 //Transforming the string Unix Time into Int data
      Serial.print("Unix Time : ");
      Serial.println(UnixTime_int);
      
 //Modifying the Unix into a HH:MM:SS
      Hour_UTC = (UnixTime_int % 86400) / 3600;
      Minute_UTC = (UnixTime_int % 3600) / 60;
      Second_UTC = UnixTime_int % 60;
      
    }
    http.end();                                                       //Close connection
  }
}


/*------------------------------------------------------------------------------------------------------------*/
void Get_Public_IP() {
 
  if (WiFi.status() == WL_CONNECTED) {
    HTTPClient httpIP;                       
    String ip;
    
    httpIP.begin("http://api.ipify.org/?format=json");
    int httpCodeIP = httpIP.GET();              //Send the request to get the Public IP of the router
  /* Getting the JSON data from the API and Parse data*/
    if (httpCodeIP > 0) {                       //Check the returning code
      String payloadIP = httpIP.getString();    //Get the request response payload

  /* Parse the payload to get Public IP of the router */
      const size_t capacityIP = JSON_OBJECT_SIZE(2) + JSON_OBJECT_SIZE(3) + 200;
      DynamicJsonDocument docIP(capacityIP);
      deserializeJson(docIP, httpIP.getString());
      String ip = docIP["ip"];
      Serial.println("Public IP address_router:");
      Serial.println(ip);
      Request = ("http://www.iplocate.io/api/lookup/"); // Careful, the "begin" is for non securisated http site, use only http site and not https site
      Request = Request+ip;                     //making the request by adding the IP to the web site API
    }
      httpIP.end();
  }
}


/*------------------------------------------------------------------------------------------------------------*/
void Get_Lamp_location(){
  if (WiFi.status() == WL_CONNECTED) {
    HTTPClient httpLamp;
    httpLamp.begin(Request);                    //Specify request destination, asking the location of the router
    int httpCodeLamp = httpLamp.GET();          //Send the request
  /* Getting the JSON data from the API and Parse data*/
    if (httpCodeLamp > 0) {                     //Check the returning code
      String payloadLamp = httpLamp.getString();//Get the request response payload
      Serial.println("Payload Lamp Location : ");
      Serial.println(payloadLamp);
      
   /* Parse the payload to get Public IP of the router */
      const size_t capacityLamp = JSON_OBJECT_SIZE(13) + 400;
      DynamicJsonDocument docLamp(capacityLamp);
      deserializeJson(docLamp, httpLamp.getString());
      latitude_Lamp = docLamp["latitude"]; // 48.8931
      longitude_Lamp = docLamp["longitude"]; // 2.3465
      Serial.println("Latitude Lamp : ");
      Serial.println(latitude_Lamp);
      Serial.println("Longitude Lamp : ");
      Serial.println(longitude_Lamp);
    
    }
    httpLamp.end(); 
  }
}


/*------------------------------------------------------------------------------------------------------------*/
void move_Latitude_Laser_Angle(int Angle_Latitude) {
  int Angle_diff = Angle_Latitude - Position_Latitude_Laser;
  
  if(Angle_diff == 0){
    Position_Latitude_Laser = Angle_Latitude;
    
    }else{
          MicroSecond = map(Angle_Latitude, Min_Latitude_ISS, Max_Latitude_ISS, Min_MicroSecond, Max_MicroSecond);
          pinMode(1, OUTPUT);
          Servo_Latitude.writeMicroseconds(MicroSecond + Correctif_Latitude);
          delay(500);
          pinMode(1, INPUT);
          Position_Latitude_Laser = Angle_Latitude;
 }
}


/*------------------------------------------------------------------------------------------------------------*/
void move_Longitude_Laser_Angle(int Angle_Longitude) {
  // IDEE FEATURE : Idee avec les neopixel, récupérer la donnée de localisation où se trouve la lampe, et si l'ISS et dans un rayons de 50km? les neopixels s'anime pour indiquer que l'on peut voir l'ISS dans le ciel

  if (Angle_Longitude == -179){                    // If the ISS angle is equal to -179, returning to -179° by a calibration with the switch (the same in the setup)
    stepper.step(-50);                            // Moving -100 (nearly -10°) steps in first place, if the laser module is after the switch
    for(int s=0; s<5000; s++){
    Etat_Buttee = digitalRead(Switch_Buttee);
    if (Etat_Buttee == LOW){
      break;
    }
     stepper.step(-10);
  }
  stepper.step(-motorSteps_Correction); 
  Position_Longitude_Laser = -180;
  
  //Positioning at -179°
  float x_pas_calibration = (motorSteps_360_degres * 1 * 1000 / 360);
  int x_pas_int_calibration = ceil(x_pas_calibration);
  stepper.step(x_pas_int_calibration);
  Position_Longitude_Laser = -179;
  delay(20000);
  }
  
//  if (Angle_Longitude == 178 || Angle_Longitude == 179){                    // If the ISS angle is 178 or 179, forcing the angle to be 177 to avoid the situation when we close the lamp where the laser is in position to reboot directly clicking the swith and turn in the wrong way
//    Angle_Longitude = 177;
//  }                               
  
  int Angle_diff = Angle_Longitude - Position_Longitude_Laser;
  if(Angle_diff == 0){
        Position_Longitude_Laser = Angle_Longitude;
        
    }else{
          int x_pas_int;
          float x_pas = (motorSteps_360_degres * Angle_diff * 1000 / 360);  // Conversion de la valeur renseignée en Angle° en nombre de step

          if(Latitude_ISS >= 41 || Latitude_ISS <= -41){                    // If the Latitude of the ISS is upper than 40° and lower than -40°
            nb_move = nb_move+1;
             // Alterning number of steps correction because +4 is too fast and +3 is too low
             if((nb_move/2)*2 != nb_move){                                  // Testing if the number of request is pair or impair, adding a different correction in the x_pas_int (ex : (5/2)=2 (and not 2,5 because integer type)
                x_pas_int = ((int) x_pas) + 5;                              // Converting the float into a upper int to avoid non-whole number
             }else{
                x_pas_int = ((int) x_pas) + 4;
             }                                // Converting the float into a upper int to avoid non-whole number
            
          }else if(Latitude_ISS >= 24 && Latitude_ISS < 41){  //27 et 42              // If the Latitude of the ISS is upper than 25° and lower than 40°
            nb_move = 0;
            x_pas_int = ((int) x_pas) + 4;
            
          }else if(Latitude_ISS <= -24 && Latitude_ISS > -41){              // If the Latitude of the ISS is lower than -25° and lower than -40°
            nb_move = 0;
            x_pas_int = ((int) x_pas) + 4;
  
          }else if(Latitude_ISS > -24 && Latitude_ISS < 24){                // If the Latitude of the ISS is upper than -25° and lower than 25°
            nb_move = nb_move+1;
             // Alterning number of steps correction because +4 is too fast and +3 is too low
             if((nb_move/2)*2 != nb_move){                                     // Testing if the number of request is pair or impair, adding a different correction in the x_pas_int (ex : (5/2)=2 (and not 2,5 because integer type)
                x_pas_int = ((int) x_pas) + 4;                                  // Converting the float into a upper int to avoid non-whole number
             }else{
                x_pas_int = ((int) x_pas) + 3;
             }
          
          }else{
            nb_move = 0;
            x_pas_int = ((int) x_pas) + 4;       
          }

          stepper.step(x_pas_int);
          Position_Longitude_Laser = Angle_Longitude;
   }
}


/*------------------------------------------------------------------------------------------------------------*/
void Sun_Position_NeoPixels(int Hour){
  
  if((latitude_Lamp >= (Latitude_ISS - 2)) && (latitude_Lamp <= (Latitude_ISS + 2)) && (longitude_Lamp >= (Longitude_ISS - 2)) && (longitude_Lamp <= (Longitude_ISS + 2))){   //if the ISS is above the lamp location, the neopixels will display a green color
    /*turn on all neopixels*/ 
    for(int z=0; z<NUMPIXELS; z++){
     strip.setPixelColor(z, strip.Color(255,255,255)); //white color
     strip.show(); // This sends the updated pixel color to the hardware.
     }
     delay(300);
    /*turn off all neopixels*/ 
    for(int z=0; z<NUMPIXELS; z++){
      strip.setPixelColor(z, strip.Color(0,0,0)); //white color
      strip.show(); // This sends the updated pixel color to the hardware.
    }
  }
  
  switch (Hour) {
  case 0:
   strip.setPixelColor(0, strip.Color(255, 90, 0));
   strip.setPixelColor(1, strip.Color(0, 0, 0));
   strip.setPixelColor(2, strip.Color(0, 0, 0));
   strip.setPixelColor(3, strip.Color(0, 0, 0));
   strip.setPixelColor(4, strip.Color(0, 0, 0));
   strip.setPixelColor(5, strip.Color(0, 0, 0));
   strip.setPixelColor(6, strip.Color(0, 0, 0));
   strip.setPixelColor(7, strip.Color(0, 0, 0));
   strip.setPixelColor(8, strip.Color(255, 90, 0));
   strip.setPixelColor(9, strip.Color(255, 90, 0));
   break;
  case 1:
   strip.setPixelColor(0, strip.Color(255, 90, 0));
   strip.setPixelColor(1, strip.Color(0, 0, 0));
   strip.setPixelColor(2, strip.Color(0, 0, 0));
   strip.setPixelColor(3, strip.Color(0, 0, 0));
   strip.setPixelColor(4, strip.Color(0, 0, 0));
   strip.setPixelColor(5, strip.Color(0, 0, 0));
   strip.setPixelColor(6, strip.Color(0, 0, 0));
   strip.setPixelColor(7, strip.Color(0, 0, 0));
   strip.setPixelColor(8, strip.Color(255, 90, 0));
   strip.setPixelColor(9, strip.Color(255, 90, 0));
   break;
  case 2:
   strip.setPixelColor(0, strip.Color(0, 0, 0));
   strip.setPixelColor(1, strip.Color(0, 0, 0));
   strip.setPixelColor(2, strip.Color(0, 0, 0));
   strip.setPixelColor(3, strip.Color(0, 0, 0));
   strip.setPixelColor(4, strip.Color(0, 0, 0));
   strip.setPixelColor(5, strip.Color(0, 0, 0));
   strip.setPixelColor(6, strip.Color(0, 0, 0));
   strip.setPixelColor(7, strip.Color(255, 90, 0));
   strip.setPixelColor(8, strip.Color(255, 90, 0));
   strip.setPixelColor(9, strip.Color(255, 90, 0));
   break;
  case 3:
   strip.setPixelColor(0, strip.Color(0, 0, 0));
   strip.setPixelColor(1, strip.Color(0, 0, 0));
   strip.setPixelColor(2, strip.Color(0, 0, 0));
   strip.setPixelColor(3, strip.Color(0, 0, 0));
   strip.setPixelColor(4, strip.Color(0, 0, 0));
   strip.setPixelColor(5, strip.Color(0, 0, 0));
   strip.setPixelColor(6, strip.Color(0, 0, 0));
   strip.setPixelColor(7, strip.Color(255, 90, 0));
   strip.setPixelColor(8, strip.Color(255, 90, 0));
   strip.setPixelColor(9, strip.Color(255, 90, 0));
   break;
  case 4:
   strip.setPixelColor(0, strip.Color(0, 0, 0));
   strip.setPixelColor(1, strip.Color(0, 0, 0));
   strip.setPixelColor(2, strip.Color(0, 0, 0));
   strip.setPixelColor(3, strip.Color(0, 0, 0));
   strip.setPixelColor(4, strip.Color(0, 0, 0));
   strip.setPixelColor(5, strip.Color(0, 0, 0));
   strip.setPixelColor(6, strip.Color(255, 90, 0));
   strip.setPixelColor(7, strip.Color(255, 90, 0));
   strip.setPixelColor(8, strip.Color(255, 90, 0));
   strip.setPixelColor(9, strip.Color(0, 0, 0));
   break;
  case 5:
   strip.setPixelColor(0, strip.Color(0, 0, 0));
   strip.setPixelColor(1, strip.Color(0, 0, 0));
   strip.setPixelColor(2, strip.Color(0, 0, 0));
   strip.setPixelColor(3, strip.Color(0, 0, 0));
   strip.setPixelColor(4, strip.Color(0, 0, 0));
   strip.setPixelColor(5, strip.Color(0, 0, 0));
   strip.setPixelColor(6, strip.Color(255, 90, 0));
   strip.setPixelColor(7, strip.Color(255, 90, 0));
   strip.setPixelColor(8, strip.Color(255, 90, 0));
   strip.setPixelColor(9, strip.Color(0, 0, 0));
   break;
  case 6:
   strip.setPixelColor(0, strip.Color(0, 0, 0));
   strip.setPixelColor(1, strip.Color(0, 0, 0));
   strip.setPixelColor(2, strip.Color(0, 0, 0));
   strip.setPixelColor(3, strip.Color(0, 0, 0));
   strip.setPixelColor(4, strip.Color(0, 0, 0));
   strip.setPixelColor(5, strip.Color(0, 0, 0));
   strip.setPixelColor(6, strip.Color(255, 90, 0));
   strip.setPixelColor(7, strip.Color(255, 90, 0));
   strip.setPixelColor(8, strip.Color(255, 90, 0));
   strip.setPixelColor(9, strip.Color(0, 0, 0));
   break;
  case 7:
   strip.setPixelColor(0, strip.Color(0, 0, 0));
   strip.setPixelColor(1, strip.Color(0, 0, 0));
   strip.setPixelColor(2, strip.Color(0, 0, 0));
   strip.setPixelColor(3, strip.Color(0, 0, 0));
   strip.setPixelColor(4, strip.Color(0, 0, 0));
   strip.setPixelColor(5, strip.Color(255, 90, 0));
   strip.setPixelColor(6, strip.Color(255, 90, 0));
   strip.setPixelColor(7, strip.Color(255, 90, 0));
   strip.setPixelColor(8, strip.Color(0, 0, 0));
   strip.setPixelColor(9, strip.Color(0, 0, 0));
   break;
  case 8:
   strip.setPixelColor(0, strip.Color(0, 0, 0));
   strip.setPixelColor(1, strip.Color(0, 0, 0));
   strip.setPixelColor(2, strip.Color(0, 0, 0));
   strip.setPixelColor(3, strip.Color(0, 0, 0));
   strip.setPixelColor(4, strip.Color(0, 0, 0));
   strip.setPixelColor(5, strip.Color(255, 90, 0));
   strip.setPixelColor(6, strip.Color(255, 90, 0));
   strip.setPixelColor(7, strip.Color(255, 90, 0));
   strip.setPixelColor(8, strip.Color(0, 0, 0));
   strip.setPixelColor(9, strip.Color(0, 0, 0));
   break;
  case 9:
   strip.setPixelColor(0, strip.Color(0, 0, 0));
   strip.setPixelColor(1, strip.Color(0, 0, 0));
   strip.setPixelColor(2, strip.Color(0, 0, 0));
   strip.setPixelColor(3, strip.Color(0, 0, 0));
   strip.setPixelColor(4, strip.Color(255, 90, 0));
   strip.setPixelColor(5, strip.Color(255, 90, 0));
   strip.setPixelColor(6, strip.Color(255, 90, 0));
   strip.setPixelColor(7, strip.Color(0, 0, 0));
   strip.setPixelColor(8, strip.Color(0, 0, 0));
   strip.setPixelColor(9, strip.Color(0, 0, 0));
   break;
  case 10:
   strip.setPixelColor(0, strip.Color(0, 0, 0));
   strip.setPixelColor(1, strip.Color(0, 0, 0));
   strip.setPixelColor(2, strip.Color(0, 0, 0));
   strip.setPixelColor(3, strip.Color(0, 0, 0));
   strip.setPixelColor(4, strip.Color(255, 90, 0));
   strip.setPixelColor(5, strip.Color(255, 90, 0));
   strip.setPixelColor(6, strip.Color(255, 90, 0));
   strip.setPixelColor(7, strip.Color(0, 0, 0));
   strip.setPixelColor(8, strip.Color(0, 0, 0));
   strip.setPixelColor(9, strip.Color(0, 0, 0));
   break;
  case 11:
   strip.setPixelColor(0, strip.Color(0, 0, 0));
   strip.setPixelColor(1, strip.Color(0, 0, 0));
   strip.setPixelColor(2, strip.Color(0, 0, 0));
   strip.setPixelColor(3, strip.Color(0, 0, 0));
   strip.setPixelColor(4, strip.Color(255, 90, 0));
   strip.setPixelColor(5, strip.Color(255, 90, 0));
   strip.setPixelColor(6, strip.Color(255, 90, 0));
   strip.setPixelColor(7, strip.Color(0, 0, 0));
   strip.setPixelColor(8, strip.Color(0, 0, 0));
   strip.setPixelColor(9, strip.Color(0, 0, 0));
   break;
  case 12:
   strip.setPixelColor(0, strip.Color(0, 0, 0));
   strip.setPixelColor(1, strip.Color(0, 0, 0));
   strip.setPixelColor(2, strip.Color(0, 0, 0));
   strip.setPixelColor(3, strip.Color(255, 90, 0));
   strip.setPixelColor(4, strip.Color(255, 90, 0));
   strip.setPixelColor(5, strip.Color(255, 90, 0));
   strip.setPixelColor(6, strip.Color(0, 0, 0));
   strip.setPixelColor(7, strip.Color(0, 0, 0));
   strip.setPixelColor(8, strip.Color(0, 0, 0));
   strip.setPixelColor(9, strip.Color(0, 0, 0));
   break;
  case 13:
   strip.setPixelColor(0, strip.Color(0, 0, 0));
   strip.setPixelColor(1, strip.Color(0, 0, 0));
   strip.setPixelColor(2, strip.Color(0, 0, 0));
   strip.setPixelColor(3, strip.Color(255, 90, 0));
   strip.setPixelColor(4, strip.Color(255, 90, 0));
   strip.setPixelColor(5, strip.Color(255, 90, 0));
   strip.setPixelColor(6, strip.Color(0, 0, 0));
   strip.setPixelColor(7, strip.Color(0, 0, 0));
   strip.setPixelColor(8, strip.Color(0, 0, 0));
   strip.setPixelColor(9, strip.Color(0, 0, 0));
   break;
  case 14:
   strip.setPixelColor(0, strip.Color(0, 0, 0));
   strip.setPixelColor(1, strip.Color(0, 0, 0));
   strip.setPixelColor(2, strip.Color(255, 90, 0));
   strip.setPixelColor(3, strip.Color(255, 90, 0));
   strip.setPixelColor(4, strip.Color(255, 90, 0));
   strip.setPixelColor(5, strip.Color(0, 0, 0));
   strip.setPixelColor(6, strip.Color(0, 0, 0));
   strip.setPixelColor(7, strip.Color(0, 0, 0));
   strip.setPixelColor(8, strip.Color(0, 0, 0));
   strip.setPixelColor(9, strip.Color(0, 0, 0));
   break;
  case 15:
   strip.setPixelColor(0, strip.Color(0, 0, 0));
   strip.setPixelColor(1, strip.Color(0, 0, 0));
   strip.setPixelColor(2, strip.Color(255, 90, 0));
   strip.setPixelColor(3, strip.Color(255, 90, 0));
   strip.setPixelColor(4, strip.Color(255, 90, 0));
   strip.setPixelColor(5, strip.Color(0, 0, 0));
   strip.setPixelColor(6, strip.Color(0, 0, 0));
   strip.setPixelColor(7, strip.Color(0, 0, 0));
   strip.setPixelColor(8, strip.Color(0, 0, 0));
   strip.setPixelColor(9, strip.Color(0, 0, 0));
   break;
  case 16:
   strip.setPixelColor(0, strip.Color(0, 0, 0));
   strip.setPixelColor(1, strip.Color(255, 90, 0));
   strip.setPixelColor(2, strip.Color(255, 90, 0));
   strip.setPixelColor(3, strip.Color(255, 90, 0));
   strip.setPixelColor(4, strip.Color(0, 0, 0));
   strip.setPixelColor(5, strip.Color(0, 0, 0));
   strip.setPixelColor(6, strip.Color(0, 0, 0));
   strip.setPixelColor(7, strip.Color(0, 0, 0));
   strip.setPixelColor(8, strip.Color(0, 0, 0));
   strip.setPixelColor(9, strip.Color(0, 0, 0));
   break;
  case 17:
   strip.setPixelColor(0, strip.Color(0, 0, 0));
   strip.setPixelColor(1, strip.Color(255, 90, 0));
   strip.setPixelColor(2, strip.Color(255, 90, 0));
   strip.setPixelColor(3, strip.Color(255, 90, 0));
   strip.setPixelColor(4, strip.Color(0, 0, 0));
   strip.setPixelColor(5, strip.Color(0, 0, 0));
   strip.setPixelColor(6, strip.Color(0, 0, 0));
   strip.setPixelColor(7, strip.Color(0, 0, 0));
   strip.setPixelColor(8, strip.Color(0, 0, 0));
   strip.setPixelColor(9, strip.Color(0, 0, 0));
   break;
  case 18:
   strip.setPixelColor(0, strip.Color(0, 0, 0));
   strip.setPixelColor(1, strip.Color(255, 90, 0));
   strip.setPixelColor(2, strip.Color(255, 90, 0));
   strip.setPixelColor(3, strip.Color(255, 90, 0));
   strip.setPixelColor(4, strip.Color(0, 0, 0));
   strip.setPixelColor(5, strip.Color(0, 0, 0));
   strip.setPixelColor(6, strip.Color(0, 0, 0));
   strip.setPixelColor(7, strip.Color(0, 0, 0));
   strip.setPixelColor(8, strip.Color(0, 0, 0));
   strip.setPixelColor(9, strip.Color(0, 0, 0));
   break;
  case 19:
   strip.setPixelColor(0, strip.Color(255, 90, 0));
   strip.setPixelColor(1, strip.Color(255, 90, 0));
   strip.setPixelColor(2, strip.Color(255, 90, 0));
   strip.setPixelColor(3, strip.Color(0, 0, 0));
   strip.setPixelColor(4, strip.Color(0, 0, 0));
   strip.setPixelColor(5, strip.Color(0, 0, 0));
   strip.setPixelColor(6, strip.Color(0, 0, 0));
   strip.setPixelColor(7, strip.Color(0, 0, 0));
   strip.setPixelColor(8, strip.Color(0, 0, 0));
   strip.setPixelColor(9, strip.Color(0, 0, 0));
   break;
  case 20:
   strip.setPixelColor(0, strip.Color(255, 90, 0));
   strip.setPixelColor(1, strip.Color(255, 90, 0));
   strip.setPixelColor(2, strip.Color(255, 90, 0));
   strip.setPixelColor(3, strip.Color(0, 0, 0));
   strip.setPixelColor(4, strip.Color(0, 0, 0));
   strip.setPixelColor(5, strip.Color(0, 0, 0));
   strip.setPixelColor(6, strip.Color(0, 0, 0));
   strip.setPixelColor(7, strip.Color(0, 0, 0));
   strip.setPixelColor(8, strip.Color(0, 0, 0));
   strip.setPixelColor(9, strip.Color(0, 0, 0));
   break;
  case 21:
   strip.setPixelColor(0, strip.Color(255, 90, 0));
   strip.setPixelColor(1, strip.Color(255, 90, 0));
   strip.setPixelColor(2, strip.Color(0, 0, 0));
   strip.setPixelColor(3, strip.Color(0, 0, 0));
   strip.setPixelColor(4, strip.Color(0, 0, 0));
   strip.setPixelColor(5, strip.Color(0, 0, 0));
   strip.setPixelColor(6, strip.Color(0, 0, 0));
   strip.setPixelColor(7, strip.Color(0, 0, 0));
   strip.setPixelColor(8, strip.Color(0, 0, 0));
   strip.setPixelColor(9, strip.Color(255, 90, 0));
   break;
  case 22:
   strip.setPixelColor(0, strip.Color(255, 90, 0));
   strip.setPixelColor(1, strip.Color(255, 90, 0));
   strip.setPixelColor(2, strip.Color(0, 0, 0));
   strip.setPixelColor(3, strip.Color(0, 0, 0));
   strip.setPixelColor(4, strip.Color(0, 0, 0));
   strip.setPixelColor(5, strip.Color(0, 0, 0));
   strip.setPixelColor(6, strip.Color(0, 0, 0));
   strip.setPixelColor(7, strip.Color(0, 0, 0));
   strip.setPixelColor(8, strip.Color(0, 0, 0));
   strip.setPixelColor(9, strip.Color(255, 90, 0));
   break;
  case 23:
   strip.setPixelColor(0, strip.Color(255, 90, 0));
   strip.setPixelColor(1, strip.Color(255, 90, 0));
   strip.setPixelColor(2, strip.Color(0, 0, 0));
   strip.setPixelColor(3, strip.Color(0, 0, 0));
   strip.setPixelColor(4, strip.Color(0, 0, 0));
   strip.setPixelColor(5, strip.Color(0, 0, 0));
   strip.setPixelColor(6, strip.Color(0, 0, 0));
   strip.setPixelColor(7, strip.Color(0, 0, 0));
   strip.setPixelColor(8, strip.Color(0, 0, 0));
   strip.setPixelColor(9, strip.Color(255, 90, 0));
   break;
 }
  strip.show(); // This sends the updated pixel color to the hardware.
  delay(50);    // Delay for a period of time (in milliseconds).
}