After the Due arrived the following transmitter was designed and implemented.
The data flow is as follows.
- Read uint10 value from an analog input.
- Normalize values to 4 bit (it was determined from testing that anything more than 4 bits and the sampling rate used the Due couldn’t process fast enough)
- Convert data to a [4:1] vector, one row per bit
- Read out the data from these two vectors
- Interlace these two outputs such that the output form the 1 sample switch is A0 B0 A1 B1 and so on
This job lies upon the “Integer to Bit” converter block.
Above is the current implementation of the transmitter. The most important part of this whole setup is how to actually convert the data properly into the desired format.
As mentioned the output of the “Integer to Bit” block is a 4 by 1 vector which requires the “index vector block to access each individual bit in order. However in order to properly interlace the bits in a regular and alternating order the counters and clock was used.
Both counters are essentially identical allowing us to index through each vector from 0 to 3 using the clock to trigger the count up. However the only difference between these two counters is when they trigger. Using the rising edge for one and the falling edge for the other allows one to use one clock cycle for two purposes..
Finally the 1 sample switch using a reset switch triggers every rising edge clock cycle allowing us to essentially interlace these two outputs.
There is a large time gap between the previous post and this post. I have been lazy to update the blog with my progress and problems and have only begun to do so now so only relevant/correct solutions the problem posed will be posted.
As a proof of concept I believe it is important to create a working prototype even if it requires using more than one input line (aka data+clock). In doing so I can be sure that when implementing a pilot to the data I will be able to know that the previous parts work.
In the process of making this, I have learned that the Simulink blocks often do not behave as u wish them to.
Firstly the digital output block.
Despite being requiring a uint8 input, it only outputs high and low aka 5V and 0V for an Arduino UNO and 3.3V and 0V for an Arduino DUE. This misconception had me confused for several hours as I struggled to understand why it was only outputting 1’s even when I internally generated a DC biased signal as an input to the digital output block.
Secondly, was the sheer overhead Simulink has in C code. Using the C code generation feature in Simulink I was surprised to find hundreds if not thousands of line of code for the simplest of block diagrams. This is no wonder that the sampling rate when using the “Analog In->Digital Out” scheme did not reach anywhere near the 16MHz clock speed of the Arduino UNO.
This prompted the idea that using Arduino Due’s with a 84 MHz clock speed might be required if a sampling rate of 15KHz is to be achieved for 2 channels.
After looking into it further, I have discovered that it is impossible to transmit data using any sort of frequency shift/phase shift digitally. This was a stupid blunder on my part and now I have decided to do all the computation in the time domain, using two different states (on and off for LEDs).
Below is an updated version of what will need to be implemented.
The input signal will be split into left and right samples (LRLRLRLR) and an N-sample switch will then be used to create a stream data in addition to a pilot pulse which will be added.
This pilot pulse will be used to synchronize the two different Arduino boards such that the correct sample will be directed to the correct left or right speaker. This will be done by checking the magnitude of sample and if the magnitude is greater than V_threshold (given that V_max_signal<V_threshold) we will subtract V_threshold and resync. Otherwise we will bypass the subtraction and simply split the signal back.
The concerns for now is how to actually split the input signal into left and right. Given that the input will be an analog signal we will need to sample (not ZOH) and create a 2D array. Secondly, how will the pass-through be implemented? I will have to look into if there are if-else implementations inside Simulink otherwise I might have to use another voltage controlled switch. However, I’m not sure what threshold voltage should be set, how to determine the incoming voltage, and how to limit the voltage.
The good news is that I am able to get the two Arduino boards to talk to each other. In fact this was all that was needed to get that to work.
The goal of this project is to create a unit which can transmit data optically from a real time source and play back the information through a second interface.
To do this I will attempt to use two Arudino Unos one for transmitting and one for receiving. The following image will represent the flow of data and an idea of how it will be implemented.
For testing I will have to find some way to save the demodulated and filtered signal onto the flash memory of the Arduino Uno/Duo.
This link I found seems to have an implementation of C/C++ code which will easily store data onto the PROGMEM data. I have yet to explore this way of storing data on the arduino easily but it may allow me to pass by the data storage limitations of the arduino.
As for the blog diagram drawn above, it will be implemented using simulink and ported to the arduino directly. In the following figure below we can see both spectrum analyzers showing both before and after the phase shifts.
By shifting by a whole copy up (in this case 40kHz) we can set our digital/normalized cut off frequencies to pi/2 in the two hp and lp filters to filter out the lower frequency copy. Here a simple FIR filter has been implemented. The final step is to shift the signal back to be centered at 0.
In the final implementation both outputs coming out of the filters will be sent into a speaker individually such that we have Left and Right channel speakers.