Multiplexer digitalRead() separate buttons

Hello!

I am building an 8-step sequencer with a touch display to draw the waves which you can have on the individual steps. Right now, I want to use my 8 step buttons and for that I have to get all the individual values, whether its pressed or not, through the multiplexer. For some reason though, if I press any of the, all the others turn on too. The problem is probably, that I don’t use the delay() function, because of obvious reasons. I also tried writing an if statement with a time interval, like if((millis() - lastMillis) > m_interval)… but it doesn’t quite work. I would appreciate every help! The relevant part of the code is in sequencer.cpp at the function stepLED().

Sequencer.cpp:

#include "Sequencer.h"
#include "Display.h"

Sequencer::Sequencer() : ADCFilter(60, 0),
                         Enc1(17, 18),
                         patchCord1(waveform1, envelope1),
                         patchCord2(envelope1, biquad1),
                         patchCord3(biquad1, 0, i2s1, 0),
                         patchCord4(biquad1, 0, i2s1, 1)

{

    biquad1.setLowpass(0, 17000, 0.7);
    AudioMemory(20);
    sgtl5000_1.enable();
    sgtl5000_1.volume(defaultVolume);
    waveform1.begin(WAVEFORM_ARBITRARY); // WAVEFORM_SINE expands to 0 WAVEFORM_ARBITRARY expands to 4
    waveform1.amplitude(amplitude);

    for (unsigned int i{0}; i < 4; ++i)
    {
        pinMode(m_stepLEDPin[i], OUTPUT);
        pinMode(m_stepButtonPin[i], INPUT_PULLUP);
    }
}

float Sequencer::getBPMInterval()
{
    pointerToAnalogValuesBPM = stepLED();
    // Serial.println(*(pointerToAnalogValuesBPM + 1));
    int RawValue = *pointerToAnalogValuesBPM;
    // int RawValue = 140;
    ADCFilter.Filter(RawValue);
    if ((millis() - m_lastMillis) > m_BPMInterval && ADCFilterBefore != ADCFilter.Current() && (ADCFilterBefore - ADCFilter.Current() > m_AnalogThreshold))
    {
        m_lastMillis = millis();
        ADCFilterBefore = ADCFilter.Current();
    }

    // subtract the last reading:
    total = total - readings[readIndex]; // Alle analoge Inputwerte zusammenaddiert, wobei der Wert der neuen Loop abgezogen wird (zieht den nullten Wert ab)
    // read from the sensor:
    readings[readIndex] = RawValue;

    // add the reading to the total:
    total = total + readings[readIndex];
    // advance to the next position in the array:
    readIndex = readIndex + 1;

    if (readIndex >= numReadings)
    {
        // ...wrap around to the beginning:
        readIndex = 0;

        // calculate the average:
        average = total / numReadings;
        average_bpm = mapper(average, 1.0, 1023.0, minBPM, maxBPM);
    }
    if (average_bpm != average_bpm_alt)
    {
        average_bpm_alt = average_bpm;
    }
    float m_interval = (60.0 / average_bpm) * 1000.0;
    return m_interval;
}

unsigned int Sequencer::counter(float interval) // Returns the current position
{
    if ((millis() - m_lastMillis) > getBPMInterval()) // m_interval = 1000 ---> 60 bpm , m_interval = 500 ---> 120bpm
    {
        m_lastMillis = millis();
        m_step++;
        if (m_step == m_STEPNUM)
        {
            m_step = 0;
        }
    }

    return m_step;
}

void Sequencer::muxInit()
{
    pinMode(pin_Out_S0, OUTPUT);
    pinMode(pin_Out_S1, OUTPUT);
    pinMode(pin_Out_S2, OUTPUT);

    pinMode(ledMuxCom, OUTPUT);
    pinMode(buttonMuxCom, INPUT_PULLUP);
    pinMode(potiMuxCom, INPUT);
}

float Sequencer::mapper(float x, float in_min, float in_max, float out_min, float out_max)
{
    return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}

