Morse Code using an LED with an array and the millis function

Too new to deal with that code, I think. You need to try some less ambitious projects first. It takes time to become a little proficient at coding, isn't it kind of the same in the Harley world? Would you recommend someone leap right into a (idk) valve replacement, or something, before mastering some easier things first? Right?

These forums are not classrooms, where contiguous and well thought out lessons can be conducted. All we can do is focus on stumbling blocks, specific limited issues that can be resolved quickly.

Can't argue with that logic but Ironically l learned more as a 16 year old tearing an old Iron head open and figuring out how it worked than I did from any formal training.

Noted, thank you for the help, I will continue to educate myself online, LOL!

You can do it. Start with one blink. Make the blink last for a short time (dit or dot). Make the blink last for a long time (dah or dash). Try to make two blinks of different length happen. You do not need tightly-wrapped code for a first try. Make it as big and ugly as you need to get it "done." You will start to see patterns that can be combined, which will shrink your code. Every time you learn a new part of coding, go back to your Morse program and refine it with the new stuff. You can do it because you can't fail if you keep asking for a hand when you are stuck.

I hear you about the tinkering. Nothing wrong with that, but you should still be doing it with something simpler...

Also I didn't say you couldn't do it, I'm just saying it's a path.

Sorry, but the Morse implementation seems clumsy. You should research how some different people have done it... another thing, String objects can be trouble on some Arduinos, causing random crashing after a while... your code look up table can just as easily be an array of character strings (char arrays). You are not doing any fancy string manipulation to justify the use of the String class.

Cheer up! You don't fully understand it, but you already kind-of figured it out. You said

And that is exactly what is happening.

Your code worked until you removed the delays. Without the delays, loop() will execute in the blink of an eye. Literally a few milliseconds. Inside loop() you have a for-loop which goes through all the letters in the message:

This for-loop also executes in the blink of an eye, because it too has no delays in it.

Inside that for-loop is another for-loop that goes through each dash and dot for each letter of the message:

loop() itself cannot complete until the for-loops inside it have also completed. So every time loop() executes, the for-loops inside it go through every dot and dash of every letter in the entire message.

No, the for-loops will execute once for each dot and dash in each letter. No more or less times than that. To make them run for longer, you could put another loop, such as a while-loop, inside those for-loops. That while-loop could keep looping until the desired duration is reached. But if you do that, all you have done is re-invented delay(). Your code would work "correctly" again but behave exactly as it did when it used delay(). Pointless!

So those for-loops have to go. You have to use global variables to keep track of which letter and which dot or dash is currently being sent. That way, loop() can execute many thousands of times before the whole message is complete.

I'm not saying you can never use for-loops again. You can, so long as those for loops can run in the blink of an eye. But if you need the for-loop to do something slowly, then you can't use a for-loop for that. Instead, you have to use a global variable which may only get updated after loop() has executed many hundreds or thousands of times and the desired duration has passed.

I found a few examples of morse code which may be of some help to you. Take a look here. Pretty interesting how the timing is used for the dots and dashes (dits and dahs). Note how the spaces are used in actual code. Been a lot of years since I used morse code. :slight_smile: The buzzer in the link can easily be replaced with a LED and LED series resistor.

Now you can tell me where I can find a good Harley Davidson mechanic in the Cleveland, Ohio area who actually works on and understands older bikes like my '92 Electra Glide Ultra? Got a nightmare timing issue. :slight_smile:

If you try to copy and paste the code you will have problems. The actual code looks like this after fixing:

int buzzer = 8; // Assign buzzer to pin 8
int note = 1000; // Set the pitch for the buzzer tone

int timeUnit = 100; // This variable will be used to measure dots, dashes, breaks, and pauses
char input; // Variable to save the input to

void setup () {
Serial.begin(9600);//for the connect with the boared
}

