        }   
   else {
      Serial.println(F("Error in OLL"));
-  }
-
-}
-
+     solving_level = 7;
+  }
+
+}
+
+
+//Method for solving the PLL
+void solvePLL() {
+   //Check that last layer permutations are already solved. If it is solved, complete the step. If not solved - find a solution.
+  if (ScannedCube[36] == ScannedCube[37] && ScannedCube[36] == ScannedCube[38] && ScannedCube[37] == ScannedCube[38] &&
+      ScannedCube[47] == ScannedCube[46] && ScannedCube[47] == ScannedCube[45] && ScannedCube[46] == ScannedCube[45] &&
+      ScannedCube[11] == ScannedCube[10] && ScannedCube[11] == ScannedCube[9] && ScannedCube[10] == ScannedCube[9] &&
+      ScannedCube[18] == ScannedCube[19] && ScannedCube[18] == ScannedCube[20] && ScannedCube[19] == ScannedCube[20]) {
+        solving_level = 5;
+        Serial.println(F("PLL solved"));
+   }
+      
+   else {
+       definePLLsequence(); 
+   }
+}
+
+//Method for defining the PLL solution sequence
+void definePLLsequence() {
+  byte index;
+  //Counter for controlling the number of u-moves
+  byte uTurnCount = 0;
+  //Flag showing that solution was found
+  boolean pllSequenceFound = false;
+  //Counter for finding the exact solution in solutions char string
+  byte pllPointCounter = 0;
+  //Search for a solution. If solution was not found - make the u-turn
+  while (pllSequenceFound == false && uTurnCount<4) {
+     for (index = 0; index <21; index++) {
+       if (ScannedCube[pgm_read_byte(&(pll_t[index][0]))] == ScannedCube[pgm_read_byte(&(pll_t[index][1]))] &&
+           ScannedCube[pgm_read_byte(&(pll_t[index][0]))] == ScannedCube[pgm_read_byte(&(pll_t[index][2]))] &&
+           ScannedCube[pgm_read_byte(&(pll_t[index][1]))] == ScannedCube[pgm_read_byte(&(pll_t[index][2]))] &&
+           ScannedCube[pgm_read_byte(&(pll_t[index][3]))] == ScannedCube[pgm_read_byte(&(pll_t[index][4]))] &&
+           ScannedCube[pgm_read_byte(&(pll_t[index][3]))] == ScannedCube[pgm_read_byte(&(pll_t[index][5]))] &&
+           ScannedCube[pgm_read_byte(&(pll_t[index][4]))] == ScannedCube[pgm_read_byte(&(pll_t[index][5]))] &&
+           ScannedCube[pgm_read_byte(&(pll_t[index][6]))] == ScannedCube[pgm_read_byte(&(pll_t[index][7]))] &&
+           ScannedCube[pgm_read_byte(&(pll_t[index][6]))] == ScannedCube[pgm_read_byte(&(pll_t[index][8]))] &&
+           ScannedCube[pgm_read_byte(&(pll_t[index][7]))] == ScannedCube[pgm_read_byte(&(pll_t[index][8]))] &&
+           ScannedCube[pgm_read_byte(&(pll_t[index][9]))] == ScannedCube[pgm_read_byte(&(pll_t[index][10]))] &&
+           ScannedCube[pgm_read_byte(&(pll_t[index][9]))] == ScannedCube[pgm_read_byte(&(pll_t[index][11]))] &&
+           ScannedCube[pgm_read_byte(&(pll_t[index][10]))] == ScannedCube[pgm_read_byte(&(pll_t[index][11]))]) {
+              pllSequenceFound = true;
+              break;
+            }
+        }
+      
+      if (pllSequenceFound == false) {
+        virtualMove('u');
+        uTurnCount ++;
+      }
+  }
+
+  Serial.print(F("PLL sequence #: "));
+  Serial.println(index);
+  
+  //Find a solution string in solutions char array
+  if (index < 21 && uTurnCount < 4) {
+      for (int k = 0; k<500; k++) { 
+          //Find the current dot separator number
+          if (pgm_read_byte(&(pll_solutions[k])) == '.') {
+            pllPointCounter ++;
+            }
+          //Perform the move if the needed solution was obtained
+          if (pllPointCounter == index && pgm_read_byte(&(pll_solutions[k])) != '.') {
+            virtualMove(pgm_read_byte(&(pll_solutions[k])));
+            }
+          //Stop as soon as the ending dot was found
+          else if (pllPointCounter > index) {
+            break;
+            }
+          }
+       }   
+  else {
+     Serial.println(F("Error in PLL"));
+     solving_level = 7;
+  }
+
+}
+
+
+void solveTLL() {
+  //Check if the upper level is rotated correctly. If not - turn it.
+  if (ScannedCube[10] == r_color && ScannedCube[19] == f_color && ScannedCube[37] == l_color && ScannedCube[46] == b_color) {
+    Serial.println(F("Last level rotated"));
+    solving_level = 6;
+    }
+  else {
+    if (ScannedCube[19] == r_color) {
+      virtualMove('u');
+    }
+    else if (ScannedCube[19] == l_color) {
+      virtualMove('U');
+    }
+    else if (ScannedCube[19] == b_color) {
+      virtualMove('U');
+      virtualMove('U');
+    }
+    else {
+      Serial.println(F("Error in TLL"));
+      solving_level = 7;
+    }
+  }
+
+}
+

  ".BlbLUUlubUBllul.RUrUrFRfUUrFRf.fBulULULUluFb.RUruLrFRfl.LFrflRURur.FURurURurf.BUbUBuLulb.rFRfUURurUfUUF.FUUFFuFufUULFl.lBLUlubLulUUL.rfRluLUrFR.BULUUluLUlb"
  ".lBLUlbLBub.FRUruf.RUrurFRf.RURRurFRURuf.bubRBrUB.rFRUrufUR.LfluLUFul.LFUfuFUful.fluLUluLUF.LFrFRfrFRFFl.LFUfuFufUFUfl.LfllBllFllbL"
  ".fRUUrUUrFFRf.LFFrfRfl.rFFLFlFR.LUlUlBLbLUUl.RUrurFRRUruf.LFrFRFFL.rfLflFFR.BLUlubUBLUlub.LrFRFrFRFFrFlR.burURB.BULulb.luBULulbL"
  ".RUburURBr.RUrURururFRf.LUlUUbuBuLul.LUUllBLbLUUl.FrfRURur.RurUURUBubur.lULUUlubUBUL.RRUrbRuRRURBr.rBLbLUUlubuB."
  ;

//Variables and counters for solving steps

    case 3:
      solveOLL();
      break;

    case 4:
      solvePLL();
      break;

    case 5:
      solveTLL();
      break;

    case 6:
      storeLCD(F("Cube solved"), 0);
      storeLCD(F("successfully!"), 1);
      delay(3000);
      solving_level = 8;
      break;

    case 7:
      storeLCD(F("Solving error"), 0);
      storeLCD(F("Check code"), 1);
      delay(3000);
      solving_level = 8;
      break;
  }
}

