Updating Data Input - Serial port

Hello everybody,

I am new to Arduino/C programming and I have a question concerning the possibility of updating the input string.
Here's the thing: I have programmed a morsecode translator.
You type in a text you want to morse and it translates the text to written morsecode and appropriate light signals.
Everything is working pretty fine,
but I want to optimize:
It bothers me that you cannot stop the Arduino from executing the program. Once you've typed in a text,
it translates and blinks, but you cannot make it stop, e.g. in case you've changed your mind about the message you wanted to send.
It would be cool if it would notice that there's new data available at all and then start again, translating the new text.
It would be even cooler if I could type in a certain command like 'Stop!" and make it stop executing and blinking so that you could
start typing a new text aferwards!

So what I've figured out is that I seem to have to make the Arduino update the information it reads
from the Serial port and then make it start the translating again, but with the new gained information.
I've read a bit about interrupts, but I don't know how to make an inerrupt through the Serial port (I tried something like

attachInterrupt(Serial, /random/translating_function, CHANGE)
and it didnt work.), and some people wrote it might not be a good idea to do that at all.
I don't know if that might be helpful since he code itself is working fine and my question is about
adding something, but here it is:

char letter;
int i;
int charposition;
int commaposition;
String string;
String input;
int x;
int length;
String code="";
String morsecode="A. -,B- . . .,C- . - .,D- . .,E.,F. . - .,G- - .,H. . . .,I. .,J. - - -,K- . -,L. - . .,M- -,N- .,O- - -,P. - - .,Q- - . -,R. - .,S. . .,T-,U. . -,V. . . -,W. - -,X- . . -,Y- . - -,Z- - . .,a. -,b- . . .,c- . - .,d- . .,e.,f. . - .,g- - .,h. . . .,i. .,j. - - -,k- . -,l - . .,m- -,n- .,o- - -,p. - - .,q- - . -,r. - .,s. . .,t-,u. . -,v. . . -,w. - -,x- . . -,y- . - -,z- - . .,0- - - - -,1. - - - -,2. . - - -,3. . . - -,4. . . . -,5. . . . .,6- . . . .,7- - . . .,8- - - . .,:- - - . . .,;- . - . - .,?. . - - . .,_. . - - . -,(- . - - .,)- . - - . -,\'. - - - - .,=- . . . -,+. - . - .,/- . . - .,@. - - . - .";
int LED=8;
int p;
String incoming;
String incomingcheck;

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

void loop()
{
  
  if (Serial.available()>0)  
  {
    chars_to_code(); 
    Serial.print("Morsing: ");
    Serial.println(input);
    Serial.println(code);
    use_code();
    Serial.flush();
    code="";
  }
  
    
}

//for 1 letter
void extract_morsecode()
        {
        charposition=morsecode.indexOf(letter);
        commaposition=morsecode.indexOf(",",charposition+1);
        string=morsecode.substring(charposition+1,commaposition)+'!';
        code+=string;
        
        }  

//for >1 letters
void chars_to_code()
{
  if (Serial.available()>0)
  {
    input=Serial.readString();
    length=input.length();
    for(x=0;x<length;x++)
    {
      letter=input[x];
      if (letter==' ')
      {
        string="S!";
        code+=string;
//        Serial.print(string);
      }
      else if (letter==',')
      {
        string="C!";
        code+=string;
//        Serial.print(string);
      }
      else
      {
        extract_morsecode();
      }
    }
  }
}

void  use_code()
{
  for(i=0;i<code.length();i++)
  {
    if (code[i]=='.')
    {
      blip();
    }
    if (code[i]=='-')
    {
      doo();
    }
    if (code[i]=='!')
    {
      exclamation();
    }
    if (code[i]=='C')
    {
      c();
    }
    if(code[i]=='S')
    {
      s();
    }
    if(code[i]==' ')
    {
      pause();
    }
  }
  
}

void pause()
{
  delay(200);
}

void blip()
{
  digitalWrite(LED,HIGH);
  delay(200);
  digitalWrite(LED,LOW);
}

void doo()
{
  digitalWrite(LED,HIGH);
  delay(600);
  digitalWrite(LED,LOW);
}

void exclamation()
{
  delay(600);
}

void s()
{
  delay(1400);
}

void c()
{
  doo();
  pause();
  doo();
  pause();
  blip();
  pause();
  blip();
  pause();
  doo();
  pause();
  doo();
}

Sorry for my English :roll_eyes: ...
but I would be so glad if somebody could help me since I have been trying to solve this for two days now!
Thank you in Advance :slight_smile:

Ariane

It bothers me that you cannot stop the Arduino from executing the program.

