Automatic Creation of Objects?

Hello,

The project I'm working on has two main purposes- to register as a voter or vote. The final project will include a fingerprint scanner, LCD screen etc... but for the time being I'm running everything through the serial monitor.

I want each person registered to be their own object. I already declared a 'Profile' class. However, I want to create a new object every time reg() is ran, but I do not know exactly how to do that. Could I make a string named 'voter' and with each instance of reg() being ran, add 1 to a stored integer and then combine those two together? So after running reg() 5 times, there would be 5 objects named:

voter0
voter1
voter2
voter3
voter4
voter5

This is what I have so far- any info would be greatly appreciated, thanks!

char inByte = 0;

int i = 0;

class Profile {
  private:
    int ID;

    String first;
    String last;
    int age;

  public:
    Profile(int ID, String first, String last, int age) {
      this->ID = ID;
      this->first = first;
      this->last = last;
      this->age = age;
    }
    
  

};

void setup() {

  Serial.begin(9600);
  Serial.println("Welcome!");
  Serial.println("Press 1 to register, press 2 to vote.");

}

void loop() {

  if (Serial.available() > 0) {

    
    inByte = Serial.read();
    
    if (inByte == '1') reg();
    else if (inByte == '2') vote();
    else return;
    
  }
}

void reg() {

  Serial.println("void reg()");
  
  
}

void vote() {

  Serial.println("void vote()");
  
}

How about an array of Profile objects and assigning each new voter the next available element of the already existing array ?

UKHeliBob:
How about an array of Profile objects and assigning each new voter the next available element of the already existing array ?

Do you have to declare the length of an array as you create it? Is there a way to declare one with a dynamic size?

Which Arduino are you using for this?

wildbill:
Which Arduino are you using for this?

The SD card and fingerprint scan are connected to an Uno. When I implement the touchscreen, that will be ran by a Mega. I've been using the Uno for this sketch.

chummer1010:
Is there a way to declare one with a dynamic size?

Yes, the 'new' operator. Be sure to check that it succeeds and returns a valid pointer. Heap memory management is now on you.

Dynamic memory allocation is risky business on a device with very little RAM, like an Uno. You're already doing some implicitly by using Strings. I assume that you're hoping to grow your array of voters as needed. That is just going to fragment your heap and likely cause premature failures.

There's a finite number of voters you can handle in the space you have. Define an array of that size and be done. It's not like you're going to get any benefit by not using that RAM. I'd suggest that you get rid of the Strings too.

chummer1010:
Do you have to declare the length of an array as you create it? Is there a way to declare one with a dynamic size?

You could probably indulge in some fancy footwork to change the size of the array on the fly but why bother ?

If the system has only enough memory for say 100 objects then whether they are created at compile time or on the fly then the limit will be the same. Indeed, the fixed length solution will probably use less memory that a solution involving manipulation of memory to extend the array.

wildbill:
Dynamic memory allocation is risky business on a device with very little RAM, like an Uno. You're already doing some implicitly by using Strings. I assume that you're hoping to grow your array of voters as needed. That is just going to fragment your heap and likely cause premature failures.

There's a finite number of voters you can handle in the space you have. Define an array of that size and be done. It's not like you're going to get any benefit by not using that RAM. I'd suggest that you get rid of the Strings too.

Then perhaps I'll just write each voter to the SD card as they're created... What should I use as opposed to a String for things like first/last name?

What should I use as opposed to a String for things like first/last name?

C style strings, ie zero terminated arrays of chars

So I've been meddling around a bit (essentially implementing the Serial Input Basics code into mine)

#include <SPI.h>
#include <SD.h>

File voterList;

char in = '1';

const byte numChars = 32;
char receivedChars[numChars];

boolean newData = false;

char vFirst[25];
char vLast[25];
char vAge = 10;
char vID[9];



class Profile {
  private:
    
    char ID[9];
    char first[25];
    char last[25];
    char age = 10;

  public:
    Profile(char ID[9], char first[25], char last[25], char age) {
      this->ID[9] = ID[9];
      this->first[25] = first[25];
      this->last[25] = last[25];
      this->age = age;
    }
    

};

void setup() {

  Serial.begin(9600);
  while (!Serial) {
    ;
  }
  
  Serial.println("Welcome!");
  Serial.println("Press 1 to register, press 2 to vote.");

}

void loop() {

  if (Serial.available() > 0) {

    in = Serial.read();
    
    if (in == '1') reg();
    else if (in == '2') vote();
    else return;
    
  }
}

void reg() {

  for (int i = 0; i < 4; i++) {

    recv(i);
    store();
    
    }
    
}

void vote() {

  Serial.println("void vote()");
  
}

void recv(int i) {

    static byte ndx = 0;
    char endMarker = '\n';
    char rc;

    if (i == 0) Serial.print("First Name: ");
    else if (i == 1) Serial.print("Last Name: ");
    else if (i == 2) Serial.print("Age: ");
    else Serial.print("ID: ");
        
    while (Serial.available() > 0 && newData == false) {
        rc = Serial.read();

        if (rc != endMarker) {
            receivedChars[ndx] = rc;
            ndx++;
            if (ndx >= numChars) {
                ndx = numChars - 1;
            }
        }
        else {
            receivedChars[ndx] = '\0'; // terminate the string
            ndx = 0;
            newData = true;
        }
    }
}
  
void store() {
  
  if (newData == true) {
    
        
        Serial.println(receivedChars);
        newData = false;
    }

}

I get my prompt whether to register or vote, however when I select register, it prints

Welcome!
Press 1 to register, press 2 to vote.
First Name: Last Name: Age: ID:

Why doesn't it print out First Name, wait for response, etc? Do I need to use a T/F variable to prevent from printing further until a response is received?

Change your while loop condition from AND to OR. Also move the if Serial.available inside the loop.

      this->ID[9] = ID[9];
      this->first[25] = first[25];
      this->last[25] = last[25];

In the constructor, set the first element beyond the end of the array to the first element beyond the end of input array. Doesn't seem like a good idea to me.

Using argument names that are the same as member names doesn't either.

essentially implementing the Serial Input Basics code into mine

Without understanding that the whole philosophy is to use the serial port in a non-blocking way.

You seem to want to do nothing after printing a prompt except sit and wait for data. I don't think that that is the proper thing to do, so I'm not going to tell you how to do that.

The proper thing to do is to understand that you have a state machine. You are in a state where you are waiting for the end of the first name packet, or you are in a state where you are waiting for the end of the last name packet, or you are in a state where you are waiting for the end of an age packet, or you are in a state where you are waiting for the end of an ID packet, or you are in a state where you are waiting for something that indicates that voting is done.

When the end of a packet arrives, what you do with the data depends on what state you are in. Sitting around with your thumb up your butt doing nothing more than reading serial data is NOT one of the states you should be in.