Having trouble compiling new library

I’m having a difficult time getting my Arduino program to compile the library files for my car_wheels program. Below is the code I am trying to use:

#include <car_wheels.h>



void setup() {
  // put your setup code here, to run once:
Move pinSetup();
}

void loop() {
  // put your main code here, to run repeatedly:
move.forward();
move.backwards();
move.turnLeft();
move.turnRight();
}

I’ve attached the car_wheels.cpp file, below is the code:

#include "Arduino.h"
#include "car_wheels.h"


void Move::pinSetup() {
	pinMode(7, OUTPUT);
	pinMode(8, OUTPUT);
	pinMode(9, OUTPUT);
	pinMode(5, OUTPUT);
	pinMode(4, OUTPUT);
	pinMode(3, OUTPUT);
	analogWrite(3, 250);
	analogWrite(9, 250);
}

void Move::forward() {
	digitalWrite(5, HIGH);
	digitalWrite(4, LOW);
	digitalWrite(8, HIGH);
	digitalWrite(7, LOW);
	delay(500);
}
void Move::backwards() {
	digitalWrite(5, LOW);
	digitalWrite(4, HIGH);
	digitalWrite(8, LOW);
	digitalWrite(7, HIGH);
	delay(500);
}
void Move::turnLeft() {
	digitalWrite(5, HIGH);
	digitalWrite(4, LOW);
	digitalWrite(8, LOW);
	digitalWrite(7, HIGH);
	delay(500);
}
void Move::turnRight() {
	digitalWrite(5, LOW);
	digitalWrite(4, HIGH);
	digitalWrite(8, HIGH);
	digitalWrite(7, LOW);
	delay(500);
}

I’ve also attached the car_wheels.h, the code is below:

#ifndef car_wheels_h
#define car_wheels_h

class Move
{
private:
	void pinSetup();
	void forward();
	void backwards();
	void turnLeft();
	void turnRight();
};
#endif

and the keywords.txt file:

Move	KEYWORD1
forward		KEYWORD2
backwards	KEYWORD2
turnLeft	KEYWORD2
turnRight	KEYWORD2

I made sure the directory file has all three files in it for proper compiling but when the program compiles I get the error:

C:\Users\samue\OneDrive\Documents\Arduino\testsketch\testsketch.ino: In function ‘void loop()’:

testsketch:13: error: ‘move’ was not declared in this scope

move.forward();

^

The most confusing part is the lines:
move.forward();
move.backwards();
move.turnLeft();
move.turnRight();
are all red indicating the compiler has recognized them as functions.

Any suggestions?

keywords.txt (93 Bytes)

The move word may be in use. This compiles, but I didn’t check if it does what you want. My Linux box won’t do the underscore thing car_wheels, so I shortened it to carwheels.

carwheels.h

#ifndef car_wheels_h
#define car_wheels_h

class Move
{
	public:
	void pinSetup();
	void forward();
	void backwards();
	void turnLeft();
	void turnRight();
};

extern Move move;
#endif

carwheels.cpp

#include "Arduino.h"
#include "carwheels.h"

void Move::pinSetup() {
	pinMode(7, OUTPUT);
	pinMode(8, OUTPUT);
	pinMode(9, OUTPUT);
	pinMode(5, OUTPUT);
	pinMode(4, OUTPUT);
	pinMode(3, OUTPUT);
	analogWrite(3, 250);
	analogWrite(9, 250);
}

void Move::forward() {
	digitalWrite(5, HIGH);
	digitalWrite(4, LOW);
	digitalWrite(8, HIGH);
	digitalWrite(7, LOW);
	delay(500);
}
void Move::backwards() {
	digitalWrite(5, LOW);
	digitalWrite(4, HIGH);
	digitalWrite(8, LOW);
	digitalWrite(7, HIGH);
	delay(500);
}
void Move::turnLeft() {
	digitalWrite(5, HIGH);
	digitalWrite(4, LOW);
	digitalWrite(8, LOW);
	digitalWrite(7, HIGH);
	delay(500);
}
void Move::turnRight() {
	digitalWrite(5, LOW);
	digitalWrite(4, HIGH);
	digitalWrite(8, HIGH);
	digitalWrite(7, LOW);
	delay(500);
}

