#include <Adafruit_NeoPixel.h>

#define PIN 6
#define PIN2 5
#define PIN3 4
#define LED_COUNT 4
#define pingPin 7

Adafruit_NeoPixel strip_a = Adafruit_NeoPixel(LED_COUNT, PIN, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel strip_b = Adafruit_NeoPixel(LED_COUNT, PIN2, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel strip_c = Adafruit_NeoPixel(LED_COUNT, PIN3, NEO_GRB + NEO_KHZ800);
void setup() {
  strip_c.begin();
  strip_c.show(); // Initialize all pixels to 'off'
  strip_b.begin();
  strip_b.show(); // Initialize all pixels to 'off'
  strip_a.begin();
  strip_a.show(); // Initialize all pixels to 'off'
  pinMode(pingPin, INPUT);
  pinMode(TESTPIN, OUTPUT);
}

void loop() {
  
  rainbowCycle(30);   //Default speed if no one is using the sensor

}

// Cycles through rainbow, with speed influenced by proximity sensor
void rainbowCycle(uint8_t wait) {
  uint16_t i, j;
  
for(j=0; j<256*5; j++) { // 5 cycles of all colors on wheel
    
    long duration, inches, cm;

  pinMode(pingPin, OUTPUT);           //to send out pulse
  digitalWrite(pingPin, LOW);         //ensure clean HIGH pulse
  delayMicroseconds(2);               
  digitalWrite(pingPin, HIGH);        // pulse on
  delayMicroseconds(5);
  digitalWrite(pingPin, LOW);         // pulse off

  pinMode(pingPin, INPUT);            //to read reflected pulse
  duration = pulseIn(pingPin, HIGH);  //record time between send and receive

  inches = microsecondsToInches(duration);  // convert the time into a distance

  wait = map(inches, 0, 40, 0, 30);   // map sensor values to useful range for function
  wait = (int) wait;
  
    for(i=0; i< strip_a.numPixels(); i++) {
      strip_a.setPixelColor(i, Wheel(((i * 256 / (strip_a.numPixels() * 10)) + j) & 255));
    }
    for(i=0; i< strip_b.numPixels(); i++) {
      strip_b.setPixelColor(i, Wheel(((i * 256 / (strip_b.numPixels()) * 1) + j) & 255));
    }
    for(i=0; i< strip_c.numPixels(); i++) {
      strip_c.setPixelColor(i, Wheel(((i * 256 / (strip_c.numPixels()) * 5) + j) & 255));
    }
    strip_a.show();
    strip_b.show();
    strip_c.show();
    delay(wait);
  }
}



// Input a value 0 to 255 to get a color value.
// The colours are a transition r - g - b - back to r.
uint32_t Wheel(byte WheelPos) {
  WheelPos = 255 - WheelPos;
  if(WheelPos < 85) {
   return strip_a.Color(255 - WheelPos * 3, 0, WheelPos * 3);
   return strip_b.Color(255 - WheelPos * 3, 0, WheelPos * 3);
  } else if(WheelPos < 170) {
    WheelPos -= 85;
   return strip_a.Color(0, WheelPos * 3, 255 - WheelPos * 3);
   return strip_b.Color(0, WheelPos * 3, 255 - WheelPos * 3);
  } else {
   WheelPos -= 170;
   return strip_a.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
   return strip_b.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
  }
}


long microsecondsToInches(long microseconds) {
  // According to Parallax's datasheet for the PING))), there are
  // 73.746 microseconds per inch (i.e. sound travels at 1130 feet per
  // second).  This gives the distance travelled by the ping, outbound
  // and return, so we divide by 2 to get the distance of the obstacle.
  // See: http://www.parallax.com/dl/docs/prod/acc/28015-PING-v1.3.pdf
  return microseconds / 74 / 2;
}
