Need help creating a class/library

Hi all,

i'm looking to learn creating classes and libraries. Right now i have a working sketch that i want to rewrite as a class. Therefore i'd really appreciate some guidance.

I have looked at the library tutorial, several forum threads and the example libraries but haven't been able to fully translate that info to the class i'm creating.

My plan is to create a .cpp and .h file for the class, and call them from a .ino sketch (that eventually will utilize more classes). More specifically, i want the class to generate four separate arrays with sixteen steps each.

Here is some of the code i have this far (I'm not 100% sure what info you need, so i'll try my best to be on point and brief):

RuleGeneratedDiatonicChords.cpp file constructor:

...


RuleGeneratedDiatonicChords::RuleGeneratedDiatonicChords {

//original sketch code here

}

RuleGeneratedDiatonicChords.h:

class RuleGeneratedDiatonicChords
{
  public:
    RuleGeneratedDiatonicChords;

    float loop1[16];  
    float loop2[16];  
    float loop3[16];  
    float loop4[16]; 

  private:
    int note;
};

Sequencer.ino:

//Instantiating class object:
RuleGeneratedDiatonicChords loopA;

...

//Calling object property:
RuleGeneratedDiatonicChords loopA.loop1[];

As you probably can tell, i am struggling quite a bit with making the syntax correct. Your help is appreciated!

If i understand right, nothing needs to be passed to the class for it to work, but i need to make the array properties public for them to be called (correct?).

(Please bear in mind that i am self taught, doing what i can with the info i find on google. In other words, your patience is appreciated! ;D)

At first glance, I see nothing that you couldn't do with a simple struct.

aarg:
At first glance, I see nothing that you couldn't do with a simple struct.

I see your point. What i've showed is one of many to-be classes, and therefore i try to make everything more managable by converting a long sketch into separate classes. The original sketch is becoming somewhat difficult to oversee...

Really? Have you done any simple code factoring by using arrays, functions and so on? Perhaps you should post your code, so we aren’t guessing in the dark…

aarg:
At first glance, I see nothing that you couldn't do with a simple struct.

tomayto tomahto

Here’s the original sketch (i cut some stuff out for brevity, but you probably get the idea):

#include <StandardCplusplus.h>
#include <vector>
#include <ADDAC.h>
#include <avr/eeprom.h>

//Debugging console
#define DEBUG

//Instansiera klasser
ADDAC VCC;

//Deklarera variabler
float interval = 0.0166666666666666667; //För att generera CV för kromatiska noter

float loop1[16];  //Loop för kanal 1
float loop2[16];  //Loop för kanal 2
float loop3[16];  //Loop för kanal 3
float loop4[16];  //Loop för kanal 4

int note;

int numberOfBars = 0; //Anger hur många gånger de fyra takterna A-D ska loopas, innan nya A-D genereras
int loopPos = 0; //Vilket steg i loopen som spelas

void setup() {

  VCC.setup();

  //Funktionsanrop
  void generateLoops();

  //För randomisering
  uint16_t seed = eeprom_read_word(0);
  randomSeed(seed++);
  eeprom_write_word(0, seed);

  //Inställningar för debug
#ifdef DEBUG
  Serial.begin(115200);
#endif

}

//Globala funktioner

