// ============================================================ // NeoPixel + Sensor de color TCS34725 // El NeoPixel refleja el color detectado por el sensor // ============================================================ #include #include "Adafruit_TCS34725.h" #include // --- Configuración de pines y LEDs --- #define PIN_NEOPIXEL 6 #define NUM_PIXELS 1 #define BRILLO 150 // 0-255, baja si el LED es muy intenso // --- Sensor: tiempo de integración largo + ganancia alta para más precisión --- Adafruit_TCS34725 tcs = Adafruit_TCS34725( TCS34725_INTEGRATIONTIME_154MS, // 154ms es buen balance velocidad/precisión TCS34725_GAIN_4X // Ajusta según la luz del entorno ); Adafruit_NeoPixel strip(NUM_PIXELS, PIN_NEOPIXEL, NEO_GRB + NEO_KHZ800); // --- Parámetros de corrección de color --- #define UMBRAL_LUZ_MINIMA 20 // Valor mínimo de C para considerar lectura válida #define GAMMA 1.8 // Corrección gamma (1.0 = sin corrección) // --- Prototipo de funciones --- uint8_t corregirGamma(uint8_t valor); uint32_t leerColorSensor(); void testNeopixel(); void mostrarError(); // ============================================================ void setup() { Serial.begin(9600); Serial.println("=== NeoPixel + TCS34725 ==="); // Iniciar NeoPixel strip.begin(); strip.setBrightness(BRILLO); strip.clear(); strip.show(); // Test de colores al arrancar testNeopixel(); // Iniciar sensor if (!tcs.begin()) { Serial.println("ERROR: Sensor TCS34725 no encontrado."); Serial.println("Verifica conexiones SDA/SCL y alimentacion."); mostrarError(); // parpadeo rojo infinito } // Apagar LED integrado del sensor para no afectar lecturas tcs.setInterrupt(true); Serial.println("Sensor OK. Leyendo colores..."); Serial.println("R\tG\tB\tC\t| rN\tgN\tbN"); } // ============================================================ void loop() { uint16_t r, g, b, c; tcs.getRawData(&r, &g, &b, &c); // Imprimir valores crudos en Serial Plotter / Monitor Serial.print(r); Serial.print("\t"); Serial.print(g); Serial.print("\t"); Serial.print(b); Serial.print("\t"); Serial.print(c); Serial.print("\t| "); if (c < UMBRAL_LUZ_MINIMA) { // Sin luz suficiente: apagar el pixel strip.setPixelColor(0, strip.Color(0, 0, 0)); strip.show(); Serial.println("--- sin luz ---"); } else { // Normalizar a 0-255 usando el canal Clear como referencia // Limitar a c para evitar desbordamiento si R+G+B > C uint8_t rN = constrain(map(r, 0, c, 0, 255), 0, 255); uint8_t gN = constrain(map(g, 0, c, 0, 255), 0, 255); uint8_t bN = constrain(map(b, 0, c, 0, 255), 0, 255); // Corrección gamma para colores más naturales uint8_t rG = corregirGamma(rN); uint8_t gG = corregirGamma(gN); uint8_t bG = corregirGamma(bN); strip.setPixelColor(0, strip.Color(rG, gG, bG)); strip.show(); Serial.print(rG); Serial.print("\t"); Serial.print(gG); Serial.print("\t"); Serial.println(bG); } // El delay debe ser mayor que el tiempo de integración del sensor delay(200); } // ============================================================ // Corrección gamma para que los colores se vean más naturales // ============================================================ uint8_t corregirGamma(uint8_t valor) { float v = valor / 255.0; v = pow(v, 1.0 / GAMMA); return (uint8_t)(v * 255.0); } // ============================================================ // Test visual: rojo → verde → azul → blanco → apagado // ============================================================ void testNeopixel() { const uint32_t colores[] = { strip.Color(255, 0, 0 ), // Rojo strip.Color(0, 255, 0 ), // Verde strip.Color(0, 0, 255), // Azul strip.Color(255, 255, 255), // Blanco }; const char* nombres[] = { "Rojo", "Verde", "Azul", "Blanco" }; Serial.println("Test NeoPixel..."); for (int i = 0; i < 4; i++) { Serial.print(" -> "); Serial.println(nombres[i]); strip.setPixelColor(0, colores[i]); strip.show(); delay(400); } strip.clear(); strip.show(); Serial.println("Test OK"); } // ============================================================ // Parpadeo rojo de error (se queda aquí si el sensor falla) // ============================================================ void mostrarError() { while (true) { strip.setPixelColor(0, strip.Color(255, 0, 0)); strip.show(); delay(200); strip.clear(); strip.show(); delay(200); } }