void loop () {
if (Serial.available()) {
input = Serial.read();//read the input
if (input == 'a' || input == 'A') {lA();}//if the input is a or A go to function lA
if (input == 'b' || input == 'B') {lB();}//same but with b letter
if (input == 'c' || input == 'C') {lC();}
if (input == 'd' || input == 'D') {lD();}
if (input == 'e' || input == 'E') {lE();}
if (input == 'f' || input == 'F') {lF();}
if (input == 'g' || input == 'G') {lG();}
if (input == 'h' || input == 'H') {lH();}
if (input == 'i' || input == 'I') {lI();}
if (input == 'j' || input == 'J') {lJ();}
if (input == 'k' || input == 'K') {lK();}
if (input == 'l' || input == 'L') {lL();}
if (input == 'm' || input == 'M') {lM();}
if (input == 'n' || input == 'N') {lN();}
if (input == 'o' || input == 'O') {lO();}
if (input == 'p' || input == 'P') {lP();}
if (input == 'q' || input == 'Q') {lQ();}
if (input == 'r' || input == 'R') {lR();}
if (input == 's' || input == 'S') {lS();}
if (input == 't' || input == 'T') {lT();}
if (input == 'u' || input == 'U') {lU();}
if (input == 'v' || input == 'V') {lV();}
if (input == 'w' || input == 'W') {lW();}
if (input == 'x' || input == 'X') {lX();}
if (input == 'y' || input == 'Y') {lY();}
if (input == 'z' || input == 'Z') {lZ();}
if (input == ' ') {wordPause();}
Serial.println (input);

}
}
//Letter functions
void lA () {dot();dash();letterPause();}//letter A in morse code!
void lB () {dash();dot();dot();dot();letterPause();}//same for B
void lC () {dash();dot();dash();dot();letterPause();}
void lD () {dash();dot();dot();letterPause();}
void lE () {dot();letterPause();}
void lF () {dot();dot();dash();dot();letterPause();}
void lG () {dash();dash();dot();letterPause();}
void lH () {dot();dot();dot();dot();letterPause();}
void lI () {dot();dot();letterPause();}
void lJ () {dot();dash();dash();dash();letterPause();}
void lK () {dash();dot();dash();letterPause();}
void lL () {dot();dash();dot();dot();letterPause();}
void lM () {dash();dash();letterPause();}
void lN () {dash();dot();letterPause();}
void lO () {dash();dash();dash();letterPause();}
void lP () {dot();dash();dash();dot();letterPause();}
void lQ () {dash();dash();dot();dash();letterPause();}
void lR () {dot();dash();dot();letterPause();}
void lS () {dot();dot();dot();letterPause();}
void lT () {dash();letterPause();}
void lU () {dot();dot();dash();letterPause();}
void lV () {dot();dot();dot();dash();letterPause();}
void lW () {dot();dash();dash();letterPause();}
void lX () {dash();dot();dot();dash();letterPause();}
void lY () {dash();dot();dash();dash();letterPause();}
void lZ () {dash();dash();dot();dot();letterPause();}

void dot() //Emit sound for 100 milliseconds
{
tone(buzzer, note, timeUnit);
delay(timeUnit * 2);
}

void dash() //Emit sound for 300 milliseconds
{
tone(buzzer, note, timeUnit * 3);
delay(timeUnit * 4);
}

void letterPause() //Delay between letters for 300 milliseconds
{
delay(timeUnit * 3);
}

void wordPause()
{
delay (timeUnit * 7);
}

A copy and paste from the website will give you Error stray '\342' in program errors because of how copy works with Unicode characters. Hope this gives you some good ideas and ride safe if you still ride. :slight_smile:

Ron

preprocessor directives. these effectively comment out the code

newb too sorry, but don't you have to subtract then compare??

That looks like a typo. BTW the cast to unsigned long is completely unnecessary. Also the parentheses around the subtraction. So:

if (currentMillis - previousMillis >= dotInterval)

All right here it is, I already new how to do this with delays, like I wrote, I really wanted to use millis but obviously it's above my pay grade currently, as I cannot figure it out, I will one day!!! Until then I am using this! I am ultimately going to use this to make a tail light controller, I have already made one for another one of my scoots, but it doesn't use Morse code it is just flashes a couple times, to grab the person's attention behind me. It works almost perfect! Everything except for the stupid slight delay when letting of the brakes and it is blocked from the delay function. Funny thing is I am the only one who notices it! Yes, I know the output to the Serial monitor needs to be removed it was only in for testing. Before any on asks no it won't be flashing "Hello Cruel World"! Any and all POSITIVE criticism is welcome and appreciated, yes I know I need comments and I know it feels clumsy!

int charCounter = 0;
int SwitchState = LOW;
int duration = 200;
const int arraySize =37;

const byte outPut1 = 10;
const byte InputPin = 4;

String morseAlphabet[arraySize] = {"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--..", 
"1.----","2..---","3...--","4....-","5.....","6-....","7--...",
"8---..","9----.","0-----", " "};




/******************************************************************************/
String myWord = "HELLO CRUEL WORLD";//HAS TO BE IN UPPER CASE LETTERS OR IT WON'T WORK!!
/******************************************************************************/


