understanding classes in arduino

hi all

i have some experience in processing, but rather less in arduino; i am trying to write a piece of code that uses instances of a single class to control multiple stepper motors in arduino.

as far as the control goes; i am fine; a simpler piece of code with the same basic functions does what i want. what i am struggling with is placing this within a class so that i can call up and execute different functions from it for multiple motors.

any pointers would be welcome; here is the code (below) - it is written in two tabs… Are classes in arduino code written differently to those in processing??

thanks

S

TAB 1:

Motor motors = {
new Motor(1);
new Motor(2);
};

void setup() {
Serial.begin(9600);
randomSeed(analogRead(0));
for (int i = 0; i < 2; i++){
motors_.setup();_

  • }*
  • }*
    void loop(){
  • //cycle through all motors and reset them if just started*
    for (int i = 0; i < 2; i++){
    _ motors*.reset();_
    _
    }_
    _
    //cycle through all motors, asses/choose position and destination and let me know*_
    for (int i = 0; i < 2; i++){
    _ motors*.think();
    }
    //cycle through all motors and call any actions*
    for (int i = 0; i < 2; i++){
    motors*.action();
    }
    delayMicroseconds(200);
    }*_

[/quote]
TAB 2:
> class Motor{
*> *
> int motor_no;
> int dirpin;
> int steppin;
> int cycles;
> int dest;
>
> long i;
> long randomWait;
> long a = 18000;
> long b = 36000;
> long distance;
> long sleep;
*> *
> boolean LEFT = true;
> boolean RIGHT = false;
> boolean at_A;
> boolean at_B;
> boolean at_C;
> boolean go_A;
> boolean go_B;
> boolean go_C;
> boolean move;
*> *
> Motor(int n){
> motor_no = n;
> dirpin = (2*n)+36;
> steppin = (2*n)+37;
> }
*> *
*> *
> void setup(){
> pinMode(dirpin, OUTPUT);

> pinMode(steppin, OUTPUT);
> }
>
> void reset(){
> if (cycles < 1){
> reset_slide();
> cycles++;
> }}
>
> void think(){
> //WHEN YOU REACH THE NEW POSITION, CLEAR THE PAUSE AND TRAVEL COUNT & CHOOSE A NEW DESTINATION
> if ((i > distance)){
> update_position();
> tell_sam();
> sleep = millis();
> randomWait = (random(1,4))*1000;
> i = 0;
> choose_destination();
> set_required_movement();
> }}
>
> void action(){
> //IF REQUIRED STEP THE MOTORS WHEN OUT OF THE PAUSE TIME
> if (((millis() - sleep) > randomWait) && move){
*> digitalWrite(steppin, LOW); *
> digitalWrite(steppin, HIGH);
> i++;
> }
*> // OTHERWISE RETURN TO THE DESTINATION CHOICE *
> else if (((millis() - sleep) > randomWait) && move == false){
> i++;
> }}
>
>
>
> ///NESTED VOIDS
> void update_position(){
> if(go_A){
> at_A = true;
> at_B = false;
> at_C = false;
> }
> else if(go_B){
> at_A = false;
> at_B = true;
> at_C = false;
> }
> else if(go_C){
> at_A = false;
> at_B = false;
> at_C = true;
> }}
>
>
> void choose_destination(){
*> dest = random(1,4); *
> if (dest == 1){
> go_A = true;
> go_B = false;
> go_C = false;
> }
> else if (dest == 2){
> go_A = false;
> go_B = true;
> go_C = false;
> }
> else if (dest == 3){
> go_A = false;
> go_B = false;
> go_C = true;
> }
> }
>
>
*> *
> void set_required_movement(){
> if (at_A && go_A){
> no_move();
> }
> else if (at_A && go_B){
> move_right(a);
> }
> else if (at_A && go_C){
> move_right(b);
> }
> else if (at_B && go_A){
> move_left(a);
> }
> else if (at_B && go_B){
> no_move();
> }
> else if (at_B && go_C){
> move_right(a);
> }
> else if (at_C && go_A){
> move_left(b);
> }
> else if (at_C && go_B){
> move_left(a);
> }
> else if (at_C && go_C){
> no_move();
> }}
*> *
*> *
> void move_right(long d){
> digitalWrite(dirpin, HIGH);
> LEFT = false; RIGHT = true;
> distance = d;
> move = true;
> }
>
> void move_left(long d){
> digitalWrite(dirpin, LOW);
> LEFT = true; RIGHT = false;
> distance = d;
> move = true;
> }
>
> void no_move(){
> distance = 0;
> randomWait = randomWait+5000;
> move = false;
> }
*> *
*> *
> void tell_sam(){
> Serial.print(motor_no);
> if (at_A){
> Serial.print(“A”);
> }
> else if (at_B){
> Serial.print(“B”);
> }
> else if (at_C){
> Serial.print(“C”);
> }
> Serial.print("—");
*> } *
*> *
> void reset_slide(){
> go_A = true;
> go_B = false;
> go_C = false;
> move_left(40000);
*> } *
> }

