Compare commits
2 Commits
012ee5ae31
...
a6eaae4da1
Author | SHA1 | Date |
---|---|---|
Neale Pickett | a6eaae4da1 | |
Neale Pickett | d8a615813e |
14
adapter.cpp
14
adapter.cpp
|
@ -16,7 +16,7 @@ VailAdapter::VailAdapter(unsigned int PiezoPin) {
|
||||||
|
|
||||||
// Send a MIDI Key Event
|
// Send a MIDI Key Event
|
||||||
void VailAdapter::midiKey(uint8_t key, bool down) {
|
void VailAdapter::midiKey(uint8_t key, bool down) {
|
||||||
midiEventPacket_t event = {down?9:8, down?0x90:0x80, key, 0x7f};
|
midiEventPacket_t event = {uint8_t(down?9:8), uint8_t(down?0x90:0x80), key, 0x7f};
|
||||||
MidiUSB.sendMIDI(event);
|
MidiUSB.sendMIDI(event);
|
||||||
MidiUSB.flush();
|
MidiUSB.flush();
|
||||||
}
|
}
|
||||||
|
@ -97,10 +97,16 @@ void VailAdapter::HandleMIDI(midiEventPacket_t event) {
|
||||||
break;
|
break;
|
||||||
case 1: // set dit duration (0-254) *2ms
|
case 1: // set dit duration (0-254) *2ms
|
||||||
this->ditDuration = event.byte3 * 2 * MILLISECOND;
|
this->ditDuration = event.byte3 * 2 * MILLISECOND;
|
||||||
|
if (this->keyer) {
|
||||||
|
this->keyer->SetDitDuration(this->ditDuration);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0xC0: // Program Change
|
case 0xC0: // Program Change
|
||||||
|
if (this->keyer) {
|
||||||
|
this->keyer->Release();
|
||||||
|
}
|
||||||
this->keyer = GetKeyerByNumber(event.byte2, this);
|
this->keyer = GetKeyerByNumber(event.byte2, this);
|
||||||
break;
|
break;
|
||||||
case 0x80: // Note off
|
case 0x80: // Note off
|
||||||
|
@ -111,3 +117,9 @@ void VailAdapter::HandleMIDI(midiEventPacket_t event) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VailAdapter::Tick(unsigned millis) {
|
||||||
|
if (this->keyer) {
|
||||||
|
this->keyer->Tick(millis);
|
||||||
|
}
|
||||||
|
}
|
|
@ -22,4 +22,5 @@ public:
|
||||||
void HandleMIDI(midiEventPacket_t event);
|
void HandleMIDI(midiEventPacket_t event);
|
||||||
void BeginTx();
|
void BeginTx();
|
||||||
void EndTx();
|
void EndTx();
|
||||||
|
void Tick(unsigned millis);
|
||||||
};
|
};
|
||||||
|
|
174
keyers.cpp
174
keyers.cpp
|
@ -35,7 +35,7 @@ public:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (int i = 0; i < arrlen; i++) {
|
for (int i = 0; i < arrlen; i++) {
|
||||||
if (arr[arrlen] == i) {
|
if (arr[arrlen] == val) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -51,21 +51,28 @@ public:
|
||||||
unsigned int ditDuration;
|
unsigned int ditDuration;
|
||||||
bool txRelays[2];
|
bool txRelays[2];
|
||||||
|
|
||||||
StraightKeyer(Transmitter *output) {
|
StraightKeyer() {
|
||||||
this->output = output;
|
|
||||||
this->ditDuration = 100;
|
|
||||||
this->Reset();
|
this->Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SetOutput(Transmitter *output) {
|
||||||
|
this->output = output;
|
||||||
|
}
|
||||||
|
|
||||||
void Reset() {
|
void Reset() {
|
||||||
|
if (this->output) {
|
||||||
this->output->EndTx();
|
this->output->EndTx();
|
||||||
}
|
}
|
||||||
|
this->ditDuration = 100;
|
||||||
|
}
|
||||||
|
|
||||||
void SetDitDuration(int duration) {
|
void SetDitDuration(int duration) {
|
||||||
this->ditDuration = duration;
|
this->ditDuration = duration;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Release() {}
|
void Release() {
|
||||||
|
this->Reset();
|
||||||
|
}
|
||||||
|
|
||||||
bool TxClosed() {
|
bool TxClosed() {
|
||||||
for (int i = 0; i < len(this->txRelays); i++) {
|
for (int i = 0; i < len(this->txRelays); i++) {
|
||||||
|
@ -103,14 +110,14 @@ public:
|
||||||
|
|
||||||
class BugKeyer: public StraightKeyer {
|
class BugKeyer: public StraightKeyer {
|
||||||
public:
|
public:
|
||||||
unsigned int pulseTime = 0;
|
unsigned int nextPulse = 0;
|
||||||
bool keyPressed[2];
|
bool keyPressed[2];
|
||||||
|
|
||||||
using StraightKeyer::StraightKeyer;
|
using StraightKeyer::StraightKeyer;
|
||||||
|
|
||||||
void Reset() {
|
void Reset() {
|
||||||
StraightKeyer::Reset();
|
StraightKeyer::Reset();
|
||||||
this->pulseTime = 0;
|
this->nextPulse = 0;
|
||||||
this->keyPressed[0] = false;
|
this->keyPressed[0] = false;
|
||||||
this->keyPressed[1] = false;
|
this->keyPressed[1] = false;
|
||||||
}
|
}
|
||||||
|
@ -124,26 +131,28 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void beginPulsing() {
|
void Tick(unsigned int millis) {
|
||||||
this->pulseTime = 1;
|
if (this->nextPulse && (millis >= this->nextPulse)) {
|
||||||
|
this->pulse(millis);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void pulse(unsigned int millis) {
|
void beginPulsing() {
|
||||||
|
if (!this->nextPulse) {
|
||||||
|
this->nextPulse = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void pulse(unsigned int millis) {
|
||||||
if (this->TxClosed(0)) {
|
if (this->TxClosed(0)) {
|
||||||
this->Tx(0, false);
|
this->Tx(0, false);
|
||||||
} else if (this->keyPressed[0]) {
|
} else if (this->keyPressed[0]) {
|
||||||
this->Tx(0, true);
|
this->Tx(0, true);
|
||||||
} else {
|
} else {
|
||||||
this->pulseTime = 0;
|
this->nextPulse = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this->pulseTime = millis + this->ditDuration;
|
this->nextPulse = millis + this->ditDuration;
|
||||||
}
|
|
||||||
|
|
||||||
void Tick(unsigned int millis) {
|
|
||||||
if (this->pulseTime && (millis >= this->pulseTime)) {
|
|
||||||
this->pulse(millis);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -172,34 +181,34 @@ public:
|
||||||
this->keyPressed[key] = pressed;
|
this->keyPressed[key] = pressed;
|
||||||
if (pressed) {
|
if (pressed) {
|
||||||
this->nextRepeat = key;
|
this->nextRepeat = key;
|
||||||
|
this->beginPulsing();
|
||||||
} else {
|
} else {
|
||||||
this->nextRepeat = this->whichKeyPressed();
|
this->nextRepeat = this->whichKeyPressed();
|
||||||
}
|
}
|
||||||
this->beginPulsing();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int keyDuration(int key) {
|
unsigned int keyDuration(int key) {
|
||||||
switch (key) {
|
switch (key) {
|
||||||
case 0:
|
case PADDLE_DIT:
|
||||||
return this->ditDuration;
|
return this->ditDuration;
|
||||||
case 1:
|
case PADDLE_DAH:
|
||||||
return 3 * this->ditDuration;
|
return 3 * (this->ditDuration);
|
||||||
}
|
}
|
||||||
return 0;
|
return this->ditDuration; // XXX
|
||||||
}
|
}
|
||||||
|
|
||||||
int nextTx() {
|
virtual int nextTx() {
|
||||||
if (this->whichKeyPressed() == -1) {
|
if (this->whichKeyPressed() == -1) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return this->nextRepeat;
|
return this->nextRepeat;
|
||||||
}
|
}
|
||||||
|
|
||||||
void pulse(unsigned int millis) {
|
virtual void pulse(unsigned int millis) {
|
||||||
int nextPulse = 0;
|
int nextPulse = 0;
|
||||||
if (this->TxClosed(0)) {
|
if (this->TxClosed(0)) {
|
||||||
// Pause if we're currently transmitting
|
// Pause if we're currently transmitting
|
||||||
nextPulse = this->ditDuration;
|
nextPulse = this->keyDuration(PADDLE_DIT);
|
||||||
this->Tx(0, false);
|
this->Tx(0, false);
|
||||||
} else {
|
} else {
|
||||||
int next = this->nextTx();
|
int next = this->nextTx();
|
||||||
|
@ -210,33 +219,28 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nextPulse) {
|
if (nextPulse) {
|
||||||
this->pulseTime = millis + nextPulse;
|
this->nextPulse = millis + nextPulse;
|
||||||
} else {
|
} else {
|
||||||
this->pulseTime = 0;
|
this->nextPulse = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class UltimaticKeyer: public ElBugKeyer {
|
class UltimaticKeyer: public ElBugKeyer {
|
||||||
public:
|
public:
|
||||||
QSet *queue;
|
QSet queue;
|
||||||
|
|
||||||
using ElBugKeyer::ElBugKeyer;
|
using ElBugKeyer::ElBugKeyer;
|
||||||
|
|
||||||
void Reset() {
|
|
||||||
ElBugKeyer::Reset();
|
|
||||||
this->queue = new QSet();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Key(Paddle key, bool pressed) {
|
void Key(Paddle key, bool pressed) {
|
||||||
if (pressed) {
|
if (pressed) {
|
||||||
this->queue->add(key);
|
this->queue.add(key);
|
||||||
}
|
}
|
||||||
ElBugKeyer::Key(key, pressed);
|
ElBugKeyer::Key(key, pressed);
|
||||||
}
|
}
|
||||||
|
|
||||||
int nextTx() {
|
virtual int nextTx() {
|
||||||
int key = this->queue->shift();
|
int key = this->queue.shift();
|
||||||
if (key != -1) {
|
if (key != -1) {
|
||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
|
@ -246,24 +250,19 @@ public:
|
||||||
|
|
||||||
class SingleDotKeyer: public ElBugKeyer {
|
class SingleDotKeyer: public ElBugKeyer {
|
||||||
public:
|
public:
|
||||||
QSet *queue;
|
QSet queue;
|
||||||
|
|
||||||
using ElBugKeyer::ElBugKeyer;
|
using ElBugKeyer::ElBugKeyer;
|
||||||
|
|
||||||
void Reset() {
|
|
||||||
ElBugKeyer::Reset();
|
|
||||||
this->queue = new QSet();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Key(Paddle key, bool pressed) {
|
void Key(Paddle key, bool pressed) {
|
||||||
if (pressed && (key == 0)) {
|
if (pressed && (key == PADDLE_DIT)) {
|
||||||
this->queue->add(key);
|
this->queue.add(key);
|
||||||
}
|
}
|
||||||
ElBugKeyer::Key(key, pressed);
|
ElBugKeyer::Key(key, pressed);
|
||||||
}
|
}
|
||||||
|
|
||||||
int nextTx() {
|
virtual int nextTx() {
|
||||||
int key = this->queue->shift();
|
int key = this->queue.shift();
|
||||||
if (key != -1) {
|
if (key != -1) {
|
||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
|
@ -278,9 +277,9 @@ public:
|
||||||
|
|
||||||
using ElBugKeyer::ElBugKeyer;
|
using ElBugKeyer::ElBugKeyer;
|
||||||
|
|
||||||
int nextTx() {
|
virtual int nextTx() {
|
||||||
int next = ElBugKeyer::nextTx();
|
int next = ElBugKeyer::nextTx();
|
||||||
if (this->whichKeyPressed() != -1) {
|
if (this->keyPressed[PADDLE_DIT] && this->keyPressed[PADDLE_DAH]) {
|
||||||
this->nextRepeat = 1 - this->nextRepeat;
|
this->nextRepeat = 1 - this->nextRepeat;
|
||||||
}
|
}
|
||||||
return next;
|
return next;
|
||||||
|
@ -289,25 +288,20 @@ public:
|
||||||
|
|
||||||
class IambicAKeyer: public IambicKeyer {
|
class IambicAKeyer: public IambicKeyer {
|
||||||
public:
|
public:
|
||||||
QSet *queue;
|
QSet queue;
|
||||||
|
|
||||||
using IambicKeyer::IambicKeyer;
|
using IambicKeyer::IambicKeyer;
|
||||||
|
|
||||||
void Reset() {
|
|
||||||
IambicKeyer::Reset();
|
|
||||||
this->queue = new QSet();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Key(Paddle key, bool pressed) {
|
void Key(Paddle key, bool pressed) {
|
||||||
if (pressed && (key == 0)) {
|
if (pressed && (key == PADDLE_DIT)) {
|
||||||
this->queue->add(key);
|
this->queue.add(key);
|
||||||
}
|
}
|
||||||
IambicKeyer::Key(key, pressed);
|
IambicKeyer::Key(key, pressed);
|
||||||
}
|
}
|
||||||
|
|
||||||
int nextTx() {
|
virtual int nextTx() {
|
||||||
int next = IambicKeyer::nextTx();
|
int next = IambicKeyer::nextTx();
|
||||||
int key = this->queue->shift();
|
int key = this->queue.shift();
|
||||||
if (key != -1) {
|
if (key != -1) {
|
||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
|
@ -317,30 +311,29 @@ public:
|
||||||
|
|
||||||
class IambicBKeyer: public IambicKeyer {
|
class IambicBKeyer: public IambicKeyer {
|
||||||
public:
|
public:
|
||||||
QSet *queue;
|
QSet queue;
|
||||||
|
|
||||||
using IambicKeyer::IambicKeyer;
|
using IambicKeyer::IambicKeyer;
|
||||||
|
|
||||||
void Reset() {
|
void Reset() {
|
||||||
IambicKeyer::Reset();
|
IambicKeyer::Reset();
|
||||||
this->queue = new QSet();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Key(Paddle key, bool pressed) {
|
void Key(Paddle key, bool pressed) {
|
||||||
if (pressed) {
|
if (pressed) {
|
||||||
this->queue->add(key);
|
this->queue.add(key);
|
||||||
}
|
}
|
||||||
IambicKeyer::Key(key, pressed);
|
IambicKeyer::Key(key, pressed);
|
||||||
}
|
}
|
||||||
|
|
||||||
int nextTx() {
|
virtual int nextTx() {
|
||||||
for (int key = 0; key < 2; key++) {
|
for (int key = 0; key < len(this->keyPressed); key++) {
|
||||||
if (this->keyPressed[key]) {
|
if (this->keyPressed[key]) {
|
||||||
this->queue->add(key);
|
this->queue.add(key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return this->queue->shift();
|
return this->queue.shift();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -365,7 +358,7 @@ public:
|
||||||
ElBugKeyer::Key(key, pressed);
|
ElBugKeyer::Key(key, pressed);
|
||||||
}
|
}
|
||||||
|
|
||||||
int nextTx() {
|
virtual int nextTx() {
|
||||||
if (this->qlen > 0) {
|
if (this->qlen > 0) {
|
||||||
int next = this->queue[0];
|
int next = this->queue[0];
|
||||||
this->qlen--;
|
this->qlen--;
|
||||||
|
@ -378,27 +371,34 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
StraightKeyer straightKeyer = StraightKeyer();
|
||||||
|
BugKeyer bugKeyer = BugKeyer();
|
||||||
|
ElBugKeyer elBugKeyer = ElBugKeyer();
|
||||||
|
SingleDotKeyer singleDotKeyer = SingleDotKeyer();
|
||||||
|
UltimaticKeyer ultimaticKeyer = UltimaticKeyer();
|
||||||
|
IambicKeyer iambicKeyer = IambicKeyer();
|
||||||
|
IambicAKeyer iambicAKeyer = IambicAKeyer();
|
||||||
|
IambicBKeyer iambicBKeyer = IambicBKeyer();
|
||||||
|
KeyaheadKeyer keyaheadKeyer = KeyaheadKeyer();
|
||||||
|
|
||||||
|
Keyer *keyers[] = {
|
||||||
|
&straightKeyer,
|
||||||
|
&bugKeyer,
|
||||||
|
&elBugKeyer,
|
||||||
|
&singleDotKeyer,
|
||||||
|
&ultimaticKeyer,
|
||||||
|
&iambicKeyer,
|
||||||
|
&iambicAKeyer,
|
||||||
|
&iambicBKeyer,
|
||||||
|
&keyaheadKeyer,
|
||||||
|
};
|
||||||
|
|
||||||
Keyer *GetKeyerByNumber(int n, Transmitter *output) {
|
Keyer *GetKeyerByNumber(int n, Transmitter *output) {
|
||||||
switch (n) {
|
if (n >= len(keyers)) {
|
||||||
case 1:
|
|
||||||
return new StraightKeyer(output);
|
|
||||||
case 2:
|
|
||||||
return new BugKeyer(output);
|
|
||||||
case 3:
|
|
||||||
return new ElBugKeyer(output);
|
|
||||||
case 4:
|
|
||||||
return new SingleDotKeyer(output);
|
|
||||||
case 5:
|
|
||||||
return new UltimaticKeyer(output);
|
|
||||||
case 6:
|
|
||||||
return new IambicKeyer(output);
|
|
||||||
case 7:
|
|
||||||
return new IambicAKeyer(output);
|
|
||||||
case 8:
|
|
||||||
return new IambicBKeyer(output);
|
|
||||||
case 9:
|
|
||||||
return new KeyaheadKeyer(output);
|
|
||||||
default:
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Keyer *k = keyers[n];
|
||||||
|
k->SetOutput(output);
|
||||||
|
return k;
|
||||||
}
|
}
|
||||||
|
|
3
keyers.h
3
keyers.h
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
PADDLE_DIT = 0,
|
PADDLE_DIT = 0,
|
||||||
PADDLE_DAH,
|
PADDLE_DAH = 1,
|
||||||
PADDLE_STRAIGHT,
|
PADDLE_STRAIGHT,
|
||||||
} Paddle;
|
} Paddle;
|
||||||
|
|
||||||
|
@ -16,6 +16,7 @@ public:
|
||||||
|
|
||||||
class Keyer {
|
class Keyer {
|
||||||
public:
|
public:
|
||||||
|
virtual void SetOutput(Transmitter *output);
|
||||||
virtual void Reset();
|
virtual void Reset();
|
||||||
virtual void SetDitDuration(int d);
|
virtual void SetDitDuration(int d);
|
||||||
virtual void Release();
|
virtual void Release();
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
#include "touchbounce.h"
|
#include "touchbounce.h"
|
||||||
|
|
||||||
void TouchBounce::attach(int pin) {
|
void TouchBounce::attach(int pin) {
|
||||||
this->qt = Adafruit_FreeTouch(pin);
|
this->qt = Adafruit_FreeTouch(pin, OVERSAMPLE_2, RESISTOR_50K, FREQ_MODE_NONE);
|
||||||
this->qt.begin();
|
this->qt.begin();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TouchBounce::readCurrentState() {
|
bool TouchBounce::readCurrentState() {
|
||||||
int val = this->qt.measure();
|
int val = this->qt.measure();
|
||||||
return val < QT_THRESHOLD;
|
return val > QT_THRESHOLD/2;
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,8 +87,11 @@ void setLED() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void loop() {
|
void loop() {
|
||||||
|
unsigned now = millis();
|
||||||
midiEventPacket_t event = MidiUSB.read();
|
midiEventPacket_t event = MidiUSB.read();
|
||||||
|
|
||||||
setLED();
|
setLED();
|
||||||
|
adapter.Tick(now);
|
||||||
|
|
||||||
if (event.header) {
|
if (event.header) {
|
||||||
adapter.HandleMIDI(event);
|
adapter.HandleMIDI(event);
|
||||||
|
@ -96,7 +99,7 @@ void loop() {
|
||||||
|
|
||||||
// Monitor straight key pin
|
// Monitor straight key pin
|
||||||
if (key.update() || qt_key.update()) {
|
if (key.update() || qt_key.update()) {
|
||||||
bool pressed = key.read() || qt_key.read();
|
bool pressed = !key.read() || qt_key.read();
|
||||||
adapter.HandlePaddle(PADDLE_STRAIGHT, pressed);
|
adapter.HandlePaddle(PADDLE_STRAIGHT, pressed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,12 +110,12 @@ void loop() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dit.update() || qt_dit.update()) {
|
if (dit.update() || qt_dit.update()) {
|
||||||
bool pressed = dit.read() || qt_dit.read();
|
bool pressed = !dit.read() || qt_dit.read();
|
||||||
adapter.HandlePaddle(PADDLE_DIT, pressed);
|
adapter.HandlePaddle(PADDLE_DIT, pressed);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dah.update() || qt_dah.update()) {
|
if (dah.update() || qt_dah.update()) {
|
||||||
bool pressed = dah.read() | qt_dah.read();
|
bool pressed = !dah.read() || qt_dah.read();
|
||||||
adapter.HandlePaddle(PADDLE_DAH, pressed);
|
adapter.HandlePaddle(PADDLE_DAH, pressed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue