Skip to content

Instantly share code, notes, and snippets.

@dkadish
Created June 13, 2015 01:39
Show Gist options
  • Save dkadish/e56caa7fd13b98ab65bf to your computer and use it in GitHub Desktop.
Save dkadish/e56caa7fd13b98ab65bf to your computer and use it in GitHub Desktop.
Code for the SoundChameleon inorganism made during the Inorganisms workshop at NORDES2015
/************************************************************
// 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