trigor_mortse/TrigorMortse.ino

231 lines
7.1 KiB
Arduino
Raw Normal View History

2022-12-20 04:55:37 +00:00
#include <Encoder.h>
#include <Arduino.h>
2023-01-21 06:40:12 +00:00
#include "src/MortseUi.h"
2022-12-20 01:13:59 +00:00
2023-01-21 05:24:51 +00:00
const byte MorseTable[] = {0b00000000,0,0b00010010,0,0,0,0,0b00011110,0b10110110,0b00101101,0,0b10101010,0b00110011,0b00100001,0b00010101,0b10110010,0b10111111,0b10101111,0b10100111,0b10100011,0b10100001,0b10100000,0b10110000,0b10111000,0b10111100,0b10111111,0b00111000,0b00101010,0,0b10110001,0,0b00001100,0b00011010,0b01000001,0b10001000,0b10001010,0b01100100,0b00100000,0b10000010,0b01100110,0b10000000,0b01000000,0b10000111,0b01100101,0b10000100,0b01000011,0b01000010,0b01100111,0b10000110,0b10001101,0b01100010,0b01100000,0b00100001,0b01100001,0b10000001,0b01100011,0b10001001,0b10001011,0b10001100,0b10110110,0,0b00101101,0,0b00001101,0b00011110,0b01000001,0b10001000,0b10001010,0b01100100,0b00100000,0b10000010,0b01100110,0b10000000,0b01000000,0b10000111,0b01100101,0b10000100,0b01000011,0b01000010,0b01100111,0b10000110,0b10001101,0b01100010,0b01100000,0b00100001,0b01100001,0b10000001,0b01100011,0b10001001,0b10001011,0b10001100,0b10110110,0,0b00101101,0};
2023-01-21 01:52:34 +00:00
const int Channel1 = 9; //Output Channel 1
const int Channel2 = 10; //Output Channel 2
const int Channel3 = 11; //Output Channel 3
2022-12-20 04:55:37 +00:00
const int Enc1P1 = 2; //Encoder 1 Pin 1 to Interrupt
const int Enc2P1 = 3; //Encoder 2 Pin 1 to Interrupt
const int Enc1P2 = 14; //Encoder 1 Pin 2 to non-Interrupting pin because we only have 2
const int Enc2P2 = 15; //Encoder 2 Pin 2 to non-Interrupting pin because we only have 2
const int Enc1Btn = 16; //Encoder 1 Button
const int Enc2Btn = 17; //Encoder 2 Button
const int ClockIn = 4; //Clock In
const int ClockDetect = 7; //Detect clock jack
2022-12-22 20:37:01 +00:00
const int DebounceTime = 10; //Debounce time in ms
2022-12-20 04:55:37 +00:00
2023-01-21 05:24:51 +00:00
const int DisplaySpi = 0; //todo: find spi port ## from library
2022-12-20 04:55:37 +00:00
Encoder LeftEnc( Enc1P1, Enc1P2);
Encoder RightEnc( Enc2P1, Enc2P2);
2023-01-21 05:45:01 +00:00
//MortseUi Ui(DisplaySpi);
2023-01-21 05:24:51 +00:00
2023-01-21 05:45:01 +00:00
String TestText = "Momento Mortse";
2023-01-21 05:24:51 +00:00
2022-12-20 04:55:37 +00:00
int E1 = 0;
int E2 = 0;
2023-01-21 05:24:51 +00:00
int Channel1Index = 0;
int MorseIndex = 0;
2022-12-20 04:55:37 +00:00
bool E1Btn = false;
bool E2Btn = false;
bool ClockState = false;
2023-01-21 05:24:51 +00:00
bool Beat = false;
2023-01-21 05:44:47 +00:00
unsigned int Channel1Trig = 0, Channel2Trig = 0, Channel3Trig = 0;
2023-01-21 05:24:51 +00:00
bool E1Prev, E2Prev, CDPrev, E1Click, E2Click, CDIn = false, Channel1State = false, Channel2State = false, Channel3State = false;
unsigned int E1Bounce, E2Bounce, CDBounce = 0, BeatBounce = 0;
unsigned long ClockPrev = 0, ClockInPrev = 0, LastBeat = 0;
byte Input = 0;
2022-12-20 04:55:37 +00:00
int PpQN = 24;
float Clock = 120;
float ClockTick = (1/((Clock * PpQN)/60)) * 1000;
unsigned long ClockTime = 0;
unsigned long LastStepTime = 0;
long EncLeft, EncRight = 0;
2022-12-20 01:13:59 +00:00
void setup() {
2022-12-20 04:55:37 +00:00
//Open Serial for output prior to installing a screen
Serial.begin( 115200 );
2023-01-21 05:24:51 +00:00
Serial.println("Momento Mortse");
2022-12-20 05:13:32 +00:00
randomSeed(analogRead(A7));
2022-12-20 04:55:37 +00:00
pinMode(Enc1Btn, INPUT_PULLUP);
pinMode(Enc2Btn, INPUT_PULLUP);
pinMode(ClockIn, INPUT);
pinMode(ClockDetect, INPUT_PULLUP);
2023-01-21 05:24:51 +00:00
pinMode(Channel1, OUTPUT);
2023-01-21 05:44:47 +00:00
pinMode(Channel2, OUTPUT);
pinMode(Channel3, OUTPUT);
E1Btn = digitalRead(Enc1Btn);
E1Prev = E1Btn;
E2Btn = digitalRead(Enc2Btn);
E2Prev = E2Btn;
ClockState = digitalRead(ClockIn);
CDPrev = digitalRead(ClockDetect);
2023-01-21 05:24:51 +00:00
digitalWrite(Channel1, 0);
digitalWrite(Channel2, 0);
digitalWrite(Channel2, 0);
2022-12-22 20:37:01 +00:00
// Timer0 is already used for millis() - we'll just interrupt somewhere
// in the middle and call the "Compare A" function below
OCR0A = 0xAF;
TIMSK0 |= _BV(OCIE0A);
2022-12-20 01:13:59 +00:00
}
void loop() {
long newLEnc = LeftEnc.read();
long newREnc = RightEnc.read();
if (digitalRead(Enc1Btn) != E1Btn){
2022-12-22 20:37:01 +00:00
if (E1Bounce == 0 & E1Click == false){
Serial.println("E1Btn State Change");
E1Btn = !E1Btn;
2022-12-22 20:37:01 +00:00
E1Bounce = DebounceTime;
E1Click = true;
}
}
if (digitalRead(Enc2Btn) != E2Btn){
2022-12-22 20:37:01 +00:00
if (E2Bounce == 0 & E2Click == false){
Serial.println("E2Btn State Change");
E2Btn = !E2Btn;
2022-12-22 20:37:01 +00:00
E2Bounce = DebounceTime;
2022-12-24 05:52:59 +00:00
E2Click = true;
2022-12-22 20:37:01 +00:00
}
}
2022-12-24 05:52:59 +00:00
//false click handler
E1Click = false;
E2Click = false;
2022-12-22 20:37:01 +00:00
bool newCD = digitalRead(ClockDetect);
if (newCD != CDPrev){
if (CDBounce == 0){
Serial.println("Clock Jack Status Change");
CDPrev = CDIn = newCD;
CDBounce = DebounceTime << 4;
}
}
if ( digitalRead(ClockIn) != ClockState){
ClockState = !ClockState;
if (ClockState){
unsigned long tmpClock = micros();
float clkInTick = tmpClock - ClockPrev;
ClockPrev = tmpClock;
2023-01-21 05:24:51 +00:00
if (abs(ClockInPrev - clkInTick) > 500){
Clock =((1.0/(clkInTick/1000000.0)) * 60.0)/(float)PpQN;
String outputBPM = "New BPM: ";
2023-01-21 05:44:47 +00:00
outputBPM.concat(Clock);
Serial.println(outputBPM);
outputBPM = "Clock Tick: ";
outputBPM.concat(clkInTick);
Serial.println(outputBPM);
ClockTick = (1/((Clock * PpQN)/60)) * 1000;
}
2023-01-21 05:24:51 +00:00
else{
Beat = true;
LastBeat = tmpClock;
}
}
}
2023-01-21 05:24:51 +00:00
if ((LastBeat + ClockTick) < micros()){
Beat = true;
LastBeat = micros();
}
if (newLEnc != EncLeft || newREnc != EncRight){
String output = "Left Enc Pos: ";
output.concat(newLEnc);
output.concat( ", Right Enc Pos: ");
output.concat(newREnc);
Serial.print(output);
if (newLEnc != EncLeft){
Clock = Clock + (((float)EncLeft - (float)newLEnc)/40.0);
} else{
Clock = Clock + ((EncRight - newREnc) * 2.5);
}
ClockTick = (1/((Clock * PpQN)/60)) * 1000;
EncLeft = newLEnc;
EncRight = newREnc;
output = " Clock: ";
output.concat(Clock);
output.concat( " Clocktick: ");
output.concat( ClockTick);
Serial.println(output);
}
2023-01-21 05:24:51 +00:00
if (Beat){
Beat = false;
if (!BeatBounce){
//Insert Beat Output here!
2023-01-21 05:44:47 +00:00
char outputChar = TestText[Channel1Index];
2023-01-21 06:40:12 +00:00
if (outputChar == '\0'){
2023-01-21 05:24:51 +00:00
Channel1Index = 0;
2023-01-21 05:44:47 +00:00
outputChar = TestText[Channel1Index];
2023-01-21 05:24:51 +00:00
}
2023-01-21 05:44:47 +00:00
byte morseLength = MorseTable[((int)outputChar - 32)];
2023-01-21 05:24:51 +00:00
byte morsePattern = morseLength;
bool trigger = (morsePattern >> MorseIndex) & 1;
if (MorseIndex == 0){
Channel1Index++;
2023-01-21 05:44:47 +00:00
outputChar = TestText[Channel1Index];
2023-01-21 05:24:51 +00:00
MorseIndex = ((MorseTable[((int)outputChar - 32)]) >> 5) - 1;
}
MorseIndex--;
if (trigger){
digitalWrite(Channel1, true);
Channel1Trig = 5;
}
}
}
if (Channel1State && !Channel1Trig){
digitalWrite(Channel1, 0);
Channel1State = false;
}
if (Channel2State && !Channel2Trig){
digitalWrite(Channel2, 0);
Channel2State = false;
}
if (Channel3State && !Channel3Trig){
digitalWrite(Channel3, 0);
Channel3State = false;
}
2023-01-21 05:45:01 +00:00
//Ui.tick();
2023-01-21 02:29:41 +00:00
2023-01-21 05:24:51 +00:00
}
2023-01-21 02:29:41 +00:00
2022-12-22 20:37:01 +00:00
// Interrupt is called once a millisecond,
SIGNAL(TIMER0_COMPA_vect)
{
E1Bounce = (E1Bounce - 1) & 0b10000000;
E2Bounce = (E2Bounce - 1) & 0b10000000;
CDBounce = (CDBounce - 1) & 0b10000000;
2023-01-21 05:24:51 +00:00
BeatBounce = (BeatBounce - 1) & 0b10000000;
Channel1Trig = (Channel1Trig - 1) & 0b10000000;
Channel2Trig = (Channel2Trig - 1) & 0b10000000;
Channel3Trig = (Channel3Trig - 1) & 0b10000000;
}