Does it bother you when a light bulb exhibits the same behavior? Turn it on, it does what it was designed (programmed) to do, until you turn it off. This seems like a desirable attribute to me. I mean, image having to periodically turn the light on again to make it put out light.

Once you've typed in a text, it translates and blinks, but you cannot make it stop

Because you have programmed it that way. You could just as easily have programmed it to send the message ONCE.

It would be cool if it would notice that there's new data available at all and then start again,

So, program it that way.

It would be even cooler if I could type in a certain command like 'Stop!" and make it stop executing and blinking so that you could start typing a new text aferwards!

So, program it that way.

I've read a bit about interrupts, but I don't know how to make an inerrupt through the Serial port

There is already an interrupt triggered when serial data arrives. You can't attach another one. And, not that way, even if you could.

The first argument to the attachInterrupt() function is the interrupt number. Serial is an instance of the HardwareSerial class, not an int containing an interrupt number.

String string;
String input;
String code="";
String morsecode="A. -,B- . . .,C- . - .,D- . .,E.,F. . - .,G- - .,H. . . .,I. .,J. - - -,K- . -,L. - . .,M- -,N- .,O- - -,P. - - .,Q- - . -,R. - .,S. . .,T-,U. . -,V. . . -,W. - -,X- . . -,Y- . - -,Z- - . .,a. -,b- . . .,c- . - .,d- . .,e.,f. . - .,g- - .,h. . . .,i. .,j. - - -,k- . -,l - . .,m- -,n- .,o- - -,p. - - .,q- - . -,r. - .,s. . .,t-,u. . -,v. . . -,w. - -,x- . . -,y- . - -,z- - . .,0- - - - -,1. - - - -,2. . - - -,3. . . - -,4. . . . -,5. . . . .,6- . . . .,7- - . . .,8- - - . .,:- - - . . .,;- . - . - .,?. . - - . .,_. . - - . -,(- . - - .,)- . - - . -,\'. - - - - .,=- . . . -,+. - . - .,/- . . - .,@. - - . - .";
String incoming;
String incomingcheck;

Loose the String class. Period.

  if (Serial.available()>0)
  {
    input=Serial.readString();
    length=input.length();

You really need to define some end-of-message marker (the carriage return and/or line feed that the Serial Monitor may add would be fine), and read and store data in a char array until that end-of-message marker arrives. Reading an arbitrary string from serial is not a good idea. The function waits up to one second for more serial data, even when there is no more coming. You could know to stop waiting long before that.

    Serial.flush();

Why is important to block, waiting for debug data to be shifted out?

It bothers me that you cannot stop the Arduino from executing the program. Once you've typed in a text,
it translates and blinks, but you cannot make it stop, e.g. in case you've changed your mind about the message you wanted to send.

Arduino is meant to run forever, at least as long power is applied. It never finishes.
Perhaps you program it to do nothing visible to the outside any more, until you press the reset button, but that's just one possibility to pass the time until power goes off.
You upload your eternal sketch once, and then it starts...

Usually it waits for events on input pins, or for data to arrive on Serial, and handles that.
E.g. it reads a character and translates that to morse code. When done, it reads the next.
If there's nothing available, it simply repeats trying to read.
That's why this function is called loop().

Once you're happy with that, you can think about more sophisticated buffering ( in case you type faster than the morse sequence takes )
(By default, you might notice that Serial buffers about 64 characters automatically)

After you got your self controlled buffering fine, you can think about interrupting and breaking a pending buffer sequence.

At first, thank you for your answers. I know my code is not perfect (how could it be, I started programming in general only a couple of weeks ago (Python), and I started C last week.) ...but still, I have the feeling I didn't get to make my point clear: I am fine with how the program works. It translates my message and it already "sends" (blinking) it only once. I just want to stop it in the middle of that. . Like, I've typed in a really long message. It blinks and blinks and blinks. Then I decide, hey, no, I don't want to send that message anymore, I want to send something else. So I interrupt the blinking.
Does that appear comprehensible? :confused:

Then I decide, hey, no, I don't want to send that message anymore, I want to send something else. So I interrupt the blinking.
Does that appear comprehensible? :confused:

Yes. You have not written your program that way, though.

Once you have defined a string to send, it sends the whole string without the ability to interrupt it.

Perhaps what you want to do is to collect the string to send, when there is serial data, and then send one character per iteration of loop(), outside of the if(Serial.available() > 0) block. That way, you would not have to wait for more than one character to be sent, before the arrival of more serial data interrupted it.

You could even have a start marker that caused the new serial data to be appended to the current message and another one that caused the serial data to replace the current message.