Go Down

Topic: problema con polimorfismo (Read 1 time) previous topic - next topic

danielleal

Hola gente, mi primera consulta, acabo de registrarme y espero poder colaborar a futuro y tambén que a alguien le sirva este ejemplo que si lo hacemos funcionar esta muy bueno como para entender el polimorfismo en Arduino.

Les comento que estoy trabajando con un Arduino Uno. Hasta donde puedo ver el ejemplo debería funcionar bien, pero luego de ejecutarse una vez y hacer el loop, falla en el segundo caso (cuando debería prender por segunda vez el led ROJO).

Para funcionar el ejemplo solo se requiere un LED rojo con una resistencia de 1k entre el pin 7 y GROUND

a continuación pongo todas las librerias y la principal para que lo prueben.

PolimorfismoExample.ino
Code: [Select]

/*
* PolimorfismoExample.ino
*
* Created: 10/5/2014 12:51:00 PM
* Author: Commander
*/

#include "Arduino.h"
#include "Mascota.h"
#include "Perro.h"
#include "Gato.h"

Mascota *p; // Perro es led Rojo 7
Mascota *g; // Gato es led Verde 13
Perro perro("Ramiro"); // Crea un perro
Gato gato("Lancelot"); // Crea un gato

void setup()
{
p = &perro;
g = &gato;

//perro.hablar(); // Hace que el "perro hable" Prende y apaga el Led 7 Rojo
//gato.hablar(); // Hace que el "gato hable" Prende y apaga el Led 13 Verde
}

void loop()
{
p->hablar(); // Hace que el "perro hable" Prende y apaga el Led 7 Rojo
delay(2000); // Hace un delay para que se note la diferencia de uno de otro

Serial.println(freeRam()); // Dice cuanta Ram queda

g->hablar(); // Hace que el "gato hable" Prende y apaga el Led 13 Verde
}

int freeRam ()
{
extern int __heap_start, *__brkval;
int v;
return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval);
}


Mascota.h
Code: [Select]

/*
* Mascota.h
*
* Created: 05/10/2014 12:53:15 p.m.
* Author: Commander
*/


#ifndef __MASCOTA_H__
#define __MASCOTA_H__

#include "Arduino.h"

class Mascota
{
public:
Mascota(String nombre, int patas);
virtual String hablar();

private:
virtual String palabra();

String nombre;
int patas;
};

#endif //__MASCOTA_H__


Mascota.cpp
Code: [Select]

/*
* Mascota.cpp
*
* Created: 05/10/2014 12:53:14 p.m.
* Author: Commander
*/

#include "Arduino.h"
#include "Mascota.h"

// Constructor de la clase Mascota que es la superClase
Mascota::Mascota(String nombre, int patas):nombre(nombre),patas(patas)
{

}

// Define el método palabra para la clase de mascota
String Mascota::palabra()
{
return "BUUU";
}

// Define el método hablar para la clase mascota
String Mascota::hablar()
{
return nombre+" dice: "+this->palabra();
}


Perro.h

Code: [Select]

/*
* Perro.h
*
* Created: 05/10/2014 12:54:12 p.m.
* Author: Commander
*/


#ifndef __PERRO_H__
#define __PERRO_H__

#include "Arduino.h"
#include "Mascota.h"

class Perro : public  Mascota
{
public:
Perro(String nombre);
String hablar();
String palabra();
};


#endif //__PERRO_H__


Perro.cpp
Code: [Select]

/*
* Perro.cpp
*
* Created: 05/10/2014 12:54:11 p.m.
* Author: Commander
*/


#include "Arduino.h"
#include "Perro.h"

// Crea el contructor de la clase y a su vez llama al constructor de la superClase
Perro::Perro(String nombre):Mascota(nombre, 4)
{
Serial.begin(115200);

// Pone el pin 7 para esta clase
pinMode(7,OUTPUT);
digitalWrite(7,LOW);
}

// Crea el método hablar, que es público y es requerido por la superclase
String Perro::hablar()
{
// Prende y apaga el LED Rojo para dar un aviso de que esta ejecutando bajo polimorfismo
digitalWrite(7,HIGH);
delay(2000);
digitalWrite(7,LOW);

// Envía la palabra asociada a la clase
Serial.println(palabra());
}

// Crea el método palabra, que es privado, requerido por la superClase y define que es un GUAU para esta clase
String Perro::palabra()
{
return "GUAU";
}


Gato.h
Code: [Select]

/*
* Gato.h
*
* Created: 05/10/2014 12:55:29 p.m.
* Author: Commander
*/


#ifndef __GATO_H__
#define __GATO_H__

#include "Arduino.h"
#include "Mascota.h"

class Gato : public  Mascota
{
public:
Gato(String nombre);
String hablar();
String palabra();
};

#endif //__GATO_H__


Gato.cpp
Code: [Select]

/*
* Gato.cpp
*
* Created: 05/10/2014 12:55:29 p.m.
* Author: Commander
*/

#include "Arduino.h"
#include "Gato.h"

// Crea el contructor de la clase y a su vez llama al constructor de la superClase
Gato::Gato(String nombre):Mascota(nombre, 4)
{
Serial.begin(115200);

// Pone el pin 13 para esta clase
pinMode(13,OUTPUT);
digitalWrite(13,LOW);
}