void Sequencer::potiUpdate()
{
    pointerToAnalogValuesFilter = stepLED();
    int filterCutoff = map((*(pointerToAnalogValuesFilter + 5)), 0, 1023, 10, 20000);
    float filterResonance = mapper((*(pointerToAnalogValuesFilter + 6)), 0.0, 1023.0, 0.0, 1.0);
    int frequency = map((*(pointerToAnalogValuesFilter + 4)), 0.0, 1023.0, 30, 20000);
    float attack = mapper((*(pointerToAnalogValuesFilter + 1)), 0.0, 1023.0, 2.0, 11800.0);
    float decay = mapper((*(pointerToAnalogValuesFilter + 2)), 0.0, 1023.0, 35.0, 11800.0);
    float release = mapper((*(pointerToAnalogValuesFilter + 3)), 0, 1023, 2, 1000);
    waveform1.frequency(frequency);
    biquad1.setLowpass(0, filterCutoff, filterResonance);
    envelope1.attack(attack);
    envelope1.decay(decay);
    envelope1.sustain(sustain);
    envelope1.release(release);
}

int *Sequencer::stepLED()
{
    waveform1.arbitraryWaveform(wave1Values, 20000);

    for (unsigned int i{0}; i < 8; ++i)
    {
        int bit1 = bitRead(i, 0);
        int bit2 = bitRead(i, 1);
        int bit3 = bitRead(i, 2);

        digitalWrite(pin_Out_S0, bit1);
        digitalWrite(pin_Out_S1, bit2);
        digitalWrite(pin_Out_S2, bit3);

        if (i == m_step)
        {
            digitalWrite(ledMuxCom, HIGH);
        }
        else if (m_stepBefore != m_step)
        {
            envelope1.noteOn();
            waveform1.amplitude(0.9);
            waveform1.frequency(frequency);
            m_stepBefore = m_step;
        }

        else
        {
            envelope1.noteOff();
            digitalWrite(ledMuxCom, LOW);
        }

        buttonMuxState[i] = digitalRead(buttonMuxCom);
        Serial.print(i);
        Serial.print(":");
        Serial.print(buttonMuxState[i]);
        Serial.print(", ");
        potiMuxState[i] = analogRead(potiMuxCom);
    }
    Serial.println();
    return potiMuxState;
}

void Sequencer::update(int16_t *arrayInput)
{
    wave1Values = arrayInput;
    potiUpdate();
    counter(getBPMInterval());
    stepLED();
    //  stepButtons();
}

Sequencer.h:

#ifndef Sequencer_h
#define Sequencer_h
#include <Encoder.h>
#include <array>
#include <Audio.h>
#include <Wire.h>
#include "Display.h"
#include <MegunoLink.h>
#include <Filter.h>

class Sequencer
{
public:
  Sequencer();
  void start();
  void stop();
  unsigned int counter(float interval);
  // void stepButtons();
  // void stepLED();
  void update(int16_t *arrayInput);
  float getBPMInterval();
  int *stepLED();
  float mapper(float x, float in_min, float in_max, float out_min, float out_max);
  void muxInit();
  void potiUpdate();
  ExponentialFilter<long> ADCFilter;
  float attack = 50;
  float decay = 200;
  float sustain = 200;
  float release = 200;
  float amplitude = 0.5;
  int frequency = 300;
  std::array<boolean, 4> digitalReadValues;
  int16_t *wave1Values;
  float defaultAttackValue = {50};
  float defaultDecayValue = {200};
  float defaultSustainValue = {200};
  float defaultReleaseValue = {200};
  float defaultVolume = {0.5};
  unsigned long m_lastMillis;
  static const int waveTotal = 4;
  float m_interval = (60.0 / average_bpm) * 1000.0;
  unsigned long m_stepStateInterval = 20;
  unsigned long m_buttonMuxInterval = 100;
  unsigned int m_STEPNUM = 8;
  unsigned int m_step = 0;
  const int numReadings = 5; // Anzahl der Readings
  int readings[5];           // the readings from the analog input
  int readIndex = 0;         // the index of the current reading
  int total = 0;             // the running total
  float average = 0;         // the average
  int inputPin = A3;         // Analog input
  int average_bpm = 120;
  int average_bpm_alt = 120;
  unsigned long m_BPMInterval = 400;
  int m_AnalogThreshold = 3;
  int ADCFilterBefore;
  float interval;
  float minBPM = 40.0;
  float maxBPM = 800.0;
  long positionEnc1 = -999;
  AudioSynthWaveform waveform1;
  AudioEffectEnvelope envelope1;
  AudioFilterBiquad biquad1;
  AudioOutputI2S i2s1;
  AudioConnection patchCord1;
  AudioConnection patchCord2;
  AudioConnection patchCord3;
  AudioConnection patchCord4;
  AudioControlSGTL5000 sgtl5000_1;
  int pin_Out_S0 = 2;
  int pin_Out_S1 = 3;
  int pin_Out_S2 = 4;
  int buttonMuxState[8];
  int potiMuxState[8];
  int ledMuxState[8];
  unsigned int m_stepBefore;

