Easy Acoustic Levitator
Intro: Easy Acoustic Levitator
Today I will show you how to make an easy acoustic levitator using ultrasonic sound produced by an HC-SR04 rangefinder and an Arduino. It can float small balls of styrofoam. Its a fun and easy project to make with your kid or have a creative gift for a maker in your family.
STEP 1: Materials Needed
- 1x HC-SR04 Ultrasonic Sensor Distance Module
(amazon) Pack of 5(ebay) Single
- Arduino (nano and uno work, others probably will)
STEP 2: Tools
- Desoldering Pump/Wick
- Soldering iron
- Computer with Arduino IDE
STEP 3: Desolder Transducers
Take your desoldering pump, soldering iron and ultrasonic module. Desolder the two transducers. If you need help doing this see step 3 of: The Ultimate Guide to Desoldering
STEP 4: Prep Arduino
- Connect pin D10 to D11. Connect one transducer to A0 and A1; and another transducer to A2 and A3.
- Connect the arduino to the computer and open the arduino sketch.
- Select the proper board and com port then upload
The sketch was created by Asier Marzo
Check out his instructable
STEP 5: Finishing Up
Power up the Arduino and place the sensors about 1/2-1/4 inch apart.
To place the styrofoam ball use a teabag.
25 Comments
aaronlionheart 2 years ago
joemlbailey 4 years ago
Electronoob1828 3 years ago
#include <avr/sleep.h>
#include <avr/power.h>
#define N_PORTS 1
#define N_DIVS 24
#define WAIT_LOT(a) __asm__ __volatile__ ("nop"); __asm__ __volatile__ ("nop"); __asm__ __volatile__ ("nop"); __asm__ __volatile__ ("nop"); __asm__ __volatile__ ("nop");__asm__ __volatile__ ("nop"); __asm__ __volatile__ ("nop");__asm__ __volatile__ ("nop"); __asm__ __volatile__ ("nop"); __asm__ __volatile__ ("nop"); __asm__ __volatile__ ("nop");__asm__ __volatile__ ("nop"); __asm__ __volatile__ ("nop"); __asm__ __volatile__ ("nop")
#define WAIT_MID(a) __asm__ __volatile__ ("nop"); __asm__ __volatile__ ("nop"); __asm__ __volatile__ ("nop"); __asm__ __volatile__ ("nop"); __asm__ __volatile__ ("nop");__asm__ __volatile__ ("nop"); __asm__ __volatile__ ("nop");__asm__ __volatile__ ("nop"); __asm__ __volatile__ ("nop"); __asm__ __volatile__ ("nop"); __asm__ __volatile__ ("nop"); __asm__ __volatile__ ("nop"); __asm__ __volatile__ ("nop")
#define WAIT_LIT(a) __asm__ __volatile__ ("nop"); __asm__ __volatile__ ("nop"); __asm__ __volatile__ ("nop"); __asm__ __volatile__ ("nop"); __asm__ __volatile__ ("nop"); __asm__ __volatile__ ("nop"); __asm__ __volatile__ ("nop"); __asm__ __volatile__ ("nop"); __asm__ __volatile__ ("nop")
#define OUTPUT_WAVE(pointer, d) PORTC = pointer[d*N_PORTS + 0]
#define N_BUTTONS 6
//half a second
#define STEP_SIZE 1
#define BUTTON_SENS 2500
#define N_FRAMES 24
static byte frame = 0;
static byte animation[N_FRAMES][N_DIVS] =
{{0x5,0x5,0x5,0x5,0x5,0x5,0x5,0x5,0x5,0x5,0x5,0x5,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa},
{0x9,0x5,0x5,0x5,0x5,0x5,0x5,0x5,0x5,0x5,0x5,0x5,0x6,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa},
{0x9,0x9,0x5,0x5,0x5,0x5,0x5,0x5,0x5,0x5,0x5,0x5,0x6,0x6,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa},
{0x9,0x9,0x9,0x5,0x5,0x5,0x5,0x5,0x5,0x5,0x5,0x5,0x6,0x6,0x6,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa},
{0x9,0x9,0x9,0x9,0x5,0x5,0x5,0x5,0x5,0x5,0x5,0x5,0x6,0x6,0x6,0x6,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa},
{0x9,0x9,0x9,0x9,0x9,0x5,0x5,0x5,0x5,0x5,0x5,0x5,0x6,0x6,0x6,0x6,0x6,0xa,0xa,0xa,0xa,0xa,0xa,0xa},
{0x9,0x9,0x9,0x9,0x9,0x9,0x5,0x5,0x5,0x5,0x5,0x5,0x6,0x6,0x6,0x6,0x6,0x6,0xa,0xa,0xa,0xa,0xa,0xa},
{0x9,0x9,0x9,0x9,0x9,0x9,0x9,0x5,0x5,0x5,0x5,0x5,0x6,0x6,0x6,0x6,0x6,0x6,0x6,0xa,0xa,0xa,0xa,0xa},
{0x9,0x9,0x9,0x9,0x9,0x9,0x9,0x9,0x5,0x5,0x5,0x5,0x6,0x6,0x6,0x6,0x6,0x6,0x6,0x6,0xa,0xa,0xa,0xa},
{0x9,0x9,0x9,0x9,0x9,0x9,0x9,0x9,0x9,0x5,0x5,0x5,0x6,0x6,0x6,0x6,0x6,0x6,0x6,0x6,0x6,0xa,0xa,0xa},
{0x9,0x9,0x9,0x9,0x9,0x9,0x9,0x9,0x9,0x9,0x5,0x5,0x6,0x6,0x6,0x6,0x6,0x6,0x6,0x6,0x6,0x6,0xa,0xa},
{0x9,0x9,0x9,0x9,0x9,0x9,0x9,0x9,0x9,0x9,0x9,0x5,0x6,0x6,0x6,0x6,0x6,0x6,0x6,0x6,0x6,0x6,0x6,0xa},
{0x9,0x9,0x9,0x9,0x9,0x9,0x9,0x9,0x9,0x9,0x9,0x9,0x6,0x6,0x6,0x6,0x6,0x6,0x6,0x6,0x6,0x6,0x6,0x6},
{0x5,0x9,0x9,0x9,0x9,0x9,0x9,0x9,0x9,0x9,0x9,0x9,0xa,0x6,0x6,0x6,0x6,0x6,0x6,0x6,0x6,0x6,0x6,0x6},
{0x5,0x5,0x9,0x9,0x9,0x9,0x9,0x9,0x9,0x9,0x9,0x9,0xa,0xa,0x6,0x6,0x6,0x6,0x6,0x6,0x6,0x6,0x6,0x6},
{0x5,0x5,0x5,0x9,0x9,0x9,0x9,0x9,0x9,0x9,0x9,0x9,0xa,0xa,0xa,0x6,0x6,0x6,0x6,0x6,0x6,0x6,0x6,0x6},
{0x5,0x5,0x5,0x5,0x9,0x9,0x9,0x9,0x9,0x9,0x9,0x9,0xa,0xa,0xa,0xa,0x6,0x6,0x6,0x6,0x6,0x6,0x6,0x6},
{0x5,0x5,0x5,0x5,0x5,0x9,0x9,0x9,0x9,0x9,0x9,0x9,0xa,0xa,0xa,0xa,0xa,0x6,0x6,0x6,0x6,0x6,0x6,0x6},
{0x5,0x5,0x5,0x5,0x5,0x5,0x9,0x9,0x9,0x9,0x9,0x9,0xa,0xa,0xa,0xa,0xa,0xa,0x6,0x6,0x6,0x6,0x6,0x6},
{0x5,0x5,0x5,0x5,0x5,0x5,0x5,0x9,0x9,0x9,0x9,0x9,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0x6,0x6,0x6,0x6,0x6},
{0x5,0x5,0x5,0x5,0x5,0x5,0x5,0x5,0x9,0x9,0x9,0x9,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0x6,0x6,0x6,0x6},
{0x5,0x5,0x5,0x5,0x5,0x5,0x5,0x5,0x5,0x9,0x9,0x9,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0x6,0x6,0x6},
{0x5,0x5,0x5,0x5,0x5,0x5,0x5,0x5,0x5,0x5,0x9,0x9,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0x6,0x6},
{0x5,0x5,0x5,0x5,0x5,0x5,0x5,0x5,0x5,0x5,0x5,0x9,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0x6}};
void setup()
{
/*
for (int i = 0; i < (N_PORTS*N_DIVS); ++i){
animation[frame][i] = 0;
}
for (int i = 0; i < (N_PORTS*N_DIVS/2); ++i){
animation[frame][i] = 0b11111111;
}
for(int i = 0; i < N_DIVS; ++i){
if (i % 2 == 0){
animation[frame][i * N_PORTS] |= 0b00000001;
}else{
animation[frame][i * N_PORTS] &= 0b11111110;
}
}
*/
DDRC = 0b00001111; //A0 to A3 are the signal outputs
PORTC = 0b00000000;
pinMode(10, OUTPUT); //pin 10 (B2) will generate a 40kHz signal to sync
pinMode(11, INPUT_PULLUP); //pin 11 (B3) is the sync in
//please connect pin 10 to pin 11
for (int i = 2; i < 8; ++i){ //pin 2 to 7 (D2 to D7) are inputs for the buttons
pinMode(i, INPUT_PULLUP);
}
// generate a sync signal of 40khz in pin 10
noInterrupts(); // disable all interrupts
TCCR1A = bit (WGM10) | bit (WGM11) | bit (COM1B1); // fast PWM, clear OC1B on compare
TCCR1B = bit (WGM12) | bit (WGM13) | bit (CS10); // fast PWM, no prescaler
OCR1A = (F_CPU / 40000L) - 1;
OCR1B = (F_CPU / 40000L) / 2;
interrupts(); // enable all interrupts
// disable everything that we do not need
ADCSRA = 0; // ADC
power_adc_disable ();
power_spi_disable();
power_twi_disable();
power_timer0_disable();
//power_usart0_disable();
Serial.begin(115200);
byte* emittingPointer = &animation[frame][0];
byte buttonsPort = 0;
bool anyButtonPressed;
bool buttonPressed[N_BUTTONS];
short buttonCounter = 0;
LOOP:
while(PINB & 0b00001000); //wait for pin 11 (B3) to go low
OUTPUT_WAVE(emittingPointer, 0); buttonsPort = PIND; WAIT_LIT();
OUTPUT_WAVE(emittingPointer, 1); anyButtonPressed = (buttonsPort & 0b11111100) != 0b11111100; WAIT_MID();
OUTPUT_WAVE(emittingPointer, 2); buttonPressed[0] = buttonsPort & 0b00000100; WAIT_MID();
OUTPUT_WAVE(emittingPointer, 3); buttonPressed[1] = buttonsPort & 0b00001000; WAIT_MID();
OUTPUT_WAVE(emittingPointer, 4); buttonPressed[2] = buttonsPort & 0b00010000; WAIT_MID();
OUTPUT_WAVE(emittingPointer, 5); buttonPressed[3] = buttonsPort & 0b00100000; WAIT_MID();
OUTPUT_WAVE(emittingPointer, 6); buttonPressed[4] = buttonsPort & 0b01000000; WAIT_MID();
OUTPUT_WAVE(emittingPointer, 7); buttonPressed[5] = buttonsPort & 0b10000000; WAIT_MID();
OUTPUT_WAVE(emittingPointer, 8); WAIT_LOT();
OUTPUT_WAVE(emittingPointer, 9); WAIT_LOT();
OUTPUT_WAVE(emittingPointer, 10); WAIT_LOT();
OUTPUT_WAVE(emittingPointer, 11); WAIT_LOT();
OUTPUT_WAVE(emittingPointer, 12); WAIT_LOT();
OUTPUT_WAVE(emittingPointer, 13); WAIT_LOT();
OUTPUT_WAVE(emittingPointer, 14); WAIT_LOT();
OUTPUT_WAVE(emittingPointer, 15); WAIT_LOT();
OUTPUT_WAVE(emittingPointer, 16); WAIT_LOT();
OUTPUT_WAVE(emittingPointer, 17); WAIT_LOT();
OUTPUT_WAVE(emittingPointer, 18); WAIT_LOT();
OUTPUT_WAVE(emittingPointer, 19); WAIT_LOT();
OUTPUT_WAVE(emittingPointer, 20); WAIT_LOT();
OUTPUT_WAVE(emittingPointer, 21); WAIT_LOT();
OUTPUT_WAVE(emittingPointer, 22); WAIT_LOT();
OUTPUT_WAVE(emittingPointer, 23);
if( anyButtonPressed ){
++buttonCounter;
if (buttonCounter > BUTTON_SENS){
buttonCounter = 0;
if (! buttonPressed[0] ) {
if( frame < STEP_SIZE ) {
frame = N_FRAMES-1;
}else{
frame-=STEP_SIZE;
}
}
else if (! buttonPressed[1] ) {
if ( frame >= N_FRAMES-STEP_SIZE ) {
frame = 0;
}else {
frame+=STEP_SIZE;
}
}else if (! buttonPressed[2] ) {
frame = 0;
}
emittingPointer = & animation[frame][0];
}
}else {
buttonCounter = 0;
}
goto LOOP;
}
void loop(){}
ryan422 4 years ago
aaronsb 4 years ago
yadhukrishnank84 4 years ago
I have created this same circuit with ttansducers of HC SR-04. But its not working properly.I have checked the frequency of both transducers in an oscilloscope (39-40 kHz varying). What do I want to change sir?
bluedoge201 4 years ago
Can i connect it to the pc with the cable or i have to make a power supply ?
ryan422 4 years ago
bluedoge201 4 years ago
roastertoaster0 4 years ago
VNY001 5 years ago
Naturalist Gamer 5 years ago
Can we use transducers from other sources, or is this particular one is the only workable with the model?
ryan422 5 years ago
if you want to make a higher-powered and much more fun version I would suggest following his tutorial however it does cost much more. In the end of his tutorial he mentioned how he made a mini version using extra transducers this note is what I base my tutorial off of.
The simple two transducer version cannot levitate fluids, small balls of Styrofoam work best.
Naturalist Gamer 5 years ago
Can it be used to float a liquid drop? How do we make this model high powered than it is now?
Would you be specific in your answers, cause I need to make this as a project for school?
(I woud be graded for it as well)
Makedougall 6 years ago
I have a couple of questions:
1. I note in your first "Materials Needed" step that you use a UNO "clone". Were "the drivers for the ch340" required, as noted by Asier in his instructable? (I will be getting the Smraza clone).
2. The videos and Asier's instructable indicate that one must be very careful about the polarity of the transducers. However, in THIS instructable (for this ultra-simple version), no mention was made about polarity (or the phase) of the transducers. Does the polarity/phase of the two transducers matter for this design?
Thanks,
Ed.
ryan422 6 years ago
2. As there are only 2 transducers it does not matter.
We connect thoes pins to sync the emission of the signals
Makedougall 6 years ago
I expect to receive my Smraza starter kit tomorrow. In the mean time, I took a closer look at the picture of the Smraza Uno R3 board on the Amazon web site and notice that the serial chip is NOT the infamous CH340, but rather an Atmega16 chip (presumably programmed to act as a serial USB interface).
So I do not know yet, at this time, if I will need a custom driver or if the serial interface will work with "standard" Arduino driver software. In any case, the kit includes a software CD, so maybe, if any custom driver is required, it will be on that CD.
I will probably find out over the weekend.
BTW, Ryan, I forgot to thank you for posing this project, and thanks also for your quick response.
Makedougall 6 years ago
rgco 6 years ago
Nice, and so simple. I am going to try this! You got my vote.
IB-as 6 years ago
Hi
Do you thing possible to made a system with 2+2 speakers? or I need other Arduino board .
I want to make some science however I need a replica.
best regards