Skip to content

Instantly share code, notes, and snippets.

@jtwalters
Created March 6, 2015 20:49
Show Gist options
  • Save jtwalters/24dbe230a91484deef2a to your computer and use it in GitHub Desktop.
Save jtwalters/24dbe230a91484deef2a to your computer and use it in GitHub Desktop.
A little Arduino-based project that sounds like a Theremin. Uses a distance sensor for one hand and a pushbutton for the other.
// #define EVENTMANAGER_EVENT_QUEUE_SIZE 20
// #define EVENTMANAGER_LISTENER_LIST_SIZE 10
// #include <EventManager.h>
#include <Event.h>
#include <Timer.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_LEDBackpack.h>
#include <RunningAverage.h>
#include <CapacitivePin.h>
// C Major notes
word freqs[24] = {1047, 1109, 1175, 1245, 1319, 1397, 1480, 1568, 1661, 1760, 1865, 1976, 2093, 2217, 2349, 2489, 2637, 2794, 2960, 3136, 3322, 3520, 3729, 3951};
float pi = 3.14159265359;
float vibratoRadians = -pi;
float vibratoValue = 0;
Adafruit_24bargraph bar = Adafruit_24bargraph();
RunningAverage runningAverage1(5);
RunningAverage runningAverage2(5);
word average1 = 0;
word average2 = 0;
word distPin = A1;
word ledPin = 10;
word touchPin = A0;
word speakerPin = 9;
byte tickEvent = 0;
// EventManager eventManager(EventManager::kNotInterruptSafe);
Timer t;
bool isPressed = false;
byte ledState = LOW;
word ledBrightness = 255;
word distValue = 0;
void setup() {
Serial.begin(9600);
pinMode(ledPin, OUTPUT);
pinMode(distPin, INPUT);
bar.begin(0x70);
for (byte b = 0; b < 24; b++) {
bar.setBar(b, LED_YELLOW);
}
bar.writeDisplay();
delay(500);
bar.setBrightness(10);
tickEvent = t.every(10, tick, (void*)0);
}
float getVibrato(float scale) {
vibratoRadians += 0.33;
if (vibratoRadians > pi) {
vibratoRadians = -pi;
}
return scale * sin(vibratoRadians);
}
void setBarPercentage(byte value) {
value = constrain(value, 0, 100);
value = map(value, 0, 100, 0, 24);
for (byte b = 0; b < 24; b++) {
bar.setBar(b, b < value ? LED_GREEN : LED_OFF);
}
bar.writeDisplay();
}
void readButton() {
byte value = readCapacitivePin(touchPin);
// isPressed = digitalRead(buttonPin) == LOW; // Inverse (INPUT_PULLUP)
isPressed = value > 1;
Serial.println(value);
}
float updateDist() {
distValue = map(analogRead(distPin), 0, 1023, 0, 5500);
if (distValue < 500) {
distValue = 0;
}
else if (distValue > 3000) {
distValue = 3000;
}
}
void distToTone() {
// byte index;
word freq;
// Serial.println(distValue);
if (average2 >= 500 && isPressed) {
// index = map(average2, 500, 3000, 0, sizeof(freqs) / sizeof(word) - 1);
// tone(speakerPin, freqs[index] + getVibrato(freqs[index] / 500));
freq = map(average2, 500, 3000, 220, 1047);
tone(speakerPin, freq + getVibrato(freq / 100));
}
else {
noTone(speakerPin);
}
}
void updateDisplay() {
word value = 0;
if (average1 >= 500) {
value = map(average1, 500, 3000, 0, 100);
}
else {
value = 0;
}
setBarPercentage(value);
analogWrite(ledPin, floor(value * 2.55));
}
void loop() {
// Update timer.
t.update();
// Handle any events that are in the queue.
// eventManager.processEvent();
}
void tick(void* context) {
updateDist();
// Calculate running averages.
runningAverage1.addValue(distValue);
average1 = runningAverage1.getAverage();
runningAverage2.addValue(average1);
average2 = runningAverage2.getAverage();
distToTone();
updateDisplay();
readButton();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment