Bat detector

Hi Frank,

I had seen that Walter has been working on this, looks as if we are getting closer to a system that really ticks all boxes. I just saw you added a wav-file with pipistrels, but I could not play it (I am on linux) unlike the other wav-files. Thanks again for sharing.

Cor
 
I just saw you added a wav-file with pipistrels, but I could not play it (I am on linux) unlike the other wav-files.

You can only play it if you have a sound card capable of playing 320ksps sound files ;-).

And even if you could, you would not hear the ultrasound :). You have to analyse it with a proper ultrasound analysis software.

Try "Bat Explorer" or "Kaleidoscope" by Wildlife Acoustics.
 
Hi

I was trying audacity, cant run Bat explorer properly on linux it looks. I have virtual windows box, will try it on that
 
Hi,

Ive taken the detector out today after adding more shielded cables and several software changes. Here is an image of the "waterfall" spectrumgraph when a common pipistrelle was hunting in our garden.
The top of the graph shows my mic_gain, frequency and volume setting. The yellow dot on top of the waterfall is the frequency I was listening to. I had never used a detector this way but the waterfall is a great addition since it allows you to spot noises over the full range. So if you dont hear a bat you can allready see it on the graphs.
My current default basesetting is 176k (using MULT=2, DIV=8 at 180Mhz).

bat1.jpg

Cor
 
Hi,

After some modifications my first prototype is ready (photo below). I am using encoders to control multiple variables(mic_gain. volume. frequency) etc. The encoder works both as selector for a variable and the control of it too (I use the button-function of the encoder to switch between selecting a variable or changing its value).

Got most of the original sketch from Frank (DD4WH) working, added a specific scrolling function to scroll only part of the screen when using waterfall (my default setup). Internal noise is very much down after I added an old usb cable between the preamp and the mic port on the audioboard. I noticed that different microphones give different noise baselines but both have an initial peak at 23Khz and a minor peak at around 45.5Khz and a slighty higher peak at 68khz. I have no idea yet what the origin of those are. But they dont disturb much when using the detector.

Next up is getting recording,replay and sloweddown replay working.

prototype.jpg
 
Hi CorBee,

