2014-09-19 12:54:49




| NO | 부품명 | 수량 | 상세설명 | 
| 1 | Arduino Flora | 1 | 아두이노 | 
| 2 | NeoPixel Ring | 1 | NeoPixel | 
| 3 | Flora Wearable Ultimate GPS Module | 1 | GPS | 
| 4 | Color Sensor(TCS34725) | 1 | Color Sensor | 
| 5 | 버튼 | 1 | 버튼 | 
| 6 | 10kΩ 저항 | 1 | 저항 | 
| 7 | 점퍼케이블 | 14 | 점퍼케이블 | 
| 부품명 | Arduino Flora | NeoPixel Ring | GPS Module | Color Sensor | Button | 10kΩ 저항 | 점퍼케이블 | 
| 파트 | ![]()  | 
![]()  | 
![]()  | 
![]()  | 
![]()  | 
![]()  | 
![]()  | 


#include <Wire.h>
#include "Adafruit_TCS34725.h"
#include <Adafruit_GPS.h>
#include <SoftwareSerial.h>
#include <Adafruit_NeoPixel.h>
#include "Flora_Pianoglove.h"
#define PIN 6
#define buttonPIN 10
#define CLEARTHRESHHOLD 2000
Adafruit_GPS GPS(&Serial1);
#define GPSECHO false
boolean usingInterrupt = false;
int temp = 0;
int buttonState = 0;
byte gammatable[256];
Adafruit_NeoPixel strip = Adafruit_NeoPixel(16, PIN, NEO_GRB + NEO_KHZ800);
Adafruit_TCS34725 tcs = Adafruit_TCS34725(TCS34725_INTEGRATIONTIME_50MS, TCS34725_GAIN_4X);
void setup()  
{
  Serial.begin(115200);
  pinMode(buttonPIN, INPUT);
  Serial.println("Adafruit GPS library basic test!");
  
  strip.begin();
  strip.show();
   if (tcs.begin()) {
    Serial.println("Found sensor");
  } 
  else {
    Serial.println("No TCS34725 found ... check your connections");
    while (1); 
  }
   
  GPS.begin(9600);
  
  GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA);
  GPS.sendCommand(PMTK_SET_NMEA_UPDATE_1HZ);  
  delay(1000);
  Serial1.println(PMTK_Q_RELEASE);
  
    for (int i=0; i<256; i++) {
    float x = i;
    x /= 255;
    x = pow(x, 2.5);
    x *= 255;
    gammatable[i] = x;      
  }
  
    tcs.setInterrupt(true);  
}
 
