Description
The device takes sound as an input and outputs light based on how loud the sound is. On one end is a microphone, which is the input. Based on how loud the sound picked up by the microphone is, a servo will turn a potentiometer a certain amount. Based on the position of the potentiometer, the LED will light up brighter or dimmer. In the end, louder sounds will lead to more light, while quieter sounds will lead to less light.
Demonstration:
Progress Videos
The progress videos of the input and output domains.
Discussion
We’ll start with what was easy. Getting the input, output, and middle man wired up was probably the easiest part. The code wasn’t too difficult, but there was some tweaking needed in order to get the desired behavior (mostly tweaking the ranges).
One of the big challenges was actually assembling the middle man portion of the device; namely, coupling the servo motor to the potentiometer. At first, I tried just taping a horn to the potentiometer shaft, but that wasn’t reliable enough, and looked terrible. In the end, I 3D printed a shaft coupler made for an SG-90 hobby servo (what we used) and drilled a hole in the other end of it to friction-fit onto the potentiometer. That did the job.
Schematic
Code
/* Project 1 Seth Geiser (sgeiser) and Olaitan Adisa (okadisa) Collaboration: Ola is my partner and she came up with the schematic and other ideas. Some references: https://courses.ideate.cmu.edu/60-223/s2020/tutorials/I2C-lcd https://courses.ideate.cmu.edu/60-223/s2020/reference/class-log#codebook-periodic-updating Challenge: The biggest challenge was coupling the servo to the potentiometer so that we could adjust the LED brightness. Next time: I don't know... keep going? Description: The purpose is to create a double-transducer. The input is sound, read by a sound detector. The sound reading triggers a servo (coupled to a potentiometer) to change its position, thus changing the potentiometer's position. This changes the brightness of the LED. Louder sounds should result in the LED emitting brighter light, and vice versa. Pin mapping: pin | mode | description -----|-------|------------ A0 input potentiometer A1 input sound detector 11 output LED 2 output servo SDA/SCL display */ #include <Wire.h> #include <LiquidCrystal_I2C.h> #include <Servo.h> Servo myservo; /* Create an LCD display object called "screen" with I2C address 0x27 which is 16 columns wide and 2 rows tall. */ LiquidCrystal_I2C screen(0x27, 16, 2); const int POTPIN = A0; const int SOUNDPIN = A1; const int LEDPIN = 11; const int SERVOPIN = 2; // "global" variables in this section can be used by any function in the whole sketch float filtered_val = 0; // this variable, of type float (decimal), holds the filtered sensor value const float PREV_WEIGHT = 0.99; // this variable, of type float (decimal), determines the previously filtered value's weight. const float CUR_WEIGHT = 1 - PREV_WEIGHT; // this variable, of type float (decimal), determines the current sample's weight. unsigned long timer = 0; // variable for timing const int INTERVAL = 250; // milliseconds between updates void setup() { pinMode(POTPIN, INPUT); pinMode(SOUNDPIN, INPUT); pinMode(LEDPIN, OUTPUT); myservo.attach(SERVOPIN); screen.init(); screen.backlight(); screen.home(); filtered_val = analogRead(SOUNDPIN); } void loop() { int soundValue = (float) analogRead(SOUNDPIN); // casting from int to float int soundValueLCD = map(soundValue, 0, 500, 0, 99); // mapping first input (sound)to range 0-99 filtered_val = filtered_val * PREV_WEIGHT + soundValue * CUR_WEIGHT; int servoPosition = map(filtered_val, 0, 400, 0, 180); // mapping sound values to range 0 - 180 degrees int servoValueLCD = map(servoPosition, 0, 180, 0, 99); // mapping first output (servo)to 0-99 myservo.write(servoPosition); int potVal = analogRead(POTPIN); int potValueLCD = map(potVal, 1, 1024, 0, 99); int mapPotVal = map(potVal, 1, 1024, 0, 254); // pot to LED values analogWrite(LEDPIN, mapPotVal); int ledValueLCD = map(mapPotVal, 0, 254, 0, 99); // updating the LCD output if (millis() >= timer) { screen.setCursor(0, 0); screen.print((String) "i:" + soundValueLCD); screen.setCursor(6, 0); screen.print((String) + "m:" + servoValueLCD); screen.setCursor(8, 1); screen.print((String) potValueLCD ); screen.setCursor(12, 1); screen.print((String) "o:" + ledValueLCD); timer = millis() + INTERVAL; // and update timer } }
Comments are closed.