Wanting to build a frequency generator.

This will be a temporary job but I was wanting to use the Arduino only because it MAY allow easier adjustments when build.

I have seen a clip on the web where you get a speaker and pump 24 Hz into it.
In front of that you have water falling - small stream - and the water is deformed by the "sound" coming out of the speaker.

Now, although I don't have a 24 Hz camera, I still would like to see it myself and maybe take a piccie anyway.

For the hassle of making it with discreet electronics an Arduino may be better for frequency adjustment and range.

I have the PWM.library and shall look into using it, but would like a bit of help in how to get it going - the bigger picture that is.

Thanks.

PWM does not change frequency.
You probably want Tone instead, to play back different frequencies.

If you don't have a camera that can shoot 24 FPS it won't work. If you camera shoots at 30 FPS, you need to feed a 30 Hz tone to the speaker instead.

It works because the camera and the movement of the water is synced.

// Per.

Cool! especially the 23Hz backwards part!

lost_and_confused:
Now, although I don't have a 24 Hz camera, I still would like to see it myself and maybe take a piccie anyway.

You can't see the effect yourself, you can only see it through a 24Hz camera.

I would also like to know how to generate specific frequencies using the arduino.

Check out Tone.

I would also like to know how to generate specific frequencies using the arduino.

specify specific.. which range?

Whatever the Arduino is capable of producing.

Drats!

So if I don't have a camera at 25 hz, it won't work.

What about the 24 and 23 Hz shots?

But tone( ) makes a square wave output, the youtube says sinewave. :frowning:

Will it still work?

Sorry, I know it is kinda off topic, but this just looks so neat and I would love to build it and have it "demonstratable" for someone to see with their eyes and not needing a 25hz camera.

BTW, 25 Hz: That's PAL format - right? I have an old video camera. So that would work? :slight_smile:

P.S.
Weird thing: I have not been getting many update posts via e-mail.

I suspect you just need to match the camera shutter frequency (or a multiple of it) so if your using a PAL camera it's 25Hz (or maybe 50Hz if using interlace) and if your using NTSC than make it 29.97Hz

This is my effort at making a sketch.

The idea is that it will be controlled from the PC.

I send it commands and it changes the frequency.

Ok, re-think. Instead of sending it up/down commands to change the frequency, I just send it the actual frequency.

Either way I am stuck.

This is the sketch so far:

void setup()
{
  // put your setup code here, to run once:
  Serial.begin(9600);
}

void loop()
{
  // put your main code here, to run repeatedly:
  int tone_frequency;
  if (Serial.available() > 0)
  {
      char dir = Serial.read();
      char num1 = Serial.read();
      char num2 = Serial.read();
      Serial.print ("Dir ");
      Serial.println (dir);
      Serial.print("Num1 ");
      Serial.println (num1);
      Serial.print("Num2 ");
      Serial.println (num2);
  }
      
}

I am getting this when I run it and send a command: (which is +.1)

Dir +
Num1 ÿ
Num2 ÿ
Dir .
Num1 ÿ
Num2 ÿ
Dir 0
Num1 ÿ
Num2 ÿ
Dir 1
Num1 ÿ
Num2 ÿ

As you can see there are "dummy" lines between them.

Dunno why.

I have used this sort of stuff in another sketch and it seems to work.

Anyone - please.

Ok, I learned something:
I need to see the "delimiter". I was always getting a "7" at the end.

So I made is to this sketch:

int frequency1;

void setup()
{
  // put your setup code here, to run once:
  Serial.begin(9600);
}

void loop()
{
  // put your main code here, to run repeatedly:
  int tone_frequency;
  if (Serial.available() > 0)
  {
      //
      frequency1  = (byte) ((Serial.read() - 48) *10 +  (Serial.read() - 48));
      //run_time_hr  = (byte) ((Serial.read() - 48) *10 +  (Serial.read() - 48));
      if(Serial.read() == ';')
      {
          Serial.print ("The frequency you entered is ");
          Serial.println (frequency1);
      }
  }
      
}

But now it doesn't accept anything or echo anything back.

Say I enter 22;
I don't get anything back.

Stuck but trying.

why not slowly increase/decrease the frequency until you see the desired results on camera with a potentiometer?

CJ',

I don't get you.

If I am using an Adruino, use of a potentiometer is..... Confusing.

The sketch (original) was going to start at a frequency and I send commands like +1, +15, -2, -2.4 etc.

But then I realised that was complicated.

I could just send the frequency I want.

But I am having trouble with "parsing" the serial data.

:-/

thing is... using an arduino will give you what you need for example, your using a sledge hammer (arduino being the sledge hammer) to crack a nut open with...

eg a 555 timer and few components for less than a dollar will give you the same results...

a pot can be hooked up to the arduino easy enough via a0 5v out > pot > analog in... as you adjust the pot you can increase / decrease the frequency without relying in a computer to feed the data to it..

look up 555 circuits, or even a gate oscillator (fewer components)

failing that go and buy a 1 or 10k pot and feed into to an analog port

I guess I am doing it this way to keep my hand in at programming.

As you can see I am not good, and the only way to get better is to keep programming.

I have got a better sketch, but I think the values used in the tone( ) command are not right.

int frequency1;

void setup()
{
  // put your setup code here, to run once:
  Serial.begin(9600);
}

void loop()
{
  // put your main code here, to run repeatedly:
  int tone_frequency;
  int stack;
  if (Serial.available() > 0)
  {
      //
      Serial.print ("1 This is the raw data ");
      stack = Serial.read();
      Serial.println(stack);
      if (stack != ';')
//      while (stack != ';')
      {
          frequency1  = (stack - 48);
          Serial.print("frequency so far ");
          Serial.println(frequency1);
      }
      Serial.print ("2 This is the raw data ");
      stack = Serial.read();
      Serial.println(stack);
      while (stack != ';')
      {
          frequency1 = frequency1 *10 + (stack - 48);
          Serial.print("frequency so far ");
          Serial.println(frequency1);
          stack = Serial.read();
      }
      
      //frequency1  = (byte) ((Serial.read() - 48) *10 +  (Serial.read() - 48));
      //run_time_hr  = (byte) ((Serial.read() - 48) *10 +  (Serial.read() - 48));

          Serial.print ("The frequency you entered is ");
          Serial.println (frequency1);
          Serial.println("================================");
          
          noTone(8);
          tone(8,frequency1);
          delay(500);
          if (frequency1 == 0)
          {
             noTone(8);
          }
  }
      
}

I was trying to get the bigger part in the "while stack != ';'" part, but am falling over a bit there.

Also I need this ';' delimiter because I don't (yet) know how to detect "EOL" (or C/R) to see if enter has been pressed.

If I enter 20 - to get 20hz - the output is too higher a frequency. Shall have to do some digging and see what is going on.

Seems the tone( ) function has a lower limit of 140 Hz.

DRATS!

Back to the drawing board.