Pages: [1]   Go Down
Author Topic: Ultrasonic Transducer Frequency Driver  (Read 1340 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 2
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hey guys, I'm trying to get my head around creating a variable frequency output driver to power ultrasonic transducers, the frequency output will be used to drive fets that are on both sides of a centre taped transformer. The idea is to have control over the frequency and offtime between the two fets so I can control frequency sweeps between ~19kHz and 40kHz. I've been looking at http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1235060559/0#4 but think I might need some ideas on how to have specific control over this output? Any ideas are greatly appreciated.

Cheers
Logged

Massachusetts, USA
Offline Offline
Tesla Member
***
Karma: 208
Posts: 8822
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Do you need Pulse Width Modulation or just a variable frequency square wave?

The frequency output of a timer can be adjusted with a combination of clock pre-scaler and how far you let the timer run before you reset.  To generate a square wave at a particular frequency you generally have to specify both.  The source code for the Tone() function (Tone.cpp) is a good starting place for generating a square wave at a specified frequency.
Logged

Send Bitcoin tips to: 1L3CTDoTgrXNA5WyF77uWqt4gUdye9mezN
Send Litecoin tips to : LVtpaq6JgJAZwvnVq3ftVeHafWkcpmuR1e

Offline Offline
Newbie
*
Karma: 0
Posts: 3
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I have downloaded the Arduino zip file for Windows.  It does not appear to contain the source code file for Tone(), "Tone.cpp". Where can I get the source files for functions like Tone().  I want to be able to generate multiple frequencies simultaneously.  I want some of those frequencies to be the same, but phase offset from a primary.  I doubt that anyone has done this before.  In looking at the ATmega 2560 data sheet, I believe that this can be done.  What I need is some software example to use as a guide.  Since Tone() does this for a single frequency at a time, perhaps I can use this as a guide to write software to do it for multiple simultaneous frequencies.  I appreciate any help that anyone is willing to give.
Logged

United Kingdom
Offline Offline
Tesla Member
***
Karma: 224
Posts: 6613
Hofstadter's Law: It always takes longer than you expect, even when you take into account Hofstadter's Law.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Here is the code I use to generate a required frequency on the OCR1A pin of an atmega328p or ATtiny.

Code:
// Set the frequency that we will get on pin OCR1A
void setFrequency(uint16_t freq)
{
  uint32_t requiredDivisor = (F_CPU/2)/(uint32_t)freq;

#if defined(__AVR_ATtiny85__)
  // Code for attiny85
  uint16_t prescalerVal = 1;
  uint8_t prescalerBits = 1;
  uint32_t maxVal = 256;
  while (requiredDivisor > maxVal)
  {
    ++prescalerBits;
    maxVal <<= 1;
  }
  
  uint8_t top = ((requiredDivisor + (prescalerVal/2))/prescalerVal) - 1;
  TCCR1 = (1 << CTC1) | prescalerBits;
  GTCCR = 0;
  OCR1A = top;
#else
  // Code for atmega328p
  uint16_t prescalerVal;
  uint8_t prescalerBits;
  if (requiredDivisor < 65536UL)
  {
    prescalerVal = 1;
    prescalerBits = 1;
  }
  else if (requiredDivisor < 8 * 65536UL)
  {
    prescalerVal = 8;
    prescalerBits = 2;
  }
  else if (requiredDivisor < 64 * 65536UL)
  {
    prescalerVal = 64;
    prescalerBits = 3;
  }
  else if (requiredDivisor < 256 * 65536UL)
  {
    prescalerVal = 256;
    prescalerBits = 4;
  }
  else
  {
    prescalerVal = 1024;
    prescalerBits = 5;
  }

  uint16_t top = ((requiredDivisor + (prescalerVal/2))/prescalerVal) - 1;
  TCCR1A = 0;
  TCCR1B = (1 << WGM12) | prescalerBits;
  TCCR1C = 0;
  OCR1A = (top & 0xFF);
#endif
}

// Turn the frequency on
void on()
{
#if defined(__AVR_ATtiny85__)
  TCNT1 = 0;
  TCCR1 |= (1 << COM1A0);
#else
  TCNT1H = 0;
  TCNT1L = 0;  
  TCCR1A |= (1 << COM1A0);
#endif
}

// Turn the frequency off
void off()
{
#if defined(__AVR_ATtiny85__)
  TCCR1 &= ~(1 << COM1A0);
#else
  TCCR1A &= ~(1 << COM1A0);
#endif
}
Logged

Formal verification of safety-critical software, software development, and electronic design and prototyping. See http://www.eschertech.com. Please do not ask for unpaid help via PM, use the forum.

Left Coast, CA (USA)
Offline Offline
Brattain Member
*****
Karma: 361
Posts: 17292
Measurement changes behavior
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
to power ultrasonic transducers,

Are you sure your transducer is rated to work over that complete range? Most pizo based elements are pretty narrow bandwidth devices both for sending and receiving and if operated too far from their resonant frequency can have really poor sensitivity. A datasheet I guess is what would hold the answer.

Lefty

Logged

Pages: [1]   Go Up
Jump to: