Eck-Eck/src/main.cpp
2025-01-19 16:54:25 -05:00

200 lines
4.4 KiB
C++

// Copyright 2025 Elizabeth Cray
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <Arduino.h>
#include <EEPROM.h>
#include <ctype.h>
#include "cw.h"
/* TODO:
* - Implement sending strings
* - Add OLED Support
*/
boolean debug = true;
uint8_t input_dit = 3, input_dah = 6, input_pot = A6;
uint8_t output = 7;
uint16_t dit = 200, dah = 500;
uint8_t debounce = 50;
uint16_t p_tol = 30, p_min = 50, p_max = 2000, p_buf = 0, p_cache = 0;
String serial_buffer = "";
char buf;
void key_string(String);
void adjust_length(uint16_t);
void set_length(uint16_t, uint16_t);
void send(bool);
void process_input(String);
void log(String);
void setup() {
Serial.begin(115200);
log("Set PinModes\n");
pinMode(input_dit, INPUT_PULLUP);
pinMode(input_dah, INPUT_PULLUP);
pinMode(input_pot, INPUT);
pinMode(output, OUTPUT);
digitalWrite(output, LOW);
log("Read EEPROM\n");
dit = EEPROM.read(20);
dah = EEPROM.read(21);
debug = EEPROM.read(22);
p_buf = analogRead(input_pot);
// adjust_length(p_buf);
log("Setup complete\n");
log("Dit length: ");
log(String(dit));
log("\n");
log("Dah length: ");
log(String(dah));
log("\n");
log("Potentiometer: ");
log(String(p_buf));
log("\n");
}
void loop() {
if (!digitalRead(input_dah)){
send(true);
}else if (!digitalRead(input_dit)){
send(false);
}
p_cache = analogRead(input_pot);
if (abs(p_cache - p_buf) > p_tol){
p_buf = p_cache;
if (p_cache < p_min){
p_cache = p_min;
} else if (p_cache > p_max){
p_cache = p_max;
}
adjust_length(p_cache);
}
if (Serial.available() > 0) {
buf = Serial.read();
if ((uint16_t) buf == 13){
process_input(serial_buffer);
serial_buffer = "";
} else if ((uint8_t) buf > 27 ){
serial_buffer += buf;
}
}
delay(debounce);
}
void adjust_length(uint16_t adjusted_length){
uint16_t new_dah = map(adjusted_length, 20, 1000, p_min, p_max);
set_length(new_dah/2, new_dah);
}
void process_input(String input){
// Commands:
// S<string> send string as CW, unavail chars become " "
// I<int> set did length (ms)
// A<Int> set dah length (ms)
// D<0/1> set debug mode
log("Processing input: ");
log(input);
log("\n");
char command = input[0];
input.remove(0,1);
log("Command: ");
log(String(command));
log(" - ");
log(input);
log("\n");
uint16_t length = 0;
if (islower(command)){
command = toupper(command);
}
switch(command){
case 'S':
key_string(input);
break;
case 'I':
length = input.toInt();
set_length(length, dah);
break;
case 'A':
length = input.toInt();
set_length(dit, length);
break;
case 'D':
debug = boolean(input.toInt()==1);
log("Debug mode enabled");
EEPROM.write(22, debug);
break;
default:
Serial.println('?');
break;
}
}
void key_string(String input){
// log("Sending string: ");
// log(input);
// log("\n");
uint8_t b = 0;
for (uint8_t i = 0; i < input.length(); i++){
char c = input[i];
if ((uint8_t)c != 32){
b = convertASCII(c);
for(uint8_t y = 0; y < strlen(morseCode[b]); y++){
send(morseCode[b][y] == '.');
delay(dit);
}
if(debug){
Serial.print(' ');
}
delay(dit);
} else {
if (debug){
Serial.println("");
}
delay(dah);
}
}
}
void send(bool b) {
if (debug){
Serial.print(b?"+":"=");
}
digitalWrite(output, HIGH);
delay(b?dit:dah);
digitalWrite(output, LOW);
}
void set_length(uint16_t length_dit, uint16_t length_dah) {
log("Setting dit length to ");
log(String(length_dit));
log(" and dah length to ");
log(String(length_dah));
log("\n");
dit = length_dit;
dah = length_dah;
EEPROM.write(20, length_dit);
EEPROM.write(21, length_dah);
return;
}
void log(String content){
if (debug){
Serial.print(content);
}
}