Cymatics Sounder - shmoodles/mtec2250 GitHub Wiki
- The Cymatics Sounder -
Welcome! My project is about sound.
Specifically, a subset of sound phenomena called "cymatics." The etymological root of the word stems from the Greek 'cyma' - meaning wave. Cymatics enables one to experience sound waves visibly. By oscillating a surface plate using a speaker which emits a range of frequencies we can demonstrate this phenomena. As the plate vibrates, it does so as a whole and in parts. Using sand or other fine particulate matter dispersed on the surface of the plate, the sand settles on the non-vibrating areas, called 'nodal lines' and forms simple to complex geometric patterns depending on the specific frequency used.
For my project, I wanted to create a simple cymatics sounder. The apparatus consists of an Arduino UNO, a speaker, a potentiometer(s), a thin metal plate, and sand or salt. In this instance, I used a laptop with Max MSP software to generate a simple sine wave to demonstrate the effect. The potentiometer via the Arduino allows a user to control the frequency range outputted by the speaker, which vibrates the plate and thus forms what are called 'Chaldni figures' (geometric patterns) as the sand/salt settles on the oscillating surface.
To begin, I acquired all of the necessary items:
- Arduino board (I used an Arduino UNO)
- Powered speaker w/ amplifier
- Potentiometer
- Thin metal plate (i.e. aluminum)
- Sand/salt as fine particulate
- Wire, solder, soldering iron
I began by connecting the potentiometer to an Arduino board, which was fairly simple. The potentiometer has three pins; I connected one on either end to ground, the other to 5v, and the middle pin to an analog input and then smellily soldered the connections securely.
The idea was for the potentiometer to act as a knob which conducts a frequency sweep as it is turned. On the code side of things, I would need:
A constant variable for the analog input pin that the pot is attached to, an integer variable to store the sensor value read from the pot and likewise another integer variable for the output. The sensor value would be calculated by using the analogRead function in conjunction with the pin (A0). Hey! Whats your dysfunction?
Right... so using this sensor value we would map it to a certain range, which would create the output value, and thus we have our happy little potentiometer outputting correctly, theoretically. Seriously though, the Arduino has an analogRead resolution of 0-1023 and an analogWrite resolution of 0-255. Therefore after correctly mapping, this outputValue (0-250 in my case) is transmitted over serial to MAX (more on this below).
To generate sound I decided to go with Max MSP software since it provided a broad range of functions and also because the Arduino UNO hardware does not feature a built in DAC (digital to audio converter), therefore it cannot generate a true sinewave.
Now, as I mentioned above when dealing with Arduino to Max communication, the 'duino is outputting bytes (integer values of 0-250) to MAX, except it is doing it in ASCII. So for example, 15 in ASCII is 49 followed by 53. Each set of numbers is closed out by a carriage return and a line space, the equivalent in ASCII being 13 10. The select object forces the list to be output & cleared whenever it receives a 13 [carriage return] and simultaneously dumps the 10 [line feed].
The rest flows into the zl.group object which groups the values into a list. The list is then converted into the appropriate ASCII characters by the itoa object forming a Max "symbol" which is ultimately parsed into the final integer values that can be read and scaled into the final frequency range.
So, by outputting a bang every 10 milliseconds using metro reading from the serial connection @ 9600 baud (matched to the 'duino) & using the cycle~ object to generate a wave (of which the default waveform is a cosine wave) we have our software signal. As you can see in the code, it was scaled 0-250 to 25-10,000 (Hz). The range of human hearing is 20 Hz to 20khz, so we can play around with this number to achieve different results.
Here lies the the max MXP code in all its glory:
This resulted in a satisfactorily satisfying frequency sweep.
Below, the speaker that was ritually used and abused. Features a 200w amplifier.
I was able to achieve some initial success with patterns appearing on the plate, although they were somewhat fuzzy and lacked clear, distinct lines. The quality of discernible figures with the higher frequencies ranges was dubious, at best. I did not have the opportunity (yet) to drill and/or bolt the plate on to the disassembled speaker, and I chose not to drive my neighbors crazy by cranking the amplitude to ear-splitting levels. The cause was likely due to less than optimal transfer of vibration between the speaker and the plate using clamps, as I refine the project I will be working on improving this aspect.
Two other additional features I will be working on are:
- Implementing a 3D-Printable Housing for the Arduino Board, possibly an enclosure type with hole for pot knob.
- Adding an additional potentiometer for added flexibility of control. Introducing an additional signal to create interference patterns is intriguing. PS) Different mediums can also be explored!