In this article, by popular demand, we will explain how to make the simplest sonar modem: some digital signal processing, some programming, some homemade printed circuit boards, and a drop of practical hydrology.
All interested - welcome under the cat, in the reverberant world of underwater communication!
But the relevant picture, to attract attention: ')
“Ultimately, the purpose of our existence is to waste energy ... And, if possible, you know, so that it is interesting to yourself and useful to others.” (C) ABS, "Noon, XXII Century"
To save your time - a summary
Hydroacoustic modems do not sell on Aliexpress yet.
There is a simple and undemanding to computing resources method of detecting the tone, the frequency of which is 4 times less than the sampling frequency; Arduino is enough for implementation
Receiving and transmitting antennas are made from piezo-diggers of 10 p each
We buy (or do it ourselves) the amplifier's headband on the TDA2030 on Ali for 50 rubles
We make LUT th preamplifier, with a total cost of ~ 100 rubles
Connect and go to the pond
Rejoice
Motivational Prelude
Now you can buy almost anything on Aliexpress or eBay. Especially a lot of different for self-manufacturing of something electronic based on Arduino. You can make (if you just buy uninteresting) a millenn-stop meteorological station with an Internet connection, an automatic cat feeder, a home brewery controller, but you still cannot buy a sonar modem, a designer for its manufacture, or at least a module for adruino. Well and good! And do not - now we will tell how to do it, and also tell you how it works.
We all thought for a long time what could be offered to lovers for self-production. Something very simple, which can be collected by a schoolchild from a stick and rope of what everyone has at hand, but at the same time necessarily representing at least the minimum practical or educational value.
Something promising a long and fascinating improvement, something that can be transferred even to arduino , be it amiss .
If we approach the question materialistically, we would like to offer a detailed tutorial for the manufacture of some simple device that would be more or less able to transmit data in a shallow water reservoir (a shallow hydroacoustic channel is the most complex), would mean the maximum production of a printed circuit board using LUT, with a total cost not exceeding two or three hundred rubles on the minimum.
What will we do today?
recall how to make a suitable sonar antenna and make a couple;
We will connect one of the antennas to the PC via an amplifier on the TDA for ~ 50 rubles and get a transmitter;
for the second we will do with the help of LUT a preamplifier for ~ 100 rubles;
write (I already wrote and put everything on Git) a simple C # modem and try everything on the nearest reservoir;
The whole idea of the simplest modem is built on, again, the simplest (coincidence?) Detector of a certain tone, about which, to my shame, I have not heard. He told me about him quite by chance andrey_9999a . He, by the way, made a preamp charge.
In this regard, I recalled a quote from the book by Leonard Susskind “The Battle of a Black Hole”:
“As a wine connoisseur, I am more or less sure that even with my eyes closed I can distinguish red from white. Even more reliably I distinguish wine from beer. But then the taste will fail me. "
I can say to myself that, as a real electronics engineer, I am more or less sure that I can definitely solder two thick wires. Even more reliably, I distinguish a hot soldering iron from a cold one even with eyes closed, but then further the skill will let me down. Therefore, all that concerns the development and manufacture of boards is the work of my comrades and colleagues andrey_9999a and StDmitriev .
So back to the detector. It is a simplified special case of calculating the Fourier integral:
In the case of a digital signal, to calculate the amplitude of an arbitrary harmonic, you need to perform a discrete Fourier transform, for Arduina it is rather heavy, but the trick is that if you take Fc as the carrier frequency such that it will be exactly 4 times lower than the sampling frequency Fs , the amplitude of this harmonic can be calculated demonically simpler.
In this case, dt = 2π * (Fs / 4) / Fs = π / 2 , and for the carrier period there are only 4 samples:
If everything is shifted by π / 4, then the samples will take only two values: √2 / 2 and -√2 / 2, for simplicity, we leave only the signs - “+” and “-” .
The essence of the method is that we represent the sinus phase as a sequence of signs “+” “+” “-” “-” , and the cosine phase as “+” “-” “-” “+” .
Let the input signal lie in the sn buffer, we have two annular averaging buffers for the sine and cosine phases - bs and bc of size N. They have common head and tail pointers - bH and bT . At the initial moment of time, bH = N-1, bT = 0 . Averaging cycle counter C = 0 .
We take 4 samples from the input buffer and fold them according to the sequences of characters.
Code example
a = sn(i) bs(bH) = a bc(bH) = a s1 = s1 + a - bs(bT) s2 = s2 + a - bc(bT) bH = (bH + 1) % N bT = (bT + 1) % N
a = sn(i+1) bs(bH) = a bc(bH) = -a s1 = s1 + a - bs(bT) s2 = s2 - a - bc(bT) bH = (bH + 1) % N bT = (bT + 1) % N
a = sn(i+2) bs(bH) = -a bc(bH) = -a s1 = s1 - a - bs(bT) s2 = s2 - a - bc(bT) bH = (bH + 1) % N bT = (bT + 1) % N
a = sn(i+3) bs(bH) = -a bc(bH) = a s1 = s1 - a - bs(bT) s2 = s2 + a - bc(bT) bH = (bH + 1) % N bT = (bT + 1) % N
After each processed four samples, we check the averaging cycle counter, and if it has passed N , then we calculate the amplitude cA of the carrier:
if ++cycle >= N cA = sqrt(s1 * s1 + s2 * s2) cycle = 0 end
This is how it looks on an ideal signal:
The signal itself is shown in blue, the carrier amplitude is shown in red (everything is reduced to a range of -1..1). In this case, N = 2 because There is no noise and everything works fine.
Now add some white noise and see how our detector reacts to this:
I added white noise so that the signal-to-noise ratio was 0 dB. In the figure above, blue shows a noisy signal, green shows the source signal, and red shows the amplitude value. In this case, the detector with N = 2 has not detected anything, and the minimum N at which it works properly is 32. Ie the size of the processing window in the samples was 32 * 4 = 128 samples.
That is, now we can analyze the input signal and estimate a parameter that quantifies the presence of frequency, four times less than the sampling rate. If we set a certain threshold value for this parameter, then everything can be binarized, and to put it simply, we can answer the question: is there a given tone in the input signal or not?
This is very good, but we need to pass bits, and the bits can take two values.
Implement a system with two signal states with the help of one - so-so idea, so we will not encode one of the states of silence (pause). It would have made the detection more difficult: it would have been necessary to somehow single out the beginning of the premise, think up how to arrange its end, etc.
Instead, "1" and "0" we will encode pulses of different lengths, between the bits there is a so-called. the guard interval - because we still need to deal with multipath propagation and reverberation. In simple terms, the guard interval is the place (time) where all the reflections of the previous bit, all sounds and echoes fade out.
Looking ahead, we note that with such a signal structure, the algorithm of the receiver operation is greatly simplified: waiting for the tone to appear, detecting the beginning, waiting for the tone to disappear, and detecting the time again - if the received time is more similar in length to “1”, we probably took a bit with a value of "1", if it looks more like a "0" - then apparently we took a bit, with a value of "0".
In general, we can say that this is some kind of Morse code.
Software part of the modem
For the impatient, an example is on GitHub . Written in haste in C # (because for the PC I write on it and I just feel more comfortable and faster).
To play and capture the sound from the microphone input is used a wonderful library NAudio .
All modem logic is in the class SUAModem (Simple Underwater Acoustic Modem).
The following parameters are passed to the constructor:
double sRateHz is the sampling rate in Hertz; int wSize - the size of the processing window in the samples; int oneMultiplier - how many "windows" the bit with the value "1" lasts int zeroMultiplier - how many "windows" the bit with the value "0" lasts double eThreshold - a threshold, let's say about it later
To generate a signal from an array of bytes, there is a ModulateData (byte [] data) method, which returns an array of 16-bit signed samples.
public short [] ModulateData (byte [] data)
publicshort[] ModulateData(byte[] data) { double alpha = 0; double phase = 0; List<short> samples = new List<short>(); BitArray bits = new BitArray(data); for (int i = 0; i < bits.Length; i++) { int sLim = (bits[i]) ? oneDurationSmp : zeroDurationSmp; alpha = 0; phase = 0; for (int sIdx = 0; sIdx <= sLim; sIdx++) { alpha = Math.Sin(phase); phase += delta; if (phase >= alimit) phase -= alimit; samples.Add(Convert.ToInt16(alpha * short.MaxValue)); } samples.AddRange(newshort[defenseIntervalSmp]); } return samples.ToArray(); }
In the main loop, the samples list is filled in by the transmitted bits. Depending on the current transmitted bit, the length of the sLim signal generated in the samples is set. A guard interval is added after each bit.
Of course...
Many may notice that when generating a signal one could do without the sine function, but this example allows, by changing the value of the delta accordingly, to change the frequency of the generated tone.
To generate a tone with a frequency at a given sampling rate corresponding value it is calculated simply:
To generate and emit a signal, there is the TransmitData (byte [] data) method, which internally calls ModulateData:
public double TransmitData (byte [] data)
publicdoubleTransmitData(byte[] data) { var samples = ModulateData(data); double txTime = ((double)samples.Length) / SampleRateHz; var rawBytes = newbyte[samples.Length * 2]; for (int i = 0; i < samples.Length; i++) { var bts = BitConverter.GetBytes(samples[i]); rawBytes[i * 2] = bts[0]; rawBytes[i * 2 + 1] = bts[1]; } using (var ms = new MemoryStream(rawBytes)) { using (var rs = new RawSourceWaveStream(ms, new WaveFormat(Convert.ToInt32(SampleRateHz), 16, 1))) { using (var wo = new WaveOutEvent()) { wo.Init(rs); wo.Play(); while (wo.PlaybackState == PlaybackState.Playing) { Thread.SpinWait(1); } } rs.Close(); } ms.Close(); } return txTime; }
The SUAModem class reports the acceptance of the next byte using the DataReceivedEventHandler event.
Input samples are acquired using the ProcessInputSignal (short [] data) method, where they are written to the ring ring buffer. The analysis takes place in a separate thread, in the Receiver method.
And the receiver itself lives in the Receive method:
From the code it is clear that the analysis is carried out on 4 samples, if you wish, you can save the state and carry out the processing and on one sample, which will be useful when transferring to some weak MC. As data is received, the value of the amplitude s is calculated at the frequency sRateHz / 4. The difference between the previous and current amplitude value is calculated and then compared with a predetermined threshold selected experimentally. The example allows in real time to change this threshold.
A sharp increase in the amplitude indicates the beginning of a “bit”, a sharp (somewhat less sharp - due to reverberation) decline - about the end of a “bit”.
After receiving the next bit, we work out the guard interval - we skip the specified number of samples - there are all sorts of echoes in them, they will only interfere with us.
The iron part of the modem
So, with the structure of the signal, everything is clear, how to take it is also clear. Things are easy - learn how to radiate a signal into the water and take it out of the water.
If you do not have hydroacoustic antennas, then it's time to make them in our previous tutorial .
I have them left from that time, so I skip this step.
That antenna, which is designed for transmission, we connect to the amplifier board with aliexpress . For several tens of meters (maybe even for a hundred) this is quite enough for us. There are no tricks here - the output of the sound card of the laptop goes to the input of the amplifier, which is powered by a lead battery of 12 volts 4 Ah. Our hydroacoustic transmitting antenna from the piezo sounder is connected to the output. In my case, it looks like this:
In the photo above, on the screen there is a small spoiler of the next article. Next time on the same pieces of iron, we will again try to transmit the “video” sound through the water, but in a completely different way than last time .
With the receiving antenna is somewhat more complicated. Although piezo squeezers are very sensitive, this is not enough. We will have to collect a preamp board with a filter for the 5-35 kHz band. Gain we take 1000.
The circuit, the PCB design, and the list of preamp components are on our GitHub: the circuit , the tracks are the top layer and the bottom layer , BOM .
LUT technology has been discussed 100 times a hundred times, but let us also make our contribution.
Photos of the process
So, we take the appropriate magazine, we have only this one at hand:
We take from there a couple of pages and print layers on them using a laser printer.
Combine with needles and glue along one side, as shown in the photo:
Before using the iron we moisten the toner with isopropyl alcohol:
Iron through folded A4 sheet:
Soak it with warm water under the tap:
And laundered leftover paper. After that we get a billet ready for pickling:
Cut off the excess with the help of scissors for metal or to whom the more convenient.
We poison in ferric chloride. Especially for the article, we bred fresh, it turned out to be so strong that from the future board there are bubbles:
As a result, after etching and washing the toner we get the following semi-finished product:
After the components are soldered and washed, the board looks like this.
And this is what the receiving part of the assembly looks like. Power is supplied from the same lead battery 12 volts:
Small filter disclaimer
If the reader wants to change the band, we suggest recalculating the 8th order filter assembled on the TL084C cheap 4-channel opamp (DA2 in the diagram ), resistors R10-R13, R15-R23 and capacitors C5-C8, C11, C12, C14 and C15.
Just in case, here are the frequency response of the current implementation of the filter:
And here's another project for this filter, created in the Qucs application.
Experiments and tests
To connect to a laptop, we use the usual Jack 3.5 mm, the very tip is a signal, the middle one is not connected, the ground is dust to dust in the ground. All amplifications and any microphone effects need to be turned off, and the volume will have to be played to reach the optimal level. The cheat should happen when the antenna connected to the preamplifier is touched with a finger and lightly stroked.
If you simply put one piezo on another without an amplifier and a preamp and connect them to the audio input and output, then everything works perfectly. Below is the signal segment and you can even determine where the values of bits are:
The signal itself is shown in blue, the difference between the current and previous amplitude values (front) is shown in red, the difference between the previous and current values (decrease) is in green. You can easily “demodulate” this part of the premise: 1 0 0 0 1 1 0. In our case, the zero is twice as long as one, and the length of the guard interval is equal to the duration of zero.
Further, also without an amplifier and a preamplifier, we lower our antennas into a metal tank, measuring 3x1.5x1.5. We have this in the laboratory, and we made a rule for ourselves that we are not engaged in any communication if it is somehow unable to work in this tank. The fact is that in such a closed volume of energy there is no particular place to go - the sound is wonderfully and repeatedly reflected from the metal walls and porridge is obtained at the point of reception. And given the fact that we usually check ready devices with energy, designed for thousands of meters, you can imagine what is happening there.
For example, our two RedLINE modems work stably in this tank only at a distance of no more than two meters, and two uWAVEs work stably at about 1 meter. While the first in open water works up to 8000 meters, and the second - up to a kilometer . Of course, all commercial products do not use such primitive modulation schemes, which are discussed in the article and are much more complicated, but now it is important for us to understand the basics and do something with our hands.
In general, we lower the antennas into the tank for a distance of about 50 centimeters and get something much less beautiful than with the direct contact of the antennas:
Although a much longer guard interval is used here, it is still evident that the echo goes almost to the next bit, the fronts and especially the recessions are very blurred. But you can still determine the content of the message: 1 0 0 0 1 1 0
In both cases, I transmitted the message "123" and these seven bits belong to the unit symbol. It looked like this, then the interface was slightly redone
From the screen above, it is clear that with those settings, the transmission of the message “Hello, habr !!! :-) ”consisting of 19 bytes takes 9.132 seconds, that is, the transmission rate was 16.6 bit / s. By the way, in order for the modem to work in our tank, we had to increase the guard interval so that the transmission rate dropped to ~ 3 bps.
We checked the homemade in the swimming pool, where it has steadily earned on 10 meters.
We also indulged in homemade products on the pond. I used an active hydrophone very similar in construction to the one proposed in the article, only instead of a piezopischalki there was used a sensor from parking sensors, the battery there was mounted in a coil onto which the cable was wound:
The receiver and transmitter antennas descended directly from the shore, the depth there dramatically decreases from 0.5 to 2 meters. In the experience shown in the photo above, oddly enough, the worst conditions, the distance there was only about 5 meters - this was the initial setting in general. Of the 20 transmitted messages of 3 bytes, in six of them one byte was beaten.
Then, when we connected the receiver to the second laptop and transferred to the other side of the pond (distance of about 30 meters), the transmission went much better - there were only a couple of errors in 40 messages ranging in size from 3 to 13 bytes.
The next photo on the map shows the places where the antennas were located.
Conclusion and further research
As promised, for a few rubles, we collected a working device. Although its practical value is doubtful, the process of manufacturing and setting up on the pond itself will be very useful for beginners. On the described carrier detection method, it is quite possible to come up with various simple navigation systems for amateur use, and what is especially nice, the computational complexity allows one to implement the method on a simple microcontroller.
In order not to be unfounded regarding the construction of navigation systems on simple signals, take a look at the interesting work in which they built a full-fledged long-base navigation system. In this system, the position of the pinger is determined, which periodically transmits its depth. The depth value is coded by the distance between two simple pulses at a certain frequency. So yes, yes, the pots are not the gods burned, the road will be mastered by walking, patience and work, learn, learn, learn - that’s all.
Perhaps, given time, we will do a DIY project for positioning an autonomous pinger, emitting simple signals. Something similar, but not DIY, we have already done on the basis of our uWAVE modems, which even tried to shoot a video . It will be very interesting to hear your opinions on this matter - it is very important to have confirmation that you are not doing something in vain.
However, returning to the main topic, we note that it would be possible to improve in the proposed scheme:
make threshold calculation adaptive
analyze the width of the signals automatically
try using different lengths for different bit combinations
screw noiseproof coding
transfer all this to arduino
the volume and threshold have to be long and tedious to pick up, so it would be good to add to the preamplifier AGC
At this meeting I will declare closed, and if you are interested in the topic, here is a list of our previous articles: