This commit is contained in:
Stefan Ritter 2023-03-15 17:02:07 +01:00
commit 5fbf5ea2e0
7 changed files with 251 additions and 0 deletions

212
Code/Code.ino Normal file
View File

@ -0,0 +1,212 @@
//
// Cavaliere Heartbeat
//
#include <EEPROM.h>
#include <Encoder.h> // Encoder by Paul Stoffregen
#include <Adafruit_SSD1306.h>
Adafruit_SSD1306 display(128, 64, &Wire, 4);
#define audio 12 // Pin for 3,5 Jack
#define led 13 // Pin for LED
#define rot_clk 4 // Rotary encoder CLK pin
#define rot_dt 3 // Rotary encoder DT pin
#define rot_sw 2 // Rotary encoder SW pin, 1 = not pushed, 0 = pushed
#define triggerLengthMS 50 // How long the trigger should stay on in milliseconds when triggerLength = 1
#define bpm_value_min 80 // 20 bpm is minimum (80 / 4)
#define bpm_value_max 1200 // 300 bpm is maximum (300 * 4)
#define offset_x 5 // Display offset
#define offset_y 5 // Display offset
int bpm; // BPM, who'd have thought
int bpms; // BPM to milliseconds
int eeprom_bpm; // BPM stored in EEPROM
int bpm_value; // Later bpm * 4 because of the 4 rotary encoder steps
int triggerLength = 2; // 1 = triggerLengthMS, 2 = half of bpm
int stayOnTime; // How long the trigger should stay on in milliseconds when triggerLength = 2
unsigned long currentTime; // Timing stuff
unsigned long previousTime = 0; // Timing stuff
int state = 0; // Prevent trigger flood
int rot_sw_state = 0; // Rotary encoder SW state
int rot_sw_temp = 0; // Some dumb temp shit
long rot_old_pos = 0; // Don't ask
// Pins for the rotary encoder up and down
Encoder rot_enc(rot_dt, rot_clk);
void setup() {
Serial.begin(9600);
// Read stored BPM data
if (EEPROM.read(0) != 1) {
// No BPM data stored, let's initialize it with 120 BPM
EEPROM.write(0, 1); // Set byte 0 to 1
EEPROM.write(1, 1); // 1 x 100
EEPROM.write(2, 2); // 2 x 10
EEPROM.write(3, 0); // 0 x 1
bpm = 120;
bpm_value = bpm * 4;
bpms = 60000 / bpm;
Serial.println("No stored BPM found. Initialized with 120 BPM.");
} else {
// BPM data stored
int a = EEPROM.read(1);
int b = EEPROM.read(2);
int c = EEPROM.read(3);
eeprom_bpm = (a * 100) + (b * 10) + (c * 1);
bpm = eeprom_bpm;
bpm_value = bpm * 4;
bpms = 60000 / bpm;
Serial.print("Stored BPM data found: ");
Serial.println(eeprom_bpm);
}
// Display
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
display.setTextColor(SSD1306_WHITE);
displayUpdate(bpm, bpm);
// Calculate how long the LED should stay on
if (triggerLength == 1) {
stayOnTime = triggerLengthMS;
} else if (triggerLength == 2) {
stayOnTime = bpms / 2;
}
// Enable inputs and outputs
pinMode(audio, OUTPUT);
pinMode(led, OUTPUT);
pinMode(rot_clk, INPUT);
pinMode(rot_dt, INPUT);
pinMode(rot_sw, INPUT);
}
void loop() {
// Beat stuff
currentTime = millis();
if (currentTime - previousTime >= bpms) {
triggerOn();
previousTime = currentTime;
state = 1;
}
if (currentTime - previousTime >= stayOnTime && state == 1) {
triggerOff();
state = 0;
}
// Rotary encoder stuff
long rot_new_pos = rot_enc.read();
if (rot_new_pos != rot_old_pos) {
if (rot_new_pos > rot_old_pos) {
bpm_value++;
if (bpm_value > bpm_value_max) {
bpm_value = bpm_value_max;
}
}
if (rot_new_pos < rot_old_pos) {
bpm_value--;
if (bpm_value < bpm_value_min) {
bpm_value = bpm_value_min;
}
}
displayUpdate(bpm, bpm_value / 4);
rot_old_pos = rot_new_pos;
}
// Rotary encoder button
rot_sw_state = digitalRead(rot_sw);
if (rot_sw_state == 1) {
rot_sw_temp = 0;
}
if (rot_sw_state == 0 && rot_sw_temp == 0) {
rot_sw_push();
rot_sw_temp = 1;
}
}
void triggerOn() {
Serial.print("Trigger ON at ");
Serial.print(currentTime);
Serial.println(" milliseconds");
digitalWrite(audio, HIGH);
digitalWrite(led, HIGH);
}
void triggerOff() {
Serial.print("Trigger OFF at ");
Serial.print(currentTime);
Serial.println(" milliseconds");
digitalWrite(audio, LOW);
digitalWrite(led, LOW);
}
void rot_sw_push() {
// Recalculate BPM stuff
bpm = bpm_value / 4;
bpms = 60000 / bpm;
if (triggerLength == 2) {
stayOnTime = bpms / 2;
}
Serial.print("BPM set to ");
Serial.println(bpm);
displayUpdate(bpm, bpm);
// Save new BPM to EEPROM
int a = bpm / 100;
int b = (bpm - (a * 100)) / 10;
int c = (bpm - (a * 100) - (b * 10));
EEPROM.write(1, a);
EEPROM.write(2, b);
EEPROM.write(3, c);
}
int displayUpdate(int bpm, int bpm2) {
display.clearDisplay();
display.setTextSize(1);
display.setCursor(0 + offset_x, 0 + offset_y);
display.println("cavaliere HEARTBEAT");
display.setTextSize(2);
display.setCursor(0 + offset_x, 18 + offset_y);
display.println("BPM");
display.setCursor(0 + offset_x, 40 + offset_y);
display.println("NEW");
String bpmToStr;
String bpm2ToStr;
// Leading whitespace when bpm < 100
display.setCursor(68 + offset_x, 18 + offset_y);
if (bpm < 100) {
bpmToStr = " " + String(bpm);
} else {
bpmToStr = String(bpm);
}
display.println(bpmToStr);
// Leading whitespace when bpm2 < 100
display.setCursor(68 + offset_x, 40 + offset_y);
if (bpm2 < 100) {
bpm2ToStr = " " + String(bpm2);
} else {
bpm2ToStr = String(bpm2);
}
display.println(bpm2ToStr);
display.display();
return 0;
}

BIN
Fritzing/Circuit.fzz Normal file

Binary file not shown.

Binary file not shown.

BIN
Front/Front Plate.psd Normal file

Binary file not shown.

BIN
Logo/LCDAssistant.exe Normal file

Binary file not shown.

39
Logo/logo Normal file
View File

@ -0,0 +1,39 @@
//------------------------------------------------------------------------------
// File generated by LCD Assistant
// http://en.radzio.dxp.pl/bitmap_converter/
//------------------------------------------------------------------------------
const unsigned char logo [] PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEF, 0xEF, 0x01, 0x01, 0x01, 0x01, 0x01,
0x00, 0x00, 0xEF, 0xFF, 0x11, 0x11, 0x11, 0xFF, 0xFF, 0xEF, 0x00, 0x1F, 0xDF, 0xC0, 0x80, 0x80,
0xDE, 0x5F, 0x1F, 0x00, 0xEF, 0xFF, 0x11, 0x11, 0x11, 0xFF, 0xFF, 0xEF, 0x00, 0xEF, 0xEF, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEF, 0xEF, 0x00, 0xEF, 0xFF, 0x11, 0x11, 0x11, 0x11, 0x11,
0x00, 0x00, 0xEF, 0xFF, 0x11, 0x11, 0x71, 0xFF, 0xDF, 0x0F, 0x00, 0xEF, 0xFF, 0x11, 0x11, 0x11,
0x11, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x81, 0x61, 0x10, 0x60, 0x80, 0x00, 0x01, 0x01, 0x00, 0x00,
0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0xE0, 0xF1, 0xF1,
0xE0, 0xC1, 0xE1, 0xF1, 0xF1, 0xE1, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01,
0x01, 0x01, 0x81, 0x61, 0x10, 0x60, 0x81, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xC0,
0x00, 0x01, 0x01, 0x81, 0xC1, 0xC1, 0x01, 0xC1, 0xC1, 0x41, 0x40, 0x40, 0x40, 0x40, 0x01, 0x06,
0xC8, 0xC6, 0x41, 0x41, 0x41, 0xC1, 0xC1, 0xC1, 0x01, 0xC1, 0xC1, 0x41, 0x41, 0x41, 0xC0, 0xC0,
0xC0, 0x00, 0x41, 0x43, 0x47, 0x4F, 0x47, 0x43, 0x41, 0x00, 0x00, 0xC0, 0xC0, 0x41, 0x41, 0x41,
0xC1, 0xC1, 0xC1, 0x01, 0xC1, 0xC1, 0x40, 0x40, 0x40, 0x40, 0x41, 0x06, 0x08, 0xC6, 0xC1, 0x41,
0x41, 0x41, 0xC1, 0xC1, 0xC1, 0x01, 0x41, 0x41, 0x41, 0x41, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
0x00, 0x00, 0x7B, 0x7F, 0x04, 0x04, 0x04, 0x3F, 0x7F, 0x7B, 0x00, 0x7B, 0x7F, 0x44, 0x44, 0x44,
0x44, 0x44, 0x00, 0x00, 0x7B, 0x7F, 0x04, 0x04, 0x04, 0x3F, 0x7F, 0x7B, 0x00, 0x7B, 0x7F, 0x04,
0x04, 0x1C, 0x7F, 0x77, 0x43, 0x00, 0x00, 0x00, 0x00, 0x77, 0x77, 0x00, 0x00, 0x00, 0x00, 0x7B,
0x7F, 0x44, 0x44, 0x44, 0x7F, 0x7F, 0x7B, 0x00, 0x7B, 0x7F, 0x44, 0x44, 0x44, 0x44, 0x44, 0x00,
0x00, 0x7B, 0x7F, 0x04, 0x04, 0x04, 0x3F, 0x7F, 0x7B, 0x00, 0x00, 0x00, 0x00, 0x77, 0x77, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};

BIN
Logo/logo.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 640 B