Skip to content

Instantly share code, notes, and snippets.

@BlueJayLouche
Last active August 26, 2022 01:50
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save BlueJayLouche/f8cfec1061713fb2e16c7d6ac02ba1ce to your computer and use it in GitHub Desktop.
Save BlueJayLouche/f8cfec1061713fb2e16c7d6ac02ba1ce to your computer and use it in GitHub Desktop.
full arduino code for colour matching interactive
#include <FastLED.h>
#include <i2c_t3.h>
byte i2cWriteBuffer[10];
byte i2cReadBuffer[10];
#define LED_PIN 36
#define NUM_LEDS_PANEL 18 //How many LEDs in each panel
#define NUM_PANELS 4 //How many levels (one side of "building")
#define NUM_COLOURS 3 //Number of potential colours
#define NUM_LEDS ((NUM_LEDS_PANEL*NUM_PANELS)*2) //Total amount of LEDs
#define BRIGHTNESS 196 // Maximum LED brightness level
#define LED_TYPE WS2812 //LED Chip type
#define COLOR_ORDER GRB // Red, Green, Blue order
//Blanket RGB Sensor configuration
#define SensorAddressWrite 0x29 //
#define SensorAddressRead 0x29 //
#define EnableAddress 0xa0 // register address + command bits
#define ATimeAddress 0xa1 // register address + command bits
#define WTimeAddress 0xa3 // register address + command bits
#define ConfigAddress 0xad // register address + command bits
#define ControlAddress 0xaf // register address + command bits
#define IDAddress 0xb2 // register address + command bits
#define ColorAddress 0xb4 // register address + command bits
#define NumSensors 4
#define colourMin 5000 //RGB values must be greater than this number to register
CRGB leds[NUM_LEDS];
CRGB ledStore[NUM_LEDS];
CRGB colourArray[NUM_COLOURS] = {
CRGB::OrangeRed, //RED colour seen on building
CRGB::LightGreen, //GREEN colour seen on building
CRGB::SkyBlue //BLUE colour seen on building
};
int panelArray[NUM_PANELS] = {
0,
NUM_LEDS_PANEL,
NUM_LEDS_PANEL*2,
NUM_LEDS_PANEL*3
};
int blockPanelArray[NUM_PANELS] = {
NUM_LEDS_PANEL*4,
NUM_LEDS_PANEL*5,
NUM_LEDS_PANEL*6,
NUM_LEDS_PANEL*7
};
int randomArray[NUM_PANELS];
int randomArrayBuffer[NUM_PANELS];
CRGB blockArray[5] = {
CRGB::Black,
CRGB::Black,
CRGB::Black,
CRGB::Black,
CRGB::Black,
};
CRGB previousBlockArray[4];
int timeout = 500; //This is the timeout instead of “X Seconds"
bool hasChanged[NumSensors]; //setup a flag to note if any block has changed.
int timer= 0;
bool matchArray[NUM_PANELS];
bool allMatch;
char mode = 'a';
int currentColour,dumpCount,ledNumber;
#define UPDATES_PER_SECOND 60
CRGBPalette16 currentPalette;
TBlendType currentBlending;
unsigned long previousMillis = 0;
unsigned long previousMillis1 = 0; // will store last time LED was updated
unsigned long blockChangeMillis = 0;
unsigned long interval = 5000; // interval at which to blink (milliseconds)
i2c_t3 wireArray[] = {
0,
1,
2,
3
};
int sensorPin[] = {
A0,
A1,
A2,
A3
};
int sensorValue[NumSensors];
bool ledState[NumSensors];
int ledPin[] = {
13,
23,
24,
25
};
void Writei2cRegisters(byte numberbytes, byte command, int wire)
{
byte i = 0;
wireArray[wire].beginTransmission(SensorAddressWrite); // Send address with Write bit set
wireArray[wire].write(command); // Send command, normally the register address
for (i=0;i<numberbytes;i++) // Send data
wireArray[wire].write(i2cWriteBuffer[i]);
wireArray[wire].endTransmission();
delayMicroseconds(100); // allow some time for bus to settle
}
void Readi2cRegisters(int numberbytes, byte command, int wire)
{
byte i = 0;
wireArray[wire].beginTransmission(SensorAddressWrite); // Write address of read to sensor
wireArray[wire].write(command);
wireArray[wire].endTransmission();
delayMicroseconds(100); // allow some time for bus to settle
wireArray[wire].requestFrom(SensorAddressRead,numberbytes); // read data
for (i=0;i<numberbytes;i++)
i2cReadBuffer[i] = wireArray[wire].read();
wireArray[wire].endTransmission();
delayMicroseconds(100); // allow some time for bus to settle
}
void init_TCS34725(void)
{
for (int i = 0; i<NumSensors;i++) {
i2cWriteBuffer[0] = 0x10;
Writei2cRegisters(1,ATimeAddress,i); // RGBC timing is 256 - contents x 2.4mS =
i2cWriteBuffer[0] = 0x00;
Writei2cRegisters(1,ConfigAddress,i); // Can be used to change the wait time
i2cWriteBuffer[0] = 0x00;
Writei2cRegisters(1,ControlAddress,i); // RGBC gain control
i2cWriteBuffer[0] = 0x03;
Writei2cRegisters(1,EnableAddress,i); // enable ADs and oscillator for sensor
}
}
void get_TCS34725ID(void)
{
for (int i = 0; i<NumSensors;i++) {
Readi2cRegisters(1,IDAddress,i);
if (i2cReadBuffer[0] == 0x44) {
Serial.println("TCS34725 is present");
}else {
Serial.println("TCS34725 not responding");
}
}
}
void get_Colors(void)
{
unsigned int red_color[NumSensors];
unsigned int green_color[NumSensors];
unsigned int blue_color[NumSensors];
for (int i = 0; i<NumSensors;i++) {
Readi2cRegisters(8,ColorAddress,i);
red_color[i] = (unsigned int)(i2cReadBuffer[3]<<8) + (unsigned int)i2cReadBuffer[2];
green_color[i] = (unsigned int)(i2cReadBuffer[5]<<8) + (unsigned int)i2cReadBuffer[4];
blue_color[i] = (((unsigned int)(i2cReadBuffer[7]<<8) + (unsigned int)i2cReadBuffer[6])*1.32); //<-- Note Blue value is increased slightly to differenciate from Green
// Compare colour values to decide the colour of the block
if ((red_color[i]>blue_color[i]) && (red_color[i]>green_color[i]) && (red_color[i]>colourMin)) {
blockArray[i] = colourArray[0];
Serial.println("detecting red");
}else if ((green_color[i]>blue_color[i]) && (green_color[i]>red_color[i]) && (green_color[i]>colourMin)) {
blockArray[i] = colourArray[1];
Serial.println("detecting green");
}else if ((blue_color[i]>red_color[i]) && (blue_color[i]>green_color[i]) && (blue_color[i]>colourMin)) {
blockArray[i] = colourArray[2];
Serial.println("detecting blue");
}else {
blockArray[i] = colourArray[3];
Serial.println("color not detectable");
}
}
}
void setup() {
delay( 1000 ); // power-up safety delay
FastLED.addLeds<LED_TYPE, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS).setCorrection( TypicalPixelString ).setTemperature( UncorrectedTemperature ) ;
FastLED.setBrightness( BRIGHTNESS );
//clear() turns all LEDs off
FastLED.clear();
wireArray[0].begin(I2C_MASTER, 0x00, I2C_PINS_33_34, I2C_PULLUP_EXT, 400000);
wireArray[1].begin(I2C_MASTER, 0x00, I2C_PINS_37_38, I2C_PULLUP_EXT, 400000);
wireArray[2].begin(I2C_MASTER, 0x00, I2C_PINS_3_4, I2C_PULLUP_EXT, 400000);
wireArray[3].begin(I2C_MASTER, 0x00, I2C_PINS_56_57, I2C_PULLUP_EXT, 400000);
Serial.begin(9600);
for (int j = 0; j < NumSensors; j++) {
pinMode(ledPin[j], OUTPUT);
digitalWrite(ledPin[j], LOW);
hasChanged[j] = false;
}
init_TCS34725();
get_TCS34725ID(); // get the device ID, this is just a test to see if we're connected
}
void loop() {
unsigned long currentMillis = millis();
for (int i = 0; i < NumSensors; i++) {
sensorValue[i] = analogRead(sensorPin[i]);
Serial.print ("sensor ");
Serial.print ( i , DEC);
Serial.print (" Value = ");
Serial.println(sensorValue[i], DEC);
if (sensorValue[i] > 200) {
ledState[i] = true;
} else {
ledState[i] = false;
}
digitalWrite(ledPin[i], ledState[i]);
}
get_Colors();
blockChange();
if (Serial.available() > 0) {
char inByte = Serial.read();
mode = inByte;
}
switch (mode) {
case 'a':
randomise(currentMillis);
break;
case 'b':
panelColours();
mode = 'c';
break;
case 'c':
play();
break;
case 'd':
juggle();
break;
}
FastLED.show();
FastLED.delay(1000 / UPDATES_PER_SECOND);
Serial.print ("Mode = ");
Serial.println (mode);
}
void randomise(unsigned long currentMillis)
{
if (currentMillis - previousMillis1 > (interval/10)) {
// // save the last time you Changed Colours
previousMillis1 = currentMillis;
for ( int i = 0; i < NUM_PANELS; i++) {
randomArray[i] = random(0, NUM_COLOURS);
}
for ( int j = 0; j < NUM_PANELS; j++) {
for ( int i = panelArray[j]; i < panelArray[j]+NUM_LEDS_PANEL; i++) {
leds[i] = colourArray[randomArray[j]];
ledStore[i] = leds[i];
}
}
for ( int j = 0; j < NUM_PANELS; j++) {
for ( int i = blockPanelArray[j]; i < blockPanelArray[j]+NUM_LEDS_PANEL; i++) {
leds[i] = blockArray[j];
}
}
}
return;
}
void blockChange()
{
//find out if any block has changed
for (int i=0;i<NumSensors;i++) {
if (blockArray[i] != previousBlockArray[i]) {
hasChanged[i] = true;
}else {
hasChanged[i] = false;
}
previousBlockArray[i] = blockArray[i];
//end for loop
if (mode == 'c' && hasChanged[i] == false && timer >= timeout) {
mode = 'a';
}
else if (mode == 'c' && hasChanged[i] == true){
//a block has been moved, so reset the timer
timer = 0;
}
else if (mode == 'a' && hasChanged[i] == true){
mode = 'b';
timer = 0;
}
else if (mode == 'd' && timer >= timeout) {
mode = 'a';
}
}
if (timer <= timeout) {
timer++; // timer will increment one every time the main loop, calls blockChange.
}
Serial.print("timer= ");
Serial.println(timer, DEC);
Serial.print("block1= ");
Serial.println(previousBlockArray[0]);
Serial.print("change ? ");
Serial.println(hasChanged[0]);
}
void panelColours() //Just need to lock-in colours from the randomiser and turn off rings for block recognition
{
for ( int j = 0; j < NUM_PANELS; j++) {
for ( int i = panelArray[j]; i < panelArray[j]+NUM_LEDS_PANEL; i++) {
leds[i] = colourArray[randomArray[j]];
}
}
ledNumber = 0;
}
void play ()
{
for ( int j = 0; j < NUM_PANELS; j++) {
for ( int i = blockPanelArray[j]; i < blockPanelArray[j]+NUM_LEDS_PANEL; i++) {
leds[i] = blockArray[j];
}
if ( blockArray[j] == leds[panelArray[j]]) {
Serial.print("match: ");
Serial.println(1+j);
matchArray[j] = true;
addGlitter(20, j);
panelColours();
} else {
matchArray[j] = false;
}
}
if (matchArray[0] == true && matchArray[1] == true && matchArray[2] == true && matchArray[3] == true) {
mode = 'd';
}
}
void addGlitter( fract8 chanceOfGlitter, int panel)
{
for ( int i = panelArray[panel]; i < panelArray[panel]+NUM_LEDS_PANEL; i++) {
if ( random8() < chanceOfGlitter) {
leds[ random16(i, (i+1)) ] += CRGB::White;
leds[ random16(i+(NUM_LEDS_PANEL*NUM_PANELS), (i+(NUM_LEDS_PANEL*NUM_PANELS))+1) ] += CRGB::White;
}
}
FastLED.show();
}
void juggle() {
// eight colored dots, weaving in and out of sync with each other
fadeToBlackBy( leds, NUM_LEDS, 20);
byte dothue = 0;
for( int i = 0; i < 8; i++) {
leds[beatsin16( i+7, 0, NUM_LEDS-1 )] |= CHSV(dothue, 200, 255);
dothue += 32;
}
}
@BlueJayLouche
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment