1

My code runs perfectly as long as the serial port is open. However if I connect it to external power, or even if I just try to run it plugged into my computer with the Serial Monitor not open, nothing happens. My project doesn't need any serial interaction, it will operate on its own far from any computers. I have it in here to help me debug.

The sticking point appears to be with if (morseInput.available()) on line 63.

Here is everything, including the libraries I am using:

Morse EnDecoder.h

#ifndef MorseEnDecoder_H
#define MorseEnDecoder_H

#if (ARDUINO <  100)
#include <WProgram.h>
#else
#include <Arduino.h> 
#endif

#define MORSE_AUDIO true
#define MORSE_KEYER false
#define MORSE_ACTIVE_LOW true
#define MORSE_ACTIVE_HIGH false


class morseDecoder
{
public:
morseDecoder(int decodePin, boolean listenAudio, boolean morsePullup);
void decode();
void setspeed(int value);
char read();
boolean available();
int AudioThreshold;
long debounceDelay;     // the debounce time. Keep well below dotTime!!
boolean morseSignalState;  
private:
int morseInPin;         // The Morse input pin
int audioSignal;
int morseTablePointer;
int wpm;                // Word-per-minute speed
long dotTime;           // morse dot time length in ms
long dashTime;
long wordSpace;
boolean morseSpace;     // Flag to prevent multiple received spaces
boolean gotLastSig;     // Flag that the last received morse signal is decoded as dot or dash
boolean morseKeyer;
boolean lastKeyerState;
boolean morseAudio;
boolean activeLow;
long markTime;          // timers for mark and space in morse signal
long spaceTime;         // E=MC^2 ;p
long lastDebounceTime;  // the last time the input pin was toggled
long currentTime;       // The current (signed) time
char decodedMorseChar;  // The last decoded Morse character
};


class morseEncoder
{
public:
morseEncoder(int encodePin);
void encode();
void setspeed(int value);
void write(char temp);
boolean available();
int morseSignals;       // nr of morse signals to send in one morse character
char morseSignalString[7];// Morse signal for one character as temporary ASCII string of dots and dashes
private:
char encodeMorseChar;   // ASCII character to encode
boolean sendingMorse;
int wpm;                // Word-per-minute speed
long dotTime;           // morse dot time length in ms
long dashTime;
long wordSpace;
int morseSignalPos;
int sendingMorseSignalNr;
long sendMorseTimer;
long lastDebounceTime;
long currentTime;
protected:
int morseOutPin;
virtual void setup_signal();
virtual void start_signal(bool startOfChar, char signalType);
virtual void stop_signal(bool endOfChar, char signalType);
};


#endif

Morse EnDecoder.cpp

