Question about Morse code library that creates a tone output

I have been working on a Morse code project that that I found, that uses a library: Morse.h.

I don't see how this library activates the Arduino to create a tone output (square-wave) for the speaker (but it does). I don't find a single mention in the library what kind of command is sent to the Arduino for creating the beep. All that I have been able to conclude is that it is somehow using the Arduino standard library tone() function but I don't see anything about that in the library code. I used tone() function to create a continuous tone on the pin, and while that was happening, the library decode functions would display the decoded text but would not make the tone, but it did work again after I used noTone().

I'm hoping someone who is familiar with Morse.h can give me a clue about how the library creates a tone. The actual program code is not in question and works fine.

//
// Arduino Morse Library
// Written by Erik Linder SM0RVV and Mark VandeWettering K6HX
// Contact: sm0rvv at google mail
//
// Released 2011 under GPLv3
//
// Version 0.2
//
// Corrected Morse Code errors , Glen Popiel KW5GP
//
// Usage:
//         Morse <handle>(<outputpin>, <speed>);
//         <handle>.sendmsg (*str);
//         <handle>.send (*char);

#include "Arduino.h"
#include "Morse.h"

  byte _speed;	// Speed in WPM
  byte _pin;	// Pin to beep or toggle
  byte _beep;	// 1 == beep to speaker, 0 == toggle pin high and low
  int _dashlen;	// Length of dash
  int _dotlen;	// Length of dot
const  byte _morsetab[] = {	// Those with value 1 has no morsecode - code is decimal - but converted to reverse binary to send
    117, //ASCII 33 !   
    82,  //ASCII 34 "   
    1,   //ASCII 35 #   
    200, //ASCII 36 $   
    1,   //ASCII 37 %   
    34,  //ASCII 38 &   
    94,  //ASCII 39 '  
    45, //ASCII 40 (	
    109, //ASCII 41 )   
    1,   //ASCII 42 *   
    42,  //ASCII 43 +   
    115, //ASCII 44 ,   
    97,  //ASCII 45 -   
    106,  //ASCII 46 .  
    41,  //ASCII 47 /  
    63,  //ASCII 48 0
    62,  //ASCII 49 1
    60,  //ASCII 50 2
    56,  //ASCII 51 3
    48,  //ASCII 52 4
    32,  //ASCII 53 5
    33,  //ASCII 54 6
    35,  //ASCII 55 7
    39,  //ASCII 56 8
    47,  //ASCII 57 9
    71, //ASCII 58 :	
    85,  //ASCII 59 ;	
    1,   //ASCII 60 <
    49,  //ASCII 61 =
    1,   //ASCII 62 >
    76,  //ASCII 63 ?
    86,  //ASCII 64 @	
    6,   //ASCII 65 A
    17,  //ASCII 66 B
    21,  //ASCII 67 C
    9,   //ASCII 68 D
    2,   //ASCII 69 E
    20,  //ASCII 70 F
    11,  //ASCII 71 G
    16,  //ASCII 72 H
    4,   //ASCII 73 I
    30,  //ASCII 74 J
    13,  //ASCII 75 K
    18,  //ASCII 76 L
    7,   //ASCII 77 M
    5,   //ASCII 78 N
    15,  //ASCII 79 O
    22,  //ASCII 80 P
    27,  //ASCII 81 Q
    10,  //ASCII 82 R
    8,   //ASCII 83 S
    3,   //ASCII 84 T
    12,  //ASCII 85 U
    24,  //ASCII 86 V
    14,  //ASCII 87 W
    25,  //ASCII 88 X
    29,  //ASCII 89 Y
    19,  //ASCII 90 Z
    1,   //ASCII 91 [    
    64,   //ASCII 92 backslash    
    1,   //ASCII 93 ]   
    1,   //ASCII 94 ^
    108,  //ASCII 95 _    
    94,  //ASCII 96 `    
    6,   //ASCII 97 a
    17,  //ASCII 98 b
    21,  //ASCII 99 c
    9,   //ASCII 100 d
    2,   //ASCII 101 e
    20,  //ASCII 102 f
    11,  //ASCII 103 g
    16,  //ASCII 104 h
    4,   //ASCII 105 i
    30,  //ASCII 106 j
    13,  //ASCII 107 k
    18,  //ASCII 108 l
    7,   //ASCII 109 m
    5,   //ASCII 110 n
    15,  //ASCII 111 o
    22,  //ASCII 112 p
    27,  //ASCII 113 q
    10,  //ASCII 114 r
    8,   //ASCII 115 s
    3,   //ASCII 116 t
    12,  //ASCII 117 u
    24,  //ASCII 118 v
    14,  //ASCII 119 w
    25,  //ASCII 120 x
    29,  //ASCII 121 y
    19,   //ASCII 122 z
    1,   //ASCII 123 left brace
    1,   //ASCII 124 vertical bar
    1,   //ASCII 125 right brace
    1,   //ASCII 126 tilde
    };
  