http://arduino.cc/en/Hacking/LibraryTutorial http://www.arduino.cc/playground/Code/Library :)

gulp....

is it really that different? s

:(

Processing is java, Arduino is c++.

A bit different.

The main difference is that c++ separates the interface from the implementation.

Read one or both of the linked tutorials, and you will be on your way of making libraries for the Arduino. :)

okey dokily

i’m a quick enough learner; but call me stupid - how do you save files with the .h and .cpp extensions?!

this is my reformatted coding… Which i’d love to test

HEADER:

#ifndef StepperMotor_h
#define StepperMotor_h

#include “WProgram.h”

class StepperMotor{

public:
StepperMotor(int n);
void reset();
void think();
void action();
void update_position();
void choose_destination();
void set_required_movement();
void move_right(long d);
void move_left(long d);
void no_move();
void tell_sam();
void reset_slide();

private:
int motor_no;
int dirpin;
int steppin;
int cycles;
int dest;

long i;
long randomWait;
long a = 18000;
long b = 36000;
long distance;
long sleep;

boolean LEFT = true;
boolean RIGHT = false;
boolean at_A;
boolean at_B;
boolean at_C;
boolean go_A;
boolean go_B;
boolean go_C;
boolean move;
};

#endif

SOURCE:

#include “WProgram.h”
#include “StepperMotor.h”

StepperMotor::StepperMotor(int n)
{
motor_no = n;
dirpin = (2n)+36;
steppin = (2
n)+37;
pinMode(dirpin, OUTPUT);
pinMode(steppin, OUTPUT);
}

void StepperMotor::reset(){
if (cycles < 1){
reset_slide();
cycles++;
}}

void StepperMotor::think(){
//WHEN YOU REACH THE NEW POSITION, CLEAR THE PAUSE AND TRAVEL COUNT & CHOOSE A NEW DESTINATION
if ((i > distance)){
update_position();
tell_sam();
sleep = millis();
randomWait = (random(1,4))*1000;
i = 0;
choose_destination();
set_required_movement();
}}

void StepperMotor::action(){
//IF REQUIRED STEP THE MOTORS WHEN OUT OF THE PAUSE TIME
if (((millis() - sleep) > randomWait) && move){
digitalWrite(steppin, LOW);
digitalWrite(steppin, HIGH);
i++;
}
// OTHERWISE RETURN TO THE DESTINATION CHOICE
else if (((millis() - sleep) > randomWait) && move == false){
i++;
}}

///NESTED VOIDS
void StepperMotor::update_position(){
if(go_A){
at_A = true;
at_B = false;
at_C = false;
}
else if(go_B){
at_A = false;
at_B = true;
at_C = false;
}
else if(go_C){
at_A = false;
at_B = false;
at_C = true;
}}

void StepperMotor::choose_destination(){
dest = random(1,4);
if (dest == 1){
go_A = true;
go_B = false;
go_C = false;
}
else if (dest == 2){
go_A = false;
go_B = true;
go_C = false;
}
else if (dest == 3){
go_A = false;
go_B = false;
go_C = true;
}
}

