       digitalWrite(ledPin, ledState);
       if (xv_config.show_dist) {
         curMillis = millis();
-        Serial.print(F("Time Interval: "));
-        Serial.println(curMillis - lastMillis);
+        if(xv_config.show_angle == SHOW_ALL_ANGLES) {
+          /*
+          Serial.print(F("Time Interval: "));
+          Serial.println(curMillis - lastMillis);
+          */
+        }
         lastMillis = curMillis;
       }
-    }
-    //Serial.print(int(data_4deg_index));
-    //Serial.println(F(" "));
-    break;
-
-  case 2: // speed in RPH low byte
-    motor_rph_low_byte = inByte;
-    break;
-
-  case 3: // speed in RPH high byte
-    motor_rph_high_byte = inByte;
+    } // if (angle == 0)
+  }  // if (bValidData)
+  return angle;
+}
+/*
+ * processSpeed- Process the packet element 'speed'
+ * speed is two-bytes of information, little-endian. It represents the speed, in 64th of RPM (aka value 
+ *    in RPM represented in fixed point, with 6 bits used for the decimal part).
+ * Enter with: bValidData = true if packet is okay (good CRC)
+ * Uses:       Packet
+ *             angle = if 0 then enable display of RPM and PWM
+ *             xv_config.show_rpm = true if we're supposed to display RPM and PWM
+ * Calls:      Serial.print
+ */
+void processSpeed(boolean bValidData) {
+  if (bValidData) {
+    motor_rph_low_byte = Packet[OFFSET_TO_SPEED_LSB];
+    motor_rph_high_byte = Packet[OFFSET_TO_SPEED_MSB];
     motor_rph = (motor_rph_high_byte << 8) | motor_rph_low_byte;
     motor_rpm = float( (motor_rph_high_byte << 8) | motor_rph_low_byte ) / 64.0;
-    if (xv_config.show_rpm and angle == 0) {
+    if (xv_config.show_rpm and startingAngle == 0) {
       Serial.print(F("RPM: "));
       Serial.print(motor_rpm);
       Serial.print(F("  PWM: "));   
       Serial.println(pwm_val);
     }
-    break;
-
-  case 4:
-    data0 = inByte; // first half of distance data
-    break;
-
-  case 5:
-    if ((inByte & 0x80) >> 7) {  // check for Invalid Flag
-      dist = 0;
-    } 
-    else {
-      dist =  data0 | (( inByte & 0x3F) << 8);
-    }
-    break;
-
-  case 6:
-    data2 = inByte; // first half of quality data
-    break;
-
-  case 7:
-    quality = (inByte << 8) | data2; 
-    if (xv_config.show_dist) {
-      if (xv_config.show_angle == 360 or xv_config.show_angle == angle) {
-        Serial.print(angle);
-        Serial.print(F(": "));
-        Serial.print(int(dist));
-        Serial.print(F(" ("));
-        Serial.print(quality);
-        Serial.println(F(")"));
-      }
-    }   
-    break;
-
-  case 8:
-    angle = data_4deg_index * 4 + 1; // 2nd angle in the set
-    data0 = inByte;
-    break;
-
-  case 9:
-    if ((inByte & 0x80) >> 7) {  // check for Invalid Flag
-      dist = 0;
-    } 
-    else {
-      dist =  data0 | (( inByte & 0x3F) << 8);
-    }
-    break;
-
-  case 10:
-    data2 = inByte; // first half of quality data
-    break;
-
-  case 11:
-    quality = (inByte << 8) | data2; 
-    if (xv_config.show_dist) {
-      if (xv_config.show_angle == 360 or xv_config.show_angle == angle) {
-        Serial.print(angle);
-        Serial.print(F(": "));
-        Serial.print(int(dist));
-        Serial.print(F(" ("));
-        Serial.print(quality);
-        Serial.println(F(")"));
-      }
-    }
-    break;
-
-  case 12:
-    angle = data_4deg_index * 4 + 2; // 3rd angle in the set
-    data0 = inByte;
-    break;
-
-  case 13:
-    if ((inByte & 0x80) >> 7) {  // check for Invalid Flag
-      dist = 0;
-    } 
-    else {
-      dist =  data0 | (( inByte & 0x3F) << 8);
-    }
-    break;
-
-  case 14:
-    data2 = inByte; // first half of quality data
-    break;
-
-  case 15:
-    quality = (inByte << 8) | data2; 
-    if (xv_config.show_dist) {
-      if (xv_config.show_angle == 360 or xv_config.show_angle == angle) {
-        Serial.print(angle);
-        Serial.print(F(": "));
-        Serial.print(int(dist));
-        Serial.print(F(" ("));
-        Serial.print(quality);
-        Serial.println(F(")"));
-      }
-    }
-    break;
-
-  case 16:
-    angle = data_4deg_index * 4 + 3;  // 4th angle in the set
-    data0 = inByte;
-    break;
-
-  case 17:
-    if ((inByte & 0x80) >> 7) {  // check for Invalid Flag
-      dist = 0;
-    } 
-    else {
-      dist =  data0 | (( inByte & 0x3F) << 8);
-    }
-    break;
-
-  case 18:
-    data2 = inByte; // first half of quality data
-    break;
-
-  case 19:
-    quality = (inByte << 8) | data2; 
-    if (xv_config.show_dist) {
-      if (xv_config.show_angle == 360 or xv_config.show_angle == angle) {
-        Serial.print(angle);
-        Serial.print(F(": "));
-        Serial.print(int(dist));
-        Serial.print(F(" ("));
-        Serial.print(quality);
-        Serial.println(F(")"));
-      }
-    }
-    break;
-
-  default: // others do checksum
-    break;
-  }  
-}
-
+  }  // if (bValidData)
+}
+/*
+ * Data 0 to Data 3 are the 4 readings. Each one is 4 bytes long, and organized as follows :
+ *   byte 0 : <distance 7:0>
+ *   byte 1 : <"invalid data" flag> <"strength warning" flag> <distance 13:8>
+ *   byte 2 : <signal strength 7:0>
+ *   byte 3 : <signal strength 15:8>
+ */
+/*
+ * processDistance- Process the packet element 'distance'
+ * Enter with: bValidData = true if packet is okay (good CRC)
+ *             iQuad = which one of the (4) readings to process, value = 0..3
+ * Uses:       Packet
+ *             dist[] = distance to object
+ * Calls:      N/A
+ */
+void processDistance(boolean bValidData, int iQuad) {
+  uint8_t dataL, dataM;
+  dist[iQuad] = 0;                       // initialize
+  if (bValidData) {
+    int iOffset = (iQuad * N_DATA_QUADS) + OFFSET_TO_4_DATA_READINGS + OFFSET_DATA_DISTANCE_LSB;    
+    // byte 0 : <distance 7:0>
+    // byte 1 : <"invalid data" flag> <"strength warning" flag> <distance 13:8>
+    dataL = Packet[iOffset];             // first half of distance data
+    dataM = Packet[iOffset + 1];         // get MSB of distance data + flags
+    if ((dataM & 0x80) == 0)             // check for Invalid Flag
+      dist[iQuad] = dataL | ((dataM & 0x3F) << 8);
+  }  // if (bValidData)
+}
+/*
+ * processSignalStrength- Process the packet element 'signal strength'
+ * Enter with: bValidData = true if packet is okay (good CRC)
+ *             iQuad = which one of the (4) readings to process, value = 0..3
+ * Uses:       Packet
+ *             quality[] = signal quality
+ * Calls:      N/A
+ */
+void processSignalStrength(boolean bValidData, int iQuad) {
+  uint8_t dataL, dataM;
+  quality[iQuad] = 0;                        // initialize
+  if (bValidData) {
+    int iOffset = (iQuad * N_DATA_QUADS) + OFFSET_TO_4_DATA_READINGS + OFFSET_DATA_SIGNAL_LSB;    
+    dataL = Packet[iOffset];                  // signal strength LSB  
+    dataM = Packet[iOffset + 1];
+    quality[iQuad] = dataL | (dataM << 8);
+  }  // if (bValidData)
+}
+
+/*
+ * eValidatePacket - Validate 'Packet'
+ * Enter with: 'Packet' is ready to check
+ * Uses:       CalcCRC
+ * Exits with: 0 = Packet is okay
+ * Error:      non-zero = Packet is no good
+ */
+byte eValidatePacket() {
+  unsigned long chk32;
+  unsigned long checksum;
+  const int bytesToCheck = PACKET_LENGTH - 2;
+  const int CalcCRC_Len = bytesToCheck / 2;
+  unsigned int CalcCRC[CalcCRC_Len];
+
+  byte b1a, b1b, b2a, b2b;
+  int ix;
+
+  for (int ix = 0; ix < CalcCRC_Len; ix++)       // initialize 'CalcCRC' array
+    CalcCRC[ix] = 0;
+    
+  // Perform checksum validity test
+  for (ix = 0; ix < bytesToCheck; ix += 2)      // build 'CalcCRC' array
+    CalcCRC[ix / 2] = Packet[ix] + ((Packet[ix + 1]) << 8);          
+
+  chk32 = 0;
+  for (ix = 0; ix < CalcCRC_Len; ix++) 
+    chk32 = (chk32 << 1) + CalcCRC[ix];            
+  checksum = (chk32 & 0x7FFF) + (chk32 >> 15);
+  checksum &= 0x7FFF;
+  
+  b1a = checksum & 0xFF;
+  b1b = Packet[OFFSET_TO_CRC_L];
+  b2a = checksum >> 8;
+  b2b = Packet[OFFSET_TO_CRC_M];
+  if ((b1a == b1b) && (b2a == b2b)) 
+    return 0;                                  // okay
+  else
+    return 1;                                  // non-zero = bad CRC
+}
+
+/*
+ * initEEPROM
+ */
 void initEEPROM() {
   xv_config.id = 0x05;
   strcpy(xv_config.version, "1.2.2");

  Serial.println(F("  ShowDist      - Show the distance data"));
  Serial.println(F("  HideDist      - Hide the distance data"));
  Serial.println(F("  ShowAngle     - Show distance data for a specific angle (0 - 359 or 360 for all)"));
  Serial.println(F("  MotorOff      - Stop spinning the lidar"));
  Serial.println(F("  MotorOn       - Enable spinning of the lidar"));
  Serial.println(F("  HideRaw       - Stop outputting the raw data from the lidar"));

  Serial.print(F("Showing RPM data"));
  Serial.println(F(" "));
}
/*
 * hideRPM
 */
void hideRPM() {
  xv_config.show_rpm = false;
  Serial.println(F(" "));
