Created
June 13, 2015 01:39
-
-
Save dkadish/e56caa7fd13b98ab65bf to your computer and use it in GitHub Desktop.
Code for the SoundChameleon inorganism made during the Inorganisms workshop at NORDES2015
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
/************************************************************ | |
// Basic Example: Inorganisms | |
// | |
// Listens to the world and responds after some delay. | |
************************************************************/ | |
#include <FiniteStateMachine.h> | |
#include <Adafruit_NeoPixel.h> // Include to make the lights work | |
// Create the states to use | |
State sensing = State(doSense); | |
State acting = State(doResponse); | |
// Create the state machine | |
FSM stateMachine = FSM(sensing); | |
// Initialize the lights | |
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(3, 6, NEO_RGB + NEO_KHZ800); | |
float sense = 1000.0; | |
long time = 0; | |
// RGB values for the three LEDs | |
int rgb[3][3]; | |
float h[] = {0, 0, 0}; | |
float s[] = {1.0, 1.0, 1.0}; | |
float v[] = {1.0, 1.0, 1.0}; | |
const int DELAY = 1000; // The delay between sensing and action | |
const int THRESHOLD = 300; // The threshold above which to respond | |
// Run once during the start up of the Arduino | |
void setup() { | |
//Serial.begin(9600); | |
//delay(1000); | |
pixels.begin(); | |
} | |
// Run over and over again | |
void loop() | |
{ | |
stateMachine.update(); // Update the state machine | |
} | |
void doSense() { | |
//Serial.print("SENSE."); | |
time = millis(); | |
// Set the colours | |
h[0] = (float)random(360); | |
h[1] = h[0] - 80; | |
h[2] = h[1] - 80; | |
s[0] = 1.0; | |
s[1] = 1.0; | |
s[2] = 1.0; | |
long t_diff = millis() - time; | |
while ( t_diff < 3000 ) { | |
if ( t_diff < 2000 ) { | |
v[0] = sin(2.0 * PI * (millis() - time) / 2000.0); | |
} else { | |
v[0] = 0.0; | |
} | |
if ( 500 < t_diff && t_diff < 2500 ) { | |
v[1] = sin(2.0 * PI * (t_diff - 500) / 2000.0); | |
} else { | |
v[1] = 0.0; | |
} | |
if ( 1000 < t_diff && t_diff < 3000 ) { | |
v[2] = sin(2.0 * PI * (t_diff - 1000) / 2000.0); | |
} else { | |
v[2] = 0.0; | |
} | |
// Respond by turning the LED on | |
for ( int i = 0; i < 3; i++ ) { | |
hsi2rgb(h[i], s[i], v[i], rgb[i]); | |
pixels.setPixelColor(i, pixels.Color(rgb[i][0], rgb[i][1], rgb[i][2])); | |
} | |
pixels.show(); | |
// Listen for stimulus | |
float reading = (float) analogRead(A0); // Take a new reading from the microphone | |
sense = 0.99 * sense + 0.1 * reading; // Listen for the value of the sensor | |
delay(1); // Delay so that it does not run at 16 MHz | |
t_diff = millis() - time; | |
} | |
for ( int i = 0; i < 3; i++ ) { | |
pixels.setPixelColor(i, pixels.Color(0, 0, 0)); | |
} | |
pixels.show(); | |
int threshold = analogRead(A1); | |
/*Serial.print(threshold); | |
Serial.print(", "); | |
Serial.println(sense);*/ | |
// If the inorganism has received a stimulus above the threshold | |
if ( sense > threshold ) { | |
// Wait to respond | |
delay(DELAY); | |
// Switch to Acting mode | |
stateMachine.transitionTo(acting); | |
} | |
} | |
void doResponse() { | |
//Serial.print("RESPONSE."); | |
for( int i = 0; i < 100; i++ ){ | |
delay(10); // Delay so that it does not run at 16 MHz | |
float reading = (float) analogRead(A0); // Take a new reading from the microphone | |
sense = 0.99 * sense + 0.1 * reading; // Listen for the value of the sensor | |
} | |
int threshold = analogRead(A1); | |
if ( sense < threshold ) { | |
// Switch to Sensing mode | |
stateMachine.transitionTo(sensing); | |
} | |
} | |
void hsi2rgb(float H, float S, float I, int* rgb) { | |
int r, g, b; | |
H = fmod(H, 360); // cycle H around to 0-360 degrees | |
H = 3.14159 * H / (float)180; // Convert to radians. | |
S = S > 0 ? (S < 1 ? S : 1) : 0; // clamp S and I to interval [0,1] | |
I = I > 0 ? (I < 1 ? I : 1) : 0; | |
// Math! Thanks in part to Kyle Miller. | |
if (H < 2.09439) { | |
r = 255 * I / 3 * (1 + S * cos(H) / cos(1.047196667 - H)); | |
g = 255 * I / 3 * (1 + S * (1 - cos(H) / cos(1.047196667 - H))); | |
b = 255 * I / 3 * (1 - S); | |
} else if (H < 4.188787) { | |
H = H - 2.09439; | |
g = 255 * I / 3 * (1 + S * cos(H) / cos(1.047196667 - H)); | |
b = 255 * I / 3 * (1 + S * (1 - cos(H) / cos(1.047196667 - H))); | |
r = 255 * I / 3 * (1 - S); | |
} else { | |
H = H - 4.188787; | |
b = 255 * I / 3 * (1 + S * cos(H) / cos(1.047196667 - H)); | |
r = 255 * I / 3 * (1 + S * (1 - cos(H) / cos(1.047196667 - H))); | |
g = 255 * I / 3 * (1 - S); | |
} | |
rgb[0] = r; | |
rgb[1] = g; | |
rgb[2] = b; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment