There are some problems with running this in windows. Mac and Linux usually work fine. Packages needed:
pip3 install pyserial
The following components were used to make the circuits in the images below.
- Photodiode
- Laser
- Opamp
- Arduino Uno and Arduino Nano (Most Arduino's will work)
Circuit for receiver.
Circuit for transmitter (Laser is pictured as LED).
First open constants.py and change these lines to point to the path of your devices. The default path is resembles the path used by macOS, for windows it is usually something like COM5
and for linux /dev/tty5
. You can find this path by using the Arduino IDE.
RECEIVINGDEVICE = '/dev/cu.usbmodem14201'
SENDINGDEVICE = '/dev/cu.usbserial-14120'
The default input and output input.html
and output.html
can also be changed here, as well as other parameters. Uplaod receivingPWM.ino
to the receiving device and sendingPWM.ino
to the sending device.
Open a terminal on the receiving device and run:
python3 receivingPC.py
Open a terminal on the sending device and run:
python3 sendingPC.py
Follow the configuration steps for transmitting files above. Then open a terminal on the receiving device and run:
python3 receivingLive.py
open a terminal on the sending device and run:
python3 sendingLive.py
If you wish to recreate or improve this product, you can use the functions defined in send.py
and receive.py
, they provide functions at multiple levels of complexity. To use these, import them in your programs
import receive
import send
To send a frame in the simplest way, use this function, passing a payload and a frameNumber. The payload should be a PAYLOADLENGHT / 8 - PARITYLENGHT / 8
long UTF-8 string. The framenumber should be an integer.
send.sendFrame(payload, frameIndex)
To send individual parts of a frame use the repeatInterval(callBack, count, argument)
function, this calls the passed callback funtion count
times and passes argument
along if an argument is provided. Example:
send.repeatInterval(packetNumber, 16, 6)
functions that can be passed as callback here are send.frameGap
, send.preamble
, send.packetNumber
and send.payload
.
To receive a frame in the simplest way, use this function, it returns a boolean received
that is true if a frame was received, another boolean frameCorrect
that is true if the frame is validated as correct, an integer frameNumber
and a string payload
.
received, frameCorrect, frameNumber, payload = receive.readFrame()
To let the device find the start of a frame, use this funtion, it returns a boolean received
that is true if a frame is found before the timeout is reached. (Flipped
is a legacy variable that isn't used anymore and will be removed)
received, flipped = receive.findFrameStart()
To receive a payload, use the readPayload()
function, it returns a binary payload string (including parity bits). Check if the frame is correct with the checkFrame()
function this returns a boolean frameCorrect
that is true if the frame is correct and a string binFrame
that is the same string that is passed, later it might change so the returned frame has corrected errors. The frame can be converted to text by using decode_binary_string()
. Example (the frame number is still in the payload and is not correctly parsed in this example):
received, flipped = receive.findFrameStart()
binFrame = receive.readPayload()
receive.decode_binary_string(binFrame)
The first thing on the roadmap is rewriting the codebase, this is currently being done on the stateFull branch. Another thing is to add bidirectional communication, there is already a bit of commented code in sendingPC.py
for receiving acknowledgements. Also, I should probably add more to this documentation, like an image of the structure of frames.