I'm currently working on some code to transmit messages/files/and other data over lasers using audio transformation. My current code uses the hexlify function from the binascii module in python to convert the data to binary, and then emits a tone for a 1 and a different tone for a 0. This in theory works, albeit not the fastest way to encode/decode, but in testing there proves to be a few errors.
the tones generated are not spot on, ie: emitting 150Hz can turn out to be 145-155Hz on the receiving end, this isn't a huge issue as I can just set the boundaries on the receiving end lower or higher.
the real problem is that if I emit a tone, and it is played, the computer on the receiving end may read it multiple times or not read it at all based on the rate it samples the incoming audio. I have tried to play the tones at the same speed it samples, but that is very iffy.
In all, I have had a couple of successful runs using short messages, but this is very unreliable and inaccurate due to the above mentioned issues.
I have looked into this further and a solution to this looks like it could involve BPSK or Binary Phase Shift Keying, although I'm not sure how to implement this. Any suggestions or code samples would be appreciated!
My code for the project can be found here but the main files I'm working on are for binary decoding and encoding which is here and here. I'm not an expert in python so please pardon me if anything I've said is wrong, my code isn't the best, or If i've overlooked something basic.
Thanks! :-)
BPSK constellation The value of M depends on the parameter k – the number of bits we wish to squeeze in a single M-PSK symbol. For example if we wish to squeeze in 3 bits (k=3) in one transmit symbol, then M = 2k = 23 = 8 and this results in 8-PSK configuration. M=2 gives BPSK (Binary Phase Shift Keying) configuration.
Phase Shift Keying (PSK) refers to a digital modulation technique in which the sine and cosine inputs of a radio wave vary at a specific time, altering the phase of the carrier signal. Binary PSK is the simplest type of phase-shift keying.
BPSK (also sometimes called PRK, phase reversal keying, or 2PSK) is the simplest form of phase shift keying (PSK). It uses two phases which are separated by 180° and so can also be termed 2-PSK.
Binary Phase-shift keying (BPSK) is a digital modulation scheme that conveys data by changing, or modulating, two different phases of a reference signal (the carrier wave). The constellation points chosen are usually positioned with uniform angular spacing around a circle.
Take a look at GNU Radio!
http://gnuradio.org/redmine/projects/gnuradio/wiki
GNU Radio is a project to do, in software, as much possible of radio signal transmission or reception. Because radio already uses phase shift keying, the GNU Radio guys have already solved the problem for you, and GNU Radio is already a Python project! And the complicated DSP stuff is written in C++ for speed, but wrapped for use in Python.
Here is a page discussing a project using Differential Binary Phase Shift Keying (DBPSK)/ Differential Quadrature Phase Shift Keying (DQPSK) to transmit binary data (in the example, a JPEG image). Python source code is available for download.
http://www.wu.ece.ufl.edu/projects/softwareRadio/
I see that your project is under the MIT license. GNU Radio is under GPL3, which may be a problem for you. You need to figure out if you can use GNU Radio without needing to make your project into a derived work, thus forcing you to change your license. It should be possible to make a standalone "sending daemon" and a standalone "receiving daemon", both of whose source code would be GPL3, and then have your MIT code connect to them over a socket or something.
By the way, one of my searches found this very clear explanation of how BPSK works:
http://cnx.org/content/m10280/latest/
Good luck!
In response to the first issue regarding the frequency:
Looking at your decoder, I see that your sample rate is 44100 and your chunk size is 2048. If am reading this right, that means your FFT size is 2048. That would put your FFT bin size at ~21hz. Have you tried to zero pad your FFT? Zero-padding the FFT won't change the frequency but will give you better resolution. I do see you are using a quadratic interpolation to improve your frequency estimate. I haven't used that technique, so I'm not familiar with the improvement you get from that. Maybe a balance between zero-padding and doing a quadratic interpolation will get you better frequency accuracy.
Also, depending on the hardware doing the transmission and receiving, the frequency error might be a result of different clocks driving the A/D - One or both of the clocks are not at exactly 44100Hz. Something like that might affect the frequency you see on your FFT output.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With