uint32_t timer = millis();
void loop(){
  // 버튼을 눌러 현재 버튼의 상태값에 따라 모드를 전환시켜줍니다. 
  if(!digitalRead(buttonPIN)){
    buttonState++;
    
    if(buttonState > 2){
      buttonState = 0;
    }
    
    delay(500);
  }
  if(buttonState == 0){
    rainbowCycle(20);
   // 대기모드(무지개 색으로 LED가 켜집니다.)
  }
  else if(buttonState == 1){
    gpsCheck();
   // GPS 시계 모드(현재 시간을 표시합니다.)
  }
  else if(buttonState == 2){
    colorPick();
    // 칼라 픽업 모드(시계 가운데 있는 센서에서 색을 측정하여 LED로 표현합니다.)
  }
  delay(10);
}
void gpsCheck(){ // 시계 모드
  char c = GPS.read();
  if (GPSECHO)
      if (c) Serial.print(c);
 
  if (GPS.newNMEAreceived()) {
    Serial.println(GPS.lastNMEA());   
  
    if (!GPS.parse(GPS.lastNMEA()))   
      return; 
  }
  
  if (timer > millis())  timer = millis();
 
  if (millis() - timer > 2000) { 
    timer = millis(); 
    int hour;
    if(GPS.hour < 3){
      hour = GPS.hour + 9;  
    }else{
      hour = GPS.hour - 3;    
    }   
   
    Serial.print("\nTime: ");
    Serial.print(hour, DEC); Serial.print(':');
    Serial.print(GPS.minute, DEC); Serial.print(':');
    Serial.println(GPS.seconds, DEC); Serial.print('.');
    
    int h = map(hour, 0, 12, 15, 0);
    int m = map(GPS.minute, 0, 59, 15, 0);
    int s = map(GPS.seconds, 0, 59, 15, 0);
    for(int i = 0; i < strip.numPixels(); i++){
      strip.setPixelColor(i, strip.Color(0, 0, 0));
      strip.show();
    }
    strip.setPixelColor(s, strip.Color(0, 0, 255));
    strip.setPixelColor(m, strip.Color(0, 255, 0));   
    strip.setPixelColor(h, strip.Color(255, 0, 0));
    
    strip.show();
    
   // Serial.println(GPS.milliseconds);
    Serial.print("Date: ");
    Serial.print(GPS.day, DEC); Serial.print('/');
    Serial.print(GPS.month, DEC); Serial.print("/20");
    Serial.println(GPS.year, DEC);
    Serial.print("Fix: "); Serial.print((int)GPS.fix);
    Serial.print(" quality: "); Serial.println((int)GPS.fixquality); 
    if (GPS.fix) {
      Serial.print("Location: ");
      Serial.print(GPS.latitude, 4); Serial.print(GPS.lat);
      Serial.print(", "); 
      Serial.print(GPS.longitude, 4); Serial.println(GPS.lon);
      
      Serial.print("Speed (knots): "); Serial.println(GPS.speed);
      Serial.print("Angle: "); Serial.println(GPS.angle);
      Serial.print("Altitude: "); Serial.println(GPS.altitude);
      Serial.print("Satellites: "); Serial.println((int)GPS.satellites);
    }
  }
}
void rainbow(uint8_t wait) { // 대기모드
  uint16_t i, j;
  for(j=0; j<256; j++) {
    for(i=0; i<strip.numPixels(); i++) {
      strip.setPixelColor(i, Wheel((i+j) & 255));
    }
    strip.show();
    delay(wait);
  }
}
// Slightly different, this makes the rainbow equally distributed throughout
void rainbowCycle(uint8_t wait) {
  uint16_t i, j;
  for(j=0; j<256; j++) { // 5 cycles of all colors on wheel
    for(i=0; i< strip.numPixels(); i++) {
      strip.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + j) & 255));
    }
    strip.show();
  }
}
// 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) {
  if(WheelPos < 85) {
   return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
  } else if(WheelPos < 170) {
   WheelPos -= 85;
   return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
  } else {
   WheelPos -= 170;
   return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
  }
}
void colorPick() { // 칼라 픽업 모드
  uint16_t clear, red, green, blue;
  tcs.setInterrupt(false);      // LED를 켭니다.
  delay(60);  //50밀리초동안 읽습니다.
  tcs.getRawData(&red, &green, &blue, &clear);
  tcs.setInterrupt(true);  // LED를 끕니다.
  //충분한 색정보를 불러올 수 있는 대상이 없을 경우
  if (clear < CLEARTHRESHHOLD) {
    for(int i = 0; i < 16; i++){
      strip.setPixelColor(i, strip.Color(0, 0, 0)); // LED를 끕니다.
      strip.show();
    }
    return;
  }
  //  Serial.print("C:\t"); Serial.print(clear);
  //  Serial.print("\tR:\t"); Serial.print(red);
  //  Serial.print("\tG:\t"); Serial.print(green);
  //  Serial.print("\tB:\t"); Serial.print(blue);
  // 시각화를 위해 hex code를 계산합니다.
  uint32_t sum = red;
  sum += green;
  sum += blue;
  sum = clear;
  float r, g, b;
  r = red; 
  r /= sum;
  g = green; 
  g /= sum;
  b = blue; 
  b /= sum;
  r *= 256; 
  g *= 256; 
  b *= 256;
  if (r > 255) r = 255;
  if (g > 255) g = 255;
  if (b > 255) b = 255;
  //  Serial.print("\t");
  //  Serial.print((int)r, HEX); Serial.print((int)g, HEX); Serial.print((int)b, HEX); 
  //  Serial.println();
  float remove, normalize;
  if ((b < g) && (b < r)) {
    remove = b;
    normalize = max(r-b, g-b);
  } 
  else if ((g < b) && (g < r)) {
    remove = g;
    normalize = max(r-g, b-g);
  } 
  else {
    remove = r;
    normalize = max(b-r, g-r);
  }
  //작은 소수를 제거합니다.
  float rednorm = r - remove;
  float greennorm = g - remove;
  float bluenorm = b - remove;
  // 가장 높은수를 정상화 합니다.
  rednorm /= normalize;
  greennorm /= normalize;
  bluenorm /= normalize;
  //  Serial.println();
 // for(int j = 0; j < 16; j++){
    strip.setPixelColor(temp, strip.Color(gammatable[(int)r], gammatable[(int)g], gammatable[(int)b]));
    
    for(temp; temp < 16; temp++){
      strip.setPixelColor(temp, strip.Color(gammatable[(int)r], gammatable[(int)g], gammatable[(int)b]));      
    }
    strip.show();
    
    if(temp < 16)
      temp++;
      
     else
      temp = 0;
 // }
  //  Serial.print(rednorm); Serial.print(", "); 
  //  Serial.print(greennorm); Serial.print(", "); 
  //  Serial.print(bluenorm); Serial.print(" "); 
  //  Serial.println();
}
RgbColor HsvToRgb(HsvColor hsv){
  
  RgbColor rgb;
  unsigned char region, remainder, p, q, t;
  if (hsv.s == 0)
  {
    rgb.r = hsv.v;
    rgb.g = hsv.v;
    rgb.b = hsv.v;
    return rgb;
  }
  region = hsv.h / 43;
  remainder = (hsv.h - (region * 43)) * 6; 
  p = (hsv.v * (255 - hsv.s)) >> 8;
  q = (hsv.v * (255 - ((hsv.s * remainder) >> 8))) >> 8;
  t = (hsv.v * (255 - ((hsv.s * (255 - remainder)) >> 8))) >> 8;
  switch (region)
  {
  case 0:
    rgb.r = hsv.v; 
    rgb.g = t; 
    rgb.b = p;
    break;
  case 1:
    rgb.r = q; 
    rgb.g = hsv.v; 
    rgb.b = p;
    break;
  case 2:
    rgb.r = p; 
    rgb.g = hsv.v; 
    rgb.b = t;
    break;
  case 3:
    rgb.r = p; 
    rgb.g = q; 
    rgb.b = hsv.v;
    break;
  case 4:
    rgb.r = t; 
    rgb.g = p; 
    rgb.b = hsv.v;
    break;
  default:
    rgb.r = hsv.v; 
    rgb.g = p; 
    rgb.b = q;
    break;
  }
  return rgb;
}
HsvColor RgbToHsv(RgbColor rgb){
  
  HsvColor hsv;
  unsigned char rgbMin, rgbMax;
  rgbMin = rgb.r < rgb.g ? (rgb.r < rgb.b ? rgb.r : rgb.b) : 
  (rgb.g < rgb.b ? rgb.g : rgb.b);
  rgbMax = rgb.r > rgb.g ? (rgb.r > rgb.b ? rgb.r : rgb.b) : 
  (rgb.g > rgb.b ? rgb.g : rgb.b);
  hsv.v = rgbMax;
  if (hsv.v == 0)
  {
    hsv.h = 0;
    hsv.s = 0;
    return hsv;
  }
  hsv.s = 255 * long(rgbMax - rgbMin) / hsv.v;
  if (hsv.s == 0)
  {
    hsv.h = 0;
    return hsv;
  }
  if (rgbMax == rgb.r)
    hsv.h = 0 + 43 * (rgb.g - rgb.b) / (rgbMax - rgbMin);
  else if (rgbMax == rgb.g)
    hsv.h = 85 + 43 * (rgb.b - rgb.r) / (rgbMax - rgbMin);
  else
    hsv.h = 171 + 43 * (rgb.r - rgb.g) / (rgbMax - rgbMin);
  return hsv;
}
void loop(){
  // 버튼을 눌러 현재 버튼의 상태값에 따라 모드를 전환시켜줍니다. 
  if(!digitalRead(buttonPIN)){
    buttonState++;
    
    if(buttonState > 2){
      buttonState = 0;
    }
    
    delay(500);
  }
  if(buttonState == 0){
    rainbowCycle(20);
   // 대기모드(무지개 색으로 LED가 켜집니다.)
  }
  else if(buttonState == 1){
    gpsCheck();
   // GPS 시계 모드(현재 시간을 표시합니다.)
  }
  else if(buttonState == 2){
    colorPick();
    // 칼라 픽업 모드(시계 가운데 있는 센서에서 색을 측정하여 LED로 표현합니다.)
  }
  delay(10);
}
    for(int i = 0; i < 16; i++){
      strip.setPixelColor(i, strip.Color(gammatable[(int)r], gammatable[(int)g], gammatable[(int)b]));      
      strip.show();
    }
    int h = map(GPS.hour, 0, 12, 15, 0);
    int m = map(GPS.minute, 0, 59, 15, 0);
    int s = map(GPS.seconds, 0, 59, 15, 0);
    for(int i = 0; i < strip.numPixels(); i++){
      strip.setPixelColor(i, strip.Color(0, 0, 0));
      strip.show();
    }
    strip.setPixelColor(s, strip.Color(0, 0, 255));
    strip.setPixelColor(m, strip.Color(0, 255, 0));   
    strip.setPixelColor(h, strip.Color(255, 0, 0));
 
		
			판다마니아
			아두이노, Flora, GPS, Color Sensor, 중급, Button, NeoPixel, LED