#include <AltSoftSerial.h>
#include <wavTrigger.h> // wavTrigger.h is changed to use hardware serial1
#include <LiquidCrystal_I2C.h> // LCD Library
#include <OneButton.h>
#include <TimerOne.h>
LiquidCrystal_I2C lcd(0x27, 20, 4); // set the LCD address to 0x27 for a 16 chars and 2 line display
#define NUM_BTN_COLUMNS (8)
#define NUM_BTN_ROWS (5)
#define NUM_KEYS (37)
#define MAX_DEBOUNCE (10)
#define encoder1A 42
#define encoder1B 43
#define encoder2A 44
#define encoder2B 45
// Global variables
static const uint8_t btnrowpins[NUM_BTN_ROWS] = {30, 31, 32, 33, 34};
static const uint8_t btncolumnpins[NUM_BTN_COLUMNS] = {22, 23, 24, 25, 26, 27, 28, 29};
static int8_t debounce_count[NUM_BTN_ROWS][NUM_BTN_COLUMNS];
wavTrigger wTrig; // WAV Trigger object
int gWTrigState = 0; // WAV Trigger state
int gRateOffset = 0; // WAV Trigger sample-rate offset
int gain = 0;
int counter1;
int counter2;
int aState1;
int aLastState1;
int aState2;
int aLastState2;
int Track = 0;
int voice1 = 0;
int voice2 = 0;
int voice1_old = 0;
int voice2_old = 0;
int Keys[NUM_KEYS];
char buffer1[17]; // lcd display line 1
char buffer2[17]; // lcd display line 2
const int numOfScreens = 19;
int currentScreen1 = 0;
int currentScreen2 = 0;
char* Bank1[numOfScreens] = {
/* "1234567890123456", "1234567890123456", "1234567890123456", */
/* 1*/ "A:MkII Flute ", "A:MkII 3 Violins", "A:MkII Guitar ",
/* 2*/ "A:MkII Organ ", "A:MkII Brass ", "A:MkII Accordion",
/* 3*/ "A:MKII Sax ", "A:MkII Vibes ", "A:MkII Tibia Org",
/* 4*/ "A:M300 Strings A", "A:M300 Strings B", "A:M400 Cello ",
/* 5*/ "A:M400 Viola ", "A:M400 16Violins", "A:M400 Strings ",
/* 6*/ "A:M400 8-V Choir", "A:M400 Boy Choir", "A:M400 Mix Choir",
/* 7*/ "A:M400 GC Brass "
};
char* Bank2[numOfScreens] = {
/* "1234567890123456", "1234567890123456", "1234567890123456", */
/* 1*/ "B:MkII Flute ", "B:MkII 3 Violins", "B:MkII Guitar ",
/* 2*/ "B:MkII Organ ", "B:MkII Brass ", "B:MkII Accordion",
/* 3*/ "B:MKII Sax ", "B:MkII Vibes ", "B:MkII Tibia Org",
/* 4*/ "B:M300 Strings A", "B:M300 Strings B", "B:M400 Cello ",
/* 5*/ "B:M400 Viola ", "B:M400 16Violins", "B:M400 Strings ",
/* 6*/ "B:M400 8-V Choir", "B:M400 Boy Choir", "B:M400 Mix Choir",
/* 7*/ "B:M400 GC Brass "
};
int voices1[19] = {
/* 1*/ 1, 36, 71,
/* 2*/ 106, 141, 176,
/* 3*/ 211, 246, 281,
/* 4*/ 316, 351, 386,
/* 5*/ 421, 456, 491,
/* 6*/ 526, 561, 596,
/* 7*/ 631
};
int voices2[19] = {
/* 1*/ 1, 36, 71,
/* 2*/ 106, 141, 176,
/* 3*/ 211, 246, 281,
/* 4*/ 316, 351, 386,
/* 5*/ 421, 456, 491,
/* 6*/ 526, 561, 596,
/* 7*/ 631
};
int i_key;
int key_input;
void setup()
{
// put your setup code here, to run once:
lcd.init(); // initialize the lcd
lcd.init();
// Print a message to the LCD.
lcd.backlight();
lcd.setCursor(3, 0);
lcd.print("Mellowtron");
lcd.setCursor(2, 1);
lcd.print("Version 1.0");
delay(5000);
lcd.begin(16, 2);
lcd.clear();
Serial.begin(9600);
wTrig.start(); // WAV Trigger startup at 57600
wTrig.samplerateOffset(gRateOffset);
wTrig.masterGain(gain);
Serial.print("Starting Setup...");
// setup hardware
setuppins();
Serial.println("Setup Complete.");
for (Track = 1; Track <= 665; Track++) {
wTrig.trackGain(Track, -10);
}
pinMode (encoder1A, INPUT);
pinMode (encoder1B, INPUT);
pinMode (encoder2A, INPUT);
pinMode (encoder2B, INPUT);
aLastState1 = digitalRead(encoder1A);
aLastState2 = digitalRead(encoder2A);
counter1 = 0;
counter2 = 0;
}
static void setuppins()
{
uint8_t i;
// initialize
// select lines
// button columns
for (i = 0; i < NUM_BTN_ROWS; i++)
{
pinMode(btnrowpins[i], OUTPUT);
// with nothing selected by default
digitalWrite(btnrowpins[i], HIGH);
}
// button row input lines
for (i = 0; i < NUM_BTN_COLUMNS; i++)
{
pinMode(btncolumnpins[i], INPUT_PULLUP);
}
// Initialize the debounce counter array
for (uint8_t i = 0; i < NUM_BTN_ROWS; i++)
{
for (uint8_t j = 0; j < NUM_BTN_COLUMNS; j++)
{
debounce_count[i][j] = 0;
}
}
}
static void scan()
{
static uint8_t current = 0;
uint8_t key_input;
uint8_t i, j;
// Select current columns
digitalWrite(btnrowpins[current], LOW);
// pause a moment
delay(0);
// Read the button inputs
for ( j = 0; j < NUM_BTN_COLUMNS; j++)
{
key_input = digitalRead(btncolumnpins[j]);
i_key = (current * NUM_BTN_COLUMNS) + j;
if (key_input == LOW)
{
// active low: val is low when btn is pressed
if ( debounce_count[current][j] < MAX_DEBOUNCE)
{
debounce_count[current][j]++;
if ( debounce_count[current][j] == MAX_DEBOUNCE )
{
if ( 1 < i_key && i_key <= 36) {
Serial.print("Key Down ");
Serial.println(i_key);
wTrig.trackPlayPoly(voice1 + i_key - 2);
/* wTrig.trackPlayPoly(voice2 + i_key - 2);*/
}
}
}
}
else
{
// otherwise, button is released
if ( debounce_count[current][j] > 0)
{
debounce_count[current][j]--;
if ( debounce_count[current][j] == 0 )
{
Serial.print("Key Up ");
Serial.println((current * NUM_BTN_COLUMNS) + j);
wTrig.trackStop(voice1 + i_key - 2);
/* wTrig.trackStop(voice2 + i_key - 2);*/
// If you want to do something when a key is released, do it here:
}
}
}
}
delay(1);
digitalWrite(btnrowpins[current], HIGH);
current++;
if (current >= NUM_BTN_ROWS)
{
current = 0;
}
}
void encoder1() {
aState1 = digitalRead(encoder1A);
if (aState1 != aLastState1) {
if (digitalRead(encoder1B) != aState1) {
if (counter1 < 18) {
counter1 ++;
}
else {
counter1 = 0;
}
wTrig.trackStop(voice1 + i_key - 2);
}
else {
if (counter1 >= 1) {
counter1 --;
}
else {
counter1 = 18;
}
wTrig.trackStop(voice1 + i_key - 2);
}
int i_voice1 = 0;
i_voice1 = i_voice1 + counter1;
voice1 = voices1[i_voice1];
lcd.setCursor(0, 0);
lcd.print(Bank1[i_voice1]);
Serial.print("Position1: ");
Serial.println(counter1);
Serial.println(Bank1[i_voice1]);
}
aLastState1 = aState1;
aState2 = digitalRead(encoder2A);
if (aState2 != aLastState2) {
if (digitalRead(encoder2B) != aState2) {
if (counter2 < 18) {
counter2 ++;
}
else {
counter2 = 0;
}
wTrig.trackStop(voice2 + i_key - 2);
}
else {
if (counter2 >= 1) {
counter2 --;
}
else {
counter2 = 18;
}
wTrig.trackStop(voice2 + i_key - 2);
}
int i_voice2 = 0;
i_voice2 = i_voice2 + counter2;
voice2 = voices2[i_voice2];
lcd.setCursor(0, 1);
lcd.print(Bank2[i_voice2]);
Serial.print("Position2: ");
Serial.println(counter2);
Serial.println(Bank2[i_voice2]);
}
aLastState2 = aState2;
}
void loop() {
// put your main code here, to run repeatedly:
encoder1();
scan();
}
Here is the updated code. You'll see a 2nd encoder (allows me to control individually two separate sound banks). I merely duplicated that for Encoder1, so the same issue follows both encoders.