  int ledMuxCom = 14;
  int buttonMuxCom = 15;
  int potiMuxCom = 16;
  int *pointerToAnalogValuesBPM;
  int *pointerToAnalogValuesFilter;

private:
};

#endif

main.cpp:

#include <Arduino.h>
#include <SD.h>
#include <SerialFlash.h>
#include <Encoder.h>
#include "Display.h"
#include "Sequencer.h"

Display display;
Sequencer sequencer;

void setup()
{
  sequencer.muxInit();
  display.init();
}

void loop()
{
  display.update();
  sequencer.update(display.wave1Values);
}

I can't troubleshoot this because you have combined code that performs different functions together. It makes understanding the operation an uphill battle. If you had a separate function to read the buttons (reasonable, no?) then I could help.

You are right. Here is the part I meant, rewrote in a simpler manner:

int pin_Out_S0 = 2;
int pin_Out_S1 = 3;
int pin_Out_S2 = 4;

unsigned int m_step = 0;
unsigned int m_stepBefore;
unsigned long m_lastMillis;
unsigned int m_STEPNUM = 8;

int buttonMuxState[8];
int potiMuxState[8];
float bpmInterval = 100.0;

int ledMuxCom = 14;
int buttonMuxCom = 15;
int potiMuxCom = 16;

int bit1 = 0;
int bit2 = 0;
int bit3 = 0;

void setup() {

  pinMode(pin_Out_S0, OUTPUT);
  pinMode(pin_Out_S1, OUTPUT);
  pinMode(pin_Out_S2, OUTPUT);

  pinMode(ledMuxCom, OUTPUT);
  pinMode(buttonMuxCom, INPUT_PULLUP);
  pinMode(potiMuxCom, INPUT);
}

void loop() {

  if ((millis() - m_lastMillis) > bpmInterval) // m_interval = 1000 ---> 60 bpm , m_interval = 500 ---> 120bpm
  {
    m_lastMillis = millis();
    m_step++;
    if (m_step == m_STEPNUM)
    {
      m_step = 0;
    }
  }

  for (unsigned int i{0}; i < 8; ++i)
  {
    int bit1 = bitRead(i, 0);
    int bit2 = bitRead(i, 1);
    int bit3 = bitRead(i, 2);

    digitalWrite(pin_Out_S0, bit1);
    digitalWrite(pin_Out_S1, bit2);
    digitalWrite(pin_Out_S2, bit3);

    if (i == m_step)
    {
      digitalWrite(ledMuxCom, HIGH);
    }

    else
    {
      digitalWrite(ledMuxCom, LOW);
    }

    buttonMuxState[i] = digitalRead(buttonMuxCom);
    Serial.print(i);
    Serial.print(":");
    Serial.print(buttonMuxState[i]);
    Serial.print(", ");
    potiMuxState[i] = analogRead(potiMuxCom);
  }
  Serial.println();
}

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.