Morse::Morse(byte pin, byte speed, byte beep)
{
  // Save values for later use
  _pin = pin;
  _speed = speed;
  _beep = beep;

  // Calculate the length of dash and dot
  _dotlen = (1200/_speed);
  _dashlen =  (3*_dotlen);

  // Set the pin to output mode
  pinMode(_pin, OUTPUT);
}

void Morse::dash()
{
  digitalWrite(_pin, HIGH);
  delay(_dashlen);
  digitalWrite(_pin, LOW);
  delay(_dotlen);
}

void Morse::dit()
{
  digitalWrite(_pin, HIGH);
  delay(_dotlen);
  digitalWrite(_pin, LOW);
  delay(_dotlen);
}

void Morse::bdash()
{
  analogWrite(_pin, 128);
  delay(_dashlen);
  analogWrite(_pin, 0);
  delay(_dotlen);
}

void Morse::bdit()
{
  analogWrite(_pin, 128);
  delay(_dotlen);
  analogWrite(_pin, 0);
  delay(_dotlen);
}

void Morse::send(char c)
{

  byte _i;
  byte _p;

  // Send space
  if (c == ' ') {
    delay(7*_dotlen) ;
    return ;
  }
  
  // Do a table lookup to get morse data
  else {
    _i = ((byte) c) - 33;
    _p = _morsetab[_i];


  }

  // Main algoritm for each morse sign
  while (_p != 1) {
    if (_p & 1)
      switch (_beep) {
	case 0:
	  dash();
	  break;
        case 1:
          bdash();
          break;
        default:
          break;
      }
    else
      switch (_beep) {
	case 0:
	  dit();
	  break;
        case 1:
          bdit();
          break;
        default:
          break;
      }
    _p = _p / 2;
  }
  // Letterspace
  delay(2*_dotlen);
}

void Morse::sendmsg(char *str)
{
  while (*str) {
    send(*str++);
  }
}
  digitalWrite(_pin, HIGH);

Presumably turns on an external active beeper

Here is the example code from the library.

// Author Erik Linder
// Released 2011 under GNU GPLv3
//
// Usage: morse( <pin number>, <speed WPM>, <1=beep, 0=PTT> )
//        sendmsg( "<text-to-send>" )
//

#include <Morse.h>

// Uncomment to beep a speaker at pin 9
Morse morse(9, 12, 1);

// Use pin 13 (built-in LED of Arduino 2009)
// Morse morse(13, 12, 0);

void setup()
{
  // Nothing here for the Morse lib
}

void loop()
{
  morse.sendmsg("HELLO WORLD!");
  delay (2000);
  morse.send(83);
  morse.send(77);
  morse.send(48);
  morse.send(82);
  morse.send(86);
  morse.send(86);
  delay (2000);
}

It generates a 500 Hz square wave beep on pin 9.

// Uncomment to beep a speaker at pin 9
Morse morse(9, 12, 1);

