SlaHuRa or Slappable Huggable Radio is a FM and AM radio that uses an accelerometer (tilt sensor) to change volume and frequency. There are no buttons to press or dials to spin. Tilting the radio from side to side adjusts the frequency. Tilting it from front to back changes the volume.
SlaHuRa : Slappable Huggable Radio from che-wei wang on Vimeo.
SlaHuRa behaves or misbehaves depending on how you treat it. It likes to be hugged, but once in a while it will misbehave and go off onto a random frequency. To make it behave and again, just slap it to teach it to behave. Likewise, hugging SlaHuRa will promote good behaviour through positive reinforcement.
It “behaves” (stays on the chosen frequency) in direct proportion to how long you “hug” (or hold the radio). The longer you hug it, the longer it will behave. Once you place it back onto a flat surface, it begins to feel axious, and will eventually flip out. If it is behaving “badly” (on a random frequency) you can slap the radio to get it back onto the right frequency.
Version 01
SlaHuRa V01 from che-wei wang on Vimeo.
Arduino Code
int minPulse = 500;
int maxPulse = 2500;
int pulse,pulseR;
long lastPulse = 0;
long resPulse = 0;
long lastAdj=0;
long lastVolAdj=0;
int refreshTime = 20;
int freq=0;
int vol=0;
int x0, y0, z0;
int xpos=625;//defalut set to 0 volume
int ypos=512;//default set to middle freq
int zpos=0;
int yposSet=0;
int setFreq;
long timer=0;
long hugTimer=0;
long badTimer=0;
long resTimer=0;
int randomBad=100;
boolean onFreq=false;
boolean freqMem=false;
boolean xTilt=false;
boolean yTilt=false;
boolean zTilt=false;
boolean shaking, tilting;
boolean badness=false;
boolean zero=false;
int hugs=35;
void setup() {
pinMode(9,OUTPUT);
pinMode(10,OUTPUT);
pinMode(11,OUTPUT);
beginSerial(9600); // Sets the baud rate to 9600
}
void loop() {
//set zero on tilt sensor
if(zero==false){
delay(500);
setZero();
}
int x=analogRead(0)-x0; //reads and represents acceleration X
int y=analogRead(1)-y0; //reads and represents acceleration Y
int z=analogRead(2)-z0; //reads and represents acceleration Z
// int cap=analogRead(5); //capacitive
// freq adjust
if(badness==false && millis() - lastAdj >= 6 && millis()-resTimer>=2500.0){
if (y>50&&y<150) ypos++;
if (y<-50&&y>-150) ypos--;
lastAdj=millis();
}
// volume adjust
if(millis()-lastVolAdj>=6){
if (x>50 && x < 150) xpos--;
if (x<-50 && x > -150) xpos++;
lastVolAdj=millis();
}
//set channel
if( millis() - timer > 1000.0*(float)(hugs-1) && onFreq==false && badness==false){
yposSet=ypos;//remember freq
onFreq=true;
//Serial.println("freq set");
}
//behave badly
if (millis() - timer >1000.0*(float)hugs && millis()-badTimer>randomBad){
ypos=ypos+random(-150,150);
//ypos=random(50,1000);
//Serial.println("badness");
badness=true;
onFreq=false;
badTimer=millis();
randomBad=random(300,750); //random timer from 100-1500
}
//slapped
if(badness==true){
if(y>200 || y<-200 || x>200 || x<-200 || z>200 || z<-200){
//Serial.println("slapped");
badness=false;
ypos=yposSet;
onFreq=false;
hugs=10;
resTimer=millis(); //so slapping doesn't affect reseting to set freq
}
}
int thres=15;
if(badness==false&& millis()-hugTimer>1000){
if(x>thres || x<-thres || y>thres || y<-thres){
hugs=hugs+1;
timer=millis();
}
else{
hugs=hugs-1;
}
hugTimer=millis();
hugs=constrain(hugs,-1,35);
//Serial.println(hugs);
//Serial.print("x");
//Serial.println(x);
//Serial.print("y");
//Serial.println(y);
//Serial.print("z");
//Serial.println(z);
}
xpos=constrain(xpos,0,1023);
ypos=constrain(ypos,0,1023);
vol = xpos*19/10+minPulse; // convert the analog value
freq = ypos*19/10+minPulse; // convert the analog value
//motor control
if (millis() - lastPulse >= refreshTime) {
digitalWrite(9, HIGH); // Turn the motor on
delayMicroseconds(vol); // Length of the pulse sets the motor position
digitalWrite(9, LOW); // Turn the motor off
digitalWrite(10, HIGH); // Turn the motor on
delayMicroseconds(freq); // Length of the pulse sets the motor position
digitalWrite(10, LOW); // Turn the motor off
lastPulse = millis(); // save the time of the last pulse
}
}
//zero all tilt sensors
void setZero(){
x0=analogRead(0);
y0=analogRead(1);
z0=analogRead(2);
zero=true;
}
1 comment
Comments are closed.