sanelss

Color Sensor

Jan 7th, 2020
290
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include <Wire.h>
  2. #include <Adafruit_NeoPixel.h>
  3.  
  4. //These values are the readings of the whitepoint of the led. Take the back of vinyl sticker and put it againts face of sensor
  5. #define LED_RED 7540.0f
  6. #define LED_GREEN 14470.0f
  7. #define LED_BLUE 7270.0f
  8.  
  9. //Calculate the balancing factors
  10. #define BAL_RED (LED_GREEN/LED_RED)
  11. #define BAL_GREEN (LED_GREEN/LED_GREEN)
  12. #define BAL_BLUE (LED_GREEN/LED_BLUE)
  13.  
  14. #define I2C_ADDR 0x52
  15. #define PIXELNUM 8
  16.  
  17. Adafruit_NeoPixel pixels(PIXELNUM, 13, NEO_GRB + NEO_KHZ800);
  18.  
  19. uint8_t readBuff[9];
  20. uint16_t ir=0;
  21. uint16_t red=0;
  22. uint16_t green=0;
  23. uint16_t blue=0;
  24.  
  25. void setup() {
  26.   Wire.begin();
  27.   Serial.begin(115200);
  28.   pixels.begin();
  29.   i2cWrite(0x00,0b0110);  //enable light sensor and activate rgb mode
  30.   i2cWrite(0x04,0b01000000); //set to 16 bit resolution for 25ms response time and set measurement rate to 25ms
  31. }
  32.  
  33. void loop() {
  34.   i2cRead(0x0A,readBuff,12);
  35.  
  36.   ir=(readBuff[1]<<8)|readBuff[0];
  37.   green=(readBuff[4]<<8)|readBuff[3];
  38.   blue=(readBuff[7]<<8)|readBuff[6];
  39.   red=(readBuff[10]<<8)|readBuff[9];
  40.  
  41.   red*=BAL_RED;
  42.   green*=BAL_GREEN;
  43.   blue*=BAL_BLUE;
  44.  
  45.   Serial.print(ir);
  46.   Serial.print(" ");
  47.   Serial.print(red);
  48.   Serial.print(" ");
  49.   Serial.print(green);
  50.   Serial.print(" ");
  51.   Serial.print(blue);
  52.   Serial.println(" ");
  53.  
  54.   //Normalize the readings to brightest channel then apply log scale to better discern the colors.
  55.   float maxV=max(blue,max(red,green));
  56.   red=255*pow(red/maxV,5);
  57.   green=255*pow(green/maxV,5);
  58.   blue=255*pow(blue/maxV,5);
  59.  
  60.   if(blue>254){ //max blue?
  61.     red=0;
  62.     green=0;
  63.     blue=255;
  64.   }
  65.   else if(green>254){ //max green?
  66.     red=0;
  67.     green=255;
  68.     blue=0;
  69.   }
  70.   else if(red>254){   //Max red occurs when it's red or yellow
  71.     if(green<25){     //Check green channel, if it's below threadhold then it's not yellow
  72.       red=255;
  73.       green=0;
  74.       blue=0;
  75.     }
  76.     else{             //red is max and green is significant portion so we can assume it's yellow (though white will also trigger this since we don't check blue channel)
  77.       red=255;
  78.       green=150;
  79.       blue=0;
  80.     }
  81.   }
  82.  
  83.   //Reduce value for neopixels so it's not blinding
  84.   red=red>>2;
  85.   green=green>>2;
  86.   blue=blue>>2;
  87.  
  88.  
  89.  
  90.   for(uint8_t i=0;i<PIXELNUM;i++){
  91.     pixels.setPixelColor(i, pixels.Color(red, green, blue));
  92.   }
  93.   pixels.show();
  94.  
  95.   delay(25);
  96. }
  97.  
  98.  
  99. void i2cWrite(uint8_t reg, uint8_t val){
  100.     Wire.beginTransmission(I2C_ADDR);
  101.     Wire.write(reg);
  102.     Wire.write(val);
  103.     Wire.endTransmission();
  104. }
  105. void i2cRead(uint8_t reg,uint8_t *val,uint16_t len){
  106.     Wire.beginTransmission(I2C_ADDR);
  107.     Wire.write(reg);
  108.     Wire.endTransmission();
  109.     Wire.requestFrom(I2C_ADDR, len);
  110.     for(uint8_t i=0;i<len;i++){
  111.       val[i]=Wire.read();
  112.     }
  113. }
RAW Paste Data