Originally I did not have an abs() on meaning that it was setting the the shortest duration to a negative, causing errors further down. @IgorTandetnik pointed this out.
for(int i=0; i < length; i++) {
if(abs(durations[i]) < shortestDuration) {
shortestDuration = durations[i];
}
}
for(int i=0; i < length; i++) {
if(abs(durations[i]) < shortestDuration) {
shortestDuration = abs(durations[i]); <-- This part
}
}
The adding the abs() call, fixed most problems put I did not handle the remaining value properly. It would be more robust with using the median and should do the timing thresholds outside the for loop.
for(int i=0; i < length; i++) {
if(durations[i] > shortestDuration * (1 - Variability) && durations[i] < shortestDuration * (1 + Variability)) {
Serial.print(".");
} else if(durations[i] > shortestDuration * (3 - Variability) && durations[i] < shortestDuration * (3 + Variability)) {
Serial.print("-");
} else if(abs(durations[i]) > shortestDuration * (3 - Variability) && abs(durations[i]) < shortestDuration * (3 + Variability)) {
Serial.print("/");
} else if(abs(durations[i]) > shortestDuration * (7 - Variability) && abs(durations[i]) < shortestDuration * (7 + Variability)) {
Serial.print(" ");
} else { // <-- This does not handle the interspace between morse characters
Serial.println("miss");
}
}
So then I changed it, with the help of @IgorTandetnik. So that it properly handles the interspace between characters and so the variability scales well.
for(int i=0; i < length; i++) {
if(durations[i] > shortestDuration * (1 - Variability) && durations[i] < shortestDuration * (1 + Variability)) {
result += ".";
} else if(durations[i] > shortestDuration * (1 - Variability)*3 && durations[i] < shortestDuration * (1 + Variability)*3) {
result += "-";
} else if(abs(durations[i]) > shortestDuration * (1 - Variability) && abs(durations[i]) < shortestDuration * (1 + Variability)) {
; // <-- This does
} else if(abs(durations[i]) > shortestDuration * (1 - Variability)*3 && abs(durations[i]) < shortestDuration * (1 + Variability)*3) {
result += "/";
} else if(abs(durations[i]) > shortestDuration * (1 - Variability)*7 && abs(durations[i]) < shortestDuration * (1 + Variability)*7) {
result += " ";
} else {
Serial.println("Duration to morse Error");
}
}
I also had a slight timing issue with random, where originally I did random(0,1) which meant that it only returned 0 as it (max - 1) which returned 0, so changing to random(2) fixes this.
void addNoise(int* array, int length, float fraction) {
for(int i=0; i < length; i++) {
long variability = random(fraction * 100);
long plusMinus = random(0,1);
if(plusMinus == 0) {
array[i] = array[i] + variability ;
} else if(plusMinus == 1) {
array[i] = array[i] - variability;
}
}
}
void addNoise(int* array, int length, float fraction) {
for(int i=0; i < length; i++) {
long variability = random(fraction * 100);
long plusMinus = random(0,1);
if(plusMinus == 0) {
array[i] = array[i] + variability ;
} else if(plusMinus == 1) {
array[i] = array[i] - variability;
}
}
}