motor shield v2: using in class

Adafruit Ethernet, Motor, Proto, Wave, Datalogger, GPS Shields - etc!

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
User avatar
wergor
 
Posts: 24
Joined: Sun Aug 31, 2014 4:38 pm

motor shield v2: using in class

Post by wergor »

i'm trying to use the motorshield with an attached stepper motor as members of a class.
my code:

Code: Select all

#include <Wire.h>
#include <Adafruit_MotorShield.h>

#include "Test.h"

Test test;

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

}

void loop() {
  // put your main code here, to run repeatedly:

test.run();    //stepper does not move

}

Code: Select all

//Test Class

#include <Wire.h>
#include <Adafruit_MotorShield.h>

class Test
{
public:
	Test();
	void run();
	void init();
private:
	//Adafruit Motor Shield object
	Adafruit_MotorShield AFMS;
	Adafruit_StepperMotor *AFStepper;
};

Code: Select all

#include "Test.h"

Test::Test()
{
}

void Test::init()
{
	Adafruit_MotorShield AFMS(0x60);
	Adafruit_StepperMotor *AFStepper = AFMS.getStepper(200, 1);

	AFMS.begin();

	while (true)
	{
		run();    //stepper does not move
		AFStepper->onestep(FORWARD, SINGLE);    //stepper moves
	}
}

void Test::run()
{
	AFStepper->onestep(FORWARD, SINGLE);
}
the code above works. as you can see, AFMS and AFStepper are members of the class; their contructors are called in test.init(). when i call AFStepper->onestep(FORWARD, SINGLE) from within the init() function, the stepper moves, but if i call run() from within init or test.run() in the loop() function, nothing happens.
does anyone have any idea why this happens?
Attachments
testino.zip
(1.05 KiB) Downloaded 20 times

User avatar
adafruit_support_bill
 
Posts: 88090
Joined: Sat Feb 07, 2009 10:11 am

Re: motor shield v2: using in class

Post by adafruit_support_bill »

Because in your init() function, you declare and initialize local variables that have the same names as your member variables. So the member variables never get initialized.

Code: Select all

   Adafruit_MotorShield AFMS(0x60);
   Adafruit_StepperMotor *AFStepper = AFMS.getStepper(200, 1);

User avatar
wergor
 
Posts: 24
Joined: Sun Aug 31, 2014 4:38 pm

Re: motor shield v2: using in class

Post by wergor »

how do i correctly initialize the members? i cannot compile with

Code: Select all

	Adafruit_MotorShield AFMS(0x60);
	Adafruit_StepperMotor *AFStepper = AFMS.getStepper(200, 1);
in the .h file.

edit: using

Code: Select all

AFStepper = AFMS.getStepper(200, 1);
in the init() correctly initializes the stepper, so my code works.
is there any way i can initialize the Adafruit_MotorShield AFMS with a non-default I2C address?

User avatar
adafruit_support_bill
 
Posts: 88090
Joined: Sat Feb 07, 2009 10:11 am

Re: motor shield v2: using in class

Post by adafruit_support_bill »

You could derive your class from Adafruit_MotorShield and pass the address to the constructor.

User avatar
wergor
 
Posts: 24
Joined: Sun Aug 31, 2014 4:38 pm

Re: motor shield v2: using in class

Post by wergor »

seems to work, thank you!

in the meantime, i have come across another problem:
i want to use the accelstepper library. i have extended my code:

Code: Select all

#include <Wire.h>
#include <Adafruit_MotorShield.h>
#include <AccelStepper.h>

#include "Test.h"

Adafruit_StepperMotor *StepperXAxis;
Adafruit_StepperMotor *StepperYAxis;

Test test;

void setup() {
  // put your setup code here, to run once:
  
  test.init();
}

void loop() {
  // put your main code here, to run repeatedly:
  
  test.run();    //stepper does not move
}

Code: Select all

#include "Test.h"

Test::Test() : Adafruit_MotorShield(0x60)	
{
}

