Why can't I create instances of this class?

Hi, I’m experimenting with classes in Arduino, and am adding it into an existing script.

const int pulseout = 2;
const int pulsein = 3;
const int piezob = 4;
class RangeFinder {
  public:
    long pulse();
  private:
    long microsecondsToCentimeters(long microseconds);
};

long RangeFinder::microsecondsToCentimeters(long microseconds) {
  return microseconds / 29 / 2;
}

long RangeFinder::pulse() {
  long duration, cm;
  digitalWrite(pulseout, LOW);
  delayMicroseconds(2);
  digitalWrite(pulseout, HIGH);
  delayMicroseconds(5);
  digitalWrite(pulseout, LOW);
  
  duration = pulseIn(pulsein, HIGH,20000);
  cm = microsecondsToCentimeters(duration);
  return cm;
}

void setup() {
  RangeFinder rd = new RangeFinder();
  pinMode(pulseout,OUTPUT);
  pinMode(pulsein,INPUT);
  pinMode(piezob,OUTPUT);
}

void loop() {
  rf = new RangeFinder();
  long distance = rf.pulse();
}

When I try and compile, I get this error:

Warning: platform.txt from core 'Arduino AVR Boards' contains deprecated recipe.preproc.macros="{compiler.path}{compiler.cpp.cmd}" {compiler.cpp.flags} {preproc.macros.flags} -mmcu={build.mcu} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.cpp.extra_flags} {build.extra_flags} {includes} "{source_file}", automatically converted to recipe.preproc.macros="{compiler.path}{compiler.cpp.cmd}" {compiler.cpp.flags} {preproc.macros.flags} -mmcu={build.mcu} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.cpp.extra_flags} {build.extra_flags} {includes} "{source_file}" -o "{preprocessed_file_path}". Consider upgrading this core.
/Users/edwin/Documents/Arduino/RangeFinderAlarm/RangeFinderAlarm.ino: In function 'void setup()':
RangeFinderAlarm:29: error: conversion from 'RangeFinder*' to non-scalar type 'RangeFinder' requested
   RangeFinder rd = new RangeFinder();
                                    ^
/Users/edwin/Documents/Arduino/RangeFinderAlarm/RangeFinderAlarm.ino: In function 'void loop()':
RangeFinderAlarm:36: error: 'rf' was not declared in this scope
   rf = new RangeFinder();
   ^
exit status 1
conversion from 'RangeFinder*' to non-scalar type 'RangeFinder' requested

Does anyone know why?

RangeFinder* rd = new RangeFinder();?

I’m not much of a C++ programmer. As far as I understand it, your code will very quickly run out of memory (once it runs).

Ah, just tested it with String. The below crashes 4 times within a second; after that I don’t have any idea what it is doing.

#define PINRED 9
#define PINYELLOW 11
#define PINGREEN 10

#define PINBUTTON 4

void setup()
{
  Serial.begin(9600);
  pinMode(PINGREEN, OUTPUT);
  pinMode(PINYELLOW, OUTPUT);
  pinMode(PINRED, OUTPUT);
  pinMode(PINBUTTON, INPUT_PULLUP);

  delay(1); // Arduino is too fast 
  Serial.println("Hello");
}


void loop()
{
  String *x = new String("Hello");
}

The String object is created on the heap. You must get rid of it (using ‘delete’) before leaving loop().

Sorry, do you have the wrong thread?

Sporech: Sorry, do you have the wrong thread?

No. He is illustrating what happens when you allocate space for an object (String in his case, RangeFinder in yours) without deleting the space when the object goes out of scope.

Why not make life simple? Create a global object:

RangeFinder rf;

No need to dynamically allocate anything. No need to delete anything.

Okay, sorry about the misunderstanding; I didn’t mean to appear rude :confused:

I’ve tried that and it works!
I’m a newbie in C++ as well, and I wasn’t too sure on the exact syntax for creating objects in this way. Thanks!
:slight_smile:

void setup() {
  RangeFinder rd = new RangeFinder();
  pinMode(pulseout,OUTPUT);
  pinMode(pulsein,INPUT);
  pinMode(piezob,OUTPUT);
}

void loop() {
  rf = new RangeFinder();
  long distance = rf.pulse();
}

Apart from the issues with "new" you should read the new sticky in the Programming section about scope. The variable rd doesn't seem to have any useful purpose.