// Crea el método hablar, que es público y es requerido por la superclase
String Gato::hablar()
{
// Prende y apaga el LED Verde para dar un aviso de que esta ejecutando bajo polimorfismo
digitalWrite(13,HIGH);
delay(2000);
digitalWrite(13,LOW);

// Envía la palabra asociada a la clase
Serial.println(palabra());
}

// Crea el método palabra, que es privado, requerido por la superClase y define que es un MIAU para esta clase
String Gato::palabra()
{
return "MIAU";
}

danielleal

Una cosita mas, por si no fui claro en el problema.

Lo que hace es: ejecuta el

1 - Loop() <- La primera vez se ejecuta completo
2 - Loop() <- Esta vez se corta y no hace mas nada despues de que perro escribe al serial

3 - Nunca llega al delay. El codigo no creo que este mal, sino no deberia ejecutarse la primera vez

danielleal

Sigo informando sobre lo que hice y cual puede haber sido la solucion,

despues de alguna modificaciones que no son relevantes, termine por poner todo lo que esta dentro del Loop() dentro de un bucle while asi:

Loop()
{
  while(1 == 1)
  {
    CODIGO EXISTENTE
  }
}

esto soluciono el problema, pero no me explico cual puede ser el problema y no me convence quedarme con esto como solución, ya que esto es un ejemplo tonto para poder probar la teoría, pero si empiezo a implementarlo y despues me genera errores raros como esto ¡¡¡QUE HAGO!!!

Algun genio que pueda tener alguna teoría para poder profundizar. Acepto cualquier tipo de sugerencias.

surbyte

Justamente cuanta RAM te quedó la primera vez
y lo debugueaste para ir viendo paso a paso que ocurre?

danielleal

Lo de la ram, me fije con la función freeRam() que esta en el archivo ino y en la primera pasada imprime 1405, en la segunda ya no llega. Llega hasta el final de perro->hablar, pero cuando deberia volver al loop y hacer el delay(2000) nunca llega.

La verdad que no lo entiendo.

surbyte

#5
Oct 07, 2014, 04:37 pm Last Edit: Oct 07, 2014, 05:15 pm by surbyte Reason: 1
sube todos los archivos por favor usando Additional Options. Asi veo que ocurre, interesante tu problema.

12.13 (hora argentina) Lo primero que veo que no me gusta o veo como sospechoso, es que en el constructor de perro y gato tienes Serial.begin(115000);
Una vez esta bien pero dos???? no se que pasa. Analizando eso....

Code: [Select]
Gato::Gato(String nombre):Mascota(nombre, 4)
{
Serial.begin(115200);

// Pone el pin 13 para esta clase
pinMode(13,OUTPUT);
digitalWrite(13,LOW);
}


Code: [Select]
Perro::Perro(String nombre):Mascota(nombre, 4)
{
Serial.begin(115200);

// Pone el pin 7 para esta clase
pinMode(7,OUTPUT);
digitalWrite(7,LOW);
}

surbyte

Problema solucionado, era tal como te decia, dos veces inicializando el puerto Serie no es apropiado.

Captura de pantalla de mis resultados



Adjunto los codigos modificados levemente para que funcione.
Aunque siguiendo tu linea lo pasteo aca

Code: [Select]
/*
* PolimorfismoExample.ino
*
* Created: 10/5/2014 12:51:00 PM
* Author: Commander
*/

#include "Arduino.h"
#include "Mascota.h"
#include "Perro.h"
#include "Gato.h"

Mascota *p; // Perro es led Rojo 7
Mascota *g; // Gato es led Verde 13
Perro perro("Ramiro"); // Crea un perro
Gato gato("Lancelot"); // Crea un gato

void setup()
{
[color=red]Serial.begin(9600);   // agregado[/color]
p = &perro;
g = &gato;

//perro.hablar(); // Hace que el "perro hable" Prende y apaga el Led 7 Rojo
//gato.hablar(); // Hace que el "gato hable" Prende y apaga el Led 13 Verde
Serial.println("Comenzando");
}

void loop()
{
p->hablar(); // Hace que el "perro hable" Prende y apaga el Led 7 Rojo
delay(2000); // Hace un delay para que se note la diferencia de uno de otro

Serial.println(freeRam()); // Dice cuanta Ram queda

g->hablar(); // Hace que el "gato hable" Prende y apaga el Led 13 Verde
}

int freeRam ()
{
extern int __heap_start, *__brkval;
int v;
return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval);
}



En los header de perro y gato, simplemente comenté // Serial.begin(115000);

danielleal

Buenisimo!!! Un genio!!! La verdad no le encontraba la vuelta, tomo en cuenta el tema de hacer multiples begin del puerto serial y voy a leer mejor como se utiliza. Por otra parte, te consulto, vi la captura de pantalla que hiciste, que programa estas usando. Te da algun tipo de simulación y debug? porque parece estar bueno, yo estoy usando visual micro pero se me va a terminar el periodo de prueba en breve.

max_saeta

Saludos danielleal
El programa que usa Surbyte es proteus y puede simular bastante bien el arduino y también algunos sensores. Yo uso la version 8, aunque algunos sketch no me corren en proteus me sirve para probar otros.

Go Up