void setup(){ 
  Serial.begin(9600);

  pinMode(outPut1, OUTPUT);
  pinMode(InputPin, INPUT);

  digitalWrite(outPut1, LOW);
  digitalWrite(InputPin, LOW);  

}

 void loop(){

  SwitchState = digitalRead(InputPin);

  if(SwitchState == HIGH  && charCounter == 0){
    
    for(int i =0; i< arraySize; i++){
            
      if(morseAlphabet[i].charAt(0) == myWord.charAt(charCounter)){
        for(int j = 0; j < morseAlphabet[i].length(); j++){
                    
          if(morseAlphabet[i].charAt(j) == '.'){                         
            SwitchState = digitalRead(InputPin);
            if(SwitchState){
              Serial.print(" . ");              
              digitalWrite(outPut1, HIGH);
              
              for(int a = 0; a < duration; a++){
              delay(1);
              }

              digitalWrite(outPut1, LOW);
              for(int a = 0; a < duration; a++){
               delay(1);
              }
            }            
          }
           
          if(morseAlphabet[i].charAt(j) == '-'){            
            SwitchState = digitalRead(InputPin);
            if(SwitchState){
              Serial.print(" - ");
              
              digitalWrite(outPut1, HIGH);
              for(int a = 0; a < (3*duration); a++){
              delay(1);
              }

              digitalWrite(outPut1, LOW);
              for(int a = 0; a < duration; a++){
               delay(1);
              }
            }
          }
          
          if(morseAlphabet[i].charAt(j) == ' '){
              SwitchState = digitalRead(InputPin);
              if(SwitchState){
              Serial.print(" ");
              
              digitalWrite(outPut1, LOW);
              for(int a = 0; a < (3*duration); a++){
              delay(1);
              }

              digitalWrite(outPut1, LOW);
              for(int a = 0; a < (3*duration); a++){
               delay(1);
              }
            }
          }
          
        }     
        i =-1;    
        Serial.println();
        charCounter++;
      }
    }
  }
  if(SwitchState == HIGH){
     Serial.println("HIGH HIGH HIGH");
     digitalWrite(outPut1, HIGH);
  }
  else{
    charCounter = 0;
    digitalWrite(outPut1, LOW);    
  }
}

Sorry, the only thing I know of Cleveland is the "Fuel Cleveland Show" I don't know of any Mechanics in that area! Yes I still ride, build, and wrench kind of what ever I want right now! I am blessed!

why not

   delay (3*duration);

oops! I think I uploaded the wrong one. let me get the right one!

I

int charCounter = 0;
int SwitchState = LOW;
int duration = 200;
const int arraySize =37;

const byte outPut1 = 10;
const byte InputPin = 4;

String morseAlphabet[arraySize] = {"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--..", 
"1.----","2..---","3...--","4....-","5.....","6-....","7--...",
"8---..","9----.","0-----", " "};




/******************************************************************************/
String myWord = "HELLO CRUEL WORLD";//HAS TO BE IN UPPER CASE LETTERS OR IT WON'T WORK!!
/******************************************************************************/


void setup(){ 
  Serial.begin(9600);

  pinMode(outPut1, OUTPUT);
  pinMode(InputPin, INPUT);

  digitalWrite(outPut1, LOW);
  digitalWrite(InputPin, LOW);  

}

 void loop(){

  SwitchState = digitalRead(InputPin);

  if(SwitchState == HIGH  && charCounter == 0){
    
    for(int i =0; i< arraySize; i++){
            
      if(morseAlphabet[i].charAt(0) == myWord.charAt(charCounter)){
        for(int j = 0; j < morseAlphabet[i].length(); j++){
                    
          if(morseAlphabet[i].charAt(j) == '.'){                         

            if(SwitchState){
              Serial.print(" . ");              
              digitalWrite(outPut1, HIGH);
              
              SwitchState = digitalRead(InputPin);             
              for(int a = 0; a < duration; a++ && SwitchState){
              delay(1);
              }
              
              SwitchState = digitalRead(InputPin);
              digitalWrite(outPut1, LOW);
              for(int a = 0; a < duration; a++ && SwitchState){
              delay(1);
              }
            }            
          }
           
          if(morseAlphabet[i].charAt(j) == '-'){            
              SwitchState = digitalRead(InputPin);
              if(SwitchState){
              Serial.print(" - ");
              
              SwitchState = digitalRead(InputPin);              
              digitalWrite(outPut1, HIGH);
              for(int a = 0; a < (3*duration); a++ && SwitchState){
              delay(1);
              }
              
              SwitchState = digitalRead(InputPin);
              digitalWrite(outPut1, LOW);
              for(int a = 0; a < duration; a++ && SwitchState){
               delay(1);
              }
            }
          }
          
          if(morseAlphabet[i].charAt(j) == ' '){
              SwitchState = digitalRead(InputPin);
              if(SwitchState){
              Serial.print(" ");
              
              SwitchState = digitalRead(InputPin);              
              digitalWrite(outPut1, LOW);
              for(int a = 0; a < (3*duration); a++ && SwitchState){
              delay(1);
              }
              
              SwitchState = digitalRead(InputPin);
              digitalWrite(outPut1, LOW);
              for(int a = 0; a < (3*duration); a++ && SwitchState){
               delay(1);
              }
            }
          }
          
        }     
        i =-1;    
        Serial.println();
        charCounter++;
      }
    }
  }
  if(SwitchState == HIGH){
     Serial.println("HIGH HIGH HIGH");
     digitalWrite(outPut1, HIGH);
  }
  else{
    charCounter = 0;
    digitalWrite(outPut1, LOW);    
  }
}