/*          MORSE ENDECODER

- Morse encoder / decoder classes for the Arduino.

Copyright (C) 2010-2012 raron

GNU GPLv3 license:

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.

Details: http://raronoff.wordpress.com/2010/12/16/morse-endecoder/

#include "MorseEnDecoder.h"


// Morse code binary tree table (dichotomic search table)

// ITU with most punctuation (but without non-english characters - for now)
const int morseTreeLevels = 6; // Minus top level, also the max nr. of morse signals
const int morseTableLength = pow(2,morseTreeLevels+1);
const char morseTable[] PROGMEM =
" ETIANMSURWDKGOHVF*L*PJBXCYZQ!*54*3***2&*+****16=/***(*7***8*90*"
"***********?_****\"**.****@***'**-********;!*)*****,****:*******\0";

morseDecoder::morseDecoder(int decodePin, boolean listenAudio, boolean morsePullup)
{
morseInPin = decodePin;
morseAudio = listenAudio;
activeLow = morsePullup;

if (morseAudio == false)
{
pinMode(morseInPin, INPUT);
if (activeLow) digitalWrite (morseInPin, HIGH);
}

// Some initial values  
wpm = 13;
AudioThreshold = 700;
debounceDelay = 20;
dotTime = 1200 / wpm;       // morse dot time length in ms
dashTime = 3 * 1200 / wpm;
wordSpace = 7 * 1200 / wpm;

morseTablePointer = 0;

morseKeyer = LOW;
morseSignalState = LOW;
lastKeyerState = LOW;

gotLastSig = true;
morseSpace = true;
decodedMorseChar = '\0';

lastDebounceTime = 0;
markTime = 0;
spaceTime = 0;
}


void morseDecoder::setspeed(int value)
{
wpm = value;
if (wpm <= 0) wpm = 1;
dotTime = 1200 / wpm;
dashTime = 3 * 1200 / wpm;
wordSpace = 7 * 1200 / wpm;
}

boolean morseDecoder::available()
{
if (decodedMorseChar) return true; else return false;
}

char morseDecoder::read()
{
char temp = decodedMorseChar;
decodedMorseChar = '\0';
return temp;
}

void morseDecoder::decode()
{
currentTime = millis();

// Read Morse signals
if (morseAudio == false)
{
// Read the Morse keyer (digital)
morseKeyer = digitalRead(morseInPin);
if (activeLow) morseKeyer = !morseKeyer;

// If the switch changed, due to noise or pressing:
if (morseKeyer != lastKeyerState) lastDebounceTime = currentTime; // reset timer

// debounce the morse keyer
if ((currentTime - lastDebounceTime) > debounceDelay)
{
  // whatever the reading is at, it's been there for longer
  // than the debounce delay, so take it as the actual current state:
  morseSignalState = morseKeyer;

  // differentiante mark and space times
  if (morseSignalState) markTime = lastDebounceTime; 
  else spaceTime = lastDebounceTime;
}
} else {
// Read Morse audio signal
audioSignal = analogRead(morseInPin);
if (audioSignal > AudioThreshold)
{
  // If this is a new morse signal, reset morse signal timer
  if (currentTime - lastDebounceTime > dotTime/2)
  {
    markTime = currentTime;
    morseSignalState = true; // there is currently a Morse signal
  }
  lastDebounceTime = currentTime;
} else {
  // if this is a new pause, reset space time
  if (currentTime - lastDebounceTime > dotTime/2 && morseSignalState == true)
  {
    spaceTime = lastDebounceTime; // not too far off from last received audio
    morseSignalState = false;     // No more signal
   }
 }
}


// Decode morse code
if (!morseSignalState)
{
  if (!gotLastSig)
  {
    if (morseTablePointer < morseTableLength/2-1)
    {
    // if pause for more than half a dot, get what kind of signal pulse (dot/dash) received last
    if (currentTime - spaceTime > dotTime/2)
    {
      // if signal for more than 1/4 dotTime, take it as a morse pulse
      if (spaceTime-markTime > dotTime/4)
      {
        morseTablePointer *= 2;  // go one level down the tree
        // if signal for less than half a dash, take it as a dot
        if (spaceTime-markTime < dashTime/2)
        {
           morseTablePointer++; // point to node for a dot
           gotLastSig = true;
        }
        // else if signal for between half a dash and a dash + one dot (1.33 dashes), take as a dash
        else if (spaceTime-markTime < dashTime + dotTime)
        {
           morseTablePointer += 2; // point to node for a dash
           gotLastSig = true;
        }
      }
    }
  } else { // error if too many pulses in one morse character
    //Serial.println("<ERROR: unrecognized signal!>");
    decodedMorseChar = '#'; // error mark
    gotLastSig = true;
    morseTablePointer = 0;
  }
}
// Write out the character if pause is longer than 2/3 dash time (2 dots) and a character received
if ((currentTime-spaceTime >= (dotTime*2)) && (morseTablePointer > 0))
{
  decodedMorseChar = pgm_read_byte_near(morseTable + morseTablePointer);
  morseTablePointer = 0;
}
// Write a space if pause is longer than 2/3rd wordspace
if (currentTime-spaceTime > (wordSpace*2/3) && morseSpace == false)
{
  decodedMorseChar = ' ';
  morseSpace = true ; // space written-flag
}

} else {
// while there is a signal, reset some flags
gotLastSig = false;
morseSpace = false;
}

// Save the morse keyer state for next round
lastKeyerState = morseKeyer;
}

morseEncoder::morseEncoder(int encodePin)
{
  morseOutPin = encodePin;
  this->setup_signal();

// some initial values
sendingMorse = false;
encodeMorseChar = '\0';

wpm = 13;
dotTime = 1200 / wpm;       // morse dot time length in ms
dashTime = 3 * 1200 / wpm;
wordSpace = 7 * 1200 / wpm; 
}

void morseEncoder::setspeed(int value)
{
wpm = value;
if (wpm <= 0) wpm = 1;
dotTime = 1200 / wpm;
dashTime = 3 * 1200 / wpm;
wordSpace = 7 * 1200 / wpm;
}

boolean morseEncoder::available()
{
if (sendingMorse) return false; else return true;
}

void morseEncoder::write(char temp)
{
if (!sendingMorse && temp != '*') encodeMorseChar = temp;
}

void morseEncoder::setup_signal()
{
pinMode(morseOutPin, OUTPUT);
digitalWrite(morseOutPin, LOW);
}

void morseEncoder::start_signal(bool startOfChar, char signalType)
{
digitalWrite(morseOutPin, HIGH);
}

void morseEncoder::stop_signal(bool endOfChar, char signalType)
{
digitalWrite(morseOutPin, LOW);
}

void morseEncoder::encode()
{
currentTime = millis();

if (!sendingMorse && encodeMorseChar)
{
// change to capital letter if not
if (encodeMorseChar > 96) encodeMorseChar -= 32;

// Scan for the character to send in the Morse table
int p;
for (p=0; p<morseTableLength+1; p++) if (pgm_read_byte_near(morseTable + p) == encodeMorseChar) break;

if (p >= morseTableLength) p = 0; // not found, but send a space instead


// Reverse binary tree path tracing
int pNode; // parent node
morseSignals = 0;

// Travel the reverse path from position p to the top of the morse table
if (p > 0)
{
  // build the morse signal (backwards morse signal string from last signal to first)
  pNode = p;
  while (pNode > 0)
  {
    if ( (pNode & 0x0001) == 1)
    {
      // It is a dot
      morseSignalString[morseSignals++] = '.';
    } else {
      // It is a dash
      morseSignalString[morseSignals++] = '-';
    }
    // Find parent node
    pNode = int((pNode-1)/2);
  }
} else { // Top of Morse tree - Add the top space character
  // cheating a little; a wordspace for a "morse signal"
  morseSignalString[morseSignals++] = ' ';
}

morseSignalString[morseSignals] = '\0';


// start sending the the character
sendingMorse = true;
sendingMorseSignalNr = morseSignals; // Sending signal string backwards
sendMorseTimer = currentTime;
if (morseSignalString[0] != ' ') this->start_signal(true, morseSignalString[morseSignals-1]);
}


// Send Morse signals to output
if (sendingMorse)
{
char& currSignalType = morseSignalString[sendingMorseSignalNr-1];
bool endOfChar = sendingMorseSignalNr <= 1;
switch (currSignalType)
{
  case '.': // Send a dot (actually, stop sending a signal after a "dot time")
    if (currentTime - sendMorseTimer >= dotTime)
    {
      this->stop_signal(endOfChar, currSignalType);
      sendMorseTimer = currentTime;
      currSignalType = 'x'; // Mark the signal as sent
    }
    break;
  case '-': // Send a dash (same here, stop sending after a dash worth of time)
    if (currentTime - sendMorseTimer >= dashTime)
    {
      this->stop_signal(endOfChar, currSignalType);
      sendMorseTimer = currentTime;
      currSignalType = 'x'; // Mark the signal as sent
    }
    break;
  case 'x': // To make sure there is a pause between signals
    if (sendingMorseSignalNr > 1)
    {
      // Pause between signals in the same letter
      if (currentTime - sendMorseTimer >= dotTime)
      {
        sendingMorseSignalNr--;
        this->start_signal(false, morseSignalString[sendingMorseSignalNr-1]); // Start sending the next signal
        sendMorseTimer = currentTime;       // reset the timer
      }
    } else {
      // Pause between letters
      if (currentTime - sendMorseTimer >= dashTime)
      {
        sendingMorseSignalNr--;
        sendMorseTimer = currentTime;       // reset the timer
      }
    }
    break;
  case ' ': // Pause between words (minus pause between letters - already sent)
  default:  // Just in case its something else
    if (currentTime - sendMorseTimer > wordSpace - dashTime) sendingMorseSignalNr--;
}
if (sendingMorseSignalNr <= 0 )
{
  // Ready to encode more letters
  sendingMorse = false;
  encodeMorseChar = '\0';
}
}
}

Morse.h

#pragma once
/**
* Generate and send Morse Code on an LED or a speaker. Allow sending
* in a non-blocking manner (by calling a 'continue sending' method
* every so often to turn an LED on/off, or to call tone/noTone appropriately).
*
* All input should be lowercase. Prosigns (SK, KN, etc) have special
* character values #defined.
*/

// for malloc and free, for the new/delete operators
#include <stdlib.h>

// Arduino language types
#if defined(ARDUINO) && ARDUINO >= 100
#include "Arduino.h"
#else
#include "WProgram.h"
#endif

#define WPM_DEFAULT 12.0
// PARIS WPM measurement: 50; CODEX WPM measurement: 60 (Wikipedia:Morse_code)
#define DITS_PER_WORD   50
// Pass to SpeakerMorseSender as carrierFrequency to suppress the carrier.
#define CARRIER_FREQUENCY_NONE  -1

// Bitmasks are 1 for dah and 0 for dit, in left-to-right order;
//  the sequence proper begins after the first 1 (a sentinel).
//  Credit for this scheme to Mark VandeWettering K6HX ( brainwagon.org ).
typedef int             morseTiming_t;
typedef unsigned char   morseBitmask_t; // see also MAX_TIMINGS
#define MORSE_BITMASK_HIGH_BIT  B10000000

// sentinel
#define END             0

// the most timing numbers any unit will need; ex: k = on,off,on,off,on,end = 5
#define MAX_TIMINGS     15

// Punctuation and Prosigns
#define PROSIGN_SK  'S'
#define PROSIGN_KN  'K'
#define PROSIGN_BT  'B'
typedef struct {
char c;
morseBitmask_t timing;
} specialTiming;
const specialTiming MORSE_PUNCT_ETC[] = {
{'.',       B1010101},
{'?',       B1001100},
{PROSIGN_SK,    B1000101},
{PROSIGN_KN,    B110110},
{PROSIGN_BT,    B110001},
{END,       B1},
};

