Utilizing Static Variable within Object Array

Hi,
I'm trying to break out some example code into it's own class so I can instantiate several sensors of the same type of multiple pins. The problem is that the loop function uses a set of static variables to avoid the variables resetting within the loop() function, but when I break out the function into a class the program treats those variables as the same for each instance of the object.

I just can't wrap my brain around how I would avoid this to make it work, obviously using a standard non-static variable would work with the object instantiation but they the logic within the loop function doesn't work properly.

Any ideas would be helpful.

#define NUM_SENSORS 4

#include "Piezo.h"

//const int analogPin = A0;
//Piezo_Drum *pad = Piezo_Drum(10, 38);
static const uint8_t analogPins[] = {A0,A1,A2,A3};
Piezo_Drum *pad[NUM_SENSORS];

void setup() {
  
  Serial.begin(115200);
  while (!Serial && millis() < 2500) /* wait for serial monitor */ ;
  Serial.println("Start...");
  
  int midiNote = 59; 
  for (int i = 0; i < NUM_SENSORS; i++) {
    int midiCh = 0; 
    midiNote++;
    pad[i] = new Piezo_Drum(midiCh,midiNote);
  }

}

void loop() {
        

      for (int i = 0; i < NUM_SENSORS; i++) {
        pad[i]->peakDetect(analogRead(analogPins[i]));
      }
          

  while (usbMIDI.read()) {
    // ignore incoming messages
  }
}
class Piezo_Drum
{
  
  private:
    int channel;  // General MIDI: channel 10 = percussion sounds
    int note;     // General MIDI: note 38 = acoustic snare
    
    const int thresholdMin = 60;  // minimum reading, avoid noise and false starts
    const unsigned int peakTrackMillis = 12;
    const unsigned int aftershockMillis = 25; // aftershocks & vibration reject

  public:
   
    Piezo_Drum(int _channel, int _note){
        this->channel = _channel;
        this->note = _note;      
        Serial.println("Loaded Piezo Sensor..." );
    }
   
  void peakDetect(int voltage) {
//    // "static" variables keep their numbers between each run of this function
    static int state;  // 0=idle, 1=looking for peak, 2=ignore aftershocks
    static int peak;   // remember the highest reading
    static elapsedMillis msec; // timer to end states 1 and 2
    

    switch (state) {
      // IDLE state: wait for any reading is above threshold.  Do not set
      // the threshold too low.  You don't want to be too sensitive to slight
      // vibration.
      case 0:
        if (voltage > thresholdMin) {
          //Serial.print("begin peak track ");
          //Serial.println(voltage);
          peak = voltage;
          msec = 0;
          state = 1;
        }
        return;
  
      // Peak Tracking state: capture largest reading
      case 1:
        if (voltage > peak) {
          peak = voltage;  
        }
        if (msec >= peakTrackMillis) {
          //Serial.print("peak = ");
          //Serial.println(peak);
          int velocity = map(peak, thresholdMin, 1023, 1, 127);
          usbMIDI.sendNoteOn(note, velocity, channel);
          Serial.println("Sending MIDI");

          msec = 0;
          state = 2;
        }
        return;
  
      // Ignore Aftershock state: wait for things to be quiet again.
      default:
        if (voltage > thresholdMin) {
          msec = 0; // keep resetting timer if above threshold
        } else if (msec > aftershockMillis) {
          usbMIDI.sendNoteOff(note, 0, channel);
          state = 0; // go back to idle when
        }
    }
  }


};

Static has a different meaning when used for class member functions and variables than it does otherwise.

Move the variable that you want to persist between to the the various class member function out of the functions and make them class member variables. But, NOT static. That will make them unique to each instance of the class and their values will persist between calls.

I made the fix as suggested in the comments, thanks so much!

FYI this code is used to input multiple piezo sensors to multiple input pins for anyone that this could help.

#define NUM_SENSORS 4

#include "Piezo.h"

//const int analogPin = A0;
//Piezo_Drum *pad = Piezo_Drum(10, 38);
static const uint8_t analogPins[] = {A0,A1,A2,A3};
Piezo_Drum *pad[NUM_SENSORS];
int state;  // 0=idle, 1=looking for peak, 2=ignore aftershocks
int peak;   // remember the highest reading
elapsedMillis msec; // timer to end states 1 and 2
    

void setup() {
  
  Serial.begin(115200);
  while (!Serial && millis() < 2500) /* wait for serial monitor */ ;
  Serial.println("Start...");
  
  int midiNote = 59; 
  for (int i = 0; i < NUM_SENSORS; i++) {
    int midiCh = 0; 
    midiNote++;
    pad[i] = new Piezo_Drum(midiCh,midiNote);
  }

}

void loop() {
        

      for (int i = 0; i < NUM_SENSORS; i++) {
        //int piezo = analogRead(analogPins[i]);
        pad[i]->peakDetect(analogRead(analogPins[i]));
      }
       // pad[0]->peakDetect(analogRead(analogPins[0]));



  // Serial.println(analogRead(analogPins[0])); DEBUG Pins 

  // MIDI Controllers should discard incoming MIDI messages.
  // http://forum.pjrc.com/threads/24179-Teensy-3-Ableton-Analog-CC-causes-midi-crash
  while (usbMIDI.read()) {
    // ignore incoming messages
  }
}
class Piezo_Drum
{
  
  private:
    int channel;  // General MIDI: channel 10 = percussion sounds
    int note;     // General MIDI: note 38 = acoustic snare
    
    const int thresholdMin = 60;  // minimum reading, avoid noise and false starts
    const unsigned int peakTrackMillis = 12;
    const unsigned int aftershockMillis = 25; // aftershocks & vibration reject
    int state;  // 0=idle, 1=looking for peak, 2=ignore aftershocks
    int peak;   // remember the highest reading
    elapsedMillis msec; // timer to end states 1 and 2


  public:
   
    Piezo_Drum(int _channel, int _note){
        this->channel = _channel;
        this->note = _note;      
        Serial.println("Loaded Piezo Sensor..." );
    }
   
  void peakDetect(int voltage) {
//    // "static" variables keep their numbers between each run of this function
//    static int state;  // 0=idle, 1=looking for peak, 2=ignore aftershocks
//    static int peak;   // remember the highest reading
//    static elapsedMillis msec; // timer to end states 1 and 2
   

    switch (state) {
      // IDLE state: wait for any reading is above threshold.  Do not set
      // the threshold too low.  You don't want to be too sensitive to slight
      // vibration.
      case 0:
        if (voltage > thresholdMin) {
          //Serial.print("begin peak track ");
          //Serial.println(voltage);
          peak = voltage;
          msec = 0;
          state = 1;
        }
        return;
  
      // Peak Tracking state: capture largest reading
      case 1:
        if (voltage > peak) {
          peak = voltage;  
        }
        if (msec >= peakTrackMillis) {
          //Serial.print("peak = ");
          //Serial.println(peak);
          int velocity = map(peak, thresholdMin, 1023, 1, 127);
          usbMIDI.sendNoteOn(note, velocity, channel);
          Serial.println("Sending MIDI");

          msec = 0;
          state = 2;
        }
        return;
  
      // Ignore Aftershock state: wait for things to be quiet again.
      default:
        if (voltage > thresholdMin) {
          msec = 0; // keep resetting timer if above threshold
        } else if (msec > aftershockMillis) {
          usbMIDI.sendNoteOff(note, 0, channel);
          state = 0; // go back to idle when
        }
    }
  }


};