RESOLVED - Program 5_05 from "Programming Arduino" book error

I copied the program exactly and get the following error:

5_05.ino:In function 'void loop()': 5_05.ino:40:39:error: 'flashSequence' was not declared in this scope.

What am I no seeing??

I don't have the book, so I can't see the code you are talking about.

look at the declaration of "flashSequence".

The usual reason you see an error like that, is that for some reason, the header file ( .h ) it is looking for, it cannot find.

Maybe it is in the wrong place, or missing, anyway the compiler cannot find it.

When you install new header files, you need to close the arduino IDE and re-open it, before it can find them.

Can you post the code of the example?

I have tried since July to post answers without success! No idea what the problem was.

I got the program to compile without errors, HOWEVER, it does not blink the Morse Code when it prints the punctuation marks to the Serial Monitor. I’ll try again to post the code here.

//Sketch 5_05Test   Morse Interpreter including punctuation

int ledPin = 13;
int dotDelay = 250;                                               //set the delay to a quarter second

char* letters[] = 
                  {
                    ".-", "-...", "-.-.", "..", ".",                          //A-Z
                     "..-.", "--.", "....", "..",
                     ".---", "-.-", ".-..", "--", "-.",                    
                     "---", ".--.", "--.-", ".-.",
                     "...", "-", "..-", "...-", ".--",                     
                     "-..-", "-.--", "--.."
                  };

char* numbers[] = 
                  {
                    "-----", ".----", "..---", "...--", "....-",  //numbers 0-9
                    ".....", "-....", "--...", "---..", "----."
                  };             
                    
char* punct[] =
                  {
                       ".-.-.-", "--..--", "..--..", ".----.",          //(punctuation marks) . , ? '
                       "-.-.--", "-.--.", "-.--.-", ".-...",           // ! ( ) &
                       " ---...", "-.-.-.", "-...-", ".-.-.",            // : ; = +
                       "-....-", "..--.-", ".-..-.", "...-..-",           // - _ " &
                       ".--.-."                                                 // @
                  }; 
                  
                      
void setup()                                                                
{
  pinMode(ledPin, OUTPUT);
  Serial.begin(9600);
  Serial.println("To send text to be displayed in Morse Code, type words above and press Send");
}

void loop()
{
  char ch;
  if (Serial.available() > 0)
  {
      ch = Serial.read();                                        //read a single letter

      if (ch >= 'a' && ch <= 'z')                              // is it lower case letter?
   {
      flashSequence(letters [ch - 'a']);
   }
  else if (ch >= 'A' && ch <= 'Z')                           // is it a capital letter?
   {
      flashSequence(letters [ch - 'A']);
   }
  else if (ch >= '0' && ch <= '9')                          // is it a number?
   {
      flashSequence (numbers[ch - '0']);
   }
  else if (ch >= '.'  &&  ch <=  '@')                      // is it punctuation?   THIS SECQUENCE DOES NOT WORK!!
   {
      flashSequence (punct[ch] - '.');
   }
    else if (ch == ' ')                                          // is it a blaqnk space?
   {
     delay(dotDelay * 4);                                     //gap between words
   }
  {    
     Serial.print(ch);
   }
  }
 }

void flashSequence (char* sequence)

{
  int i = 0;
  while  (sequence[i] != NULL)
  {
    flashDotOrDash(sequence[i]);
    i++;
  }
  delay(dotDelay * 3);                              //gap between letters
}

void flashDotOrDash (char dotOrDash)
{
  digitalWrite(ledPin, HIGH);
  if (dotOrDash == '.')
  {
    delay (dotDelay);
  }
  else                                          // must be a -
  {
    delay (dotDelay * 2);
  }
  digitalWrite(ledPin, LOW);
  delay(dotDelay);                              //gap between flashes
}

There is one error:

void flashSequence (char* sequence)

{
  int i = 0;
  while  (sequence[i] != NULL)
  {
    flashDotOrDash(sequence[i]);
    i++;
  }
  delay(dotDelay * 3);                              //gap between letters
}

change it to:

void flashSequence (char character)

{
  if  (character != NULL)
  {
    flashDotOrDash(character);
  }
  delay(dotDelay * 3);                              //gap between letters
}

I don't know if is the only thing that is wrong, but you need to change at least this to the program work like you want.