I was attempting to stop and prevent as much delay when the switch was released as possible, not sure if it will stop it or it just pointless and using up memory but is seems to work.

would it be better to use

Then what I have???

seems unnecessary to test for the SwitchState during mid- dot. wouldn't after the end of a character be sufficient.

so like this???

            if(SwitchState){
              Serial.print(" . ");              
              digitalWrite(outPut1, HIGH);           
              delay(duration);
              
              digitalWrite(outPut1, LOW);
              delay(duration);             
            }

I was trying to use the examples off the bald engineers website!

tossed this into an online simulator.
breaking out of the loops seems to make it stop a bit faster.

int charCounter = 0;
int SwitchState = LOW;
int duration = 200;
const int arraySize =37;

const byte outPut1 = 10;
const byte InputPin = 4;

String morseAlphabet[arraySize] = {"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--..", 
"1.----","2..---","3...--","4....-","5.....","6-....","7--...",
"8---..","9----.","0-----", " "};




/******************************************************************************/
String myWord = "HELLO CRUEL WORLD";//HAS TO BE IN UPPER CASE LETTERS OR IT WON'T WORK!!
/******************************************************************************/





void setup() {
  // put your setup code here, to run once:
Serial.begin(9600);

  digitalWrite(InputPin, LOW);    
  pinMode(outPut1, OUTPUT);
  pinMode(InputPin, INPUT);

  digitalWrite(outPut1, LOW);

}

void loop() {
  // put your main code here, to run repeatedly:

    SwitchState = digitalRead(InputPin);

  if(SwitchState == HIGH  && charCounter == 0){
    
    for(int i =0; i< arraySize; i++){

      if (!digitalRead(InputPin)){break;}      
      if(morseAlphabet[i].charAt(0) == myWord.charAt(charCounter)){
        for(int j = 0; j < morseAlphabet[i].length(); j++){
          if (!digitalRead(InputPin)){break;}      
                    
          if(morseAlphabet[i].charAt(j) == '.'){                         

            if(SwitchState){
              Serial.print(" . ");              
              digitalWrite(outPut1, HIGH);
              
              SwitchState = digitalRead(InputPin);             
              for(int a = 0; a < duration; a++ && SwitchState){
              if (!digitalRead(InputPin)){break;}      
              delay(1);
              }
              
              SwitchState = digitalRead(InputPin);
              digitalWrite(outPut1, LOW);
              for(int a = 0; a < duration; a++ && SwitchState){
              if (!digitalRead(InputPin)){break;}      
              delay(1);
              }
            }            
          }
           
          if(morseAlphabet[i].charAt(j) == '-'){            
              SwitchState = digitalRead(InputPin);
              if(SwitchState){
              Serial.print(" - ");
              
              SwitchState = digitalRead(InputPin);              
              digitalWrite(outPut1, HIGH);
              for(int a = 0; a < (3*duration); a++ && SwitchState){
              if (!digitalRead(InputPin)){break;}      
              delay(1);
              }
              
              SwitchState = digitalRead(InputPin);
              digitalWrite(outPut1, LOW);
              for(int a = 0; a < duration; a++ && SwitchState){
               if (!digitalRead(InputPin)){break;}      
               delay(1);
              }
            }
          }
          
          if(morseAlphabet[i].charAt(j) == ' '){
              SwitchState = digitalRead(InputPin);
              if(SwitchState){
              Serial.print(" ");
              
              SwitchState = digitalRead(InputPin);              
              digitalWrite(outPut1, LOW);
              for(int a = 0; a < (3*duration); a++ && SwitchState){
              if (!digitalRead(InputPin)){break;}      
              delay(1);
              }
              
              SwitchState = digitalRead(InputPin);
              digitalWrite(outPut1, LOW);
              for(int a = 0; a < (3*duration); a++ && SwitchState){
              if (!digitalRead(InputPin)){break;}      
               delay(1);
              }
            }
          }
          
        }     
        i =-1;    
        Serial.println();
        charCounter++;
      }
    }
  }


  SwitchState = digitalRead(InputPin);

  if(SwitchState == HIGH){
     Serial.println("HIGH HIGH HIGH");
     digitalWrite(outPut1, HIGH);
  }
  else{
    charCounter = 0;
    digitalWrite(outPut1, LOW);    
  }


}