Last active
August 26, 2022 01:50
-
-
Save BlueJayLouche/f8cfec1061713fb2e16c7d6ac02ba1ce to your computer and use it in GitHub Desktop.
full arduino code for colour matching interactive
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
https://forum.arduino.cc/index.php?topic=517167.0