I found it distracting to see the onboard LED flashing Morse while the I/O leds were also flashing because Simon didn’t buffer the input. Also, you can simplify a few things, too. I also commented out the Serial call that displays the letter just display on the LED because of the I/O LED flashing while it was sent. Lastly, Morse code is normally a 1:3 ration dits to dahs, character spacing is 3 dits, and word spacing is 7 dits. Farnsowrth encoding screws these timings up, but the ratios here are commonly used.

//Sketch 5_05Test   Morse Interpreter including punctuation

int ledPin = 13;
int dotDelay = 150;                                               //set the delay to a quarter second

char* letters[] =
{
  ".-", "-...", "-.-.", "..", ".",                          //A-Z
  "..-.", "--.", "....", "..",
  ".---", "-.-", ".-..", "--", "-.",
  "---", ".--.", "--.-", ".-.",
  "...", "-", "..-", "...-", ".--",
  "-..-", "-.--", "--.."
};

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

char* punct[] =
{
  ".-.-.-", "--..--", "..--..", ".----.",          //(punctuation marks) . , ? '
  "-.-.--", "-.--.", "-.--.-", ".-...",           // ! ( ) &
  " ---...", "-.-.-.", "-...-", ".-.-.",            // : ; = +
  "-....-", "..--.-", ".-..-.", "...-..-",           // - _ " &
  ".--.-."                                                 // @
};


void setup()
{
  pinMode(ledPin, OUTPUT);
  Serial.begin(115200);
  Serial.println("To send text to be displayed in Morse Code, type words above and press Send");
}

void loop()
{
  char ch;
  char buff[100];
  int i;

  if (Serial.available() > 0)
  {
    i = Serial.readBytesUntil('\n', buff, 99);    //read all
    buff[i] = '\0';
    i = 0;
    while (buff[i]) {
      ch = toupper(buff[i++]);
      if (ch >= 'A' && ch <= 'Z')                           // is it a capital letter?
      {
        flashSequence(letters [ch - 'A']);
      }
      else if (ch >= '0' && ch <= '9')                          // is it a number?
      {
        flashSequence (numbers[ch - '0']);
      }
      else if (ch >= '.'  &&  ch <=  '@')                      // is it punctuation?   THIS SECQUENCE DOES NOT WORK!!
      {
        flashSequence (punct[ch] - '.');
      }
      else if (ch == ' ')                                          // is it a blaqnk space?
      {
        delay(dotDelay * 7);                                     //gap between words
      }
      {
        //Serial.print(ch);
      }
    }
  }
}

void flashSequence (char* sequence)
{
  int i = 0;
  while  (sequence[i])
  {
    flashDotOrDash(sequence[i++]);
  }
  delay(dotDelay * 3);                              //gap between letters
}

void flashDotOrDash (char dotOrDash)
{
  digitalWrite(ledPin, HIGH);
  if (dotOrDash == '.')
  {
    delay (dotDelay);
  }
  else                                          // must be a -
  {
    delay (dotDelay * 3);
  }
  digitalWrite(ledPin, LOW);
  delay(dotDelay);                              //gap between flashes
}

The problem in this code in regards to the punctuation is that the ASCII values for the punctuation characters are not sequential and easily transposed into the dot/dash arrays. The letters are sequential from 65 to 90, and 97 to 122. The numbers are sequential from 48 to 57, but the punctuation values run from 33 (!) to 95(_) and are not sequential.

I have modified the code to make the punctuation values sequential so they transpose into the array of dot/dash values.

I changed some dot/dash time values so I could see what was going on, and I did not make the changes luisilva suggested.

//Sketch 5_05Test   Morse Interpreter including punctuation

int ledPin = 13;
int dotDelay = 250; //set the delay to a quarter second

char ch;
byte newch;  //transposed punctuation values

char* letters[] = 
                  {
                    ".-", "-...", "-.-.", "..", ".",                          //A-Z
                     "..-.", "--.", "....", "..",
                     ".---", "-.-", ".-..", "--", "-.",                    
                     "---", ".--.", "--.-", ".-.",
                     "...", "-", "..-", "...-", ".--",                     
                     "-..-", "-.--", "--.."
                  };

