Skip to content

Commit

Permalink
Modification:
Browse files Browse the repository at this point in the history
1. Change the testbed circuit.
The TX and RX Arduinos now use "Serial1" to synchronize between
experimental traces, which is a more robust way than the previous one
(the voltage of two digital pins are not stable enough during
transmission, and will lead to unexpected save file break).

2. Change the Arduino codes according to the above modification.

3. Fix some bugs in the "plain0" TX Arduino codes.

4. Fix some bugs in the data processing and figure plotting code.
Some data processing were missing, and figure plotting used wrong
results.

5. Add a main file "main_sim_txrx.m" which calls the simulation
functions used in the early stage of the project, which is not fully
compatible with the latest decoder.

6. About documentation.
- Add detailed description on the two MATLAB toolboxes used in the code,
which are highly recommended. The modification of corresponding codes to
avoid these toolboxes are also provided.
- Fix the description about the symbol interval of the data.
  • Loading branch information
JMWinding committed Oct 26, 2023
1 parent 049940c commit 1778bb6
Show file tree
Hide file tree
Showing 47 changed files with 3,138 additions and 3,019 deletions.
340 changes: 167 additions & 173 deletions Arduino/1Tx_gold/1Tx_gold.ino

Large diffs are not rendered by default.

342 changes: 168 additions & 174 deletions Arduino/1Tx_goldman/1Tx_goldman.ino

Large diffs are not rendered by default.

347 changes: 170 additions & 177 deletions Arduino/1Tx_plain0/1Tx_plain0.ino

Large diffs are not rendered by default.

362 changes: 178 additions & 184 deletions Arduino/2Tx_gold/2Tx_gold.ino

Large diffs are not rendered by default.

364 changes: 179 additions & 185 deletions Arduino/2Tx_goldman/2Tx_goldman.ino

Large diffs are not rendered by default.

380 changes: 187 additions & 193 deletions Arduino/3Tx_gold/3Tx_gold.ino

Large diffs are not rendered by default.

382 changes: 188 additions & 194 deletions Arduino/3Tx_goldman/3Tx_goldman.ino

Large diffs are not rendered by default.

402 changes: 198 additions & 204 deletions Arduino/4Tx_goldman/4Tx_goldman.ino

Large diffs are not rendered by default.

404 changes: 199 additions & 205 deletions Arduino/4Tx_goldman0/4Tx_goldman0.ino

Large diffs are not rendered by default.

400 changes: 197 additions & 203 deletions Arduino/4Tx_ooc0/4Tx_ooc0.ino

Large diffs are not rendered by default.

407 changes: 200 additions & 207 deletions Arduino/4Tx_plain0/4Tx_plain0.ino

Large diffs are not rendered by default.

422 changes: 208 additions & 214 deletions Arduino/5Tx_goldman/5Tx_goldman.ino

Large diffs are not rendered by default.

442 changes: 218 additions & 224 deletions Arduino/6Tx_goldman/6Tx_goldman.ino

Large diffs are not rendered by default.

42 changes: 29 additions & 13 deletions Arduino/Rx/Rx.ino
Original file line number Diff line number Diff line change
Expand Up @@ -10,34 +10,32 @@ const int Ts = 5; //Gap between sampling in ms
//********************************************

//*****************Setup Connections**********
const int sync = 9;
const int ack = 8; //acknowledge to tx that rx is ready
const int chipSelect = 10;
int record = LOW;
const int chipSelect = 53;
const byte ECsensorPin = A1; // EC Meter analog output,pin on analog 1
//********************************************

//*******************Variables****************
File myFile;

int fileIndex = 15;
int fileIndex = 6;
char fileName[50];
int activated = 0;

unsigned int AnalogReading;
unsigned long AnalogSampleTime;

//*********************************************
void rx_receive (void);
Ticker timerRx (rx_receive, Ts, 0, MILLIS);

