Hello!
I'm trying to begin to code a MIDI sequencer with Teensy 4.1 and 40x4 LCD. Chat GPT 4 gave me this code, but I have a problem with it and GPT 4 cannot find out what the problem is. Now it's your time to shine and show that you are smarter that GPT 4! LOL
So, here's the code. The problem is that even that I change tempo to whatever BMP, the sequencer playback doesn't respond to the change for some reason. Any ideas what's going on?
This is just a first test with millis-function. I think I'm going to use interrupts with Teensy just like GPT 4 suggested.
Thank you!
// MIDI sequencer test
// TEENSY 4.1 with 40x4 LCD
#include <LiquidCrystal.h>
const int rs = 2, en1 = 3, en2 = 4, d4 = 5, d5 = 6, d6 = 7, d7 = 8;
const int buttonPin = 30, ledPin = 13, playButtonPin = 31;
const int encoderPinA = 9, encoderPinB = 10;
unsigned long totalTicks = 0;
const int backlightPin = 13;
const int backlightToggleButton = 30;
volatile int newTempo = 180;
volatile bool tempoChanged = false;
LiquidCrystal lcd1(rs, en1, d4, d5, d6, d7);
LiquidCrystal lcd2(rs, en2, d4, d5, d6, d7);
unsigned long lastBacklightToggleTime = 0;
unsigned long lastPlayButtonTime = 0;
bool backlightState = true;
volatile int encoderPos = 0;
volatile int lastEncoded = 0;
unsigned long lastEncoderUpdateTime = 0;
bool lastButtonState = HIGH, currentButtonState = HIGH;
bool lastPlayButtonState = HIGH, currentPlayButtonState = HIGH;
unsigned long lastDebounceTime = 0, debounceDelay = 200;
bool isPlaying = false;
unsigned long tempo = 120;
unsigned int ticksPerBeat = 96;
unsigned long tickDuration = 60000 / (tempo * ticksPerBeat);
unsigned long lastTickTime = 0;
int currentTick = 0;
void setup() {
pinMode(ledPin, OUTPUT);
pinMode(buttonPin, INPUT_PULLUP);
pinMode(playButtonPin, INPUT_PULLUP);
pinMode(encoderPinA, INPUT);
pinMode(encoderPinB, INPUT);
lcd1.begin(40, 2);
lcd2.begin(40, 2);
encoderPos = 120;
pinMode(backlightPin, OUTPUT);
pinMode(backlightToggleButton, INPUT_PULLUP);
digitalWrite(backlightPin, backlightState);
}
void loop() {
unsigned long currentTime = millis();
bool backlightReading = digitalRead(backlightToggleButton);
if (backlightReading == LOW && currentTime - lastBacklightToggleTime > debounceDelay) {
backlightState = !backlightState;
digitalWrite(backlightPin, backlightState);
lastBacklightToggleTime = currentTime;
}
bool playButtonReading = digitalRead(playButtonPin);
if (playButtonReading == LOW && currentTime - lastPlayButtonTime > debounceDelay) {
isPlaying = !isPlaying;
if (isPlaying) {
lastTickTime = currentTime;
}
lastPlayButtonTime = currentTime;
}
if (isPlaying && currentTime - lastTickTime >= tickDuration) {
lastTickTime += tickDuration;
currentTick = (currentTick + 1) % ticksPerBeat;
totalTicks++;
updateSequencerDisplay();
}
}
void updateSequencerDisplay() {
int measure = (totalTicks / (ticksPerBeat * 4)) + 1;
int beat = ((totalTicks % (ticksPerBeat * 4)) / ticksPerBeat) + 1;
// Tikit yhden iskun sisällä (1-96, jos ticksPerBeat on 96)
int tickWithinBeat = (totalTicks % ticksPerBeat) + 1;
char buffer[40];
sprintf(buffer, "[SONG:01] [M=%03d/%02d/%02d] [T=%03lu 4/4]", measure, beat, tickWithinBeat, tempo);
lcd1.setCursor(0, 0);
lcd1.print(buffer);
lcd1.setCursor(0, 1);
lcd1.print(" |");
for (int i = 0; i < 4; i++) {
lcd1.print((beat - 1 == i) ? char(255) : '.');
lcd1.print(".......");
}
lcd1.print("|");
}