}
flashMessage();
}
Serial communication is used to set a new message, either using the serial monitor of the Arduino IDE or, as you will see in “Using the Morse Beacon” on page 205, a terminal program running on a Raspberry Pi.
Every time the message is changed, it is saved in EEPROM, so during the setup process, the sketch reads any stored message from EEPROM. If no message has been set, the if statement in setup sets the default message to “SOS.” Finally, at flashmessage, the setup function flashes the message for the first time.
The loop function first checks whether a new message has been sent over the serial connection:
void loop()
{
if (Serial.available()) // Is there anything to be read from USB?
{
int n = Serial.readBytesUntil('\n', message, maxMessageLen-1);
message[n] = '\0';
EEPROM_writeAnything(0, message);
Serial.println(message);
flashMessage();
}
if (millis() > lastFlashTime + gapBetweenRepeats * 1000L)
{
flashMessage();
}
}
Any new message is read into the message character array until the newline character (\n) is read. The null character ’\0’ is added to the end of the message. This is the Arduino’s way of indicating the end of a string of characters. Once the whole message has been read through, it is saved into EEPROM (EEPROM_writeAnything), and then the new message begins flashing immediately.
The remainder of the loop function checks whether enough time has passed before it can repeat the message. This could be done more simply using delay, but we would be unable to interrupt the loop if a new message arrived during the delay.
The flashMessage function is the most complex function in the sketch.
void flashMessage()
{
Serial.print("Sending: ");
Serial.println(message);
int i = 0;
while (message[i] != '\0' && i < maxMessageLen)
{
if (Serial.available()) return; // new message
char ch = message[i];
i++;
if (ch >= 'a' && ch <= 'z')
{
flashSequence(letters[ch - 'a']);
}
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); // gap between words
}
}
lastFlashTime = millis();
}
The flashMessage function starts by echoing the message it is about to send to reassure you that it is sending what you want it to. It then loops over every character in the message. Before each character, it uses Serial.available to check for a new message. If a new message has come in, the function stops sending its message in order to receive the new message from your computer or Raspberry Pi; then it begins sending the new message instead.
The flashMessage function determines whether the character is an uppercase letter, a lowercase letter, a number, or the space character and then takes the appropriate action.
If the character is a lowercase letter, the index position of the sequence of dots and dashes held in the letters array is provided as a parameter to the flashSequence function, which then flashes those dots and dashes. The other options are handled in the same way.
Finally, when the whole message has been sent, the lastFlashTime variable is set to the current time so the loop function can work out when it is time to start flashing the message again.
The work of flashing the sequence of dots and dashes for a particular character is handled by the flashSequence function:
void flashSequence(char* sequence)
{
int i = 0;
while (sequence[i] != NULL)
{
flashDotOrDash(sequence[i]);
i++;
}
delay(dotDelay * 3); // gap between letters
}
This loops over each dot or dash, calling flashDotOrDash:
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 flashDotOrDash function uses the appropriate delay period to flash a dot or dash.
USING THE MORSE BEACON
Upload the sketch to your Arduino and power up the project. The default message should start to flash. If it doesn’t, go back and check over all your wiring. To change the message, attach your Arduino to your computer, open the serial monitor on the Arduino IDE, and type in a new message (Figure 10-16).
Figure 10-16: Changing the message using the serial monitor
Here, the current message, “There are survivors here,” should change to “Watch out zombies about” when the Send button is pressed.
If you prefer to use your Raspberry Pi to change the message, install the terminal program screen (your Raspberry Pi will need an Internet connection):
$ sudo apt-get install screen
Once screen is installed, connect the USB lead between your Raspberry Pi and the Arduino and then enter the following command on your Raspberry Pi:
$ screen /dev/ttyACM0 9600
At this point, anything you type should be sent to the Arduino, and any messages coming from the Arduino should be displayed. Figure 10-17 shows the message being changed using screen. Note that the message will not appear on the screen as you type it but only after you press ENTER.
Figure 10-17: Changing the message using the screen command
Once the message has been changed, the Arduino will remember it, so you can unplug the Arduino to get ready for installation. Unplugging the Arduino will quit the screen command by closing the serial connection to the Raspberry Pi.