void setup()
{
pinMode (sync, INPUT);
pinMode (ack, OUTPUT);
digitalWrite (ack,LOW);

void setup ()
{
while (activated == 0)
{
Serial.begin (115200);
Serial1.begin (19200);

Serial.print ("\n\n\n\n\n");
Serial.print ("Initializing SD card...");
if (!SD.begin (chipSelect))
Expand All @@ -54,19 +52,36 @@ void setup()
AnalogReading = 0;
AnalogSampleTime = millis ();
AnalogReading = analogRead (ECsensorPin);
digitalWrite (ack, HIGH);
Serial1.write ('a');
}

void loop ()
{
switch (digitalRead (sync))
Serial1.write ('a');
if (Serial1.available ())
{
switch (Serial1.read ())
{
case 'a':
record = HIGH;
break;
case 'z':
record = LOW;
break;
default:
Serial.println ("Tx sent a wrong message");
exit (0);
}
}

switch (record)
{
case HIGH:
if (!myFile)
{
Serial.print ("Opening File Number: ");
Serial.println (fileIndex);
sprintf(fileName, "%02d.txt", fileIndex);
sprintf (fileName, "%02d.txt", fileIndex);
if (SD.exists (fileName)) {SD.remove (fileName);}
myFile = SD.open (fileName, FILE_WRITE);
if (myFile) {Serial.println ("File Created");}
Expand Down Expand Up @@ -103,4 +118,5 @@ void rx_receive (void)
myFile.print (AnalogSampleTime);
myFile.print ('\t');
myFile.println (AnalogReading);
// Serial.println (AnalogReading);
}
53 changes: 47 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,46 @@ Use `git clone` to download this repository.

This project is composed of the experiment part and the data processing part.

For experiment part, please prepare two Arduinos (one for TXs and one for RX) and install the Arduino IDE. The required `Ticker.h` and `OneWire.h` can be downloaded from the Arduino IDE library.

For data processing part, please install MATLAB R2019b or any later version. Please install any toolbox that is reported missing when you run the scripts.
### Experiment

For experiment part, please prepare two Arduinos (one for TXs and one for RX) and install the Arduino IDE. The following two header files required to run the code, which can be found in the Arduino IDE library (In the Arduino IDE, click the `Tools > Manage Libraries...`).

* `Ticker.h`
* `OneWire.h`

And of course, you need to prepare pumps, tubes, salt (and/or baking soda) and the [EC reader](https://www.dfrobot.com/product-1123.html).

### Data processing

For data processing part, please install MATLAB R2019b or any later version. The following toolboxes are **_highly recommended_**.

* `Communication Toolbox`
+ This toolbox is used in `code_algo/get_gold_code.m` to generate Gold code of certain parameters, and `code_algo/get_gold_code2.m` to generate MoMA code (which is Gold code modulated with Manchester code).
+ However, these two functions are only used in simulation for the early stage of the research. Once we go to experiment, we only need to generate the codes of required length and store in a TXT file before hand. Thus, during transmission the TX Arduino will pick the code for each TX from this file. Since MoMA assumes that the RX knows the pre-assigned code to each TX, the decoding will proceed depending on this assignment.

* `Parallel Computing Toolbox`
+ This toolbox is used in `loop_emulates_txrx_all.m` and `loop_emulates_txrx_noncoherent.m` to parallel the decoding of multiple traces, thus accelerate the whole result generating procedure. Note that this toolbox is NOT used to speed up the decoding of ONE trace. Instead, each CPU core is used to process different traces concurrently.
+ You can get rid of this toolbox by making the following modifications to the code, **_which will definitely and extremely increase the time to generate the results_**.
- In `main_emulates_txrx_allloop.m`, comment the following code from line 5 to 7.
```
if isempty(gcp("nocreate"))
parpool(feature("numcores"));
end
```
This code creates the maximum number of workers, which is the same as the number of the CPU cores. But you can also specify a suitable number you want, e.g. 8 workers with the following code
```
if isempty(gcp("nocreate"))
parpool(8);
end
```
- In `loop_emulates_txrx_all.m` and `loop_emulates_txrx_noncoherent.m`, change the code in line 108 from
```
parfor kk = 1:totalruns
```
to
```
for kk = 1:totalruns
```
## How to run this artifact?
Expand All @@ -28,10 +65,14 @@ The data processing codes are MATLAB scripts and functions.
We provide two MATLAB scripts that can directly generate the figures in the paper.
[`main_emulates_txrx_allloop.m`](/main_emulates_txrx_allloop.m) processes the experiment data and save the results as `.mat` files in corresponding folders. The script contains multiple loops, each defining a variable that specifies either the experiment data or the algorithm. Since not all combinations are reported in the paper, we add multiple `if` conditions and mark in comment their corresponding figure indices. Please feel free to modify the `if` conditions if you would like to see other results.
[`main_emulates_txrx_allloop.m`](/main_emulates_txrx_allloop.m) processes the experiment data and save the results as `.mat` files in corresponding folders. The script contains multiple loops, each defining a variable that specifies either the experiment data or the algorithm. Since not all combinations are reported in the paper, we add multiple `if` conditions and mark in comment their corresponding figure indices. Please feel free to modify the `if` conditions if you would like to see other results. The script then calls [`loop_emulates_txrx_all.m`](/loop_emulates_txrx_all.m) and [`loop_emulates_txrx_noncoherent.m`](/loop_emulates_txrx_noncoherent.m) to process the specified data in the specified way.
[`code_figure/generate_all_fig.m`](/code_figure/generate_all_fig.m) reads the results in `.mat` files and generate the figures. It calls multiple scripts, each generating one figure, and corresponding indices in the paper are marked in comment. And you can run each of them separately as well.
Simply running these two scripts in sequence will generate all the reported figures, but `main_emulates_txrx_allloop.m` may take a long time.
Simply running these two scripts in sequence will generate all the reported figures, but `main_emulates_txrx_allloop.m` may take a long time.
## How to reuse this artifact?
[`main_emulate_txrx.m`](/main_emulate_txrx.m) is a cleaner version of `main_emulates_txrx_allloop.m`, which is used to debug the algorithms with a single experiment trace.
For more details about the scripts, please refer to [Processing the data](/documentation/data_process.md).
For more details about the scripts, please refer to [Processing the data](/documentation/data_process.md).
2 changes: 1 addition & 1 deletion code_algo/DecodeSequence_ViterbiBackward.m
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
dBit = params.dBit;
lags = params.lags;
catch
error('decoding missing variables');
error("decoding missing variables");
end

%%
Expand Down
32 changes: 16 additions & 16 deletions code_algo/DecodeSequence_ViterbiForward4.m
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
hPres = params.hPres;
chan = params.chan;
catch
error('decoding missing variables');
error("decoding missing variables");
end

%%
Expand All @@ -22,9 +22,9 @@
try lags_new = params.lags_new; catch, lags_new = inf(1,nTx); end
try cpIdx = params.cpIdx; catch, cpIdx = 0; end
try endIdx = params.endIdx; catch, endIdx = length(yd{1}); end
try mode = params.mode; catch, mode = 'de'; end
try mode = params.mode; catch, mode = "dc"; end

try code = params.code; catch, code = 'goldman'; end
try code = params.code; catch, code = "goldman"; end
for j = 1:nMo
for i = 1:nTx
xChip{j,i} = GenerateCodeChips(xChip{j,i},code);
Expand Down Expand Up @@ -174,14 +174,14 @@
end
end
end
clear('VStatesTemp2');
clear("VStatesTemp2");

% delete inf
ind = isinf(cell2mat(VStatesTemp(:,end)));
VStatesTemp(ind,:) = [];
VTraces{j,jy+1}(ind,:) = [];
if size(VStatesTemp,1) == 0
error('viterbi reaches all states with zero probability');
error("viterbi reaches all states with zero probability");
end

% probability of current state
Expand Down Expand Up @@ -215,12 +215,12 @@
end

switch mode
case 'pd'
case "pd"
ViterbiLogProbCurrent(k) = -abs(yd{j}(jy) - yh);
case 'ce'
case "ce"
ViterbiLogProbCurrent(k) = ComputeViterbiLogProb(yd{j}(jy), yh, ...
10*chan.nn{j}, 10*chan.np{j});
case 'de'
case "dc"
ViterbiLogProbCurrent(k) = ComputeViterbiLogProb(yd{j}(jy), yh, ...
chan.nn{j}, chan.np{j});
end
Expand All @@ -240,7 +240,7 @@
end

% sort and truncate lower probability
[~, ind] = sort(cell2mat(VStatesTemp(:,end)), 'descend');
[~, ind] = sort(cell2mat(VStatesTemp(:,end)), "descend");
if length(ind) > nTracks
ind(nTracks+1:end) = [];
end
Expand All @@ -253,19 +253,19 @@
%% values for next window (only once)
if jy == cpIdx
checkpoint = struct( ...
'tracedBits', {tracedBits}, ...
'VTraceLast', {VTraces(:,jy+1)}, ...
'VStateLast', {VStates});
"tracedBits", {tracedBits}, ...
"VTraceLast", {VTraces(:,jy+1)}, ...
"VStateLast", {VStates});
end
end

%%
if exist('checkpoint', 'var')
if exist("checkpoint", "var")
rval.checkpoint = checkpoint;
end
rval.viterbi = struct( ...
'tracedBits', {tracedBits}, ...
'VStates', {VStates}, ...
'VTraces', {VTraces});
"tracedBits", {tracedBits}, ...
"VStates", {VStates}, ...
"VTraces", {VTraces});

end
Loading

0 comments on commit 1778bb6

Please sign in to comment.