// Buzz Pot // Eric Mika, 2009 // Provides tactile feedback for a potentiometer to denote changes // from one value range to another. Ideal for situations where an unknown // number of values must be set by a single potentiometer. // To do: // 1. Debounce the thresholds. // 2. Handle fringe-case runtime channel count changes. int vibratorPin = 9; // Turns the vibration motor on and off through a transistor. int potPin = 0; // Reads the potentiometer. int potValue = 0; // Stores the potentiometer value. int channels = 10; // Number of values selectable by the pot. int currentChannel = 0; // Starting value. int lastChannel = 0; int vibDuration = 200; // How long to turn the motor on when thresholds are crossed. unsigned long vibStart = 0; // Keep track of time so we know when to turn off the motor. // Map digital pins to their respective LEDs in the 7 segment display. // Could use a shift register instead to save pins. int dispA = 2; int dispB = 3; int dispC = 4; int dispD = 5; int dispE = 6; int dispF = 7; int dispG = 8; void setup() { // Set up 7 segment display pins. pinMode(dispA, OUTPUT); pinMode(dispB, OUTPUT); pinMode(dispC, OUTPUT); pinMode(dispD, OUTPUT); pinMode(dispE, OUTPUT); pinMode(dispF, OUTPUT); pinMode(dispG, OUTPUT); // Set up vibrator pin. pinMode(vibratorPin, OUTPUT); } void loop() { // Read the analog input into a variable, correct for value inversion. potValue = 1023 - analogRead(potPin); // If 10 channels, return a number between 0 and 9... // Constrain to catch rounding errors at the top end. currentChannel = constrain(potValue / (1023 / channels), 0, channels - 1); // Show the current channel number on the 7 segment display. displayDigit(currentChannel); // Vibrate if we change channels. if (lastChannel != currentChannel) { vibStart = millis(); } // Keep vibrating for the full duration... if ((millis() - vibStart) <= vibDuration) { digitalWrite(vibratorPin, HIGH); } else { digitalWrite(vibratorPin, LOW); } lastChannel = currentChannel; } // Shows a number on the 7 segment display. // It's a common anode model, so LOW is actually on. void displayDigit(int digit) { switch (digit) { case 0: digitalWrite(dispA, LOW); digitalWrite(dispB, LOW); digitalWrite(dispC, LOW); digitalWrite(dispD, LOW); digitalWrite(dispE, LOW); digitalWrite(dispF, LOW); digitalWrite(dispG, HIGH); break; case 1: digitalWrite(dispA, HIGH); digitalWrite(dispB, LOW); digitalWrite(dispC, LOW); digitalWrite(dispD, HIGH); digitalWrite(dispE, HIGH); digitalWrite(dispF, HIGH); digitalWrite(dispG, HIGH); break; case 2: digitalWrite(dispA, LOW); digitalWrite(dispB, LOW); digitalWrite(dispC, HIGH); digitalWrite(dispD, LOW); digitalWrite(dispE, LOW); digitalWrite(dispF, HIGH); digitalWrite(dispG, LOW); break; case 3: digitalWrite(dispA, LOW); digitalWrite(dispB, LOW); digitalWrite(dispC, LOW); digitalWrite(dispD, LOW); digitalWrite(dispE, HIGH); digitalWrite(dispF, HIGH); digitalWrite(dispG, LOW); break; case 4: digitalWrite(dispA, HIGH); digitalWrite(dispB, LOW); digitalWrite(dispC, LOW); digitalWrite(dispD, HIGH); digitalWrite(dispE, HIGH); digitalWrite(dispF, LOW); digitalWrite(dispG, LOW); break; case 5: digitalWrite(dispA, LOW); digitalWrite(dispB, HIGH); digitalWrite(dispC, LOW); digitalWrite(dispD, LOW); digitalWrite(dispE, HIGH); digitalWrite(dispF, LOW); digitalWrite(dispG, LOW); break; case 6: digitalWrite(dispA, LOW); digitalWrite(dispB, HIGH); digitalWrite(dispC, LOW); digitalWrite(dispD, LOW); digitalWrite(dispE, LOW); digitalWrite(dispF, LOW); digitalWrite(dispG, LOW); break; case 7: digitalWrite(dispA, LOW); digitalWrite(dispB, LOW); digitalWrite(dispC, LOW); digitalWrite(dispD, HIGH); digitalWrite(dispE, HIGH); digitalWrite(dispF, HIGH); digitalWrite(dispG, HIGH); break; case 8: digitalWrite(dispA, LOW); digitalWrite(dispB, LOW); digitalWrite(dispC, LOW); digitalWrite(dispD, LOW); digitalWrite(dispE, LOW); digitalWrite(dispF, LOW); digitalWrite(dispG, LOW); break; case 9: digitalWrite(dispA, LOW); digitalWrite(dispB, LOW); digitalWrite(dispC, LOW); digitalWrite(dispD, LOW); digitalWrite(dispE, HIGH); digitalWrite(dispF, LOW); digitalWrite(dispG, LOW); break; default: digitalWrite(dispA, HIGH); digitalWrite(dispB, HIGH); digitalWrite(dispC, HIGH); digitalWrite(dispD, HIGH); digitalWrite(dispE, HIGH); digitalWrite(dispF, HIGH); digitalWrite(dispG, HIGH); } }