// Morse Code (explicit declaration of letter timings)
const morseBitmask_t MORSE_LETTERS[26] = {
/* a */ B101,
/* b */ B11000,
/* c */ B11010,
/* d */ B1100,
/* e */ B10,
/* f */ B10010,
/* g */ B1110,
/* h */ B10000,
/* i */ B100,
/* j */ B10111,
/* k */ B1101,
/* l */ B10100,
/* m */ B111,
/* n */ B110,
/* o */ B1111,
/* p */ B10110,
/* q */ B11101,
/* r */ B1010,
/* s */ B1000,
/* t */ B11,
/* u */ B1001,
/* v */ B10001,
/* w */ B1011,
/* x */ B11001,
/* y */ B11011,
/* z */ B11100,
};


/**
* Define the logic of converting characters to on/off timing,
* and encapsulate the state of one sending-in-progress Morse message.
*
* Subclasses define setOn and setOff for (for example) LED and speaker output.
*/
class MorseSender {
protected:
const unsigned int pin;
// The setOn and setOff methods would be pure virtual,
// but that has compiler issues.
// See: http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1167672075 .

/**
 * Called to set put the output in 'on' state, during a dit or dah.
 */
virtual void setOn();
virtual void setOff();

/**
 * Called before sending a message. Used for example to enable a
 * carrier. (Noop in the base class.)
 */
virtual void setReady();
virtual void setComplete();

private:
morseTiming_t DIT, DAH;
String message;

// on,off,...,wait,0 list, millis
morseTiming_t timingBuffer[MAX_TIMINGS+1];

// index of the character currently being sent
unsigned int messageIndex;
// timing unit currently being sent
unsigned int timingIndex;

// when this timing unit was started
unsigned long lastChangedMillis;

/**
 * Copy definition timings (on only) to raw timings (on/off).
 * @return the number of 'on' timings copied
 */
int copyTimings(morseTiming_t *rawOut,
    morseBitmask_t definition);

/**
 * Fill a buffer with on,off,..,END timings (millis)
 * @return the index at which to start within the new timing sequence
 */
unsigned int fillTimings(char c);

public:
/**
 * Create a sender which will output to the given pin.
 */
MorseSender(unsigned int outputPin, float wpm=WPM_DEFAULT);

/**
 * To be called during the Arduino setup(); set the pin as OUTPUT.
 */
void setup();

/**
 * Set the words per minute (based on PARIS timing).
 */
void setWPM(float wpm);

/**
 * Set the duration, in milliseconds, of a DIT.
 */
void setSpeed(morseTiming_t duration);

/**
 * Set the message to be sent.
 * This halts any sending in progress.
 */
void setMessage(const String newMessage);

/**
 * Send the entirety of the current message before returning. See the "simple"
 * example, which uses sendBlocking to send one message.
 */
void sendBlocking();

/**
 * Prepare to send and begin sending the current message. After calling this,
 * call continueSending repeatedly until it returns false to finish sending
 * the message. See the "speeds" example, which calls startSending and
 * continueSending on two different senders.
 */
void startSending();

/**
 * Switch outputs on and off (and refill the internal timing buffer)
 * as necessary to continue with the sending of the current message.
 * This should be called every few milliseconds (at a significantly
 * smaller interval than a DIT) to produce a legible fist.
 *
 * @see startSending, which must be called first
 * @return false if sending is complete, otherwise true (keep sending)
 */
boolean continueSending();

void *operator new(size_t size);
void operator delete(void* ptr);
};


