From 2f3c81a8a4052502258ba3e77c04675b5d9c49c9 Mon Sep 17 00:00:00 2001 From: --global <--global> Date: Sun, 22 Jan 2023 18:33:17 +0200 Subject: [PATCH] first working code --- software/GToE/GToE.ino | 201 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 201 insertions(+) create mode 100644 software/GToE/GToE.ino diff --git a/software/GToE/GToE.ino b/software/GToE/GToE.ino new file mode 100644 index 0000000..80111ff --- /dev/null +++ b/software/GToE/GToE.ino @@ -0,0 +1,201 @@ +#include +#include +#include +#include +#include +#include + +#define SCREEN_ADDRESS 0x3C + +#define INPUT_CONNECTED_PIN 12 +#define INPUT_PIN 2 +#define ENC_BTN_PIN 17 +#define ENC_D1_PIN 4 +#define ENC_D2_PIN 3 +#define START_STOP_BTN_PIN 14 + +//Output pins are defined in the array below + + +//TODO : +//Add min and max values +//External clock +//Switch to another timer lib (FlexiTimer?) +//Switch to U8G2 for screen +//Save state to EEPROM when stopped + +int outsPins[6] = {5, 6, 7, 8, 9, 10}; +int outsValues[6] = {1, 2, 4, -4, 1, 1}; //positive - divide, negative - multiply, 0 - off +int outsPeriods[6]; +int outsClocksCounts[6] = {0, 0, 0, 0, 0, 0}; + +bool clockMode; +bool clockModeOld; +int inputMode; //clock, reset, start/stop +int clockCount = 0; + +int bpm = 120; +int bpmPeriod; +bool isPlaying = 0; + +int displayTab = 0; +int displayTabOld; +bool needToChangeTab = 0; +bool buttonPushed = false; + +bool changesSaved; + +int encPositionOld = 0; + +Adafruit_SSD1306 display(128, 64, &Wire, -1); +RotaryEncoder encoder(ENC_D1_PIN, ENC_D2_PIN, RotaryEncoder::LatchMode::TWO03); + +void setup() { + Serial.begin(9600); + + pinMode(INPUT_CONNECTED_PIN, INPUT_PULLUP); + pinMode(ENC_BTN_PIN, INPUT_PULLUP); + pinMode(START_STOP_BTN_PIN, INPUT_PULLUP); + pinMode(INPUT_PIN, INPUT_PULLUP); //probably will need interrupt + + for (int i=0; i<6; i++) { + pinMode(outsPins[i], OUTPUT); + } + + display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS); + + updateScreen(); + updatePeriods(); + + MsTimer2::set(1, internalClock); // 1ms period + MsTimer2::start(); +} + +void loop() { + checkInputs(); +} + +void internalClock() { + if (isPlaying) { + for (int i = 0; i<6; i++) { + if (outsClocksCounts[i] >= outsPeriods[i]) { + outsClocksCounts[i] = 0; + } + if (outsClocksCounts[i] == 0) { + digitalWrite(outsPins[i], HIGH); + } + if (outsClocksCounts[i] == 15) { + digitalWrite(outsPins[i], LOW); + } + outsClocksCounts[i]++; + } + } +} + +void updatePeriods() { + bpmPeriod = 60000 / bpm; + for (int i = 0; i<6; i++) { + if (outsValues[i]>0) { + outsPeriods[i] = bpmPeriod * outsValues[i]; + } else { + outsPeriods[i] = bpmPeriod / outsValues[i] * - 1; + } + } +} + +void checkInputs() { + clockMode = digitalRead(INPUT_CONNECTED_PIN); + if (clockMode != clockModeOld) { + updateScreen(); + clockModeOld = clockMode; + } + if (needToChangeTab == 0 && digitalRead(ENC_BTN_PIN) == 0) { + needToChangeTab = 1; + } + + if (needToChangeTab == 1 && digitalRead(ENC_BTN_PIN) == 1) { + displayTabOld = displayTab; + displayTab++; + if (displayTab>6) { + displayTab = 0; + } + needToChangeTab = 0; + updateScreen(); + } + + encoder.tick(); + int encPosition = encoder.getPosition(); + if (encPositionOld != encPosition) { + int change = encPositionOld - encPosition; + if (displayTab == 0) { + bpm = bpm + change; + } else { + outsValues[displayTab-1] = outsValues[displayTab-1] + change; + } + updatePeriods(); + updateScreen(); + encPositionOld = encPosition; + } + + if (!digitalRead(START_STOP_BTN_PIN) && !buttonPushed) { + isPlaying = !isPlaying; + buttonPushed = true; + } else if (digitalRead(START_STOP_BTN_PIN) && buttonPushed) { + buttonPushed = false; + } +} + +void updateScreen() { + display.clearDisplay(); + + //Tabs + display.setCursor(0,0); + display.setTextSize(1); + if (displayTab == 0) { + display.setTextColor(SSD1306_BLACK, SSD1306_WHITE); + display.print(F(" ")); + display.setTextColor(SSD1306_WHITE); + display.print(F(" bpm ")); + } else { + display.setTextColor(SSD1306_BLACK, SSD1306_WHITE); + display.print(F(" bpm")); + } + + for (int i = 1; i <= 6; i++) { + if (displayTab == i) { + display.setTextColor(SSD1306_BLACK, SSD1306_WHITE); + display.print(" "); + display.setTextColor(SSD1306_WHITE); + display.print(" "); + display.print(i); + display.print(" "); + } else { + display.setTextColor(SSD1306_BLACK, SSD1306_WHITE); + display.print(" "); + display.print(i); + } + } + + display.setTextColor(SSD1306_BLACK, SSD1306_WHITE); + display.println(F(" ")); + + display.println(); + + //Content + display.setTextSize(3); + display.setTextColor(SSD1306_WHITE); + + if (displayTab == 0) { + display.print(bpm); + display.println(F("bpm")); + } else { + if (outsValues[displayTab-1]>0) { + display.print(F("/")); + } else { + display.print(F("x")); + } + display.print(abs(outsValues[displayTab-1])); + } + + display.display(); +}