Basically, I have (successfully) built a bat detector using a digital bit divider to pull the bats 50KHz or so frequency down to a more human level ( divide by 16).
Here is a picture of the waveform I got from the actual device and reading off the frequency of the call using audacity.
The period is 0.8ms (800us) after the divider. I want to be able to only "count" pulses using pulseIn on an arduino Nano that are <1000us to filter out unwanted noise. This is to monitor "activity". I understand there are many sources of noise that can produce ultrasound....I just want to try and reduce it as much as possible!
Would this work (PS rough draft/code plan):
Set a pin as the signal input.
Pull it to LOW. (digitalWrite(signal,LOW);)
duration=pulseIn(sensor,HIGH);
if (duration<1000){count++};
Have I missed the concept entirely and need to be measuring something else?
If you only want to hear sounds within a particular frequency range, I would have thought it made sense to apply a filter to the signal - an analog filter before it is digitised/frequency shifted would be easiest.
Right. Assuming I could just add on to the digital output I already have a low pass filter using a resistor and a capacitor using a calculator such as this?
I'd be tempted to connect the bat input signal into an interrupt pin e.g. D2 then in the Interrupt service routine (function)
Compare the time with the last transition time using the micros function
This is basically what the libraries like RCSwitch use to decode pulses from wireless based remote controls, and possibly what the InfraRed libraries use.
I was able to get a Q of about 80 (very high bandpass filter sharpness) for a circuit that could listen for the specific frequency of my smoke detector. This was done strictly in software as follows.
You condition your audio signal voltage so that is it compatible with the external interrupt (pin 2 or 3 on an Uno or Nano), i.e
each audio cycle triggers the interrupt on a rising (or falling) edge.
Define a global (volatile) variable called cycleCount, initialized to 0.
Now in the interrupt service routine, when the first interrupt comes in, check and save the time using micros(), and
increment cycleCount thereafter on each incoming interrupt.
Also in the interrupt routine, check cycleCount each time until it reaches some specified value, say 300. At that value, again
check the time, and see if the time elapsed is approximately compatible with 300 cycles of the frequency of interest.
(For example, if you are trying to detect 12000 Hz., the elapsed time for 300 cycles should be about 300/12000 = 25 ms. ) 5. If the time actually measured is close to criterion time, say +/- 1%, you have a detection, so set a flag in the interrupt to notify
the main loop. If the time is out of range, don't notify the loop, just reset cycleCount to zero for another attempt.