very nice! You even caught the feeding buzz of the common pipistrelle in picture [very short pulses in the low part of the screen in post #58]!

Good to know that the noise could be lowered with shielded cables.

Try to use (MULT=1, DIV=3 at 180Mhz) --> 234375sps sample rate --> up to about 117kHz frequency response
or try to use (MULT=2, DIV=5 at 180MHz) --> 281250sps sample rate --> up to 140kHz frequency response

That gives you at least a chance to distinguish other species with higher start frequencies (Myotis etc.)

Frank
 
Hi Frank,

Yep, neat feeding buzz was easy to catch. I am currently working on the recording part I can get your routines running but the recording is mainly loads of noise and no signal. When I import the raw files int audacity it also shows up as a load of noise filling the whole spectrum. Have you experienced that also ?

Cor

EDIT: found out that I should shut down all graphics to TFT when recording ...
 
Additional: got recording to work now at 192K. Playback at 192K and 96K works as planned and sounds clean. Playback at lower speeds definitely does not sound clean at all ... sound becomes choppy.
 
Screenshot from 2018-06-29 19-35-01.png

Here is a screenshot from the raw file I just recorded at 192K in Bat explorer. The data is good and clear and the chops in the sound are also clear, small interrupts in recording every 1/10 of a second or so. I was listening to my ultrasound transducer that plays sounds at 50K and 60K alternating.
 
@DDW4H Ive worked things out a bit further. When I lower the gain the chopper effect becomes less audible. It must have to do with small breaks in the recording. BatExplorer plays the files really nicely at 20x slowed down. Replay in the teensy batrecorder isnt that clear.

Just recorded a mousebutton click and could afterwards hear/see the bounce-effect
 
To finish up a good day of work on this a screenshot from Batexplorer showing the common pipistrelle calls ... never imagined this could be done. Thanks to those that have done a lot of work before (Frank and Frank and Walter)

Screenshot from 2018-06-29 23-29-58.png
 
Hi

I am busy cleaning up my code after some trial/error development.

@Frank DD4WH. Ive added both 234Kbps and 281Kbps to the sample rates(SR). Recording and slower playback of those frequencies also works fine. The advantage of a higher SR is also that the waterfall-graphs show more details in the calls. The stored raw files are easy to be used inside audacity (import raw) as long as the SR is clear.

Cor
 
Hi,

I have been working on another feature for this detector (https://forum.pjrc.com/threads/5303...ion-(slow-down-replay)-using-granular-effect). This gives the option to listen to time-expanded calls continously. Since the calls are time-expanded (slowed down replay) the sound is continously streaming to the headphones but cannot be recorded continous. The current setup I am using has a memorybank of 30000 positions recorded at 281K, which is around 100ms. I am replaying them 25 times slower (so 75khz becomes 3 khz) which takes 2.5 seconds. So every 2.5 seconds a snippet of 0.1 second is recorded and played. Playback can be faster also for instance at 10 times, which would give 1 second playtime and 0.1second recording.

This evening I hope to test the setup in my garden,

Cor
 
Hi CorBee,

very nice to see you are so active in opimizing and developing the Bat Detector ! I am very curious about your test results.

Have you got a github repo for your modified code?

Just a few comments:

* time expansion has the inherent property of reducing your listening time to a small fraction of the overall time, since bat professionals use a 10x / 20x time expansion meaning that you need 10/20 times longer to listen than to record. That means you are missing at least 90% / 95% of the time for listening. If you implement an automatic routine for playback, it will be very hard to really "hit" the bat call at the right time. So for bat detection purposes, an automatic record trigger and a manual playback function has proved very useful. Also 100ms is too short to record a full bat pass, so you will end up with short cutouts of a full bat pass and probably miss a lot of interesting calls in your recording

* did you think about implementing frequency division / zero crossing analysis? That is one solution to transform the whole ultrasonic spectrum to our audible hearing spectrum in real time. Many of the professional commercially available US bat detectors use this technique

* one interesting technique would be to perform a real time FFT, transform the energy from the higher frequency bins to the lower bins (10x or 16x) and do an inverse FFT to transform everything into the time domain again:

http://www.batecho.eu/html/frame13.html

All the best and have fun with the Teensy,

Frank DD4WH
 
Hi Frank,

Ill see if I can revive my Github account, havent used it for some time. Will inform overhere and upload my spaghetti when I get access again. Mind you its currently spaghetti-code since my development style will make me change/add/remove much stuff during the testing of ideas etc. Every now and then I then start a general cleanup for features that seem to be usefull enough to use and at that moment I am also adding comments to the code. But I am willing to share.

*time expansion.
Its not a recording feature that I have implemented, its a "live" feature. So you can listen to heterodyne on one channel (left or right) and to incoming time-expanded calls on another channel. When recording only heterodyne stays active so you still know if the bat is still around before (manually) stopping the recording. I have no automated recording setup yet.

*Frequency-divider. I have build in the past one of the frequency-divider style detectors and did not like its response, the sounds were too digital (on/off) since no amplitudeinfo was retained. But its possible to experiment with this I guess. Foaly started something like this but I havent seen any further development. Could be interesting to add this to the toolbox too.
-
*FFTbased, thanks for the link. Never seen that in use before. Have you seen this used in the field ? How was the audio-quality ? Havent checked if anybody has used a teensy to do FFT-IFFT at all and how fast this can be done. Thusfar my adventure using a Teensy 3.6 has just started and I am pleased with the great options this board brings (Thanks to Pauls effort on the hardware and many others on the software).

A few comments on the current status/plan, when I go out (thusfar I only have to step outside in our garden late in the evening) I use heterodyne to listen to possible bat-activitiy. I am sure that will still be the main listening mode for some time as it often gives feedback really fast. I am now adding "live" time-expansion (albeit sparse 1/10 of the time capturing) to that, so heterodyne Left and TimeExpansion on the right (or vv). Thusfar I have seen that the output of the FFT is a real great asset. I have several times detected bats/crickets and probably mice not by hearing them on the heterodyne but simply by spotting them as repeating blips on the waterfall graph.

I am planning to make a simple autodetect feature that will make the heterodyne centre-frequency jump to the peakvalue (based on FFT) of an incoming signal based on a user-set band of frequencies.

Playback and recording have been implemented, at startup the system checks for an SDcard and if available will make a listing of all *.raw files in the root. The user can select any of these and play them, during play the sample_rate can be changed between 8-44K. The TFT-screen also shows the progress of the raw-file playing. Recording is currently done using a default frequency(281k) but I am planning to make that also easy to change. When a recording is started the File will be given a name BXXX_YYY.raw where XXX is just a sequential number and YYY corresponds to the sample_rate. That makes it easier to use the recordings also outside the detector.

TFTscreen

As stated in an earlier message I have added a scrollable area since the ILI9341 allows that to be used,
Code:
void ILI9341_t3::setScrollarea(uint16_t bottom, uint16_t top)
{
	SPI.beginTransaction(SPISettings(SPICLOCK, MSBFIRST, SPI_MODE0));
	writecommand_cont(0x33);
	writedata16_last(bottom);
	writedata16_last(ILI9341_TFTHEIGHT-top-bottom);
	writedata16_last(top);
	
	SPI.endTransaction();
}
The scroll functionality than prevents the top/bottom sections to be overwritten during a scroll. In my setup the bottom shows the active menu settings for my left/right encoder. The top shows settings for volume, gain, frequency and samplerate, a simple axis for frequencies with ticks every 10Khz and a dot that corresponds to the current heterodyne centre-frequency.

Additional functions:
Denoise FFTgraph.
Although the performance and soundquality is good according to me I still see noisebands every 22500hz (and multiples). A simple function can be used to capture 1000 FFTs and calculate the average level for each bin. After a 1000 have been collected I subtract those values from the bins and the FFTgraphs (waterfall) becomes a lot cleaner and easier to use.

Encoders
I am still struggling to think of the best/most intuitive way to use the encoders. Currently they have two modes, they either allow you to select a function or they allow you to change the value of a function (left and right work independent). So you select a function, press the encoder to "lock" the function and then you can use the same encoder to change the value. Press the encoder again and you are in the menu mode. For some functions like playing files I am using both encoders as that looks easier, not sure however if I will keep it like that.

Enough to tinker on ;)

cheers
Cor
 
Hi,

Added the initial frequencydividercode as part of the effect_granular code (will split these into a separate library as soon as I can). The code is shown below, its a raw implementation that changes the audiooutput to be the same for 10 samples in a row. Since the total amount of samples coming in is 128 its not yet really ready I think. The output when listening to my artifical bat was tonally not very interesting. If that is due to the artificial bat (gives blips at different frequencies that last about 2 ms) or due to the setup I dont know. A longer stretched tone (200ms blip) at 35kHz clearly heard but still not a pure tone. Since we have the option to for instance interpolate the quality can possibly be improved on. Amplitude this way is allready preserved and thus a lot better than a simple digital divider.

Will test it this evening, I tested the time-expansion code yesterday and it works as expected. Every now and then a bat-call gets passed and you can hear a slowed-down call. I think this can be a lot improved by waiting for a signal that has an ultrasonic peak and play that and stop play as soon as the signal falls away. Then catch the next etc etc.

Cor

as part of effect_granular.h
Code:
void beginDivider(float grain_length) {
		if (grain_length <= 0.0) return;
		beginDivider_int(grain_length);
	}

and added to effect_granular.cpp
Code:
void AudioEffectGranular::beginDivider_int(int grain_samples)
{
	__disable_irq();
	grain_mode = 4;
	if (allow_len_change) {
		if (grain_samples > max_sample_len) {
		grain_samples = max_sample_len;
	     } 
		glitch_len = grain_samples;
	}
	sample_loaded = false;
	write_en = false;
	sample_req = true;
	__enable_irq();
}

and inside void AudioEffectGranular::update(void)
Code:
else if (grain_mode == 4) {
		//DIVIDER
		int8_t subsample=0;
		int16_t current_input=block->data[0];
		for (int k = 0; k < AUDIO_BLOCK_SAMPLES; k++) 
		 { 
	           subsample++;
                   if (subsample%10==0)
                {current_input = block->data[k];
					  }
			 
			block->data[k] = current_input;
			 
			
		}
	}
 
changed the code a bit, instead of simply picking every 10th sample I now collect samples and use a moving average on the last 10 samples. Tonally this seems to be a bit less "blocky".

Code:
else if (grain_mode == 4) {
		//DIVIDER
		int8_t subsample=0;
		int16_t current_input=block->data[0];
		float collector=0;
		int16_t samples[10];
		for (int k = 0; k < AUDIO_BLOCK_SAMPLES; k++) 
		 { 
		   //collect the last 10 samples
		  samples[subsample%10]=block->data[k];
 		  subsample++;
		 	 // wait with pushing averaged samples until 10 are collected
    		    if (subsample<10)
                         { current_input = block->data[0];
			  }
		  	 else
			   {  collector=0;
			     for (uint8_t i=0; i<10; i++)
				 {
						  collector+=samples[i];
				  }
				current_input=collector/10;  
			   }		  
			 
			block->data[k] = current_input;
			 
			
		}
	}
 
Tested the code of message #72 yesterday evening. The frequency-divider easily detected bats, the output was - as expected - less tonal compared to listening by heterodyne. But it does react directly to any sound coming in and thus not require any tuning to listen for bats.
 
HI,

An update of the work of the past days. I have been restructuring the code and the menu's. Its now possible to choose 4 different detector modes.
1) Heterodyne, default mode where a user has to set the heterodyne centre frequency
2) Heterodyne-auto, teensy changes the heterodyne centre frequency based on the peakfrequency from FFT-analysimeis (current update speed set to 1 second )
3) Didiver, using extension of the effect_granular (got to split this still into a new library) all frequencies are divided by 10 to become audible
4) Auto-TimeExpansion, if a batcall(a click) is detected it is recorded and directly played at 1/10 of the original speed thus lowering the frequencies. This routine restarts automatically after the play of a call has ended. So If a single click lasts 10ms the play will last 100ms and only after that will record/play again. This does thus not play all the incoming calls directly but does allow to listen to bats in a rather special way.

TFT: Ive added a power-spectrum graph that gets updated regular (if batclicks are registered), the spectrum also shows the peakfrequency and an estimate of the lowest/highest frequencies.

IMG_20180712_085816204-1.jpg

Edit: Finally Ive set the default kbps to 352 (multiplier=1, divider=2). Dont know if recording properly at that speed is possible, will test that today probably

Its fun to play with a teensy !

regards
Cor
 
Last edited:
Screenshot from 2018-07-13 07-42-19.png

This is a screenshot of a raw recording (analysis in audacity) done at 352kbps, the recording show the default noisebands (they appear at multiples of 22.5khz more visible than they are audible). The bat-call is from a common pipistrelle and shows two harmonic curves above the principle call that goes from around 100Khz down to 45Khz. The recording at 352k looks to work fine with a teensy 3.6.
 
Back
Top