char* numbers[] = 
                  {
                    "-----", ".----", "..---", "...--", "....-",  //numbers 0-9
                    ".....", "-....", "--...", "---..", "----."
                  };             
                    
char* punct[] =
                  {
                       ".-.-.-", "--..--", "..--..", ".----.",          //(punctuation marks) . , ? '
                       "-.-.--", "-.--.", "-.--.-", ".-...",           // ! ( ) &
                       "---...", "-.-.-.", "-...-", ".-.-.",            // : ; = +
                       "-....-", "..--.-", ".-..-.", "...-..-",           // - _ " &
                       ".--.-."                                                 // @
                  }; 
                  
                      
void setup()                                                                
{
  pinMode(ledPin, OUTPUT);
  Serial.begin(9600);
  Serial.println("To send text to be displayed in Morse Code, type words above and press Send");
}

void loop()
{
 
  if (Serial.available() > 0)
  {
      ch = Serial.read();                                        //read a single letter

      if (ch >= 'a' && ch <= 'z')                              // is it lower case letter?
   {
      flashSequence(letters [ch - 'a']);
   }
  else if (ch >= 'A' && ch <= 'Z')                           // is it a capital letter?
   {
      flashSequence(letters [ch - 'A']);
   }
  else if (ch >= '0' && ch <= '9')                          // is it a number?
   {
      flashSequence (numbers[ch - '0']);
   }
  else if (ch >= 33  &&  ch <=  95)                      // is it punctuation?   THIS SEQUENCE DOES NOT WORK!!//Now it does
   {

      punctuationTranspose();
      flashSequence (punct[newch]); 
      
   }
    else if (ch == ' ')                                      // is it a blank space?
   {
     delay(dotDelay * 4);                                   //gap between words
   }
  {    
     Serial.print(ch);
   }
  }
 }

void flashSequence (char* sequence)

{
  int i = 0;
  while  (sequence[i] != NULL)
  {
    flashDotOrDash(sequence[i]);
    i++;
  }
  delay(dotDelay * 3);     //gap between letters
}

void flashDotOrDash (char dotOrDash)
{
  digitalWrite(ledPin, HIGH);
  if (dotOrDash == '.')
  {
    delay (dotDelay);
  }
  else                                          // must be a -
  {
    delay (dotDelay *4);    // was2 dash lengthened for debug
  }
  digitalWrite(ledPin, LOW);
  delay(dotDelay*2);  // was dotDelay lengthened for debug                           //gap between flashes
}

byte punctuationTranspose(){
  
  if (ch=='.') 
  newch= 0;
  if (ch==',')
  newch= 1;
  if(ch=='?')
  newch= 2;
  if(ch==39)//apostrophe
  newch= 3;
  if (ch=='!')
  newch= 4;
  if (ch=='(')
  newch= 5;
  if (ch==')')
  newch= 6;
  if (ch=='&')  //first ampersand
  newch= 7;
  if (ch==':')
  newch= 8;
  if (ch==';')
  newch= 9;
  if (ch=='=')
  newch= 10;
  if (ch=='+')
  newch= 11;
  if (ch=='-')
  newch= 12;
  if (ch=='_')
  newch= 13;
  if (ch=='"')
  newch= 14;
  if (ch=='#')  //second ampersand; call it #
  newch= 15;
  if (ch=='@')
  newch= 16;
  
  return newch;
  
}

There was a bracket error in the original code, but it was not the cause of the problem

flashSequence (punct[ch] - '.');

should be

flashSequence (punct[ch - '.']);

There are two ampersands(&) in the punctuation table. There was an error in the definition of the colon : in that there was an extra space between the " and the dot/dash sequence.

Thank you all for your input and efforts!!!
I tried all three responses. I copied luisilva’s code and pasted it in my Arduino IDE. I could not get it to compile. Did the same with the code provided by econjack. It compiled, but when I typed something into the Serial Monitor, nothing happened on the Arduino. Cattledog 's revisions worked perfectly! I will now study that coding and find where I went wrong. Again, my thanks to you all for your efforts!!

Also, my not being able to responde earlier to anyone was due to Internet Explorer 11.0.9. It would block my entries. I switched to FireFox 31.0 and now have no problems.

Bob
p.s.: I’m really enjoying this board, it’s software and the HELPFUL people involved with this site!! THANKS!

