states.f2 = 0;
states.norm_rx_timing = 0;
states.ppm = 0;
+ states.prev_pkt = [];
endfunction
% build up array for CRC16 check
- if ch_dec == 42
+ if ch_dec == 42
rx_crc = crc16(str_dec);
ptx_crc = nstr+1;
else
% Use soft decision information to find bits most likely in error. I think
% this is some form of maximum likelihood decoding.
-%
-% TODO: ignore rs232 start and stop bits, ie remove from weakest bit list
-% insert known good bits (copy from prev packet with gd CRC)
-% use other apriori info, like if a lat or long isn't a digit, use last packet as guess
-function [str crc_ok] = sd_bit_flipping(states, rx_bits_log, rx_bits_sd_log, st, uw_loc);
+function [str crc_ok rx_bits_log_flipped] = sd_bit_flipping(states, rx_bits_log, rx_bits_sd_log, st, uw_loc);
+
+ % force algorithm to ignore rs232 sync bits by marking them as "very likely", they have
+ % no input to crc algorithm
+
+ nfield = states.nfield;
+ npad = states.npad;
+ for i=st:nfield+npad:uw_loc
+ rx_bits_sd_log(i+nfield:i+nfield+npad-1) = 1E6;
+ end
+
+ % make a list of bits with smallest soft decn values
[dodgy_bits_mag dodgy_bits_index] = sort(abs(rx_bits_sd_log(st+length(states.uw):uw_loc)));
dodgy_bits_index += length(states.uw) + st - 1;
- nbits = 8;
- ntries = nbits^2;
+ nbits = 6;
+ ntries = 2^nbits;
str = "";
crc_ok = 0;
-
+
% try various combinations of these bits
for i=1:ntries-1
str = str_flipped;
crc_ok = crc_ok_flipped;
end
- end
+ end
endfunction
%save -ascii horus_msg.txt msg
% simulate bit error for testing
- %rx_bits_log(st+100) = xor(rx_bits_log(st+100),1);
+ %rx_bits_log(st+200) = xor(rx_bits_log(st+100),1);
%rx_bits_sd_log(st+100) = 0;
[str crc_ok] = extract_ascii(states, rx_bits_log, st, uw_loc);
if crc_ok == 0
- [str_flipped crc_flipped_ok] = sd_bit_flipping(states, rx_bits_log, rx_bits_sd_log, st, uw_loc);
+ [str_flipped crc_flipped_ok rx_bits_log] = sd_bit_flipping(states, rx_bits_log, rx_bits_sd_log, st, uw_loc);
if crc_flipped_ok
str = sprintf("%s fixed", str_flipped);
end
end
+ % update memory of previous packet, we use this to guess where errors may be
+ if crc_ok || crc_flipped_ok
+ states.prev_pkt = rx_bits_log(st+length(states.uw):uw_loc);
+ end
printf("%s\n", str);
end
% simulation of tx and rx side, add noise, channel impairments ----------------------
function run_sim
- frames = 100;
+ frames = 10;
EbNodB = 26;
timing_offset = 0.0; % see resample() for clock offset below
test_frame_mode = 4;
% fsk_horus_stream.m
% David Rowe 13 Oct 2015
%
-% Experimental near space balloon FSK demodulator, takes 8kHz 16 bit samples from
-% stdin, output txt string on stdout
+% Experimental real time near space balloon FSK demodulator, takes
+% 8kHz 16 bit samples from stdin, output txt string on stdout
%
% usage:
% $ chmod 777 fsk_horus_stream.m
% $ rec -t raw -r 8000 -s -2 -c 1 - -q | ./fsk_horus_stream.m
%
-% or to test with a stored file:
+% OR to test with a stored file (8kHz 16-bit shorts):
% $ cat ~/Desktop/vk5arg-3.wav | ./fsk_horus_stream.m
%
-% include library (make sure calls to test functions at bottom are disabled)
+% include modem library
-fsk_horus_as_a_lib = 1;
+fsk_horus_as_a_lib = 1; % make sure calls to test functions at bottom are disabled
fsk_horus;
gps_log = "~/Desktop/gps_log.txt"
rx = [rx s'];
- % demodulate to bit stream
+ % demodulate samples to bit stream
while length(rx) > nin
[rx_bits states] = fsk_horus_demod(states, rx(1:nin)');
[str_flipped crc_flipped_ok] = sd_bit_flipping(states, rx_bits_buf, rx_bits_sd_buf, uw_loc1, uw_loc2);
if crc_flipped_ok
str = sprintf("%s fixed", str_flipped);
+ crc_ok = 1;
end
end
rx_bits_buf = rx_bits_buf(uw_loc2-1:length(rx_bits_buf));
rx_bits_sd_buf = rx_bits_sd_buf(uw_loc2-1:length(rx_bits_sd_buf));
- % extract GPS coords and save to log file for mapping software
- % TODO: sanitise, make sure they are all numbers, decimal point in right place
+ if crc_ok
+ % extract GPS coords and save to log file for mapping software
- str_split = strsplit(str,",");
- if length(str_split) > 4
- lat = str_split{1,4}; long = str_split{1,5};
- f = fopen(gps_log,"at");
- fprintf(f,"%s,%s\n", lat, long);
- fclose(f);
- end
+ str_split = strsplit(str,",");
+ if length(str_split) > 4
+ lat = str_split{1,4}; long = str_split{1,5};
+ f = fopen(gps_log,"at");
+ fprintf(f,"%s,%s\n", lat, long);
+ fclose(f);
+ end
- % TODO: thin out log file to points_max points to lighten plotting load
+ % TODO: thin out log file to max_points to lighten plotting load
- % tell foxtrotGPS to plot track
+ % tell foxtrotGPS to plot track
- system(system_command);
+ system(system_command);
+ end
end
else
% Truncate buffers if no UW found so they don't grow endlessly with no signal.
rx_bits_sd_buf = rx_bits_sd_buf(length(rx_bits_sd_buf)-length(uw):length(rx_bits_sd_buf));
end
end
+
[s,c] = fread(stdin, N, "short");
endwhile