Code:
/**
* @file main.cpp
* @author Christian Grothe
* @brief
* @version 0.1
* @date 2023-01-27
*
* @copyright Copyright (c) 2023
*
*/
#include <Arduino.h>
#include <EEPROM.h>
#include <Bounce2.h>
#include "LedControl.h"
/**
* @brief Constants
*
*/
const uint8_t NUM_BUTTONS = 3;
const uint8_t NUM_BITOUT = 6;
const uint8_t NUM_BITS = 3;
const uint8_t DOTS = 36;
const uint8_t ROWS = 6;
// Matrix Buttons
Bounce *buttonsX = new Bounce[8];
Bounce *buttonsY = new Bounce[8];
/**
* @brief GPIO
*
*/
const uint8_t interruptPinA = 2;
const uint8_t interruptPinB = 3;
const uint8_t gateOutA = 4;
const uint8_t gateOutB = 5;
// bit outs for 4051 Buttons
const uint8_t muxOut1 = 6;
const uint8_t muxOut2 = 7;
const uint8_t muxOut3 = 8;
const uint8_t muxReturnA = 9;
const uint8_t muxReturnB = 10;
const uint8_t din = 15;
const uint8_t clck = 14;
const uint8_t load = 13;
LedControl ledMatrix = LedControl(din, clck, load, 1);
// bit outs for 4051 Seqence
const uint8_t BitOut[NUM_BITOUT] = {16, 17, 18, 19, 20, 21};
/**
* @brief Variable Variables
*
*/
// Sequence Counters
volatile int counterA = 3;
volatile int counterB = 3;
// populated with presets in setup
bool Presets[6][DOTS] = {{}, {}, {}, {}, {}, {}};
// handle gate Out
bool isGateOnA = false;
bool isGateOnB = false;
unsigned long millisCountA = 0;
unsigned long millisCountB = 0;
unsigned int gateLengthA = 20;
unsigned int gateLengthB = 20;
// bit counts for 4051
int muxBit1;
int muxBit2;
int muxBit3;
// populated with bit read
int bits[ROWS];
// menu
int shownPreset = 0;
int usedPreset = 1;
int presetCount = 0;
bool setStates[6] = {0, 0, 0, 0, 0, 0};
bool lastStates[6] = {0, 0, 0, 0, 0, 0};
bool lastBitStatesA[3] = {0,0,0};
bool lastBitStatesB[3] = {0,0,0};
int presetToggler = 0;
enum Menue
{
main,
setPresetCount,
setChangePresets
};
Menue menue = setPresetCount;
// temp
bool PresetA[DOTS] = {1, 0, 0, 0, 0, 0,
0, 1, 0, 0, 0, 0,
0, 0, 1, 0, 0, 0,
0, 0, 0, 1, 0, 0,
0, 0, 0, 0, 1, 0,
0, 0, 0, 0, 0, 1};
bool PresetB[DOTS] = {0, 0, 0, 0, 0, 0,
0, 0, 0, 1, 0, 0,
0, 0, 0, 0, 0, 0,
0, 1, 0, 0, 0, 1,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 1, 0};
bool PresetC[DOTS] = {0, 0, 0, 0, 0, 0,
0, 0, 0, 1, 0, 0,
0, 0, 0, 0, 0, 0,
1, 0, 0, 0, 0, 0,
0, 0, 0, 0, 1, 0,
0, 0, 1, 0, 0, 0};
bool PresetD[DOTS] = {0, 0, 0, 0, 0, 0,
0, 0, 1, 0, 0, 0,
0, 0, 0, 0, 0, 1,
1, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0, 0, 0, 1, 0, 0};
bool PresetE[DOTS] = {0, 1, 0, 0, 0, 0,
0, 0, 0, 0, 0, 1,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 1, 0,
0, 1, 0, 0, 0, 0};
bool PresetF[DOTS] = {0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 1, 0,
0, 0, 1, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0, 0, 0, 1, 0, 0,
0, 0, 0, 0, 0, 1};
/**
* @brief Functions
*
*/
void presetToggling()
{
presetToggler++;
if (presetToggler == 6)
{
presetToggler = 0;
}
}
void configPresetCounter(int bits[])
{
//byte states[4] = {B00000000, B11100000, B00011100, B11111100};
byte states[2] = {B00000000, B11100000};
for (int i = 0; i < 6; i++)
{
if (buttonsX[i].rose())
{
setStates[i] = !setStates[i];
}
//ledMatrix.setRow(0, i, states[bits[i] + setStates[i] * 2]);
ledMatrix.setRow(0, i, states[bits[i]]);
}
}
void presetCounter(int bits[])
{
for (int i = 0; i < 6; i++)
{
if (bits[i] != lastStates[i])
{
if (setStates[i])
{
presetCount++;
if (presetCount == 6)
{
presetCount = 0;
}
lastStates[i] = bits[i];
}
}
}
}
void changePreset(int preset) {
for (int i = 0; i < 6; i++) {
for (int j = 0; j < 6; j++) {
if ((buttonsX[i].rose() && buttonsY[j].read() == HIGH) || (buttonsX[i].read() == HIGH && buttonsY[j].rose())) {
Presets[preset][i + 6 * j] = !Presets[preset][i + 6 * j];
}
}
}
}
void showPresetOnMatrix(int preset)
{
for (int i = 0; i < ROWS; i++)
{
ledMatrix.setLed(0, 0, i, Presets[preset][i]);
ledMatrix.setLed(0, 1, i, Presets[preset][i + ROWS]);
ledMatrix.setLed(0, 2, i, Presets[preset][i + ROWS * 2]);
ledMatrix.setLed(0, 3, i, Presets[preset][i + ROWS * 3]);
ledMatrix.setLed(0, 4, i, Presets[preset][i + ROWS * 4]);
ledMatrix.setLed(0, 5, i, Presets[preset][i + ROWS * 5]);
}
}
bool sumofbits_function(int column, int preset) {
for (int i = 0; i < 6; i++) {
if (bits[i] && Presets[preset][column + i * 6]) {
return 1;
}
}
return 0;
}
void countingA()
{
counterA = (counterA == 7) ? 0 : counterA + 1;
}
void countingB()
{
counterB = (counterB == 7) ? 0 : counterB + 1;
}
void saveChangesToEEPROM()
{
for (int i = 0; i < DOTS; i++)
{
EEPROM.update(i, Presets[0][i]);
EEPROM.update(i + DOTS, Presets[1][i]);
EEPROM.update(i + (DOTS * 2), Presets[2][i]);
EEPROM.update(i + (DOTS * 3), Presets[3][i]);
EEPROM.update(i + (DOTS * 4), Presets[4][i]);
EEPROM.update(i + (DOTS * 5), Presets[5][i]);
}
}
/**
* @brief Teensy Setup
*
*/
void setup()
{
Serial.begin(9600);
pinMode(interruptPinA, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(interruptPinA), countingA, FALLING);
pinMode(interruptPinB, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(interruptPinB), countingB, FALLING);
// Display Setup
ledMatrix.shutdown(0, false);
ledMatrix.setIntensity(0, 5);
ledMatrix.clearDisplay(0);
// reading from the EEPROM
for (int i = 0; i < DOTS; i++)
{
Presets[0][i] = PresetA[i];
Presets[1][i] = PresetB[i];
Presets[2][i] = PresetC[i];
Presets[3][i] = PresetD[i];
Presets[4][i] = PresetE[i];
Presets[5][i] = PresetF[i];
// Presets[0][i] = EEPROM.read(i);
// Presets[1][i] = EEPROM.read(i + DOTS);
// Presets[2][i] = EEPROM.read(i + DOTS * 2);
// Presets[3][i] = EEPROM.read(i + DOTS * 3);
// Presets[4][i] = EEPROM.read(i + DOTS * 4);
// Presets[5][i] = EEPROM.read(i + DOTS * 5);
}
// Set Up BitOut to 4051 SQ
for (int i = 0; i < NUM_BITOUT; i++)
{
pinMode(BitOut[i], OUTPUT);
}
for (int i = 0; i < 8; i++)
{
buttonsX[i].attach(muxReturnA, INPUT);
buttonsX[i].interval(20);
buttonsY[i].attach(muxReturnB, INPUT);
buttonsY[i].interval(20);
}
pinMode(muxOut1, OUTPUT);
pinMode(muxOut2, OUTPUT);
pinMode(muxOut3, OUTPUT);
pinMode(gateOutA, OUTPUT);
pinMode(gateOutB, OUTPUT);
}
/**
* @brief Teensy Main Loop
*
*/
void loop()
{
//multiplexer for buttons
for (int i = 0; i < 8 ; i++)
{
buttonsX[i].update();
buttonsY[i].update();
muxBit1 = ((i + 1) & 0b001);
muxBit3 = ((i + 1) & 0b100) >> 2;
muxBit2 = ((i + 1) & 0b010) >> 1;
digitalWrite(muxOut1, muxBit1);
digitalWrite(muxOut2, muxBit2);
digitalWrite(muxOut3, muxBit3);
}
// convert count to bits
for (int i = 0; i < NUM_BITS; i++)
{
bits[i] = bitRead(counterA, i);
bits[i + 3] = bitRead(counterB, i);
}
// change preset
for (int i = 0; i < 6; i++)
{
if (buttonsY[6].read() == HIGH && buttonsX[i].rose())
{
shownPreset = i;
usedPreset = i;
}
}
// bit output to 4051 SQ
for (int i = 0; i < 3; i++)
{
int stateA = sumofbits_function(i + 3, presetCount);
int stateB = sumofbits_function(i, presetCount);
digitalWrite(BitOut[i], stateA);
digitalWrite(BitOut[i+3], stateB);
if (stateA != lastBitStatesA[i]){
digitalWrite(gateOutA, HIGH);
lastBitStatesA[i] = stateA;
isGateOnA = true;
millisCountA = millis();
}
if (stateB != lastBitStatesB[i]){
digitalWrite(gateOutB, HIGH);
lastBitStatesB[i] = stateB;
isGateOnB = true;
millisCountB = millis();
}
}
if(millis() - millisCountA >= gateLengthA && isGateOnA){
digitalWrite(gateOutA, LOW);
isGateOnA = false;
gateLengthA = random(20,30);
}
if(millis() - millisCountB >= gateLengthB && isGateOnB){
digitalWrite(gateOutB, LOW);
isGateOnB = false;
gateLengthB = random(20,30);
}
// toggle menue
if (buttonsY[7].rose())
{
menue = setPresetCount;
}
else if (buttonsY[6].rose())
{
menue = main;
}
else if (buttonsX[7].rose())
{
menue = setChangePresets;
presetToggling();
}
else if (buttonsX[6].rose())
{
saveChangesToEEPROM();
}
switch (menue)
{
case main:
showPresetOnMatrix(presetCount);
//changePreset(presetCount);
//presetCounter(bits);
break;
case setPresetCount:
// presetCounter(bits);
configPresetCounter(bits);
break;
case setChangePresets:
//showPresetOnMatrix(presetToggler);
// changePreset(presetToggler);
// presetCounter(bits);
break;
default:
break;
}
}
/// End Of Main Loop ///