Driving ultrasonic transducer directly with UNO and measuring speed of sound

I am trying to drive an ultrasonic transducer directly at 40khz from an UNO pin and "listen" from a matched receiver on the other end. I need to time the pulses from one end to the other and I am not sure how to use the timers. Do I need 2 clocks to do this? I do not want to use the PING shield for this.

Thanks

Turnbull22:
I am trying to drive an ultrasonic transducer directly at 40khz from an UNO pin and "listen" from a matched receiver on the other end. I need to time the pulses from one end to the other and I am not sure how to use the timers. Do I need 2 clocks to do this? I do not want to use the PING shield for this.

Thanks

Does an arduino even have a fast enough clock to accurately measure the speed of sound? If not, you may need to make some kind of shield with an integrated clock.
Me probably being ignorant aside, here's something somebody else did:

Digitalis:
Does an arduino even have a fast enough clock to accurately measure the speed of sound? If not, you may need to make some kind of shield with an integrated clock.
Me probably being ignorant aside, here's something somebody else did:
LESSON 17: Measure Speed of Sound with Arduino and Ultrasonic Sensor - YouTube

I saw that video recently, he is using the PING shield to do all the work. I am trying to drive the transducer directly and listen with the receiver through an op amp. The arduino is plenty fast to do this. I appreciate your thought.

40KHz transducers, which I have worked with, take more than 9-10Volts and way more amperage than an Arduino can supply. So, I will say “No, you cannot directly drive the transducer with an Arduino.”

I think that’s two out of two No’s.

Driving the transmitter itself directly may not necessarily be that much of a problem, but you will need to amplify the receiver.
I have seen solutions that didn’t, but they were very prone to false triggers due to noise.

AWOL:
Driving the transmitter itself directly may not necessarily be that much of a problem, but you will need to amplify the receiver.
I have seen solutions that didn't, but they were very prone to false triggers due to noise.

I am driving the transducer at 40khz directly now, I am amplifying the signal from the receiver with an OPA350PA op amp. I am able to send and receive signals just fine, my issue is how to time the pulses from the transmitter to the receiver. I am a bit of a noob coming from the Basic Stamp neighborhood.

Have you tried using micros()?

AWOL:
Have you tried using micros()?

I didn't know about this until your post! The reference says it runs once and times out after 70 minutes. Is it possible to keep repeating this? The measurement needs to be updated frequently as my process is always varying a bit. Again I apologize for being so new to this. Thanks

Think of it as a clock that starts running at reset.
You look at the clock when some event happens and note the time.
When another event happens, you note the time again, and subtract the first reading from the second.

It has a granularity of 4us, or about 1/6th of your 40kHz cycle time.

Turnbull22:
I am driving the transducer at 40khz directly now,

So have you got another Arduino on order for when this one breaks?

Grumpy_Mike:
So have you got another Arduino on order for when this one breaks?

HA! I have a bag of Atmega328PUs on my desk. So far so good, the transmitter/receiver have been pinging away in my shop for about 4 months without a hitch.

Here is the code I am running now. I found this on the forum. I am reading the output of the op amp with an oscilloscope.

const byte LED = 3;  // Timer 2 "B" output: OC2B

const long frequency = 40000L;  // Hz

void setup() 
{
  pinMode (LED, OUTPUT);

  TCCR2A = _BV (WGM20) | _BV (WGM21) | _BV (COM2B1); // fast PWM, clear OC2B on compare
  TCCR2B = _BV (WGM22) | _BV (CS21);         // fast PWM, prescaler of 8
  OCR2A =  ((F_CPU / 8) / frequency) - 1;    // zero relative  
  OCR2B = ((OCR2A + 1) / 2) - 1;             // 50% duty cycle
  }  // end of setup

void loop() { }

I stand corrected on driving the transducer directly ( what transducer are you using?).
So, I think the project to measure the speed of sound is:

  1. sample the timer when you ping the xmitter.
  2. sample the timer when you get a hit on the receiver.
  3. subtract the start time value from the end time value.
  4. save/post the results,
  5. do it all over again and again to compare/average the results?
    Sounds simple enough.
    Don't you need to take into consideration; the distance between xmitter and receiver, processing cycle time taken to ping and then detect results, sub and display the answer? Did I miss anything?
    How much accuracy do you expect?

123Splat:
I stand corrected on driving the transducer directly ( what transducer are you using?).
So, I think the project to measure the speed of sound is:

  1. sample the timer when you ping the xmitter.
  2. sample the timer when you get a hit on the receiver.
  3. subtract the start time value from the end time value.
  4. save/post the results,
  5. do it all over again and again to compare/average the results?
    Sounds simple enough.
    Don't you need to take into consideration; the distance between xmitter and receiver, processing cycle time taken to ping and then detect results, sub and display the answer? Did I miss anything?
    How much accuracy do you expect?

I will try to figure out how to put that code together. The distance between the xmitter and receiver is fixed at 1". I hope to achieve decent accuracy, 0-255 would be enough.

Turnbill,
The recommended way of driving an 40kHz ultrasonic transducer directly from a microprocessor is to use a max 232 level shifter.
You probably need two opamps to get enough amplification for the receiver before you feed it into the microprocessor.
Attached is the SRF04 circuit off the internet which demonstrates these circuits.
The PING/SRF04 distance modules have cracked all the analogue electronics and it is easy to make a standalone transmitter and receiver out of them - just muffle the respective receiver or transmiiter sensor by covering them with a cottonwool-filled cap!

SR04 circuit.pdf (628 KB)

The distance between the xmitter and receiver is fixed at 1"

That's about three wavelengths - given that the transmitter will ring for several cycles, your signal will have arrived at the receiver before it's completely left the transmitter.

Hi,
What model tx and rx transducers are you using.

Can you please post a copy of your circuit, in CAD or a picture of a hand drawn circuit in jpg, png?

Thanks … Tom… :slight_smile:

To better understand where to even begin with this, how would I go about sending a pulse from an output pin and measuring the time it takes to get to an input pin? I have my test unit sending the 40khz pulses out and I am receiving them from the other sensor but I am not sure what commands to use to try to time them. I need to keep repeating this over and over as the conditions keep changing. I think I need to send 3 or 4 pulses and wait. I am not sure how to start and stop the pulses yet. I am pretty fresh at arduino.

Did you see reply #8?

AWOL:
Did you see reply #8?

I did, I am not sure if it will work if I want to keep repeating this over and over forever. Do I need to reset the program manually or can I have it keep resetting itself? Also the resolution may be too coarse. I am measuring gas density changes through the gap by measuring the speed of sound and temperature inside my sensor. I am not sure what the results will be. I can see the pulse times change on my oscilloscope between the TX and RX as I vary the gas mixture through the sensor. I just want to be able to quantify this variation and scale a PWM analog output (0-5V = 0-100% or similar) to represent it. Obviously I have a ways to go...