ChrisRowland
Active member
Hi,
I'm trying to write a morse keyer using a Teensy LC.
I'm using Snooze.sleep to reduce the current consumption while waiting for a key to be pressed.
The key press and release events are detected in ISRs.
This is all fine using a spin loop to wait for a key change event but if I use Snooze.sleep it works most of the time but not always. Sometimes it recovers but eventually it gets into a state where neither of the wake up events are seen.
This is the code. cut down to a minimum
Does anyone have any suggestions for finding out what's going wrong. I've tried using AttachInterrupt after the exit from Snooze and it didn't seem to help.
I know this trivial example doesn't need the key events in an ISR but the full code does.
Thanks,
Chris
I'm trying to write a morse keyer using a Teensy LC.
I'm using Snooze.sleep to reduce the current consumption while waiting for a key to be pressed.
The key press and release events are detected in ISRs.
This is all fine using a spin loop to wait for a key change event but if I use Snooze.sleep it works most of the time but not always. Sometimes it recovers but eventually it gets into a state where neither of the wake up events are seen.
This is the code. cut down to a minimum
Code:
// snooze with interrupt test
#define USE_SNOOZE
#ifdef USE_SNOOZE
#include <Snooze.h>
#endif
#define DIT_PIN 8
#define TIP_SW_PIN 9
#define COM_PIN 10
#define RING_SW_PIN 10
#define DAH_PIN 12
#define LED_PIN 13
#define TONE_PIN 17
#ifdef USE_SNOOZE
//load snooze drivers
SnoozeDigital digital;
Snoozelc5vBuffer lc5vBuffer;
// and the snooze block, with the drivers?
SnoozeBlock config_teensyLC(lc5vBuffer, digital);
#endif
// used to detect the dit and dah switches
volatile bool ditDown, dahDown, change;
int dotLen = 60;
void setup()
{
pinMode(DIT_PIN, INPUT_PULLUP);
pinMode(DAH_PIN, INPUT_PULLUP);
pinMode(COM_PIN, INPUT); // connected to ground
pinMode(TIP_SW_PIN, INPUT); // unused
pinMode(RING_SW_PIN, INPUT); // unused
pinMode(LED_PIN, OUTPUT);
pinMode(TONE_PIN, OUTPUT);
digitalWrite(LED_PIN, HIGH);
sender(1);
ditDown = dahDown = change = false;
// set up normal interrupts
attachInterrupt(digitalPinToInterrupt(DIT_PIN), ditEvent, CHANGE);
attachInterrupt(digitalPinToInterrupt(DAH_PIN), dahEvent, CHANGE);
sender(2);
#ifdef USE_SNOOZE
// set up snooze interrupt/wakeup input pins
digital.pinMode(DIT_PIN, INPUT_PULLUP, CHANGE);
digital.pinMode(DAH_PIN, INPUT_PULLUP, CHANGE);
#endif
sender(3);
}
void loop()
{
int who = 0;
// go to sleep, wake on a pin change
digitalWrite(LED_PIN, LOW);
#ifdef USE_SNOOZE
who = Snooze.sleep(config_teensyLC ); // return module that woke processor
if (who == DIT_PIN)
{
noInterrupts();
ditDown = !digitalRead(DIT_PIN);
interrupts();
}
if (who == DAH_PIN)
{
noInterrupts();
dahDown = !digitalRead(DAH_PIN);
interrupts();
}
#else
change = false;
while(!change);
#endif
digitalWrite(LED_PIN, HIGH);
// we stay in this loop while a key is on
while (ditDown || dahDown)
{
if (ditDown)
{
sender(1); //MorseSymbol.Dit);
}
if (dahDown)
{
sender(3); //(MorseSymbol.Dah);
}
}
}
void sender(int dots)
{
tone(TONE_PIN, 800);
delay(dotLen * dots);
noTone(TONE_PIN);
delay(dotLen);
}
// paddle Pine interrupts
void dahEvent()
{
dahDown = !digitalRead(DAH_PIN);
change = true;
}
void ditEvent()
{
ditDown = !digitalRead(DIT_PIN);
change = true;
}
Does anyone have any suggestions for finding out what's going wrong. I've tried using AttachInterrupt after the exit from Snooze and it didn't seem to help.
I know this trivial example doesn't need the key events in an ISR but the full code does.
Thanks,
Chris