Showing posts with label sensor. Show all posts
Showing posts with label sensor. Show all posts

Wednesday, June 25, 2025

TCS34725 Color Sensing Cube with Arduino

-----

Whatever color the TCS34725 sensor "sees" is reproduced on the orb on top of the cube.   The switch in front is hardwired to the LED light on the front of the sensor because we found the LED annoying and most of the time unnecessary.

-----

Bill of Materials....

     TCS34725

     The orb is a plastic cover from a non functioning LED light bulb: 

     An old Arduino Nano: 
    A switch and a 3D Printed Box:  
-----

Wire per the comments in the Arduino sketch below and you should get this:


-----

// Read Color Sensor.  Mimic color on RGB LED sees
// https://www.whiskeytangohotel.com/
// JUNE 2026

// Arduino Nano but, must selected under Tools → Processor:
// ATmega328P (Old Bootloader) or suffer the avrdude error.

#include <Wire.h>
#include "Adafruit_TCS34725.h"

// TCS34725 SDA pin should be connected to A4
// TCS34725 SCL pin should be connected to A5
// TCS34725 GND to GND
// TCS34725 3.3V to 5V (Vin is No Connect)
// TCS34725 LED goes to hardwired switch  

// Define pins for RGB LED
const int RED_PIN = 10;
const int GREEN_PIN = 9;
const int BLUE_PIN = 11;

// Define digital pin for TCS34725 LED control
const int SENSOR_LED_PIN = 6;  // Not used, this LED is controlled with a hardwired switch

// Initialize the sensor
Adafruit_TCS34725 tcs = Adafruit_TCS34725(
  TCS34725_INTEGRATIONTIME_50MS,
  TCS34725_GAIN_4X
);

void setup() {
  Serial.begin(9600);  // We use the serial monitor for debug
  
  // RGB LED pins
  pinMode(RED_PIN, OUTPUT);
  pinMode(GREEN_PIN, OUTPUT);
  pinMode(BLUE_PIN, OUTPUT);

  // Sensor LED control pin
  pinMode(SENSOR_LED_PIN, OUTPUT);
  digitalWrite(SENSOR_LED_PIN, LOW); // turn off sensor LED initially

  if (tcs.begin()) {
    Serial.println("TCS34725 sensor found");
    // Self-test only if sensor found: cycle RGB LED through R, G, B 
    for (int i = 7; i > 0; i--) {
      // Red
      Serial.println("RED Self Test");
      analogWrite(RED_PIN, 255);
      analogWrite(GREEN_PIN, 0);
      analogWrite(BLUE_PIN, 0);
      delay(50 * i);

      // Green
      Serial.println("GREEN Self Test");
      analogWrite(RED_PIN, 0);
      analogWrite(GREEN_PIN, 255);
      analogWrite(BLUE_PIN, 0);
      delay(50 * i);

      // Blue
      Serial.println("BLUE Self Test");
      analogWrite(RED_PIN, 0);
      analogWrite(GREEN_PIN, 0);
      analogWrite(BLUE_PIN, 255);
      delay(50 * i);  
    }  
  } else {
    Serial.println("No TCS34725 sensor found ... check wiring?");
    // RED LED to show error
    analogWrite(RED_PIN, 155);
    analogWrite(GREEN_PIN, 0);
    analogWrite(BLUE_PIN, 0);
    while (1);
  }
}

void loop() {
  uint16_t r, g, b, c;
  tcs.getRawData(&r, &g, &b, &c);

  if (c < 5) {
    // In near total darkness: cycle through rainbow
    showRainbowCycle();
  } else {
    // Normal color mimic
    uint16_t maxRaw = max(max(r, g), b);
    if (maxRaw == 0) maxRaw = 1;

    int redVal   = (uint32_t)r * 255 / maxRaw;
    int greenVal = (uint32_t)g * 255 / maxRaw;
    int blueVal  = (uint32_t)b * 255 / maxRaw;

    redVal   = constrain(redVal, 0, 255);
    greenVal = constrain(greenVal, 0, 255);
    blueVal  = constrain(blueVal, 0, 255);

    analogWrite(RED_PIN,   gammaCorrect(redVal));
    analogWrite(GREEN_PIN, gammaCorrect(greenVal));
    analogWrite(BLUE_PIN,  gammaCorrect(blueVal));
  }

  delay(50); // smooth update
}


int gammaCorrect(int val) {  // makes it look "better"
  float gamma = 2.2;
  return pow(val / 255.0, gamma) * 255.0;
}

void showRainbowCycle() {  // If full dark gentle cycle thru colors
  static float hue = 0;
  hue += 0.5;  // Change speed here
  if (hue > 360) hue = 0;

  float r, g, b;
  float s = 1.0;
  float v = 1.0;
  float h = hue;

  int i = int(h / 60.0) % 6;
  float f = h / 60.0 - i;
  float p = v * (1 - s);
  float q = v * (1 - f * s);
  float t = v * (1 - (1 - f) * s);

  switch(i) {
    case 0: r = v, g = t, b = p; break;
    case 1: r = q, g = v, b = p; break;
    case 2: r = p, g = v, b = t; break;
    case 3: r = p, g = q, b = v; break;
    case 4: r = t, g = p, b = v; break;
    case 5: r = v, g = p, b = q; break;
  }

  analogWrite(RED_PIN,   gammaCorrect(int(r * 255)));
  analogWrite(GREEN_PIN, gammaCorrect(int(g * 255)));
  analogWrite(BLUE_PIN,  gammaCorrect(int(b * 255)));
}
-----

Saturday, September 29, 2012

FRDM-KL25Z Demo: Freescale Development Platform


We put an early pre-order in with ELEMENT14 for Freescale's Kinetis KL25Z development board and it arrived this week.  The dev board has a very solid feel and cost only $12.95.  A great value when you consider all the features; including a Freescale MMA8451Q 3-axis accelerometer glued right onto the board!  Freescale's description on the dev board is "The Freescale Freedom development platform is a low-cost evaluation and development platform featuring Freescale's newest ARM® Cortex™-M0+ based Kinetis KL25Z MCUs."
-----
Here is a short video demonstrating the MMA8451Q in action.  The tri-color LED is White when flat; Red when tilted up; Blue when tilted sideways:
-----
The kit comes with headers, a quick start guide, and has the following high level feature set:
- KL25128VLK4 - Cortex micro controller with:
     128Kb FLASH, 16Kb SRAM
     48MHz operation
     Full speed USB controller
     OpenSDA USB debug interface
     Tri-color LED
     Capacitive touch slider
     Reset button
     Expansion IO accepts Arduino form factor shields
-----
More fun to come.  Stay tuned.