//Generera en ackordloop på 16 steg
void generateLoops(float loop1[], float loop2[], float loop3[], float loop4[]) {
  int major[] = {1, 3, 5, 6, 8, 10, 12, 13, 15, 17, 18, 20, 22, 24, 25, 27, 29, 30, 32};   //Durskalans notsteg i halvnoter
  for (int i = 15; i > -1 ; i--) {

    if (i == 15) {
      int randomNote = random(2);
      if (randomNote == 0) {
        note = 4;                                       //Avsluta sekvensens steg 16 med ett V-ackord
        Serial.print("V   ");
      }
      else if (randomNote == 1) {
        note = 6;                                       //Avsluta sekvensens steg 16 med ett vii-ackord
        Serial.print("vii ");
      }
    }

    else if (i == 14) {                                //Bestäm ackord som leder upp till steg 16
      do {
        int randomNote = random(5);
        if (randomNote == 0) {
          note = 0;                         //Ackord I
        }
        else if (randomNote == 1) {
          note = 1;                         //Ackord ii
        }
        else if (randomNote == 2) {
          note = 3;                         //Ackord IV
        }
        else if (randomNote == 3) {
          note = 4;                         //Ackord V
        }
        else if (randomNote == 4) {
          note = 6;                         //Ackord vii
        }
      } while ((loop1[15] == 8 && note == 4) || (loop1[15] == 12 && note == 6));

...

    else if (i == 1) {
      do {
        int randomNote = random(1, 7);
        note = randomNote;
      } while (major[note] == loop1[2]);

      if (note == 1) {
        Serial.print("ii  ");                     //Ackord ii
      }
      else if (note == 2) {
        Serial.print("iii ");                     //Ackord iii
      }
      else if (note == 3) {
        Serial.print("IV  ");                     //Ackord IV
      }
      else if (note == 4) {
        Serial.print("V   ");                     //Ackord V
      }
      else if (note == 5) {
        Serial.print("vi  ");                     //Ackord vi
      }
      else if (note == 6) {
        Serial.print("vii ");                     //Ackord vii
      }
    }

    else if (i == 0) {
      note = 0;
      Serial.print("I   ");
    }

    loop1[i] = major[note];
    int note2 = note + 2;
    int note3 = note + 4;
    int note4 = note + 6;
    loop2[i] = major[note2];                      //Genererar tersen, två skaltoner ovanför grundton
    loop3[i] = major[note3];                      //Genererar kvinten, fyra skaltoner ovanför grundton
    loop4[i] = major[note4];                    //Genererar septiman, sex skaltoner ovanför grundton
    Serial.println(String(i + 1) + ": " + String(loop1[i]));  // + " " + String(loop2[i]) + " " + String(loop3[i]) + " " + String(loop4[i]));
  }
  Serial.println();
}



void loop() {
  VCC.update();                                    //Uppdaterar instansen VCC
  //Serial.println("VCC uppdaterad");
  generateLoops(loop1, loop2, loop3, loop4);
  if (VCC.MODE == 1) {                                       //Mode 1: Generera en loop, och lägg till ters, kvint och septima
    if (VCC.SUBMODE == 0) {                                  //Submode 0:
      for (int numberOfBars = 0; numberOfBars < 4 ; numberOfBars++) {  //Loopar de 16 stegen * numberOfBars
        //Generera struktur för bars här
        for (int loopPos = 0; loopPos < 16; loopPos++) {

          /*
            Serial.print("Takt " + String(numberOfBars + 1) + " ");
            Serial.print("Steg " + String(loopPos + 1) + ": ");
            Serial.print(" - Toner " + String(loop1[loopPos]) + " ");


            Serial.print(String(loop1[loopPos]) + " ");
            Serial.print(String(loop2[loopPos]) + "  ");
            Serial.print(String(loop3[loopPos]) + "  ");
            Serial.println(String(loop4[loopPos]));

            Serial.println();
          */

          VCC.WriteChannel(0, loop1[loopPos] * interval);     //Skickar kromatisk CV till output 1 efter genererad loop
          VCC.WriteChannel(1, loop2[loopPos] * interval);     //Skickar kromatisk CV till output 2 efter genererad loop
          VCC.WriteChannel(2, loop3[loopPos] * interval);     //Skickar kromatisk CV till output 3 efter genererad loop
          VCC.WriteChannel(3, loop4[loopPos] * interval);     //Skickar kromatisk CV till output 4 efter genererad loop

          delay(300);
        }
      }
    }
  }
#ifdef DEBUG
  //Serial.println("Takt " + String(numberOfBars + 1) + " Steg " + String(loopPos + 1) + " " + String(loop1[loopPos]) + String(interval));
#endif
}

I ask about creating classes is because i am looking to integrate a bunch of other similar sketches besides this one. Therefore the need for a more structured approach. The idea is that writing classes instead of having 7-8 separate sketches could help me integrate everything, as soon as i’ve gotten my head around the syntax/structure for classes/libraries. Does this make sense? :wink:

That is not how to define a constructor

  public:
    RuleGeneratedDiatonicChords;

same here

RuleGeneratedDiatonicChords::RuleGeneratedDiatonicChords {
class Dumbo {
public:
  Dumbo(); // a constructor without parameters
};
Dumbo::Dumbo() {
}

aarg:
At first glance, I see nothing that you couldn't do with a simple struct.

And a struct is different from a class..... How? (apart from having all members, by default, public)

Regards,
Ray L.

Classes and libraries aren't the same thing, you can have one without the other. If you just want functions to use in multiple programs, you can place them in a .cpp and .h file in a library folder and use them just as any other Arduino library (just without OO).

Honestly, I think you have a lot to learn about basic C++ before jumping into objects.

RayLivingston:
And a struct is different from a class..... How? (apart from having all members, by default, public)

Regards,
Ray L.

It has no methods. :slight_smile:

aarg:
It has no methods. :slight_smile:

only if you made it thusly.

structs can most certainly have them

Ok, learn something new every day. But if I needed that feature, I would just make a class.

The gist of what I was trying to say to the OP was that a good first step would be to design good containers.

aarg:
It has no methods. :slight_smile:

Only by convention. The language definition places no such limitation.

Regards,
Ray L.

aarg:
Ok, learn something new every day. But if I needed that feature, I would just make a class.

and so goes the OP…

:slight_smile:

aarg:
Ok, learn something new every day. But if I needed that feature, I would just make a class.

You still seem to be missing the point. In every way, a class and a struct are EXACTLY the same thing, with the one exception that struct members are, by default, public, while class members are, by default, private. There is NO other difference between the two either in implementation or function.

Regards,
Ray L.

This discussion turned meta pretty fast. :smiley:

aarg:
Ok, learn something new every day. But if I needed that feature, I would just make a class.

The gist of what I was trying to say to the OP was that a good first step would be to design good containers.

And if that's more suitable than creating a class, what is your advice on going about doing that? Any link, description or similar would really help.

There are now a lot of people here that can answer the original question, how to implement the code in reply #5 as a class library. Have fun!

Anyone?

You got your answer in Reply #6

Regards,
Ray L.

go through some tutorials on making a class.

since no one knows what you are really trying to do, you should then (once you understand class objects) start to think about which member variables and functions you need.

this is a good starting point if you want to try learning about classes because it shows you an evolution from basic code through a class.