After you typed in a sentence on the Serial monitor and clicked Send, did you bother to look at the LED on the Arduino board?

You might want to change cattledog's function punctuationTranspose() from a bunch of if expressions to a switch. The reason is because, if the character coming in happens to be a period character, it matches the first test, but the code then performs 15 unnecessary if tests.

Yes, I did look. While it did compile, I do not know why nothing happened. There were no flashes, and the simple sentence I typed in the Serial Monitor did not write back as it was supposed to during the response. I haven't looked yet to see if I can find out why not.

Also, just read your second response. I'll look into your "switch" recommendation. Thanks!!

Yes, switch will be more efficient than the if chain.

The punctuation array should be defined in order of frequency of usage. The first four characters are certainly more common than the last, so maybe it already is in the order which will make the program switch as soon as possible once it starts checking.

Will work on your suggestion. Thanks!

Cattledog,
I corrected my mistakes, took your suggestions and re-did the code. Now it does just what I want! Thanks!!
(I re-entered the punctuation array and switch cases in an order (I thought) would fit what you said about frequency of use.)

//Sketch 5_05WORKS   Morse Interpreter including punctuation

int ledPin = 13;
int dotDelay = 250; //set the delay to a quarter second

char ch;
byte newch;  //transposed punctuation values

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

char* numbers[] =                                              // numbers 0-9         
                  {
                    "-----", ".----", "..---", "...--", "....-",  
                    ".....", "-....", "--...", "---..", "----."
                  };             
                    
char* punct[] =                                                // punctuation marks
                  {
                   ".-.-.-", "--..--", ".----.",  "..--..",       //  .  ,   '   ?    
                   "-.--.", "-.--.-", "-.-.--", "-.-.-.",        //  (  )   !   ;
                   "---...", ".-..-.", ".--.-.", "-....-",        //  :  "  @  -
                   "..--.-", ".-.-.", "...-..-", "-...-",         //  _  +  $  =
                   ".-..."                                        //  &

                   
                   
                   
                   
                    ".-.-.-", "--..--", "..--..", ".----.",          //  (punctuation marks) . , ? '
                       "-.-.--", "-.--.", "-.--.-", ".-...",            //    ! ( ) &
                       "---...", "-.-.-.", "-...-", ".-.-.",            //    : ; = +
                       "-....-", "..--.-", ".-..-.", "...-..-",          //     - _ " $
                       ".--.-."                                         //    @
                  }; 
                  
                      
void setup()                                                                
{
  pinMode(ledPin, OUTPUT);
  Serial.begin(9600);
  Serial.println("To send text to be displayed in Morse Code, type words above and press Send");
}

void loop()
{
 
  if (Serial.available() > 0)
  {
      ch = Serial.read();                                        //read a single letter

      if (ch >= 'a' && ch <= 'z')                              // is it lower case letter?
   {
      flashSequence(letters [ch - 'a']);
   }
  else if (ch >= 'A' && ch <= 'Z')                           // is it a capital letter?
   {
      flashSequence(letters [ch - 'A']);
   }
  else if (ch >= '0' && ch <= '9')                          // is it a number?
   {
      flashSequence (numbers[ch - '0']);
   }
  else if (ch >= 33  &&  ch <=  95)                      // is it punctuation?   THIS SEQUENCE DOES NOT WORK!!//Now it does
   {

      punctuationTranspose();
      flashSequence (punct[newch]); 
      
   }
    else if (ch == ' ')                                          // is it a blank space?
   {
     delay(dotDelay * 4);                                    //gap between words
   }
  {    
     Serial.print(ch);
   }
  }
 }

void flashSequence (char* sequence)

{
  int i = 0;
  while  (sequence[i] != NULL)
  {
    flashDotOrDash(sequence[i]);
    i++;
  }
  delay(dotDelay * 3);                                     //gap between letters
}

void flashDotOrDash (char dotOrDash)
{
  digitalWrite(ledPin, HIGH);
  if (dotOrDash == '.')
  {
    delay (dotDelay);
  }
  else                                                           // must be a -
  {
    delay (dotDelay *2);                                  
  }
  digitalWrite(ledPin, LOW);
  delay(dotDelay);                                         //gap between flashes
}

