OFDM transceiver with rayleigh channel using Standard PDP in matlab - pdp

I have built an OFDM transceiver with rayleigh channel using standard PDP's Like EPA,EVA and ETU.The problem is I am getting very high BER even for BPSK i.e 50-60 % or higher bits in error.Scatterplotting confirms it.My OFDM transceiver blocks include:
---- Random Data -- Modulation(BPSK,QPSK,QAM) -- Serial2Parallel -- IFFT -- CyclicPrefix >>> Rayleigh Ch >>> Remove CP Data---FFT --- Par2Ser ---DeMod --- Sink Data.
I have used builtin matlab function to create Rayleigh channel passing standard PDP as parameter.
channelObj = rayleighchan(tSampling,fDoppler,tau_in_sec,pdb_in_dB);
channelObj.ResetBeforeFiltering=0; % channel remains static before filtering
Filtering for n-OFDM symbols & calculating CIR
for symb=1:OFDMSymb
ofdm_td_rx_signal(:,symb) = filter(channelObj, ofdm_td_TXdata(:,symb));
channel_cir(tapIndices,symb)= (channelObj.PathGains).';
end
channel_cfr = fft(channel_cir,nCarrier); % freq. response from CIR
Similarly at receiver,after FFT block,I just tried to use this CFR by dividing received symbol by CFR as
fft_RXdata=fft_data./channel_cfr;
What I am getting is very high SNR and scattered constellation symbols.Rest of transceiver blocks are simple and all verified as bug free...Do let me how to improve it.
How I could get improve BER?
Any need of equalizer?Should a match filter would help?Thanks in advance.
NOTE:ONLY RAYLEIGH CHANNEL IS USED AWGN NOISE IS NOT ADDED AT ALL ...

One possible solution that have helped me is use of block based pilots(reference dummy data) transmission with OFDM symbols.Least square channel estimation is performed at RX using received pilots data which inherently captured the channel behavior.

Related

What commands can be sent on the message port of UHD USRP Sink block?

I have been experimenting with message passing in the Signal Source block in GNU Radio companion. I can see from its source code that we can pass messages to change the frequency, amplitude, offset and phase of the source. For example, the following message PMT sent from a message strobe can change the amplitude of the signal to 0.5.
pmt.dict_add(pmt.make_dict(), pmt.intern("ampl"), pmt.from_double(0.5))
But when I viewed the code of UHD USRP Sink, I couldn't get a clear idea as to what commands can be sent to this block or that which parameters can be changed. I have read at some places in the documentation that frequency, gain, LO offset, timestamp, center frequency and other transceiver related settings of the USRP Sink can be manipulated through command messages.
What commands can be sent to the USRP Sink block from a message strobe (in the pmt format) and which parameters (and their keys) can be modified?
This is officially documented:
https://www.gnuradio.org/doc/doxygen/page_uhd.html#uhd_command_syntax
Command name
Value Type
Description
chan
int
Specifies a channel. If this is not given, either all channels are chosen, or channel 0, depending on the action. A value of -1 forces 'all channels', where possible.
gain
double
Sets the Tx or Rx gain (in dB). Defaults to all channels.
power_dbm
double
Sets the Tx or Rx power reference level (in dBm). Defaults to all channels. Works for certain devices only, and only if calibration data is available.
freq
double
Sets the Tx or Rx frequency. Defaults to all channels. If specified without lo_offset, it will set the LO offset to zero.
lo_offset
double
Sets an LO offset. Defaults to all channels. Note this does not affect the effective center frequency.
tune
tune_request
Like freq, but sets a full tune request (i.e. center frequency and DSP offset). Defaults to all channels.
mtune
tune_request_t
Like tune, but supports a full manual tune request as uhd::tune_request_t. Defaults to all channels.
lo_freq
double
For fully manual tuning: Set the LO frequency (RF frequency). Conflicts with freq, lo_offset, and tune.
dsp_freq
double
For fully manual tuning: Set the DSP frequency (CORDIC frequency). Conflicts with freq, lo_offset, and tune.
direction
string
Used for timed transceiver tuning to ensure tuning order is maintained. Values other than 'TX' or 'RX' will be ignored.
rate
double
See usrp_block::set_samp_rate(). Always affects all channels.
bandwidth
double
See usrp_block::set_bandwidth(). Defaults to all channels.
time
timestamp
Sets a command time. See usrp_block::set_command_time(). A value of PMT_NIL will clear the command time.
mboard
int
Specify mboard index, where applicable.
antenna
string
See usrp_block::set_antenna(). Defaults to all channels.
gpio
gpio
PMT dictionary including bank, attr, value, mask for GPIO. See notes.

