Pages: [1]   Go Down
Author Topic: Servo y clase heredada  (Read 1224 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 8
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Buenos días. Mi intención es poder hacer una clase ("Motor") donde poder controlar un servo, con una función ( avan() decir que vaya de 90º a 180º). Y posteriormente poder llamar a esa función desde el programa principal.

Motor bot(6) //indico el pin donde voy a conectarlo

bot.avan() //llamo a la función que hace que el servo vaya de 90º a 180º

Si hago esto mismo sin utilizar la clase Motor, es decir, si lo hago directamente en el programa de arduino, funciona perfectamente. Pero haciendo la clase intermedia no me funciona.

Entiendo que la clase Motor es heredada de la clase Servo.h (la cual tengo que tener en la misma carpeta que la clase motor). Os dejo el código a ver si se os ocurre algo. Muchas gracias.

Motor.h

Code:
#ifndef Motor_h
#define Motor_h

#include "WProgram.h";
#include "Servo.h";

class Motor:public Servo{
  public:
    Servo mymotor;
    Motor(int pin);
    void avan();
   
 };

#endif


Motor.cpp

Code:
#include "WProgram.h";
#include "Motor.h";
#include "Servo.h";



Motor::Motor(int pin) {
  this->mymotor.attach(pin);
}


void Motor::avan(){
  this->mymotor.write(90);
  delay(2000);

  this->mymotor.write(180);
  delay(2000);

}

Programa Principal (LIBMotor.pde)

Code:
#include <Motor.h>

Motor bot(6);

void setup(){
}

void loop(){

  bot.avan();
}

PD.: El servo se queda en la posición central "temblando".
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 8
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Parece que ya he encontrado la solución. Por lo visto el problema estaba en que el "attach" tengo que ponerlo si o si en el setup() del programa principal de arduino.

No vale con ponerlo en el constructor

^^.
Logged

Palencia, Spain
Offline Offline
God Member
*****
Karma: 25
Posts: 506
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hola. A pesar de que tu código funciona, creo que tienes un poco difuso el concepto de herencia. No es lo mismo que una clase contenga un objeto de otra a que una clase herede de otra. En tu caso haces ambas cosas a la vez. Me imagino que si declaras tu clase sin :public Servo funcione igualmente.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 8
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Efectivamente también funciona sin el ":public Servo". Pero es que la clase Motor es una clase Servo ¿no?

Quiero decir que Motor "hereda" de Servo, no es que lo "contenga". Aún así ¿Sería entonces más correcto ponerlo sin el ":public Servo"?
Logged

Palencia, Spain
Offline Offline
God Member
*****
Karma: 25
Posts: 506
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Si declaras motor como clase heredada de servo, un objeto motor es un objeto servo más lo que añadas al heredar. No es necesario que incluyas el objeto myservo.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 8
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Entonces ¿sería correcto lo siguiente?

Motor.cpp

Code:
#include "WProgram.h"
#include "Motor.h"

Motor::Motor() {}

void Motor::avan(){
  write(90);
  delay(2000);
 
  write(180);
  delay(2000);

Motor.h

Code:
#include <Servo.h>
#include "WProgram.h"

#ifndef Motor_h
#define Motor_h

class Motor:public Servo{
  public:

    Motor();
    void avan();
};

#endif

Programa Principal (LIBMotor.pde)

Code:
#include <Servo.h>
#include "Motor.h"


Motor bot;

void setup(){

  bot.attach(9);
}

void loop(){

  bot.avan();
 
}

Gracias.
Logged

Palencia, Spain
Offline Offline
God Member
*****
Karma: 25
Posts: 506
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Te falta elaborar el constructor, esencialmente para llamar al constructor de servo. Echa un vistazo a esta página y de paso a los capítulos relacionados.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 8
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Esta forma es la única que entiendo de utilizar el constructor, pero no se si es a lo que te referías.

Motor.cpp

Code:
#include "WProgram.h"
#include "Motor.h"

Motor::Motor(int x, int y) {
  this -> x = x;
  this -> y = y;
}

void Motor::avan(){
  write(x);
  delay(2000);
 
  write(y);
  delay(2000);
}

Motor.h

Code:
#include <Servo.h>
#include "WProgram.h"

#ifndef Motor_h
#define Motor_h

class Motor:public Servo{
  public:

    Motor(int x, int y);
    void avan();
   
  private:
 
    int x, y;
};

#endif


Programa principal (LIBMotor.pde)

Code:
#include <Servo.h>
#include "Motor.h"


Motor bot(90, 180);

void setup(){

  bot.attach(9);
}

void loop(){

  bot.avan();
 
}

Gracias.
« Last Edit: July 25, 2013, 02:56:28 pm by Metalpuzzle » Logged

Palencia, Spain
Offline Offline
God Member
*****
Karma: 25
Posts: 506
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Mil disculpas, pues igual te he confundido. Pensé que el constructor servo necesitaba parámetros, de ahí lo que te decía de llamar al constructor de servo desde el de motor. Eso unido a que estoy leyendo/escribiendo con la incomodidad de la pantalla del móvil me despistó. Tu código del penúltimo post creo que es correcto.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 8
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ok, muchas gracias por todo noter ^^.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 8
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Buenos días. Se me ha presentado otro problema relacionado con el tema.

Lo que quiero ahora es hacer una clase intermedia que "conecte" la clase "Motor" con el programa principal "LIBMotor.pde"

El error que me da al compilar es:

LIBMotor.cpp.o.: In function
`_static_initialization_and_destruction_0´:
/B.h:7: multiple definition of `r´
B.cpp.o:C:\Users\...../B.cpp:5: first defined here

¿Alguna idea?

Muchas gracias.

Motor.h

Code:
#include <Servo.h>
#include "WProgram.h"

#ifndef Motor_h
#define Motor_h

//Como ya comenté en otros post la clase Motor la creo como parte de la clase Servo.h

class Motor:public Servo{
    public:

        Motor();
        void avanM();
};

#endif

Motor.cpp

Code:
#include "Motor.h"

Motor::Motor(){}

void Motor::avanM()
{
    write(90);
}

//Ahora creo la clase intermedia. (Lo anterior, sin la clase intermedia, conseguí que funcionara, como ya dije en otro post)

B.h

Code:
#include "WProgram.h"
#include "Motor.h"

#ifndef B_h
#define B_h

Motor r; [b]//aquí es donde están los problemas (creo yo)[/b]

class B{
    public:

        B();
        void avanB();
};

#endif

B.cpp

Code:
#include "B.h"
#include "WProgram.h"

B::B(){}

void B::avanB()
{
    r.avanM(); [b]//Llamo al objeto r de la clase M.[/b]
}

LIBMotor.pde (Programa principal)

Code:
#include "B.h"
#include <Servo.h>

B s;

void setup()
{
    r.attach(9); [b]//Como ya vimos, he de poner el attach de Motor en el setup del programa principal,
                     //si no, me da error al compilar.[/b]
}

void loop()
{
    s.avanB();
}
Logged

Palencia, Spain
Offline Offline
God Member
*****
Karma: 25
Posts: 506
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

¿Cuál es el propósito de la "clase intermedia"? Si te das cuenta, declaras un objeto r y una clase para trabajar con ese objeto externo a ella. Además, el único método que declaras, realiza una llamada a un método preexistente de la clase motor. Vamos; un batiburrillo a mi parecer. Si quieres sencillamente evitar el error de compilación, declara r como static Motor; pero creo que sería mejor si intentaras explicar qué quieres que haga cada clase.
Como punto de partida, esto me compila (aunque no sé si funcionará, supongo que sí):

Motor.h
Quote
#include <Servo.h>

#ifndef Motor_h
#define Motor_h

class Motor:public Servo{ //Motor hereda de la clase Servo
    public:

        Motor(int pin=9); //Si se invoca el constructor sin parámetros, tomará por defecto el pin 9
        void avanM();
};

#endif


Motor.cpp
Quote
#include "Motor.h"

Motor::Motor(int pin){attach(pin);} //En el propio constructor realizamos el attach del pin

void Motor::avanM()
{
    write(90);
}

libmotor.ino
Quote
#include <Servo.h>
#include "Motor.h"

Motor s=Motor(); // Al no indicar pin, tomará el 9 podríamos haber declarado s=Motor(7) para pin 7
void setup()
{
}

void loop()
{
    s.avanM();
}

Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 8
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Buenos días, antes de nada quería disculparme por no haber contestado antes, pero no he tenido posibilidad de conectarme a internet hasta hoy.

De todas formas al final conseguí solucionar el problema. El attach (como ya deduje al principio) debe ir en el setup del programa principal, pero al tener un objeto de Motor (Motor r) en la clase B y luego tratar de llamar a ese objeto en el programa principal parece que falla.

La solución que he encontrado es poner una función en la clase B:

Code:
void B::setup_motor()
{
    r.attach(9);
}

Y luego llamarla en el setup del programa principal:
Code:
void setup()
{
    s.setup_motor();
}
Con eso tengo todos los objetos (B s) en el programa principal y todos los objetos (Motor r) en el B.cpp. Y con eso funciona (a demás de parecer lógico).

Respuesta a la pregunta =P

El objetivo de esto es para un proyecto más grande. Donde haga un "coche".

Tendré una clase Motor (que significará cómo se mueve un servo).

Una clase intermedia llamada Base: esta clase lo que hace es definir funciones llamadas avanzar, parar, girar a la derecha, etc. Esta clase llama a la clase motor y le manda los parámetros del giro.

Y luego el programa principal: recibe los parámetros que le envíe y dependiendo del parámetro así llama a la función avanzar, parar, girar a la derecha, etc. de la clase Base.


Así es como me dijo el tutor que lo planificase ^^.

De nuevo MUCHAS GRACIAS noter por responder ^^.

PD.: No se muy bien para que sirve aumentarte el karma (malo no debe ser)... pero creo que te lo mereces!! Así que ahí va!! karma++ =P
Logged

Pages: [1]   Go Up
Jump to: