Revert pointer change. not worth the few bytes it saved.

This commit is contained in:
2025-05-31 20:28:17 -07:00
parent 18e53e90c1
commit edd7df1cd6
6 changed files with 103 additions and 113 deletions

View File

@ -111,3 +111,4 @@ void UpdateDisplay() {
gravity.display.display(); gravity.display.display();
} }
``` ```

View File

@ -33,11 +33,8 @@ class EncoderDir {
Direction dir; Direction dir;
public: public:
EncoderDir() { EncoderDir() : encoder_(ENCODER_PIN1, ENCODER_PIN2, RotaryEncoder::LatchMode::FOUR3),
encoder_ = new RotaryEncoder(ENCODER_PIN1, ENCODER_PIN2, RotaryEncoder::LatchMode::FOUR3); button_(ENCODER_SW_PIN) {}
button_ = new Button(ENCODER_SW_PIN);
}
~EncoderDir() {} ~EncoderDir() {}
// Set to true if the encoder read direction should be reversed. // Set to true if the encoder read direction should be reversed.
@ -58,15 +55,15 @@ class EncoderDir {
// Parse EncoderButton increment direction. // Parse EncoderButton increment direction.
Direction RotateDirection() { Direction RotateDirection() {
int dir = (int)(encoder_->getDirection()); int dir = (int)(encoder_.getDirection());
return rotate_(dir, reversed_); return rotate_(dir, reversed_);
} }
void Process() { void Process() {
// Get encoder position change amount. // Get encoder position change amount.
int encoder_rotated = _rotate_change() != 0; int encoder_rotated = _rotate_change() != 0;
bool button_pressed = button_->On(); bool button_pressed = button_.On();
button_->Process(); button_.Process();
// Handle encoder position change and button press. // Handle encoder position change and button press.
if (button_pressed && encoder_rotated) { if (button_pressed && encoder_rotated) {
@ -74,32 +71,32 @@ class EncoderDir {
if (on_press_rotate != NULL) on_press_rotate(dir, change); if (on_press_rotate != NULL) on_press_rotate(dir, change);
} else if (!button_pressed && encoder_rotated) { } else if (!button_pressed && encoder_rotated) {
if (on_rotate != NULL) on_rotate(dir, change); if (on_rotate != NULL) on_rotate(dir, change);
} else if (button_->Change() == Button::CHANGE_RELEASED && !rotated_while_held_) { } else if (button_.Change() == Button::CHANGE_RELEASED && !rotated_while_held_) {
if (on_press != NULL) on_press(); if (on_press != NULL) on_press();
} }
// Reset rotate while held state. // Reset rotate while held state.
if (button_->Change() == Button::CHANGE_RELEASED && rotated_while_held_) { if (button_.Change() == Button::CHANGE_RELEASED && rotated_while_held_) {
rotated_while_held_ = false; rotated_while_held_ = false;
} }
} }
// Read the encoder state and update the read position. // Read the encoder state and update the read position.
void UpdateEncoder() { void UpdateEncoder() {
encoder_->tick(); encoder_.tick();
} }
private: private:
int previous_pos_; int previous_pos_;
bool rotated_while_held_; bool rotated_while_held_;
bool reversed_ = true; bool reversed_ = true;
RotaryEncoder * encoder_ = nullptr; RotaryEncoder encoder_;
Button * button_ = nullptr; Button button_;
// Return the number of ticks change since last polled. // Return the number of ticks change since last polled.
int _rotate_change() { int _rotate_change() {
int position = encoder_->getPosition(); int position = encoder_.getPosition();
unsigned long ms = encoder_->getMillisBetweenRotations(); unsigned long ms = encoder_.getMillisBetweenRotations();
// Validation (TODO: add debounce check). // Validation (TODO: add debounce check).
if (previous_pos_ == position) { if (previous_pos_ == position) {

View File

@ -61,16 +61,16 @@ void setup() {
gravity.Init(); gravity.Init();
// Clock handlers. // Clock handlers.
gravity.clock->AttachExtHandler(ExtClock); gravity.clock.AttachExtHandler(ExtClock);
gravity.clock->AttachIntHandler(IntClock); gravity.clock.AttachIntHandler(IntClock);
// Encoder rotate and press handlers. // Encoder rotate and press handlers.
gravity.encoder->AttachPressHandler(HandleEncoderPressed); gravity.encoder.AttachPressHandler(HandleEncoderPressed);
gravity.encoder->AttachRotateHandler(HandleRotate); gravity.encoder.AttachRotateHandler(HandleRotate);
gravity.encoder->AttachPressRotateHandler(HandlePressedRotate); gravity.encoder.AttachPressRotateHandler(HandlePressedRotate);
// Button press handlers. // Button press handlers.
gravity.play_button->AttachPressHandler(HandlePlayPressed); gravity.play_button.AttachPressHandler(HandlePlayPressed);
} }
void loop() { void loop() {
@ -88,8 +88,8 @@ void loop() {
// //
void ExtClock() { void ExtClock() {
if (gravity.clock->ExternalSource()) { if (gravity.clock.ExternalSource()) {
gravity.clock->Tick(); gravity.clock.Tick();
app.refresh_screen = true; app.refresh_screen = true;
} }
} }
@ -119,8 +119,8 @@ void IntClock(uint32_t tick) {
} }
void HandlePlayPressed() { void HandlePlayPressed() {
gravity.clock->Pause(); gravity.clock.Pause();
if (gravity.clock->IsPaused()) { if (gravity.clock.IsPaused()) {
for (int i = 0; i < OUTPUT_COUNT; i++) { for (int i = 0; i < OUTPUT_COUNT; i++) {
gravity.outputs[i].Low(); gravity.outputs[i].Low();
} }
@ -149,10 +149,10 @@ void HandleRotate(Direction dir, int val) {
if (app.selected_channel == 0) { if (app.selected_channel == 0) {
switch (app.selected_param) { switch (app.selected_param) {
case 0: case 0:
if (gravity.clock->ExternalSource()) { if (gravity.clock.ExternalSource()) {
break; break;
} }
gravity.clock->SetTempo(gravity.clock->Tempo() + val); gravity.clock.SetTempo(gravity.clock.Tempo() + val);
app.refresh_screen = true; app.refresh_screen = true;
break; break;
@ -163,7 +163,7 @@ void HandleRotate(Direction dir, int val) {
app.selected_source = static_cast<Source>((app.selected_source + val) % SOURCE_LAST); app.selected_source = static_cast<Source>((app.selected_source + val) % SOURCE_LAST);
} }
gravity.clock->SetSource(app.selected_source); gravity.clock.SetSource(app.selected_source);
app.refresh_screen = true; app.refresh_screen = true;
break; break;
} }
@ -222,7 +222,7 @@ Channel& GetSelectedChannel() {
void UpdateDisplay() { void UpdateDisplay() {
app.refresh_screen = false; app.refresh_screen = false;
gravity.display->clearDisplay(); gravity.display.clearDisplay();
if (app.selected_channel == 0) { if (app.selected_channel == 0) {
DisplayMainPage(); DisplayMainPage();
@ -231,51 +231,52 @@ void UpdateDisplay() {
} }
// Show selected param indicator // Show selected param indicator
gravity.display->drawChar(0, app.selected_param * 10, 0x10, 1, 0, 1); gravity.display.drawChar(0, app.selected_param * 10, 0x10, 1, 0, 1);
// Global channel select UI. // Global channel select UI.
DisplaySelectedChannel(); DisplaySelectedChannel();
gravity.display->display(); gravity.display.display();
} }
void DisplaySelectedChannel() { void DisplaySelectedChannel() {
gravity.display->drawLine(1, 52, 126, 52, 1); gravity.display.drawLine(1, 52, 126, 52, 1);
for (int i = 0; i < 7; i++) { for (int i = 0; i < 7; i++) {
(app.selected_channel == i) (app.selected_channel == i)
? gravity.display->fillRect(i * 18, 52, 18, 12, 1) ? gravity.display.fillRect(i * 18, 52, 18, 12, 1)
: gravity.display->drawLine(i * 18, 52, i * 18, 64, 1); : gravity.display.drawLine(i * 18, 52, i * 18, 64, 1);
int selected = app.selected_channel == i; int selected = app.selected_channel == i;
if (i == 0) { if (i == 0) {
char icon = gravity.clock->IsPaused() ? CHAR_PAUSE : CHAR_PLAY; char icon = gravity.clock.IsPaused() ? CHAR_PAUSE : CHAR_PLAY;
gravity.display->drawChar((i * 18) + 7, 55, icon, !selected, selected, 1); gravity.display.drawChar((i * 18) + 7, 55, icon, !selected, selected, 1);
} else { } else {
gravity.display->drawChar((i * 18) + 7, 55, i + 48, !selected, selected, 1); gravity.display.drawChar((i * 18) + 7, 55, i + 48, !selected, selected, 1);
} }
} }
gravity.display->drawLine(126, 52, 126, 64, 1); gravity.display.drawLine(126, 52, 126, 64, 1);
} }
void DisplayMainPage() { void DisplayMainPage() {
gravity.display->setCursor(10, 0); gravity.display.setCursor(10, 0);
gravity.display->print(F("Tempo: ")); gravity.display.print(F("Tempo: "));
gravity.display->print(gravity.clock->Tempo()); gravity.display.print(gravity.clock.Tempo());
gravity.display->setCursor(10, 10); gravity.display.setCursor(10, 10);
gravity.display->print(F("Source: ")); gravity.display.print(F("Source: "));
switch (app.selected_source) { switch (app.selected_source)
{
case SOURCE_INTERNAL: case SOURCE_INTERNAL:
gravity.display->print(F("INT")); gravity.display.print(F("INT"));
break; break;
case SOURCE_EXTERNAL_PPQN_24: case SOURCE_EXTERNAL_PPQN_24:
gravity.display->print(F("EXT 24 PPQN")); gravity.display.print(F("EXT 24 PPQN"));
break; break;
case SOURCE_EXTERNAL_PPQN_4: case SOURCE_EXTERNAL_PPQN_4:
gravity.display->print(F("EXT 4 PPQN")); gravity.display.print(F("EXT 4 PPQN"));
break; break;
// case SOURCE_EXTERNAL_MIDI: // case SOURCE_EXTERNAL_MIDI:
// gravity.display->print(F("EXT MIDI")); // gravity.display.print(F("EXT MIDI"));
// break; // break;
default: default:
break; break;
@ -285,28 +286,28 @@ void DisplayMainPage() {
void DisplayChannelPage() { void DisplayChannelPage() {
auto& ch = GetSelectedChannel(); auto& ch = GetSelectedChannel();
gravity.display->setCursor(10, 0); gravity.display.setCursor(10, 0);
gravity.display->print(F("Mod: ")); gravity.display.print(F("Mod: "));
if (clock_mod[ch.clock_mod_index] > 1) { if (clock_mod[ch.clock_mod_index] > 1) {
gravity.display->print(F("/ ")); gravity.display.print(F("/ "));
gravity.display->print(clock_mod[ch.clock_mod_index]); gravity.display.print(clock_mod[ch.clock_mod_index]);
} else { } else {
gravity.display->print(F("X ")); gravity.display.print(F("X "));
gravity.display->print(abs(clock_mod[ch.clock_mod_index])); gravity.display.print(abs(clock_mod[ch.clock_mod_index]));
} }
gravity.display->setCursor(10, 10); gravity.display.setCursor(10, 10);
gravity.display->print(F("Probability: ")); gravity.display.print(F("Probability: "));
gravity.display->print(ch.probability); gravity.display.print(ch.probability);
gravity.display->print(F("%")); gravity.display.print(F("%"));
gravity.display->setCursor(10, 20); gravity.display.setCursor(10, 20);
gravity.display->print(F("Duty Cycle: ")); gravity.display.print(F("Duty Cycle: "));
gravity.display->print(ch.duty_cycle); gravity.display.print(ch.duty_cycle);
gravity.display->print(F("%")); gravity.display.print(F("%"));
gravity.display->setCursor(10, 30); gravity.display.setCursor(10, 30);
gravity.display->print(F("Offset: ")); gravity.display.print(F("Offset: "));
gravity.display->print(ch.offset); gravity.display.print(ch.offset);
gravity.display->print(F("%")); gravity.display.print(F("%"));
} }

View File

@ -19,22 +19,15 @@ void Gravity::Init() {
} }
void Gravity::InitClock() { void Gravity::InitClock() {
clock = new Clock(); clock.Init();
clock->Init();
} }
void Gravity::InitInputs() { void Gravity::InitInputs() {
shift_button = new Button(); shift_button.Init(SHIFT_BTN_PIN);
play_button = new Button(); play_button.Init(PLAY_BTN_PIN);
shift_button->Init(SHIFT_BTN_PIN);
play_button->Init(PLAY_BTN_PIN);
cv1 = new AnalogInput(); cv1.Init(CV1_PIN);
cv2 = new AnalogInput(); cv2.Init(CV2_PIN);
cv1->Init(CV1_PIN);
cv2->Init(CV2_PIN);
encoder = new EncoderDir();
// Pin Change Interrupts for Encoder. // Pin Change Interrupts for Encoder.
// Thanks to https://dronebotworkshop.com/interrupts/ // Thanks to https://dronebotworkshop.com/interrupts/
@ -57,25 +50,23 @@ void Gravity::InitOutputs() {
outputs[5].Init(OUT_CH6); outputs[5].Init(OUT_CH6);
} }
void Gravity::InitDisplay() { void Gravity::InitDisplay() {
display = new Adafruit_SSD1306(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
// OLED Display configuration. // OLED Display configuration.
display->begin(SSD1306_SWITCHCAPVCC, OLED_ADDRESS); display.begin(SSD1306_SWITCHCAPVCC, OLED_ADDRESS);
delay(1000); delay(1000);
display->setRotation(2); // rotates text on OLED 1=90 degrees, 2=180 degrees display.setRotation(2); // rotates text on OLED 1=90 degrees, 2=180 degrees
display->clearDisplay(); display.clearDisplay();
display->setTextSize(1); display.setTextSize(1);
display->setTextColor(WHITE); display.setTextColor(WHITE);
display->display(); display.display();
} }
void Gravity::Process() { void Gravity::Process() {
// Read peripherials for changes. // Read peripherials for changes.
shift_button->Process(); shift_button.Process();
play_button->Process(); play_button.Process();
encoder->Process(); encoder.Process();
cv1->Process(); cv1.Process();
cv2->Process(); cv2.Process();
// Update Output states. // Update Output states.
for (int i; i < OUTPUT_COUNT; i++) { for (int i; i < OUTPUT_COUNT; i++) {
@ -84,7 +75,7 @@ void Gravity::Process() {
} }
void ReadEncoder() { void ReadEncoder() {
gravity.encoder->UpdateEncoder(); gravity.encoder.UpdateEncoder();
} }
// Define Encoder pin ISR. // Define Encoder pin ISR.

View File

@ -16,7 +16,8 @@
class Gravity { class Gravity {
public: public:
// Constructor // Constructor
Gravity() {} Gravity()
: display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1) {}
// Deconstructor // Deconstructor
~Gravity() {} ~Gravity() {}
@ -27,14 +28,14 @@ class Gravity {
// Polling check for state change of inputs and outputs. // Polling check for state change of inputs and outputs.
void Process(); void Process();
Adafruit_SSD1306 * display = nullptr; // OLED display object. Adafruit_SSD1306 display; // OLED display object.
Clock * clock = nullptr; // Clock source wrapper. Clock clock; // Clock source wrapper.
DigitalOutput outputs[OUTPUT_COUNT]; // An array containing each Output object. DigitalOutput outputs[OUTPUT_COUNT]; // An array containing each Output object.
EncoderDir * encoder = nullptr; // Rotary encoder with button instance EncoderDir encoder; // Rotary encoder with button instance
Button * shift_button = nullptr; Button shift_button;
Button * play_button = nullptr; Button play_button;
AnalogInput * cv1 = nullptr; AnalogInput cv1;
AnalogInput * cv2 = nullptr; AnalogInput cv2;
private: private:
void InitClock(); void InitClock();

View File

@ -15,7 +15,6 @@
#define OLED_ADDRESS 0x3C #define OLED_ADDRESS 0x3C
#define SCREEN_WIDTH 128 #define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64 #define SCREEN_HEIGHT 64
#define OLED_RESET -1
// Peripheral input pins // Peripheral input pins
#define ENCODER_PIN1 17 // A3 #define ENCODER_PIN1 17 // A3