Morse Code Programming Help

So I'm new to arduino and done very basic things so far, such as blinking leds etc.

I'm trying to progress and want to do a morse code ir tx and ir rx.

So far I have built a morse code that outputs via led when read from the serial monitor. Here i used a book for the code. Here is the code;

int ledPin = 12;

char* letters[] = {
  ".-", "-...", "-.-", "-..", ".", "..-.", "--.", "....", "..",     //Letters A-I
  ".---", "-.-", ".-..", "--", "-.", "---", ".--.", "--.-", ".-.",  //Letters J-R
  "...", "-", "..-", "...-", ".--", "-..-", "-.--", "--.."          //Letters S-Z 
 };

char* numbers[] ={
  "-----", ".----", "..---", "...--", "....-", ".....", "-....",
  "--...", "---..", "----." //Numbers 0-9
 };

 int dotDelay = 200;
 
 void setup()
 {
   pinMode(ledPin, OUTPUT);
   Serial.begin(9600);  //Set the communications speed between the Arduino board and the USB 9600 baud
 }
 
 void loop()
 {
   char ch;
   if (Serial.available())  //Constantly checks to see if any letters have been sent over the USB Connection and if the letter needs to be processed
   
   {
     ch = Serial.read(); //Reads a single letter
     if (ch >= 'a' && ch <= 'z')
     {
       flashSequence(letters[ch - 'a']); //Flashes the LED to match the string that has been input
     }
     else if (ch >='A' && ch <= 'Z')
     {
       flashSequence(letters[ch - 'A']);
     }
     else if (ch >='0' && ch <= '9')
     {
       flashSequence(numbers[ch - '0']);
     }
     else if (ch == ' ')
     {
       delay(dotDelay * 4);
     }
   }
 }
 
 void flashSequence(char* sequence)
 {
     int i = 0;
     while (sequence !=NULL)
     {
       flashDotOrDash(sequence);
       i++;
     }
     delay(dotDelay * 3);  //Gap between each letter
 }
 
 void flashDotOrDash(char dotOrDash)
  {
    digitalWrite(ledPin, HIGH);
    if (dotOrDash == '.')
    {
      delay(dotDelay);
    }
    else //must be a dash
    {
      delay(dotDelay * 3);
    }
    digitalWrite(ledPin, LOW);
    delay(dotDelay);  //Gap between flashes
  }

I have now wired up the ir tx and ir rx on the breadboard. See attached.

Can anyone help me implement the code to read input from the serial monitor (using ir tx) and receiving it in the serial monitor as output (using the ir rx). This need to be any text string.

I am a beginner with programming language as well.

Thank you in advance.

Moderator edit: Quote tags changed to code tags. (Nick Gammon)

Duplicate of this post deleted.

DO NOT CROSS-POST - it wastes time.

I posted in the wrong section the first time and couldn't delete the original. Honest mistake.

Can anyone help me implement the code to read input from the serial monitor (using ir tx) and receiving it in the serial monitor as output (using the ir rx). This need to be any text string.

That code already reads input from the serial monitor and outputs it as Morse code. What it appears that you now need to do is read when the receiver LED goes HIGH or LOW, and record when that happens.

Using that information, you can determine whether the receiver is receiving a dot, a dash, or a pause between characters.

There are two ways that you can go about this. The simplest is to buy another Arduino as the receiver. The delays being used on the sender mean that you can't read data from the receiver LED while the sender is sending. And, you certainly can't read it later.

The other thing that you could do is to restructure the sender to get rid of all delays, and record when a dot, dash, or pause started being sent. Periodically, then, you check to see if it was time to stop sending the dot, dash, or pause. Effectively, this is the reverse of how you need to write the receiver code.

Look at the blink without delay example, whichever way you go.

The only problem with that code is it reads the serial monitor outputs as morse via the led. I want this to go from serial monitor to infrared transmitter across to the infrared receiver and then back out as text string in the serial monitor.

But I have very little idea how to code that.

Thanks for your reply.

The only problem with that code is it reads the serial monitor outputs as morse via the led.

No, that is not true. There is NO output to the Serial Monitor. There is input FROM the Serial Monitor that is output TO the LED.

But, 100% of your time is spent reading serial data, setting the pin HIGH or LOW, and waiting. Mostly waiting. There is absolutely no time left to do anything else.

Now, if you got rid of the delay() calls, so you spent no time waiting, you'd go from something to do 100% of the time to something to do 0.1% of the time, leaving you lots of time to read from the receiver LED.

I want this to go from serial monitor to infrared transmitter

That is happening now.