Move move;

‘move’ is not declared. ‘Move’ is. But if you change that ‘m’, you’ll get a different error :frowning:

When you define a class, to call its methods either those methods need to be static or you need an instance of the class. That’s kinda the whole point really.

This line of your code

Move pinSetup();

doesn’t do what you think. It isn’t calling the pinsetup method on move: it’s decaring a variable named pinSetup whose type is move, and it’s calling the default no-argument constructor of that object.

Now, you can make everthing static by putting ‘static’ in front of your methods, and call it like so:

void setup() {
  Move::pinSetup();
}

void loop() {
  Move::forward(); 
  Move::backwards();
  Move::turnLeft();
  Move::turnRight();
}

But all that really accomplishes is to create a name space for your methods. They are still ordinary old global functions. Oh, and these methods are private, so you cvan’t call 'em anyway.

What I tend to do instead is to put the pins inside the object. This means that you can create another ‘Move’ thing with different pin assignments, if you want. Even arrays of them, if you have enough pins.

Like this:

Move.h

class Move
{
private:
  const byte flPin, brPin, frPin, blPin;
  // you use some other pins, too, in your piSetup, but I don't know what they do
  // you get the idea, I hope
public:
  Move(const byte flPinAttach, const byte brPinAttach, const byte frPinAttach, const byte blPinAttach);

  void pinSetup();
  void forward();
  void backwards();
  void turnLeft();
  void turnRight();
};

Move.cpp

void Move::Move(const byte flPinAttach, const byte brPinAttach, const byte frPinAttach, const byte blPinAttach) :
  flPin(flPinAttach),
  brPin(brPinAttach),
  frPin(frPinAttach),
  blPin(blPinAttach)
{}

void Move::pinSetup() {
 pinMode(flPinAttach, OUTPUT);
 pinMode(brPinAttach, OUTPUT);
 pinMode(frPinAttach, OUTPUT);
 pinMode(blPinAttach, OUTPUT);
  // you use some other pins, too, in your piSetup, but I don't know what they do
  // you get the idea, I hope
}

void Move::forward() {
 digitalWrite(flPin, HIGH);
 digitalWrite(brPin, LOW);
 digitalWrite(frPin, HIGH);
 digitalWrite(blPin, LOW);
 delay(500);
}
void Move::backwards() {
 digitalWrite(flPin, LOW);
 digitalWrite(brPin, HIGH);
 digitalWrite(frPin, LOW);
 digitalWrite(blPin, HIGH);
 delay(500);
}
void Move::turnLeft() {
 digitalWrite(flPin, HIGH);
 digitalWrite(brPin, LOW);
 digitalWrite(frPin, LOW);
 digitalWrite(blPin, HIGH);
 delay(500);
}
void Move::turnRight() {
 digitalWrite(flPin, LOW);
 digitalWrite(brPin, HIGH);
 digitalWrite(frPin, HIGH);
 digitalWrite(blPin, LOW);
 delay(500);
}

And your main. Hey! Let’s make two cars and put them in an array!!!

Move someCars[] = { Move(5,4,8,7), Move(9,10,11,12)};

// or
// Move redCar(5,4,8,7), blueCar(9,10,11,12);

// or just plain old
// Move theCar(5,4,8,7);

void setup() {
  for(int i = 0; i<2; i++) someCars[i].pinSetup();

  // or theCar.pinSetup();
}


void loop() {
someCars[0].forward();
someCars[1].backwards();
someCars[0]turnLeft();
someCars[0]turnRight();
someCars[1].forward();


// or
// theCar.forward();
// theCar.backward();
// theCar.left();
// theCar.right();
}

