-
Notifications
You must be signed in to change notification settings - Fork 0
/
ArduinoPuffSuckMorser.ino
292 lines (264 loc) · 6.5 KB
/
ArduinoPuffSuckMorser.ino
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
/*
Based on tutorial at http://mypetarduino.com/ReadCode/readCode.01.html
WB7FHC's Morse Code Decoder v. 1.1 (c) 2014, Budd Churchward - WB7FHC This is an Open Source Project http://opensource.org/licenses/MIT
Search YouTube for 'WB7FHC' to see several videos of this project as it was developed.
and https://vk8da.com/an-arduino-iambic-keyer/, which further gives credit to http://www.jel.gr/cw-mode/iambic-keyer-with-arduino-in-5-minutes/
(looks like a dead page).
No licenses found for the latter 2, please inform me if you find one!
*/
// Iambic keyer
#define DIT_PIN 8
#define DAH_PIN 10
#define LED 13
#define SPEAKER 11
// keyer state
enum
{
IDLE,
DIT,
DAH,
};
int dit, dah;
int state;
/* The way we are translating morse code is we have a start bit (1) and for each dot, we shift
* our number left. For each dash, we add one and shift our number left. The seemingly random
* letterset array has the corresponding letters.
*/
char LetterSet[] = "##TEMNAIOGKDWRUS##QZYCXBJP#L#FVH09#8###7#####\\=61####+##2###3#45";
// baud settings
#define BAUD_DURATION 120 //mSec default
#define TOUCH_THRESHOLD 0 //how long to wait in uSec, before sampling the touch pin.
#define interbaud_duration BAUD_DURATION * 1 //wait between dots and dashes
#define dit_duration BAUD_DURATION * 1 //length of a dot
#define dah_duration BAUD_DURATION * 3 //length of a dash
#define NearLineEnd 60 //number of characters before sending newline (to make serial easier to read)
//waits
#define FullWait BAUD_DURATION * 1 //Length between characters
#define WordWait BAUD_DURATION * 4 //Length between words
int WaitWait = FullWait; //Character counter
boolean characterDone = true;
int letterCount = 0; //Line end counter
uint8_t downtime = 0; //Counts a dit or a dah
int ShiftNum = 0; //Number to be shifted and added to depending on dits or dahs
int NewWord = WordWait; //Word counter
void readDit() //Checks if there's a dit
{
delayMicroseconds(TOUCH_THRESHOLD);
if (digitalRead(DIT_PIN))
{
dit = 1;
}
else
{
dit = 0;
}
}
void readDah() //Checks if there's a dah
{
delayMicroseconds(TOUCH_THRESHOLD);
if (digitalRead(DAH_PIN))
{
dah = 1;
}
else
{
dah = 0;
}
}
void setup()
{
// setup input pins
pinMode(DIT_PIN, INPUT);
pinMode(DAH_PIN, INPUT);
// setup output pins
pinMode(LED, OUTPUT);
digitalWrite(LED, LOW); //turn off led
Serial.begin(9600);
state = IDLE;
}
// handles the output of the ciruit.
// if state is 1 then the contact is closed or led is turned on
void contact(unsigned char state)
{
if (state)
{
digitalWrite(LED, HIGH);
tone(SPEAKER, 650);
}
else
{
digitalWrite(LED, LOW);
noTone(SPEAKER);
}
}
void loop()
{
if (state == IDLE) //If nothing is being pressed
{
if (NewWord > 0)
NewWord--; //Deplete new word counter
if (NewWord == 1)
printSpace(); //Print space if the counter is done (word over)
// now, if dit is pressed go there, else check for dah
readDit();
if (dit)
{
state = DIT;
}
else
{
readDah();
if (dah)
{
state = DAH;
}
}
if (!characterDone)
{
WaitWait--; //Count down the character counter
if (WaitWait == 0) //Character is done
{
printCharacter(); //Print it
characterDone = true; //The character is done
ShiftNum = 0; //Reset the shifting number
}
}
}
else if (state == DIT)
{
WaitWait = FullWait; //Reset the counters
NewWord = WordWait;
characterDone = false;
contact(1);
delay(dit_duration);
contact(0);
delay(interbaud_duration);
downtime++;
if (ShiftNum == 0)
{
ShiftNum = 1; // This is our start bit
}
shiftBits();
// now, if dah is pressed go there, else check for dit
readDah();
if (dah)
{
state = DAH;
}
else
{
// read dit now
readDit();
if (dit)
{
state = DIT;
}
else
{
delay(interbaud_duration);
state = IDLE;
}
}
}
else if (state == DAH)
{
WaitWait = FullWait; //Reset counters
NewWord = WordWait;
characterDone = false;
contact(1);
delay(dah_duration);
contact(0);
delay(interbaud_duration);
downtime += 3;
if (ShiftNum == 0)
{
ShiftNum = 1; // This is our start bit
}
shiftBits();
// now, if dit is pressed go there, else check for dah
readDit();
if (dit)
{
state = DIT;
}
else
{
//read dit now
readDah();
if (dah)
{
state = DAH;
}
else
{
delay(interbaud_duration);
state = IDLE;
}
}
}
delay(1);
}
void printSpace()
{
letterCount++;
if (letterCount > NearLineEnd)
{
Serial.println(); //Print newline if we're over 60 characters on the current line
letterCount = 0;
return; // Go back to loop(), we're done here.
}
Serial.print(' ');
}
void shiftBits()
{
//Serial.println('m');
if (downtime == 1)
{
ShiftNum = ShiftNum << 1; // shift bits left
ShiftNum++; //Add one
}
else if (downtime == 3)
{
// We got a dah
ShiftNum = ShiftNum << 1; // shift bits left
}
downtime = 0;
}
void printCharacter()
{
NewWord = WordWait;
letterCount++;
if (ShiftNum > 63) //Not in the array
{
printPunctuation();
return; // Go back to the main loop(), we're done here.
}
Serial.print(LetterSet[ShiftNum]);
}
void printPunctuation()
{
char pMark = '#'; // Just in case nothing matches
if (ShiftNum == 71)
pMark = ':';
else if (ShiftNum == 76)
pMark = ',';
else if (ShiftNum == 85)
pMark = ';';
else if (ShiftNum == 84)
pMark = '!';
else if (ShiftNum == 94)
pMark = '-';
else if (ShiftNum == 97)
pMark = '\'';
else if (ShiftNum == 101)
pMark = '@';
else if (ShiftNum == 106)
pMark = '.';
else if (ShiftNum == 109)
pMark = '"';
else if (ShiftNum == 114)
pMark = '_';
else if (ShiftNum == 115)
pMark = '?';
Serial.print(pMark);
}