Created
August 10, 2016 07:44
-
-
Save mbrav/875aec5f8ded109240a5f900c5b3f0cb to your computer and use it in GitHub Desktop.
A cube that senses physical movements, touches, changes in light intensity, and temperature
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
// Emotion Cube | |
// created by Michael Braverman | |
// October 8th, 2015 | |
// Video: https://vimeo.com/144803164 | |
#include <Metro.h> | |
// Read the sensor only once per 100ms (10Hz) | |
Metro metroSensor = Metro(100); | |
Metro fadeStep = Metro(5); | |
// analog readings | |
const byte tempPin = A0; | |
const byte lightPin = A1; | |
const byte lightPin2 = A2; | |
const byte touchPin = A3; | |
// RGB led | |
const byte redPin = 11; | |
const byte greenPin = 10; | |
const byte bluePin = 9; | |
// accelerometer | |
const byte xPin = 6; // X output of the accelerometer | |
const byte yPin = 7; // Y output of the accelerometer | |
// vibration motor | |
const byte vibrationPin = 5; | |
// values | |
int bright = 9999; | |
int dark; | |
int lightMemory[60]; | |
int lightMemory2[60]; | |
int tempMemory[60]; | |
int fade; | |
unsigned long shakeMillis; | |
unsigned long recordMillis; | |
boolean toggle; | |
int step; | |
int nextStep; | |
boolean vBlink; | |
// Analog readings | |
int lightRead; | |
int lightRead2; | |
int tempRead; | |
int touchRead; | |
int accelerationX; | |
int accelerationY; | |
boolean DEBUG = true; | |
void setup() { | |
Serial.begin(115200); | |
pinMode(lightPin, INPUT); | |
pinMode(lightPin2, INPUT); | |
pinMode(tempPin, INPUT); | |
pinMode(touchPin, INPUT); | |
pinMode(xPin, INPUT); | |
pinMode(yPin, INPUT); | |
pinMode(redPin, OUTPUT); | |
pinMode(greenPin, OUTPUT); | |
pinMode(bluePin, OUTPUT); | |
pinMode(vibrationPin, OUTPUT); | |
pinMode(13, OUTPUT); | |
// Necessary to set values instead of default (zero) | |
for(int i = 0; i < sizeof(lightMemory); i++){ | |
lightMemory[i] = -99; | |
lightMemory2[i] = -99; | |
tempMemory[i] = 99; | |
} | |
int setupTimer = 0; | |
boolean switchState; | |
boolean switchState2; | |
Serial.println("-------------------------------------------------"); | |
Serial.println("Wave your hand over the sensor to calibrate"); | |
delay(100); | |
// change the setupTimer if it is too fast or slow | |
while (setupTimer < 20000) { | |
lightRead = analogRead(lightPin); | |
if (bright > lightRead) { | |
bright= lightRead; | |
} | |
if (dark < lightRead) { | |
dark = lightRead; | |
} | |
// Make the LED Flash | |
if(setupTimer % 100 == 0) { | |
switchState = !switchState; | |
} | |
// Make the motor vibrate | |
if(setupTimer % 400 == 0) { | |
switchState2 = !switchState2; | |
} | |
digitalWrite(13, switchState); | |
digitalWrite(vibrationPin, switchState2); | |
setupTimer++; | |
} | |
digitalWrite(13, LOW); | |
digitalWrite(vibrationPin, LOW); | |
Serial.println("LIGHT SENSOR CALIBRATED!"); | |
Serial.print("Bright = "); | |
Serial.println(bright); | |
Serial.print("Dark = "); | |
Serial.println(dark); | |
delay(100); | |
} | |
void loop() { | |
int tempMemoryReturn = senseTempChange(); | |
int lightMemoryReturn = senseLightChange(); | |
updateSensorValues(); | |
// these functions are checked by proiority | |
// if one returns true, then the rest are ignored | |
if (isShaked(accelerationX, accelerationY)) { | |
// do not allow the timer to add up multiple times | |
if (shakeMillis < millis()) { | |
// time the shake for 3 seconds | |
shakeMillis = millis() + 3000; | |
} | |
} | |
// check if the timer is sill bigger | |
else if (shakeMillis > millis()) { | |
if (fadeStep.check()) { | |
vibrateBlink(5, 200); | |
if (step % 5 == 0) { | |
toggle = !toggle; | |
Serial.println("----------------TOGGLE-------------------------"); | |
} | |
step++; | |
} | |
LEDfade(toggle); | |
} | |
// check if it became hot | |
else if (tempMemoryReturn == 3 || tempMemoryReturn == 1) { | |
doubleBlink(1); | |
digitalWrite(vibrationPin, LOW); | |
} | |
// check the cold function | |
else if (tempMemoryReturn == 4 || tempMemoryReturn == 2) { | |
doubleBlink(3); | |
digitalWrite(vibrationPin, LOW); | |
} | |
// check the dark function | |
else if (senseLightChange() == 4 || senseLightChange() == 2) { | |
if (fadeStep.check()) { | |
if (step % 40 == 0) { | |
toggle = !toggle; | |
} | |
step++; | |
} | |
LEDfade(toggle); | |
} | |
// check the bright function | |
else if (senseLightChange() == 3 || senseLightChange() == 1) { | |
digitalWrite(vibrationPin, LOW); | |
if (fadeStep.check()) { | |
if ((step + nextStep) % 80 == 0 && toggle) { | |
toggle = !toggle; | |
nextStep = 0; | |
} else if (step % 80 == 0) { | |
toggle = !toggle; | |
// if the LED is set to OFF | |
if (toggle) { | |
// this value makes the tiem the LED is OFF shorter | |
// can be changed as long as it is smaller than n in (step % n == 0) | |
nextStep = 70; | |
} | |
} | |
step++; | |
} | |
LEDfade(toggle); | |
} | |
// this is the default which just fades the LED | |
else if (fadeStep.check()) { | |
LEDfade(false); | |
step++; | |
} | |
if (recordMillis < millis()) { | |
// add a 1 minute interval | |
shiftMemory(); | |
recordMillis = millis() + 60000; | |
} | |
// debug, otherwise check the performace | |
if (DEBUG) { | |
Serial.print("Light:"); | |
Serial.print(lightRead); | |
Serial.print(" \t Light2:"); | |
Serial.print(lightRead2); | |
Serial.print(" \tTemp:"); | |
Serial.print(tempRead); | |
Serial.print(" \tX:"); | |
Serial.print(accelerationX); | |
Serial.print(" \tY:"); | |
Serial.print(accelerationY); | |
Serial.print(" \tFade:"); | |
Serial.print(fade); | |
Serial.print("\tSMillis:"); | |
Serial.print(shakeMillis); | |
Serial.print("\tMillis:"); | |
Serial.print(millis()); | |
Serial.print(" \tLightReturn/TempReturn/Shaked:"); | |
Serial.print(" \t"); | |
Serial.print(lightMemoryReturn); | |
Serial.print("/"); | |
Serial.print(tempMemoryReturn); | |
Serial.print("/"); | |
Serial.println(isShaked(accelerationX, accelerationY) ); | |
} else { | |
; | |
} | |
} | |
/////// NEEED TO BE RE-WORKED ///////////// | |
void vibrateBlink(int peroid, int intensity){ | |
if (fade % peroid == 0) { | |
vBlink = !vBlink; | |
} | |
if (vBlink) { | |
analogWrite(vibrationPin, intensity); | |
} else { | |
analogWrite(vibrationPin, 0); | |
} | |
} | |
void LEDfade(boolean blink) { | |
if (blink) { | |
LEDcolor(0,0,0); | |
} else if (fade < 255) { | |
// fade BLUE down, RED up | |
LEDcolor(fade, 0, 255 - fade); | |
} else if (fade < 510) { | |
// fade RED down, GREEN up | |
LEDcolor(255 - (fade - 255), fade - 255, 0); | |
} else if (fade < 765) { | |
// fade GREEN down, BLUE up | |
LEDcolor(0, 255 - (fade - 510), fade - 510); | |
} else { | |
fade = 0; | |
} | |
fade ++; | |
} | |
void doubleBlink(int color) { | |
byte red = 0; | |
byte green = 0; | |
byte blue = 0; | |
if (color == 1) { | |
red = 255; | |
} else if (color == 2) { | |
green = 255; | |
} else if (color == 3) { | |
blue = 255; | |
} | |
if (fade < 50) { | |
LEDcolor(red, green, blue); | |
} else if (fade < 100) { | |
LEDcolor(0, 0, 0); | |
} else if (fade < 150) { | |
LEDcolor(red, green, blue); | |
} else if (fade < 200) { | |
LEDcolor(0, 0, 0); | |
} else if (fade >= 765) { | |
fade = 0; | |
} | |
fade++; | |
} | |
void LEDcolor(byte red, byte green, byte blue) { | |
analogWrite(redPin, red); | |
analogWrite(greenPin, green); | |
analogWrite(bluePin, blue); | |
} | |
////// UNTILL HERE | |
void updateSensorValues() { | |
lightRead = analogRead(lightPin); | |
lightRead2 = analogRead(lightPin2); | |
tempRead = analogRead(tempPin); | |
//check the sensor periodicly, not every time | |
if (metroSensor.check()) { | |
int pulseX; | |
int pulseY; | |
pulseX = pulseIn(xPin, HIGH); | |
pulseY = pulseIn(yPin, HIGH); | |
accelerationX = ((pulseX / 10) - 500) * 8; | |
accelerationY = ((pulseY / 10) - 500) * 8; | |
} | |
} | |
boolean isShaked(int x, int y) { | |
boolean xShake, yShake; | |
if (x > 1700 || x < -1700) { | |
xShake = true; | |
} else { | |
xShake = false; | |
} | |
if (y > 1700 || y < -1700) { | |
yShake = true; | |
} else { | |
yShake = false; | |
} | |
if (xShake == true || yShake == true) { | |
return true; | |
} else { | |
return false; | |
} | |
} | |
void shiftMemory() { | |
// Shift all the records further by one index | |
for(int i = sizeof(lightMemory); i > 0; i--){ | |
lightMemory[i+1] = lightMemory[i]; | |
lightMemory2[i+1] = lightMemory2[i]; | |
tempMemory[i+1] = tempMemory[i]; | |
} | |
// Set the first records as the current readings | |
lightMemory[0] = lightRead; | |
lightMemory2[0] = lightRead; | |
tempMemory[0] = tempRead; | |
} | |
int senseTempChange() { | |
int adder; | |
int adder2; | |
int average; | |
int average2; | |
// check the change that happend during the last 5 minutes | |
for(int i = 1; i < 5; i++){ | |
adder = adder + tempMemory[i]; | |
} | |
// check the change that happend during the last hour | |
for(int i = 1; i < sizeof(tempMemory); i++){ | |
adder2 = adder2 + tempMemory[i]; | |
} | |
average = adder / 4; | |
average2 = adder2 / (sizeof(tempMemory)-1); | |
if (average2 < tempRead - 5) { | |
return 3; | |
} else if (average2 > tempRead + 5) { | |
return 4; | |
} else if (average < tempRead - 5 ) { | |
return 1; | |
} else if (average > tempRead + 5) { | |
return 2; | |
} else { | |
return 0; | |
} | |
} | |
int senseLightChange() { | |
int adder; | |
int adder2; | |
int average; | |
int average2; | |
// check the change that happend during the last 5 minutes | |
for(int i = 1; i < 5; i++){ | |
adder = adder + (lightMemory[i] + lightMemory[i])/2; | |
} | |
// check the change that happend during the last hour | |
for(int i = 1; i < sizeof(lightMemory); i++){ | |
adder2 = adder2 + (lightMemory[i] + lightMemory[i])/2; | |
} | |
average = adder / 4; | |
average2 = adder2 / (sizeof(lightMemory)-1); | |
if (average2 < lightRead - 5) { | |
return 3; | |
} else if (average2 > lightRead + 5) { | |
return 4; | |
} else if (average < lightRead - 5 ) { | |
return 1; | |
} else if (average > lightRead + 5) { | |
return 2; | |
} else { | |
return 0; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment