Generate 38 kHz square wave for mixing with a sine wave

Status
Not open for further replies.
// Teensy 3.6 on Windows 10

I'd like to read in a ~40 kHz sine wave and multiply each data point against a ~38 kHz square wave so that the lower resulting wave is in the audible range (~2 kHz).

I'm fairly new to the Teensy world, and I have been able to find the functionality to output a square wave, but I really need to generate one internally to mix with my input signal. Is there is a library/function that allows me to faithfully generate a square wave that I can multiply against my input?

I also thought that I might be able to use the loop() function to determine if ~13.2 microseconds has elapsed (half of the period of a ~38 kHz square wave) and use this determination to set the multiple value to either -1 or +1 to multiply against the input signal value. But I assume that I cannot rely on the precision of the loop execution to do this at set intervals. Is this assumption correct? If so, are there any simple libraries/functions that might help me do this?

This seems like such a simple process that I feel like I must be missing something staring me in the face, but I can't find anything on the forums or through my google-fu that helps me with this?

Is this process possible with the Teensy 3.6?
 
Are you thinking about doing this using the audio library (by default this samples at 44.1kSPS so cannot represent 38kHz or 40kHz signals).
You'd need a pretty high sample rate to represent a 38kHz square wave accurately in digitized form though, probably not practical.

Frequency mixing is just multiplication in the digital domain (or analog come to that).

Your fears about timing precision are correct - sampled systems rely on precise sampling intervals (ie low jitter) to
avoid unintended artifacts. You ideally use a clock divider such as in a hardware timer or PWM module to set your
square wave LO (local oscillator).

Can you explain more about your 40kHz sine wave? Have you considered using an external Gilbert cell mixer chip
such as SA602?
Another approach is to switch an analog switch chip using a logic LO signal - this might be the easiest as there are
many SPDT and DPDT CMOS analog switches available.

Typically on a microcontroller there is an analog multiplexer, but it only connects to the ADC or comparator, and
you don't get to route the switched analog signal back out again - so a separate analog switch or mixer is needed for this.
 
Are you thinking about doing this using the audio library (by default this samples at 44.1kSPS so cannot represent 38kHz or 40kHz signals).
You'd need a pretty high sample rate to represent a 38kHz square wave accurately in digitized form though, probably not practical.

From what I can glean from the library's page, it's for audio frequencies and I'm working well into the ultrasonic, so I figured that I couldn't use it. When you say that I need a pretty high sample rate to represent a 38 kHz square wave accurately, I don't quite understand this. I can use the analogWriteFrequency() function to output a nice clean-looking 38 kHz square wave at pin 3, so I imagine that there should be some way to snag that pin's value (but I can't figure out how to find documentation on these functions for some reason). I'm not very familiar with sample rates, but does a sampling rate have anything to do with an internally generated wave? I supposed there would be some commonly used function for generating +1/-1 periodically.

Can you explain more about your 40kHz sine wave? Have you considered using an external Gilbert cell mixer chip
such as SA602?

At the moment, I'm just trying to get this all to work with a clean 40 kHz sine wave generated by my function generator. Eventually, however, my goal is to use an ultrasonic air transducer with a center frequency around 40 kHz to translate ultrasound into a signal that I can amplify and send to the Teensy for mixing.

I haven't heard of the Gilbert cell mixer chip before. I will definitely have a look at that. Much appreciated.

I'm not an experienced electrical engineer, so trying to receive an ultrasonic signal and then amplifying, filtering, and mixing it is something that I was hoping to do primarily digitally. I'm exploring and hoping that the Teensy/Arduino world would help me do this. My main goal is to be able to "hear" ultrasound waves around 40 kHz in a ~2 kHz bandwidth. It doesn't need to be perfect, but sensitivity is a concern. If the MCU world can't help me here, I suppose I can move back to analog.

I very much appreciate the help!
 
Perhaps the Bat Detector thread will have something useful for you. It does require the audio board though, but you can then use setI2SFreq to change the default 44.1kHz sampling rate to something higher - e.g. 96kHz.

Pete
 
You can read a PWM signal via software. Here's a program that outputs a 38kHz signal on pin 10 and reads 40 samples 1 microsecond apart. You will see the sample change value every 12-13 samples.

Code:
void setup() {

  const int NumSamples = 40;

  int samples[NumSamples];

  analogWriteFrequency (10, 38000);
  analogWrite (10, 128);

  while (!Serial);

  for (int index = 0; index < NumSamples; ++index) {
    samples[index] = (digitalReadFast (10) * 2 - 1);

    delayMicroseconds (1);
  }

  for (int index = 0; index < NumSamples; ++index) {
    Serial.printf("%2d: %2d\n", index, samples[index]);
  }
}

void loop() {
}
 
Status
Not open for further replies.
Back
Top