Skip to content

Instantly share code, notes, and snippets.

@mbrav
Created August 10, 2016 07:44
Show Gist options
  • Save mbrav/875aec5f8ded109240a5f900c5b3f0cb to your computer and use it in GitHub Desktop.
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
// 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