across to the infrared receiver

Assuming that the hardware is wired correctly, and I have no reason to believe that it is not, that too is happening.

and then back out as text string in the serial monitor.

There is a lot of code needed to do this, as I explained earlier, and no time in which to execute that code.

As I've explained already, you have two choices. Run the receiver code on another Arduino, or get rid of the delay() calls. When you have made a decision, more help can be provided, assuming that you share that decision and that you need help implementing that decision.

Many thanks for your patience on this issue.

I don't have the money at the moment to use a separate arduino. So as the decision goes I will remove the delay calls.

I will definitely need your help implementing this decision if you can.

As I have the ir tx going to pin 13 and pin 9 (for pwm-do I need extra code). I havent referenced pin 9 in the code. The analogue (A0) to the ir receiver I'm assuming will need to be INT as well?

How do I then get output to the serial monitor. I have tried searching for help, but like I said I am a beginner in terms of programming language?

Again, many thanks.

As I have the ir tx going to pin 13 and pin 9 (for pwm-do I need extra code). I havent referenced pin 9 in the code. The analogue (A0) to the ir receiver I'm assuming will need to be INT as well?

Perhaps YOU need to look at the code. Your transmitter is on pin 12. It doesn't need PWM, nor does the receiver need to be on an analog pin. You have plenty of free digital pins.

How do I then get output to the serial monitor.

When you have some, Serial.print() will come in useful.

I'm going to look at the code now I'm back at home.

I attached a picture in the first post to show how it is now wired.

The code I posted was when I had just wired one led to receive morse. So I'm trying to use this existing code to modify to do what I want now its wired differently.

I'm going to read some stuff on serial.print also.

Cheers

Ok so ive had a go at modifying the code. See below.

int irtxPin = 12;
int irrxPin = 2;

char* letters[] = {
  ".-", "-...", "-.-", "-..", ".", "..-.", "--.", "....", "..",     //Letters A-I
  ".---", "-.-", ".-..", "--", "-.", "---", ".--.", "--.-", ".-.",  //Letters J-R
  "...", "-", "..-", "...-", ".--", "-..-", "-.--", "--.."          //Letters S-Z  
 };

char* numbers[] ={
  "-----", ".----", "..---", "...--", "....-", ".....", "-....",
  "--...", "---..", "----." //Numbers 0-9
 };

 
 void setup()
 {
   pinMode(irtxPin, INPUT);
   Serial.begin(9600);  //Set the communications speed between the Arduino board and the USB 9600 baud
   pinMode(irtxPin, OUTPUT);
 }
 
 void loop()
 {
   char ch;
   if (Serial.available())  //Constantly checks to see if any letters have been sent over the USB Connection and if the letter needs to be processed
   
   {
     ch = Serial.read(); //Reads a single letter
     if (ch >= 'a' && ch <= 'z')
     { 
       Serial.print(letters[ch - 'a']); //Flashes the LED to match the string that has been input
     } 
     else if (ch >='A' && ch <= 'Z')
     {
       Serial.print(letters[ch - 'A']);
     }
     else if (ch >='0' && ch <= '9')
     {
       Serial.print(numbers[ch - '0']);
     }
  }
}

I now get serial monitor output.

Does this now mean that it has travelled via infrared over the infrared transmitter to the infrared receiever or just purely reading the serial monitor input and the outputing this in the serial monitor?

Secondly, the output to serial monitor is in dots and dashes, how do i get this into readable text string.

Again many thanks for your help.

I have attached a photo showing how it is wired.

Please edit your post, select the code, and put it between [code] ... [/code] tags.

You can do that by hitting the # button above the posting area.

I've done it for you once in the first post. Now it's your turn.

  • moderator

Does this now mean that it has travelled via infrared over the infrared transmitter to the infrared receiever or just purely reading the serial monitor input and the outputing this in the serial monitor?

The latter. Nowhere do you actually read what the sender IR is sending.

And, you're not actually sending anything, anymore.

I've just done a simple test by unplugging the infrared transmitter and putting text in serial monitor and got output. So clearly its not going via infrared.

How do I get it to do this?

Apologies for my lack of knowledge, as i say this is all new to me.

I just posted at the same time you did.

To do this do I need to use digital.write/digital.read?

To do this do I need to use digital.write/digital.read?

The digitalWrite() function does the sending. The digitalRead() function detects when the sender starts sending and when it stops sending. It does, that is, if called often enough. Which is why you can't use delay(). The delay() function means that you can't call digitalRead() often enough.

So where in the void loop would this go? Or are each of these functions seperate in terms of where they can be place in the code?