void StepperMotor::set_required_movement(){
if (at_A && go_A){
no_move();
}
else if (at_A && go_B){
move_right(a);
}
else if (at_A && go_C){
move_right(b);
}
else if (at_B && go_A){
move_left(a);
}
else if (at_B && go_B){
no_move();
}
else if (at_B && go_C){
move_right(a);
}
else if (at_C && go_A){
move_left(b);
}
else if (at_C && go_B){
move_left(a);
}
else if (at_C && go_C){
no_move();
}}

void StepperMotor::move_right(long d){
digitalWrite(dirpin, HIGH);
LEFT = false; RIGHT = true;
distance = d;
move = true;
}

void StepperMotor::move_left(long d){
digitalWrite(dirpin, LOW);
LEFT = true; RIGHT = false;
distance = d;
move = true;
}

void StepperMotor::no_move(){
distance = 0;
randomWait = randomWait+5000;
move = false;
}

void StepperMotor::tell_sam(){
Serial.print(motor_no);
if (at_A){
Serial.print(“A”);
}
else if (at_B){
Serial.print(“B”);
}
else if (at_C){
Serial.print(“C”);
}
Serial.print("—");
}

void StepperMotor::reset_slide(){
go_A = true;
go_B = false;
go_C = false;
move_left(40000);
}

EXAMPLE SKETCH:

#include <StepperMotor.h>

StepperMotor stepperMotor = {
new StepperMotor(1),
new StepperMotor(2),
};

void setup() {
Serial.begin(9600);
randomSeed(analogRead(0));
}

void loop(){
//cycle through all motors and reset them if just started
for (int i = 0; i < stepperMotor.length; i++){
stepperMotor*.reset();*
}
//cycle through all motors, asses/choose position and destination and let me know
for (int i = 0; i < stepperMotor.length; i++){
_ stepperMotor*.think();_
_
}_
_
//cycle through all motors and call any actions*_
for (int i = 0; i < stepperMotor.length; i++){
_ stepperMotor*.action();
}
delayMicroseconds(200);
}*_

[/quote]

ignore that last… i’ve had too much coffee
s

Your source and header looks correct. Good job!

If you want to save as .cpp or .h you simply use a text editor, and select something like 'save as any type' or as notepad say 'All Files'.

Then you write the extension in the name:

StepperMotor.h

For instance.

hi there,

yes - i realized that (!) bit slow today.

there were a few problems with the code above, but i fixed them; the final library and header/source codes i’ll copy in below

What it does: basically an array of eight(or more) stepper motors each choose a random position from A,B or C and step until they reach it; they then pause before repeating the process. i am using these to drive a collection of curtains, but it could be adapted to do many things. if anyone adapts it then it would be good to hear about.

i have included a serial print of the curtain positions - intending to one day have it interfacing to a processing sketch that i have. I’ve noticed that the serial print seems to take a few milliseconds, which interferes with the stepper action very slightly - a minor issue, but if anyone knows how to get round it is would be good to fix.

thanks for the help with libraries - i learnt something today

S

EXAMPLE:

#include <StepperMotor.h>

int l = 8;
StepperMotor stepperMotor = {
StepperMotor(1),
StepperMotor(2),
StepperMotor(3),
StepperMotor(4),
StepperMotor(5),
StepperMotor(6),
StepperMotor(7),
StepperMotor(8),
};
void setup() {
Serial.begin(9600);
randomSeed(analogRead(0));
}

void loop(){
//cycle through all motors and reset them if just started
for (int i = 0; i < l; i++){
stepperMotor*.reset();*
}
//cycle through all motors, asses/choose position and destination and let me know
for (int i = 0; i < l; i++){
_ stepperMotor*.think();_
_
}_
_
//cycle through all motors and call any actions*_
for (int i = 0; i < l; i++){
_ stepperMotor*.action();
}
delayMicroseconds(100);
}*_

