-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmorse_sender.ino
163 lines (137 loc) · 5.17 KB
/
morse_sender.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
#define VRX_PIN A0 // Analog read from VRX pin
#define VRY_PIN A1 // Analog read from VRY pin
#define SW_PIN 12 // Digital read from SW pin
#define CURSOR_MAX 1000 // Coordinate values obtained from the joystick will range from 0 to this
#define CURSOR_MARGIN 100 // If cursor is off the considered end by no more than this margin, we consider that it moved
#define LED_PIN_MORSE 2 // Pin for the LED that sends the message
#define LED_PIN_CURSOR 3 // Pin for the navigation LED
#define DIT_TIME 200 // Duration of each Morse code unit. One dit (dot) lasts one.
#define PRESS_TIME 1000 // Time for a button press to be considered
#define POSITION_CHANGE_DELAY 200 // Minimum time between two position changes
/* JOYSTICK COORDINATION */
int xValue = 0; // X axis (Left: 0, Middle: 500, Right: 1000)
int yValue = 0; // Y axis (Top: 0, Middle: 500, Down: 1000)
int swValue = 0; // Whether it's pressed down (1: Up [not pressed], 0: Down [pressed])
bool cursor_led_on = false; // Navigation LED status
/** MORSE CODE CHARACTERS AND COMMANDS
* This table can be navigated with the joystick
* Special strings that code subroutines instead of characters are in CAPS
**/
String codes[5][8] = {
{".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "...."},
{"..", ".---", "-.-", ".-..", "--", "-.", "---", ".--."},
{"--.-", ".-.", "...", "-", "..-", "...-", ".--", "-..-"},
{"-.--", "--..", "-----", ".----", "..---", "...--", "....-", "....."},
{"-....", "--...", "---..", "----.", "/", "ERASE", "CLEAR", "ENTER"}
};
// coordinates where we are in the table
int letter_pos_x = 0;
int letter_pos_y = 0;
// message to be sent, constructed from the various characters
String messageToSend = "";
// index of the last character of the message, to be used for the ERASE subroutine
int last_char_index = 0;
/* FUNCTIONS BEGIN HERE */
void setup() {
pinMode(LED_PIN_MORSE, OUTPUT);
pinMode(LED_PIN_CURSOR, OUTPUT);
Serial.begin(9600);
}
void loop() {
// read analog X and Y analog values and SW digital value, for later processing
xValue = analogRead(VRX_PIN);
yValue = analogRead(VRY_PIN);
swValue = digitalRead(SW_PIN);
// move within the table according to the joystick
// (also inverts the navigation LED)
if(xValue < CURSOR_MARGIN && letter_pos_x > 0){
letter_pos_x--;
invertCursorLED();
Serial.println(codes[letter_pos_y][letter_pos_x]);
}
else if(xValue > CURSOR_MAX - CURSOR_MARGIN && letter_pos_x < 7){
letter_pos_x++;
invertCursorLED();
Serial.println(codes[letter_pos_y][letter_pos_x]);
}
if(yValue < CURSOR_MARGIN && letter_pos_y > 0){
letter_pos_y--;
invertCursorLED();
Serial.println(codes[letter_pos_y][letter_pos_x]);
}
else if(yValue > CURSOR_MAX - CURSOR_MARGIN && letter_pos_y < 4){
letter_pos_y++;
invertCursorLED();
Serial.println(codes[letter_pos_y][letter_pos_x]);
}
if(swValue == 0){ // if joystick is pressed down...
delay(PRESS_TIME); // ...we want to first make sure it wasn't an accident by waiting a bit!
if(digitalRead(SW_PIN) == 0){ // now yes
String character = codes[letter_pos_y][letter_pos_x]; // extract from table @ the cursed position of (y,x)
// Erase last character, if there is one
if(character == "ERASE"){
if((last_char_index = messageToSend.length() - 1) != -1){
while(messageToSend[last_char_index] != ' ' && last_char_index != 0){
last_char_index--;
}
messageToSend.remove(last_char_index);
Serial.println(messageToSend);
}
}
// Clear message
else if(character == "CLEAR"){
messageToSend = "";
Serial.println(messageToSend);
}
// Send message (and don't clear since we might want to repeat it)
else if(character == "ENTER"){
blink_morse(messageToSend);
}
// Or add more to the message, with an extra space before any new character
else{
if(messageToSend != "")
messageToSend += " ";
messageToSend += character;
Serial.println(messageToSend);
}
}
}
delay(POSITION_CHANGE_DELAY);
}
/* SWITCH THE NAVIGATION LED */
void invertCursorLED() {
if(cursor_led_on)
digitalWrite(LED_PIN_CURSOR, LOW);
else
digitalWrite(LED_PIN_CURSOR, HIGH);
cursor_led_on = !cursor_led_on;
Serial.println(cursor_led_on);
}
/** EXECUTE THE MESSAGE
* Number of units:
* Dot: 1
* Dash: 3
* Interval in letter: 1
* Interval between letters in word: 3
* Interval between words: 7
*/
void blink_morse(String message) {
for(int i = 0; i < message.length(); i++){
if(message[i] == '.'){
blink(DIT_TIME);
}
else if(message[i] == '-'){
blink(3*DIT_TIME);
}
else if(message[i] == '/' || message[i] == ' '){
delay(2*DIT_TIME);
}
}
}
/* INDIVIDUAL BLINK */
void blink(int time) {
digitalWrite(LED_PIN_MORSE, HIGH);
delay(time);
digitalWrite(LED_PIN_MORSE, LOW);
delay(DIT_TIME);
}