How ETX (Estimated Transmissions) is implemented in contikiRPL?

I am working on creating a modified version of MRHOF for RPL. However, I
have some doubts about the ETX metrics used. i am running an rpl-udp example (..../contiki-3.0/examples/ipv6/rpl-udp).
As per my understanding, the general definition of ETX is following:
ETX = 1/(df * dr)
where df is the measured probability that a data packet successfully arrives at the recipient and dr is the probability that the ACK packet is successfully received.
The implementation of ETX is defined in neighbor_link_callback(rpl_parent_t *p, int status, int numtx) (contiki/core/net/rpl/rpl-mrhof.c) as below:
new_etx = ((uint32_t)recorded_etx * ETX_ALPHA +(uint32_t)packet_etx * (ETX_SCALE - ETX_ALPHA)) / ETX_SCALE
where
recorded_etx = nbr->link_metric
packet_etx = MAX_LINK_METRIC * RPL_DAG_MC_ETX_DIVISOR
nbr->link_metric = RPL_INIT_LINK_METRIC * RPL_DAG_MC_ETX_DIVISOR (rpl-dag.c)
RPL_INIT_LINK_METRIC = 2 (rpl-conf.h)
ETX_SCALE = 100
ETX_ALPHA = 90
RPL_DAG_MC_ETX_DIVISOR = 256 (rpl-private.h)
MAX_LINK_METRIC = 10
Here every time when link layer receives an ACK or time-out event the function inside this file (neighbor_link_callback) is fired.
I understood the formal definition of ETX, but when i am trying to map the standard ETX formula with contikiRPL's ETX formula then i am facing some trouble in understanding the implementation of ETX in contikiRPL.
How the probability of a data packet successfully arrives at the recipient (df) and probability that the ACK packet is successfully received (dr) are implemented in ContikiRPL?
In the code, df and dr individually are not known. The algorithm is run on the sender device, which has no means to differentiate between the case when the packet is lost and the case when the ACK is lost. They look exactly the same to it: as the absence of the
The value of packet_etx roughly corresponds to 1 / (df * dr) of the last packet. Note that a single packet already may have had multiple retransmissions on the link. The metric is updated only when the packet is successfully ACKed or when the maximal number of retransmissions is exceeded.
Another issue in Contiki is that since its designed for embedded systems, it does not have the memory to keep in track the ETX of many recent packets. Instead, this information is aggregated in single value with the help of exponentially weighted moving average (EWMA) filter. The \alpha paramter of the algorithm is given as ETX_ALPHA / ETX_SCALE in the code; the scaling is done to avoid the more expensive floating point operations.
The value of recorded_etx is the previous value of the ETX, reflecting the ETX calculated from all of the previous packets. The value of new_etx is the value of the link's ETX when the previous ETX and the last packet's ETX have been combined with the ETX algorithm.

Bsd correction possible?

I am looking at using the BSD checksum described here at wiki BSD does anyone know if you can use it for basic error correction?
Consider an 8 bit or 16 bit left rotating checksum where all the message bytes are supposed to be zero, but one them has a single bit error. The checksum will detect the error, but you'd get the same checksum for message[0] = 0x01, or message[1] = 0x02, ... , or message[7] = 0x80. The checksum can't determine which of these 8 (or more) possible error cases occurred, so it can't be used for error correction.
You'd need at least something like a Hamming code, BCH code or RS code to be able to correct one more bit errors. Since you have CRC as a tag, a single bit correcting binary BCH code is essentially the same as a CRC using a "primitive" polynomial that is the basis for a finite field, if the message length (including the CRC) is shorter than the number of possible values in the finite field. For example, a 15 bit message would have 11 data bits and 4 "parity" bits, based on a finite field of GF(2^4) (GF(16)).

Reading incorrect temperature value from thermistor using EVK1100

I want to get the temperature from a thermistor, so I made a voltage divider (3.3V to 10k resistor and between ground a 10k thermistor) I read the ADC between the 10k resistor and the thermistor.
The BCOEFFICIENT is 3977, the NOMINAL TEMPERATURE is 25C and I use the simple B parameter equation. I'm not sure where I'm doing mistake, I read room temperature as 10.5C which was suppose to be around 24C. The following is the part of the program that I used for temperature sensor(developed in AVR studio),
#define TEMPERATURENOMINAL 25
#define TERMISTORNOMINAL 10000
#define BCOEFFICIENT 3977
#define SERIESRESISTOR 10000
{
float ke1,tempa,xin
ke1 = adc_get_value(peak_adc2,peak2);
xin=(1023/ke1)-1;
xin=SERIESRESISTOR/xin;
tempa=xin/TERMISTORNOMINAL;
tempa=log(tempa);
tempa/= BCOEFFICIENT;
tempa+=1.0/(TEMPERATURENOMINAL + 273.15);
tempa=1.0/tempa;
tempa-=273.15;
dip204_set_cursor_position(1,3);
//sprintf(ui, "Temp is %.2f deg", Ref);
sprintf(ui, "Temp is %.2f deg", tempa);
dip204_write_string(ui);
}
I checked the voltage using multi-meter for instance in between the thermistor and 10k resistor and in the EVK 1100 using the following line
ke1 = adc_get_value(peak_adc2,peak2)*3.3/1024;
I get the same voltage in both.
Not sure where I'm doing a mistake, Hope someone guide me in right direction
Your code looks correct to me, and I suspect a hardware problem may be the culprit.
It seems likely you have inadvertently connected two 10K-ohm pull-up resistors between the ADC input and the +3.3V reference: perhaps one is already populated on the EVK1100 board, and you have added another one externally connected to your thermistor. This would be equivalent to putting both 10K-ohm resistors in parallel with each other, which would be equivalent to a 5K-ohm resistor in series with the thermistor. At 25°C, the thermistor resistance Rt would read 10K ohms, which would produce a voltage of:
+3.3V * (Rt / (Rt + 5K))
= 2.20V
instead of the correct +1.65V. This number is very close to the result you are seeing (+2.17V # 24°C).
You can verify this hypothesis by looking at the schematic and/or PCB for the EVK1100 to see if a 10K-ohm pull-up resistor is connected from the ADC input to +3.3V. If this is the problem, remove one of the two resistors and you should see correct behavior.

measuring time between two rising edges in beaglebone

I am reading sensor output as square wave(0-5 volt) via oscilloscope. Now I want to measure frequency of one period with Beaglebone. So I should measure the time between two rising edges. However, I don't have any experience with working Beaglebone. Can you give some advices or sample codes about measuring time between rising edges?
How deterministic do you need this to be? If you can tolerate some inaccuracy, you can probably do it on the main Linux OS; if you want to be fancy pants, this seems like a potential use case for the BBB's PRU's (which I unfortunately haven't used so take this with substantial amounts of salt). I would expect you'd be able to write PRU code that just sits with an infinite outerloop and then inside that loop, start looping until it sees the pin shows 0, then starts looping until the pin shows 1 (this is the first rising edge), then starts counting until either the pin shows 0 again (this would then be the falling edge) or another loop to the next rising edge... either way, you could take the counter value and you should be able to directly convert that into time (the PRU is states as having fixed frequency for each instruction, and is a 200Mhz (50ns/instruction). Assuming your loop is something like
#starting with pin low
inner loop 1:
registerX = loadPin
increment counter
jump if zero registerX to inner loop 1
# pin is now high
inner loop 2:
registerX = loadPin
increment counter
jump if one registerX to inner loop 2
# pin is now low again
That should take 3 instructions per counter increment, so you can get the time as 3 * counter * 50 ns.
As suggested by Foon in his answer, the PRUs are a good fit for this task (although depending on your requirements it may be fine to use the ARM processor and standard GPIO). Please note that (as far as I know) both the regular GPIOs and the PRU inputs are based on 3.3V logic, and connecting a 5V signal might fry your board! You will need an additional component or circuit to convert from 5V to 3.3V.
I've written a basic example that measures timing between rising edges on the header pin P8.15 for my own purpose of measuring an engine's rpm. If you decide to use it, you should check the timing results against a known reference. It's about right but I haven't checked it carefully at all. It is implemented using PRU assembly and uses the pypruss python module to simplify interfacing.