[/quote]

(otherwise known as my first library)

FINAL HEADER

#ifndef StepperMotor_h
#define StepperMotor_h

#include “WProgram.h”

class StepperMotor{

public:
StepperMotor(int n);
void reset();
void think();
void action();
void update_position();
void choose_destination();
void set_required_movement();
void move_right(long d);
void move_left(long d);
void no_move();
void tell_sam();
void reset_slide();

private:
int motor_no;
int dirpin;
int steppin;
int cycles;
int dest;

long i;
long randomWait;
long a;
long b;
long distance;
long sleep;

boolean LEFT;
boolean RIGHT;
boolean at_A;
boolean at_B;
boolean at_C;
boolean go_A;
boolean go_B;
boolean go_C;
boolean move;
};

#endif

FINAL SOURCE

#include “WProgram.h”
#include “StepperMotor.h”

StepperMotor::StepperMotor(int n)
{
motor_no = n;
dirpin = (2n)+36;
steppin = (2
n)+37;
a = 18000;
b = 36000;
LEFT = true;
RIGHT = false;
pinMode(dirpin, OUTPUT);
pinMode(steppin, OUTPUT);
}

void StepperMotor::reset(){
if (cycles < 1){
reset_slide();
cycles++;
}}

void StepperMotor::think(){
//WHEN YOU REACH THE NEW POSITION, CLEAR THE PAUSE AND TRAVEL COUNT & CHOOSE A NEW DESTINATION
if ((i > distance)){
update_position();
tell_sam();
sleep = millis();
randomWait = (random(1,4))*1000;
i = 0;
choose_destination();
set_required_movement();
}}

void StepperMotor::action(){
//IF REQUIRED STEP THE MOTORS WHEN OUT OF THE PAUSE TIME
if (((millis() - sleep) > randomWait) && move){
digitalWrite(steppin, LOW);
digitalWrite(steppin, HIGH);
i++;
}
// OTHERWISE RETURN TO THE DESTINATION CHOICE
else if (((millis() - sleep) > randomWait) && move == false){
i++;
}}

///NESTED VOIDS
void StepperMotor::update_position(){
if(go_A){
at_A = true;
at_B = false;
at_C = false;
}
else if(go_B){
at_A = false;
at_B = true;
at_C = false;
}
else if(go_C){
at_A = false;
at_B = false;
at_C = true;
}}

void StepperMotor::choose_destination(){
dest = random(1,4);
if (dest == 1){
go_A = true;
go_B = false;
go_C = false;
}
else if (dest == 2){
go_A = false;
go_B = true;
go_C = false;
}
else if (dest == 3){
go_A = false;
go_B = false;
go_C = true;
}
}

void StepperMotor::set_required_movement(){
if (at_A && go_A){
no_move();
}
else if (at_A && go_B){
move_right(a);
}
else if (at_A && go_C){
move_right(b);
}
else if (at_B && go_A){
move_left(a);
}
else if (at_B && go_B){
no_move();
}
else if (at_B && go_C){
move_right(a);
}
else if (at_C && go_A){
move_left(b);
}
else if (at_C && go_B){
move_left(a);
}
else if (at_C && go_C){
no_move();
}}

void StepperMotor::move_right(long d){
digitalWrite(dirpin, HIGH);
LEFT = false; RIGHT = true;
distance = d;
move = true;
}

void StepperMotor::move_left(long d){
digitalWrite(dirpin, LOW);
LEFT = true; RIGHT = false;
distance = d;
move = true;
}

void StepperMotor::no_move(){
distance = 0;
randomWait = randomWait+5000;
move = false;
}

void StepperMotor::tell_sam(){
Serial.print(motor_no);
if (at_A){
Serial.print(“A”);
}
else if (at_B){
Serial.print(“B”);
}
else if (at_C){
Serial.print(“C”);
}
Serial.print("—");
}

void StepperMotor::reset_slide(){
go_A = true;
go_B = false;
go_C = false;
move_left(40000);
}