For more stuff on the kinds of thing you can accomplish with C++ classes, see my page on Arduino and OO.

SurferTim: The move word may be in use. This compiles, but I didn't check if it does what you want. My Linux box won't do.......

This compiles but it doesn't do anything. It seems to recognize the functions without the code inside of the function. Why is this?

PaulMurrayCbr: 'move' is not declared. 'Move' is. But if you change that 'm', you'll get a different error :(

When you define a class, to call its methods either those methods need to be static or you need an [u]instance[/u] of the class. That's kinda the whole point really.

Excuse my lack of knowledge but this seems complicated. Is there a way to make it so when I call the functions from the library it uses preset parameters so I don't have to put in the extra parameters everytime I call it?

For example: move.forward(); would call the function forward(); in the move class with the preset code of

digitalWrite(5, HIGH); digitalWrite(4, LOW); digitalWrite(8, HIGH); digitalWrite(7, LOW); delay(500);

Oh, and I'm using an Arduino 101 with the L298n D.C. motor controller board to control 4 D.C. servo motors. The analogWrite (3, 250); command works the PWM pin for the servo power/speed. I think.

It works here.

Here is carwheels.ino

#include <carwheels.h>

void setup() {
  move.pinSetup();
}

void loop() {
  move.forward();
  move.backwards();
  move.turnLeft();
  move.turnRight();
}

Here is a modified version of carwheels.cpp. It turns on and off D13’s LED.

#include "Arduino.h"
#include "carwheels.h"


void Move::pinSetup() {
 pinMode(13, OUTPUT);
}

void Move::forward() {
 digitalWrite(13, HIGH);
 delay(500);
}
void Move::backwards() {
 digitalWrite(13, LOW);
 delay(500);
}
void Move::turnLeft() {
 digitalWrite(13, HIGH);
 delay(500);
}
void Move::turnRight() {
 digitalWrite(13, LOW);
 delay(500);
}

Move move;
#include "carWheels.h"

CarWheels myCarWheels;

void setup() {
  // put your setup code here, to run once:
  myCarWheels.pinSetup();

}

void loop() {
  // put your main code here, to run repeatedly:
  myCarWheels.forward();
  myCarWheels.backwards();
  myCarWheels.turnLeft();
  myCarWheels.turnRight();
  
}
#ifndef carWheels_h
#define carWheels_h

class CarWheels
{
public:
    void pinSetup();
    void forward();
    void backwards();
    void turnLeft();
    void turnRight();
};
#endif
#include "Arduino.h"
#include "carWheels.h"


void CarWheels::pinSetup() {
    pinMode(7, OUTPUT);
    pinMode(8, OUTPUT);
    pinMode(9, OUTPUT);
    pinMode(5, OUTPUT);
    pinMode(4, OUTPUT);
    pinMode(3, OUTPUT);
    analogWrite(3, 250);
    analogWrite(9, 250);
}

void CarWheels::forward() {
    digitalWrite(5, HIGH);
    digitalWrite(4, LOW);
    digitalWrite(8, HIGH);
    digitalWrite(7, LOW);
    delay(500);
}
void CarWheels::backwards() {
    digitalWrite(5, LOW);
    digitalWrite(4, HIGH);
    digitalWrite(8, LOW);
    digitalWrite(7, HIGH);
    delay(500);
}
void CarWheels::turnLeft() {
    digitalWrite(5, HIGH);
    digitalWrite(4, LOW);
    digitalWrite(8, LOW);
    digitalWrite(7, HIGH);
    delay(500);
}
void CarWheels::turnRight() {
    digitalWrite(5, LOW);
    digitalWrite(4, HIGH);
    digitalWrite(8, HIGH);
    digitalWrite(7, LOW);
    delay(500);
}

ieee488:

#include "carWheels.h"

CarWheels myCarWheels;

This worked perfectly! Thank you for your help.