/**
* Adapt Morse sending to use the Arduino language tone() and noTone()
* functions, for use with a speaker.
*
* If a carrierFrequency is given, instead of calling noTone, call tone
* with a low frequency. This is useful ex. for maintaining radio links.
*/
class SpeakerMorseSender: public MorseSender {
private:
    unsigned int frequency;
    unsigned int carrFrequency;
protected:
    virtual void setOn();
    virtual void setOff();
    virtual void setReady();
    virtual void setComplete();
public:
    // concert A = 440
    // middle C = 261.626; higher octaves = 523.251, 1046.502
    SpeakerMorseSender(
        int outputPin,
        unsigned int toneFrequency=1046,
        unsigned int carrierFrequency=CARRIER_FREQUENCY_NONE,
        float wpm=WPM_DEFAULT);
};


/**
* Sends Morse on a digital output pin.
*/
class LEDMorseSender: public MorseSender {
protected:
    virtual void setOn();
    virtual void setOff();
public:
    LEDMorseSender(int outputPin, float wpm=WPM_DEFAULT);
};


/**
* Sends Morse on an analog output pin (using PWM). The brightness value is
* between 0 and 255 and is passed directly to analogWrite.
*/
class PWMMorseSender: public MorseSender {
private:
    byte brightness;
protected:
    virtual void setOn();
    virtual void setOff();
public:
    PWMMorseSender(int outputPin, float wpm=WPM_DEFAULT, byte brightness=255);
    void setBrightness(byte brightness);
};

morse.cpp

// Morse Code sending library

#include <morse.h>


// MorseSender
int MorseSender::copyTimings(
morseTiming_t *rawOut,
morseBitmask_t definition)
{
int t = 0;
boolean foundSentinel = false;
for(morseBitmask_t mask = MORSE_BITMASK_HIGH_BIT;
    mask > 0; mask = mask >> 1)
{
    boolean isDah = (mask & definition) > 0;
    if(!foundSentinel)
    {
        if (isDah) { foundSentinel = true; }
        continue;
    }
    rawOut[2*t] = isDah ? DAH : DIT;
    rawOut[2*t + 1] = DIT;
    t++;
}
return t;
}
unsigned int MorseSender::fillTimings(char c)
{
int t = 0;
unsigned int start = 0;
if (c >= 'a' && c <= 'z')
{
    t = copyTimings(timingBuffer, MORSE_LETTERS[c-'a']);
}
else if (c >= '0' && c <= '9')
{
    int n = c - '0';
    boolean ditsFirst = (n <= 5);
    if (!ditsFirst)
    {
        n -= 5;
    }
    while(t < 5)
    {
        timingBuffer[2*t] = ((t < n) == ditsFirst) ? DIT : DAH;
        timingBuffer[2*t + 1] = DIT;
        t++;
    }
}
else
{
    int s = 0;
    while(MORSE_PUNCT_ETC[s].c != END)
    {
        if(MORSE_PUNCT_ETC[s].c == c)
        {
            t = copyTimings(timingBuffer,
                MORSE_PUNCT_ETC[s].timing);
            break;
        }
        s++;
    }
    if (MORSE_PUNCT_ETC[s].c == END)
    {
        start = t = 1; // start on a space
    }
}

timingBuffer[2*t - 1] = DAH;
timingBuffer[2*t] = END;

return start;
}