byte punctuationTranspose()
{
  switch(ch)
  {
  case 1:
  ch=='.';
  newch= 0;
  break; 
 
  case 2:
  ch==',';
  newch= 1;
  break;
  
  case 3:
  ch==39;
  newch= 2;
  break;
  
  case 4:
  ch=='?';
  newch= 3;
  break;
  
  case 5:
  ch=='(';
  newch= 4;
  break;
  
  case 6:
  ch==')';
  newch= 5;
  break;
  
  case 7:
  ch=='!';
  newch= 6;
  break;
  
  case 8:
  ch==';';  
  newch= 7;
  break;
  
  case 9:
  ch==':';
  newch= 8;
  break;
  
  case 10:
  ch=='"';
  newch= 9;
  break;
  
  case 11:
  ch=='@';
  newch= 10;
  break;
  
  case 12:
  ch=='-';
  newch= 11;
  break;
  
  case 13:
  ch=='_';
  newch= 12;
  break;
  
  case 14:
  ch=='+';
  newch= 13;
  break;
  
  case 15:
  ch=='

;
  newch= 14;
  break;
 
  case 16:
  ch==’=’; 
  newch= 15;
  break;
 
  case 17:
  ch==’&’;
  newch= 16;
  break;
 
  return newch;
  }
}

case 2:
  ch==',';
  newch= 1;
  break;

What’s the comparison for?

Your punctuationTranspose() function is not correct. In each case, you have something like:

  case 1:
  ch=='.';      // The equality operator doesn't do anything here
  newch= 0;
  break;

If fact, if you look at every case, you assign newch a value that is exactly 1 less than ch. In essence, all your function does is reduce the index number by 1. I think this is because you forgot that C arrays begin with 0, not 1. You can prove this to yourself by replacing your punctuationTranspose() with:

byte  punctuationTranspose(
  newch = ch - 1;
  return newch;
}

It also seems like your punctuation array has a lot of duplicate entries in it, which is wasteful, especially on boards like there which have limited memory. Indeed, the punctuationTranspose() function isn’t needed at all. Try:

 else if (ch >= 33  &&  ch <=  95)                      // is it punctuation?   THIS SEQUENCE DOES NOT WORK!!//Now it does
   {

      //punctuationTranspose();      // Get rid of the next two lines...
      //flashSequence (punct[newch]); 

      flashSequence (punct[ch - 1]);
   }

There are several other things that don’t make sense to me, but these should make you stop and review your code.

Indeed, the punctuationTranspose() function isn't needed at all.

This is not correct. The char values need to be converted to array indexes.

The code you proposed is pretty much identical to the code which began this thread.

 flashSequence (punct[ch - 1]);

For example, the period . is char 46 and is at index 0 in the array punct[ ]. flashSequence(punct[45]) will not produce the period and is out of the array index.

Bohicaman forgot to comment out the original punctuation array, or made a cut and paste error. There should not be two instances of punct[ ] in the code.

The syntax of the switch case is not correct. It should be

byte punctuationTranspose()
{
  switch(ch)
  {
  case '.':
  newch= 0;
  break; 

  case ',':
  newch= 1;
  break;
  
  case 39:
  newch= 2;
  break;
  
  case '?':
  newch= 3;
  break;
  
  case '(':
  newch= 4;
  break;
  
  case ')':
  newch= 5;
  break;
  
  case '!':
  newch= 6;
  break;
  
  case ';':
  newch= 7;
  break;
  
  case ':':
  newch= 8;
  break;
  
  case '"':
  newch= 9;
  break;
  
  case '@':
  newch= 10;
  break;
  
  case '-':
  newch= 11;
  break;
  
  case '_':
  newch= 12;
  break;
  
  case '+':
  newch= 13;
  break;
  
  case '

:   newch= 14;   break;     case '=':   newch= 15;   break;     case '&':   newch= 16;   break;   } } ```

Ok folks, First, you're right, I forgot to "comment" out the second punctuation. That's now corrected.

Now, the second item. I ran the code and it blinks out the "period" and also types it back to the Serial Monitor. I don't see the problem being talked about. Keep in mind I'm new at Arduino programming!

Thanks for the comments though! I will review my coding.

Bob

Regarding the recommendation to change the "switch"...

The syntax of the switch case is not correct. It should be...

Read up on my coding and have applied your suggestions for changing the switch to the shorter, simplier version! Again, THANKS!! B.