void Test::init()
{
	//AFMS = AFMS(0x60);
	StepperXAxis = Adafruit_MotorShield::getStepper(200, 1);
	StepperYAxis = Adafruit_MotorShield::getStepper(200, 2);

	Adafruit_MotorShield::begin();

        AccelStepper StepperX(ForwardStepX, BackwardStepX);    //correctly initializes AccelStepper, but only works inside the init() function
        AccelStepper StepperY(ForwardStepY, BackwardStepY);    //correctly initializes AccelStepper, but only works inside the init() function
        
        //StepperX(ForwardStepX, BackwardStepX);  //error: no match for call to '(AccelStepper) (void ()(), void ()())'
        //StepperY(ForwardStepX, BackwardStepX);  //error: no match for call to '(AccelStepper) (void ()(), void ()())'

	//set default parameters for the stepper motors
	StepperX.setMaxSpeed(400.0);		//speed in steps / second
	StepperX.setAcceleration(100.0);	//steps / second^2
	StepperX.moveTo(1000000);			//default destination

	StepperY.setMaxSpeed(400.0);       //speed in steps / second
	StepperY.setAcceleration(100.0);   //steps / second^2
	StepperY.moveTo(1000000);		   //default destination

	while (true)
	{
		run();    //stepper does not move
                StepperX.run();    //stepper moves
                StepperY.run();    //stepper moves
	}
}

void Test::run()
{
        StepperX.run();
	StepperY.run();
}

//X Axis: go 1 step forward
void Test::ForwardStepX() {
	StepperXAxis->onestep(FORWARD, SINGLE);
}
//X Axis: go 1 step backward
void Test::BackwardStepX() {
	StepperXAxis->onestep(BACKWARD, SINGLE);
}
//Y Axis: go 1 step forward
void Test::ForwardStepY() {
	StepperYAxis->onestep(FORWARD, SINGLE);
}
//Y Axis: go 1 step backward
void Test::BackwardStepY() {
	StepperYAxis->onestep(BACKWARD, SINGLE);
}

Code: Select all

//Test Class

#include <Wire.h>
#include <Adafruit_MotorShield.h>
#include <AccelStepper.h>

extern Adafruit_StepperMotor *StepperXAxis;
extern Adafruit_StepperMotor *StepperYAxis;

class Test : public Adafruit_MotorShield
{
public:
	Test();
	void run();
	void init();

	static void ForwardStepX();
	static void BackwardStepX();
	static void ForwardStepY();
	static void BackwardStepY();
private:
	//Adafruit Motor Shield object

	//AccelStepper wrapper
	AccelStepper StepperX;
	AccelStepper StepperY;
	//AccelStepper *StepperX;
	//AccelStepper *StepperY;
};
a similar problem like before.
i cannot initialize the AccelStepper objects like the Adafruit_MotorShield object in my first response. (i also think deriving the class fom AccelStepper won't help in this case, as i need 2 AccelStepper objects.)
when i try to define AccelStepper *StepperX; and AccelStepper *StepperY; and then initialize them with StepperX(ForwardStepX, BackwardStepX); and StepperY(ForwardStepY, BackwardStepY); in the init() function, i get the following error:
error: '((Test*)this)->Test::StepperX' cannot be used as a function
at
StepperX(ForwardStepX, BackwardStepX);
StepperY(ForwardStepX, BackwardStepX);
in init().

i would be most grateful if you could help me with this too.
Attachments
testino.zip
(1.5 KiB) Downloaded 19 times

User avatar
adafruit_support_bill
 
Posts: 88090
Joined: Sat Feb 07, 2009 10:11 am

Re: motor shield v2: using in class

Post by adafruit_support_bill »

You could declare the AccelSteppers as pointers. Then use the 'new' operator in either the constructor or the init().

Dynamic allocations via new and malloc are discouraged in embedded applications. It can be a particular problem on a resource limited platform like the Arduino. But if you keep all the allocations to the setup phase, you should stay out of trouble.

User avatar
wergor
 
Posts: 24
Joined: Sun Aug 31, 2014 4:38 pm

Re: motor shield v2: using in class

Post by wergor »

works! thanks a lot!
i tried new... before, but it did not work. i probably just forgot to exchange some '.' with '->' for function calls.

Locked
Please be positive and constructive with your questions and comments.

Return to “Arduino Shields from Adafruit”