// Use pin 13 (built-in LED of Arduino 2009)
// Morse morse(13, 12, 0);

Switching the code around at the lines will instead flash the LED on pin 13 instead of a beep on pin 9, so the library is taking care of generating a beep on pin 9 for the same duration as the LED on at pin 13, only I can't see anything that shows how it is causing the Arduino to generate a 500 Hz on/off of pin 9.

I can't see anything that shows how it is causing the Arduino to generate a 500 Hz on/off of pin 9.

Neither can I

Does the code in reply #2 actually produce a 500 Hz output or have you seen something that suggests that it does ?

I am using an Arduino Uno running on just the USB power. There is nothing else connected to it and with an oscilloscope there is a 500 Hz square wave on pin 9 beeping out the "Hello World" Morse code, and looping continuously. If I switch the code to the LED, then pin 13 flashes the equivalent of the Morse key being keyed. The sample program is encoding the text and sending out the morse code for it in either key or tone form.

The library doesn't seem to be commented enough for me to figure out how it even works, but it does!

Here is the Morse.h to go along with the Morse.cpp that I posted earlier, if it will help. I'm sorry that I'm so unknowing about figuring this out myself.

//
// Arduino Morse Library
// Written by Erik Linder SM0RVV and Mark VandeWettering K6HX
//
// Released 2011 under GPLv3
//
// Version 0.2
//

#ifndef Morse_h
#define Morse_h

#include "Arduino.h"

class Morse
{
 public:
 Morse(byte pin, byte speed, byte beep);
 void sendmsg(char *str);
 void send(char c);
 private:
 void dash();
 void dit();
 void bdash();
 void bdit();
};
#endif

mirromatic:
I am using an Arduino Uno running on just the USB power. There is nothing else connected to it and with an oscilloscope there is a 500 Hz square wave on pin 9 beeping out the "Hello World" Morse code, and looping continuously. If I switch the code to the LED, then pin 13 flashes the equivalent of the Morse key being keyed. The sample program is encoding the text and sending out the morse code for it in either key or tone form.

The library doesn't seem to be commented enough for me to figure out how it even works, but it does!

Don't need comments to see all the library does is turn a pin on and off with delays based on the timing for dots, dashes, and the corresponding delay between them.

Paul

I am using an Arduino Uno running on just the USB power. There is nothing else connected to it and with an oscilloscope there is a 500 Hz square wave on pin 9 beeping out the "Hello World" Morse code,

Run the Blink sketch and 'scope the output pin. Do you see a 500Hz square wave ?

With the Blink sketch loaded, my 'scope showes a 1 Hz square wave on pin 13.

I think I can figure this all out by making a test sketch that does not include Morse.h, but instead, I will paste parts of the library into the sketch as I figure out what each one does. I think I can vaguely see something in the Morse.cpp library under "// Main algoritm for each morse sign" where this is being controlled but it jumps to too many other subroutines for me to follow on the screen. If I build the test sketch with all the subroutines, then I should understand. Tomorrow I will report with the results. This is all kind of a wast of time except I want practice to analyze how a library works.

Thanks to both of you for the help so far and stay tuned...

This creates a tone on '_pin':

 analogWrite(_pin, 128);

aarg:
This creates a tone on '_pin':

 analogWrite(_pin, 128);

But the library posted above uses digitalWrite(_pin, HIGH)

@aarg, I think you found it. I wasn't aware of that Arduino function. I had seen it in Morse.cpp and wondered about it but as UKHeliBob mentioned I also thought the statement didn't refer to digital pin 9 (however, _pin does refer to pin 9 so that should have been a clue to me). After looking at the Arduino Reference, I see that it is the only way a square wave could be generated without timing loops in the code. Now I know where to start in testing out the parts of the library that I don't yet understand. Thank you!

UKHeliBob:
But the library posted above uses digitalWrite(_pin, HIGH)

My bad, I forgot to mention where it came from...