Morse coder/decoder with 2 arduinos not decoding well

As said in Title , I am making morse coder/decoder with 2 arduino. I have 2 codes, one is for sending sign and the other one is for decoding sign.

Links of codes here:
DECODER

CODER

When I try to send lets say : E sign in morse it decodes sometimes B and sometimes some other letter.
I used serial monitor for the CODER to see if it prits out good letter and it does, I think its the problem in DECODER but I cant seem to figure it out .

If anyone know smth thank you for your answers :slight_smile:

Please post your code here

DECODER

int LDR_Pin = A0; //analog pin 0
int led = 13;

int LDR_Maxvalue=800;
int dot_length=800;
int dash_length=2500;
int letter_pause=2400;

#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

// 10k between GND and A0
// LDR between 5V and A0


void setup(){
  Serial.begin(9600);
  pinMode(led, OUTPUT);  

lcd.begin(16,2);

  
}
int counter_high = 0;
int counter_low = 0;

void loop(){

  int LDRReading = analogRead(LDR_Pin);
   
  if (LDRReading >= LDR_Maxvalue){
  counter_high++ ;
   if ( counter_low > 0 ){
 //    Serial.print("Low\t");
//     Serial.print(counter_low);
//     Serial.print("\n");
   }
   if ( counter_low >= letter_pause) {
      Serial.println();
      lcd.setCursor(0, 0); 
     }
     
     counter_low=0;
     digitalWrite(led, HIGH);

  
  } 
  else {
//   Serial.print(".");
  counter_low++;
  if ( counter_high > 0 ){
//      Serial.print("High\t");  
//   Serial.print(counter_high);

  }
  if ( (counter_high <= letter_pause ) &&( counter_high >=dot_length)){
//      Serial.print(counter_high);
    Serial.print(".");
    lcd.print(".");
  }
  if ( counter_high > letter_pause ){
 //         Serial.print(counter_high);
        Serial.print("-");
        lcd.print("-");
  }

      counter_high=0;
      digitalWrite(led, LOW);

  }

 
}

CODER

const int ledPin = 13; 
int unit = 250;
char* morseLet[]= {".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....", "..", ".---", "-.-", ".-..", "--", "-.", "---", ".--.", "--.-", ".-.", "...", "-", "..-", "...-", ".--", "-..-", "-.--", "--.."};
char* morseNum[]= {"-----", ".----", "..---", "...--", "....-", ".....", "-....", "--...", "---..", "----."};
void setup() {
pinMode(ledPin, OUTPUT);
delay(1000);
Serial.begin(9600);
}
void loop() {
char info;
if(Serial.available() >0) {
info = Serial.read();
if(info  >= 'a' && info <= 'z'){
interp(morseLet[info - 'a']);
}
else if(info  >= 'A' && info <= 'Z'){
interp(morseLet[info - 'A']);
}
else if(info  >= '0' && info <= '9'){
interp(morseLet[info - 0]);
}
else if (info== ' '){
delay(unit*7);
}
}
}
void interp(char* character){
int i=0;
while (character[i] != '\0'){
output (character[i]);
i++;
}
delay (unit*3);
}
void output(char outp){
digitalWrite(ledPin, HIGH);
if(outp =='.') {
delay(unit);
}
else {
delay(unit*3);
}
digitalWrite(ledPin, LOW);
delay(unit);
}

It is very likely that there are timing errors in the receive code.

LDRs are very slow, and you forgot to mention how you arrived at the possibly inaccurate mystery constants:

int LDR_Maxvalue=800;
int dot_length=800;
int dash_length=2500;
int letter_pause=2400;

Why is dash_length not 3 dot lengths?

Thank you for your answer.
dot_length is length of dot state in LED and you are right that there should be dash_length 2400, and letter_pause is pause between letters time when diode is turned off.

Shall I use another approach for timing domain?

ye i got it , will try to do

when i put timers on 800ms it is not reacting , program not working . I give up hahaha :smiley:

I give up hahaha :smiley:

OK. Have a nice life!

Generally, the receiver code would be something like

uint32_t startMs;

char buf[20];
char bufct = 0;

boolean we_might_need_to_handle_a_long_gap = false;
byte previous_LDR_state = LOW;

loop() {
  if the ldr was previoulsy low and it is now high
    handle_a_low(millis()-startMs);
    startMs = millis();
    previous_LDR_state = HIGH;
  else
  if the ldr was previoulsy high and it is now low
    handle_a_high(millis()-startMs);
    startMs = millis();
    previous_LDR_state = LOW;
    we_might_need_to_handle_a_long_gap = true;
  else 
  if the ldr has been low for some time (unit*10, say) and we_might_need_to_handle_a_long_gap
    handle_a_low(millis()-startMs);
    we_might_need_to_handle_a_long_gap = false;
  end
    
}

void handle_a_low(uint32_t ms) {
  if(ms<unit/2) {
    looks like noise, do nothing
  }
  else if(ms < unit * 2) {
    handle_a_gap_between_dotdash()
  }
  else if (ms < gap * 4) {
    handle_a_gap_between_letters();
  }
  else {
    handle_a_gap_between_words();
  }
}

void handle_a_high(uint32_t ms) {
  if(ms<unit/2) {
    looks like noise, do nothing
  }
  else if(ms < unit * 2) {
    handle_a_dot()
  }
  else if(ms < unit * 5) {
    handle_a_dash()
  }
  else {
    looks like the sender is stuck, do nothing
  }
}

void handle a dot() {
  add a dot to the buffer, making sure not to overwrite the end of the buffer
}

void handle a dash() {
  add a dash to the buffer, making sure not to overwrite the end of the buffer
}

void handle a gap between letters() {
  check the buffer aginast letters we recognize, print out the letter
  clear the buffer
}

void handle a gap between words() {
  handle a gap between letters(); // take care of the pending letter
  print out a space
}