// see note in header about pure-virtual-ness
void MorseSender::setOn() {};
void MorseSender::setOff() {};

// noop defaults
void MorseSender::setReady() {};
void MorseSender::setComplete() {};

MorseSender::MorseSender(unsigned int outputPin, float wpm) :
pin(outputPin)
{
setWPM(wpm);
}

void MorseSender::setup() { pinMode(pin, OUTPUT); }

void MorseSender::setWPM(float wpm)
{
setSpeed((morseTiming_t)(1000.0*60.0/(max(1.0, wpm)*DITS_PER_WORD)));
}

void MorseSender::setSpeed(morseTiming_t duration)
{
DIT = max(1, duration);
DAH = 3*DIT;
}

void MorseSender::setMessage(const String newMessage)
{
message = newMessage;

// Force startSending() before continueSending().
messageIndex = message.length();

// If a different message was in progress, make sure it stops cleanly.
if (timingIndex % 2 == 0) {
    setOff();
}
}

void MorseSender::sendBlocking()
{
//Serial.println("Sending blocking: ");
//Serial.println(message);
startSending();
while(continueSending());
}

void MorseSender::startSending()
{
messageIndex = 0;
if (message.length() == 0) { return; }
timingIndex = fillTimings(message[0]);
setReady();
if (timingIndex % 2 == 0) {
    setOn();
    //Serial.print("Starting with on, duration=");
} else {
    //Serial.print("Starting with off, duration=");
}
lastChangedMillis = millis();
//Serial.println((int)timingBuffer[timingIndex]);
}

boolean MorseSender::continueSending()
{
if(messageIndex >= message.length()) { return false; }

unsigned long elapsedMillis = millis() - lastChangedMillis;
if (elapsedMillis < timingBuffer[timingIndex]) { return true; }

timingIndex++;
if (timingBuffer[timingIndex] == END)
{
    messageIndex++;
    if(messageIndex >= message.length()) {
        setOff();
        setComplete();
        return false;
    }
    timingIndex = fillTimings(message[messageIndex]);
}

lastChangedMillis += elapsedMillis;
//Serial.print("Next is       ");
if (timingIndex % 2 == 0) {
    //Serial.print("(on) ");
    setOn();
} else {
    //Serial.print("(off) ");
    setOff();
}
//Serial.println((int)timingBuffer[timingIndex]);

return true;
}

void *MorseSender::operator new(size_t size) { return malloc(size); }
void MorseSender::operator delete(void* ptr) { if (ptr) free(ptr); }

// SpeakerMorseSender

void SpeakerMorseSender::setOn() { tone(pin, frequency); }
void SpeakerMorseSender::setOff() {
if (carrFrequency == CARRIER_FREQUENCY_NONE) {
    noTone(pin);
} else {
    tone(pin, carrFrequency);
}
}
void SpeakerMorseSender::setReady() { setOff(); }
void SpeakerMorseSender::setComplete() { noTone(pin); }
SpeakerMorseSender::SpeakerMorseSender(
int outputPin,
unsigned int toneFrequency,
unsigned int carrierFrequency,
float wpm)
: MorseSender(outputPin, wpm),
frequency(toneFrequency),
carrFrequency(carrierFrequency) {};


// LEDMorseSender

void LEDMorseSender::setOn() { digitalWrite(pin, HIGH); }
void LEDMorseSender::setOff() { digitalWrite(pin, LOW); }
LEDMorseSender::LEDMorseSender(int outputPin, float wpm)
: MorseSender(outputPin, wpm) {};


// PWMMorseSender

void PWMMorseSender::setOn() { analogWrite(pin, brightness); }
void PWMMorseSender::setOff() { analogWrite(pin, 0); }
void PWMMorseSender::setBrightness(byte bright) {
brightness = bright;
}
PWMMorseSender::PWMMorseSender(
    int outputPin,
    float wpm,
    byte bright)
: MorseSender(outputPin, wpm), brightness(bright) {};

And finally, here is my code:

#include <avr/pgmspace.h>
#include <MorseEnDecoder.h>
#include <stdio.h>
#include <morse.h>
#define PIN_STATUS  13
#define CPU_RESTART_ADDR (uint32_t *)0xE000ED0C
#define CPU_RESTART_VAL 0x5FA0004
#define CPU_RESTART (*CPU_RESTART_ADDR = CPU_RESTART_VAL);

// Pin mapping
const byte morseInPin = 7;
const byte morseOutPin = 13;
String check = "";
String origin = "SOS";
const int maxItems = 3;
int x;
char myArray[maxItems], curChar;
char nextChar;
int i;
int y;

// Instantiate Morse objects
morseDecoder morseInput(morseInPin, MORSE_KEYER, MORSE_ACTIVE_LOW);
morseEncoder morseOutput(morseOutPin);

// Variables dealing with formatting the output somewhat
// by inserting CR's (carriage returns)
long lastTransmissionTime;
long currentTime;
boolean transmissionEnded = true; // Flag to mark old transmission is finished

// Minimum transmission pause time to insert carriage returns (CR)
// Adjust depending on Morse speed. IE 13 wpm = 646 ms between words (no CR).
const long transmissionPaused   = 1000; // Suitable for 13 wpm?

LEDMorseSender sender(PIN_STATUS);

void setup()
{
  Serial.begin(9600);
  Serial.println("Morse EnDecoder Geocache");

  // Setting Morse speed in wpm - words per minute
  // If not set, 13 wpm is default anyway
  morseInput.setspeed(5);
  morseOutput.setspeed(5);

  lastTransmissionTime = (long)millis();
}

void(* resetFunc) (void) = 0; //declare reset function @ address 0

void loop()
{
  currentTime = (long)millis();

  // Need to call these once per loop
  morseInput.decode();
  morseOutput.encode();

  // RECEIVE MORSE (INPUT)
  // If a character is decoded from the input, write it to serial port
  if (morseInput.available())
  {
    char receivedMorse = morseInput.read();
    Serial.print(receivedMorse);
    // A little error checking
    if (receivedMorse == '#') Serial.println("< ERROR:too many morse signals! >");
    morseOutput.write('#');
    morseOutput.encode();

    //Create Array out of receivedMorse Chars

    curChar = 0;
    nextChar = receivedMorse;
    curChar += nextChar;
    myArray[i] = curChar;
    check.concat(myArray[i]);
    Serial.println(check);

    //Check input and respond
    if (check == origin)      //GOOD JOB!!  Your reward is as follows
    {
      Serial.println("check = origin");
      Serial.println(check);
      sender.setup();
      sender.setWPM(5);
      sender.setMessage(String("help is coming"));
      sender.startSending();
    }
    else if (check == "S") {}
    else if (check == "SO") {}
    else if (check == " SOS") {}
    else if (check.length() > 4)
    {
      delay(100);
      Serial.println("resetting");
      delay(500);
      resetFunc();  //call reset
      delay(100);
    }
    else {}
  }
  sender.continueSending();
}
  • I'm not keen on resetFunc(); //call reset - that doesn't actually reset the chip, you know. It just jumps to the reset vector, that is something else (the hardware is not reset). – Nick Gammon Sep 10 '16 at 1:48
  • if I just try to run it plugged into my computer with the serial monitor not open, nothing happens - without trying to understand all your code, what are you expecting to happen, that doesn't happen, if you don't see the serial output? – Nick Gammon Sep 10 '16 at 1:50
  • I want it to run the code, I'm not trying to sound facetious, but it literally will not run anything unless serial monitor is open. It is supposed to read in and decode morse code input from a button on digital pin 7 then it is supposed to compare this string of morse code with another string and if they match it is supposed to output morse code to the LED. – user26383 Sep 10 '16 at 3:21
  • An idea occurred to me that could be the culprit. The code may be sending the character to the serial monitor after it decodes it (turns button pushes into a character). If this is the case it would not run without the serial monitor, but I have no idea about how to fix this. – user26383 Sep 10 '16 at 3:23
  • Can you please specify the exact board you are using? As a side note, you might want to use a non invasive approach to system debug, like github.com/rlogiacco/MicroDebug. – Roberto Lo Giacco Sep 10 '16 at 11:50
0

It would appear that with this code, the serial.print commands were interfering with the code running as strange as that seems. I was able to delete the offending serial commands and now the code works. With a few tweaks, it should be flawless.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.