1

I haven't used an Arduino for anything as complicated as this project before (single sketch projects so far), and am struggling getting my code to compile now that I'm creating my own libraries for the project.

I can see that it's the class' methods that return something that cause an issue, those that directly edit the classes variables instead don't appear to cause issues when compiling (i.e. void functions).

I can't share the actual code, but here's an altered and stripped down version that shows the same issue.

The sketch:

//Issues.ino

#include "CmdLib.cpp"

void setup() {
  //Setup USB
  Serial.begin(19200);
  Serial.flush();

  //Setup Bluetooth
  Serial0.begin(9600);
  Serial0.flush();
}

void loop(){
  CheckForPCMessages();       //Parses any messages from USB and Bluetooth
  //All the other things we need to do
}

void CheckForPCMessages(){
  CheckForMessages(&Serial);  //Check USB first
  CheckForMessages(&Serial0); //Then check Bluetooth
}

template <class T> void CheckForMessages(T *port){
  //Using function template so that works for USB and Hardware Serial
  if(port->available() != 0){
    String received_string = port->readStringUntil('\n');
    port->flush();
    Serial.print(received_string);
    Serial.println(" was received.");
    Command received_cmd(received_string);
    //Do stuff with the command (add it to a Q, etc, etc)
  }
}

The Header:

//CmdLib.h

#ifndef CmdLib_h
#define CmdLib_h

#include "Arduino.h"

enum CommandLabel{
  //Not a command
  NO_COMMAND = 0,

  //...
  //A whole bunch of other options that I can't share
  //...
};

enum CommandType{
  NA = 0,  
  //...
  //A whole bunch of other options that I can't share
  //...
};

class Command{
  public:
    Command(String msg);
    String GetCmdStringFromMessageString(String full_string);
    CommandLabel GetLabelFromString(String labelstr);
    void SetLabelAndType(String labelstr);
    void SetLabel(CommandLabel label);
    void SetType(CommandLabel label);

  private:
    String _x = "";
    String _y = "";
    String _z = "";
    CommandLabel _label = NO_COMMAND;
    CommandType _type = NA;
};

#endif

The cpp file:

//CmdLib.cpp

#include "CmdLib.h"

Command::Command(String msg){
  String labelstr = Command::GetCmdStringFromMessageString(msg); //Separates label from msg
  Command::SetLabelAndType(labelstr); //Sets _label & _type vars
}

String GetCmdStringFromMessageString(String full_string){
  //Pulls out everything before first comma
  int first_comma = full_string.indexOf(',');
  String output;
  if(first_comma != -1){
    output = full_string.substring(0,first_comma);
  }
  else{
    output = full_string;
  }
  return output;
}

void Command::SetLabelAndType(String labelstr){
  CommandLabel label = GetLabelFromString(labelstr);  //Get label from string
  Command::SetLabel(label);                           //Set label 
  Command::SetType(label);                            //Set type based on label
}

CommandLabel GetLabelFromString(String labelstr){
  //...
  //Cleverness to determine which to return...
  //...
  return NO_COMMAND;
}

void Command::SetLabel(CommandLabel label = NO_COMMAND){
  _label = label;
}

void Command::SetType(CommandLabel label){    //Set _type to appropriate type based upon label
  //...
  //Cleverness to determine which to return...
  //...
  _type = NA;
  return;
}

And here's the Error:

sketch\CmdLib.cpp.o: In function `Command::SetLabelAndType(String)':

[REDACTED]/temp/arduino_build_557572/sketch/cmdlib.cpp:24: undefined reference to `Command::GetLabelFromString(String)'

sketch\CmdLib.cpp.o: In function `Command::Command(String)':

[REDACTED]/temp/arduino_build_557572/sketch/cmdlib.cpp:6: undefined reference to `Command::GetCmdStringFromMessageString(String)'

collect2.exe: error: ld returned 255 exit status

exit status 255 Error compiling for board Fubarino Mini.

I've found previous answers where the same compile error occurred with class variables that were called to without being given an initial value, but can't find similar solutions for the error when created by a call to a function.

Any help would be greatly appreciated.

1

You forgot to put the function in the class:

CommandLabel GetLabelFromString(String labelstr){

should be:

CommandLabel Command::GetLabelFromString(String labelstr) {

Also, on a side note, if you must use String objects (ugh!) then please pass them as reference so as to avoid needless heap allocation and data copying:

CommandLabel Command::GetLabelFromString(String &labelstr) {
  • ... Damn it. Well, thank you for saving me from myself! Edit: Good point on the String referencing - in this case I do need to use them, as I won't know the length of the char array being sent in advance – JRVeale May 18 '18 at 13:53
  • The simplest mistakes are often the hardest to spot. It's called going "code blind". – Majenko May 18 '18 at 14:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.