Hola a todo el mundo.
He desarrollado un modulo LCD 40x4 con un teclado especial a través de puerto serie.
Ya tengo montada toda la librería, y lo único que no consigo es comunicar a través de la libreria SofwareSerial. Buscando aqui en eel foro, he encontrado este post
https://forum.arduino.cc/index.php?topic=412274.0
y he seguido los pasos que ha dado el amigo "bidi3".
Todo va va bien excepto que el compilador da un error que por más vueltas que le doy no consigo solucionarlo.
.............ies\LCD40x4/LCD40x4.h:24:64: error: return type specification for constructor invalid
- byte LCD_40x4_Serial (byte rx, byte tx, dword baud_rate);*
exit status 1
Error compilando para la tarjeta Arduino Nano.
El código que tengo el fichero .h es
.
.
.
.
#include <SoftwareSerial.h>
class LCD_40x4_Serial
{
public:
byte LCD_40x4_Serial (byte rx, byte tx, dword baud_rate);
.
.
.
.
private:
SoftwareSerial Serial_to_LCD;
.
.
.
.
}
en el fichero .cpp
#include <SoftwareSerial.h>
byte LCD_40x4_Serial::LCD_40x4_Serial::Serial_to_LCD (byte rx, byte tx, dword baud_rate)
{
Serial_to_LCD.begin(baud_rate);
}
Y en el fichero .ino
LCD_40x4_Serial LCD(A1, A2 , 19200);
Agradecería que alguien me pudiera poner luz para solucionar el problema que tengo.
Muchas gracias por adelantado.
Saludos
Primero: nunca he visto que se pueda especificar tipo de retorno en un constructor.
Segundo: el constructor de SoftwareSerial por fuerza necesita dos enteros: pin para RX y pin para TX.
Hola Lucario:
Primero: nunca he visto que se pueda especificar tipo de retorno en un constructor.
Correcto, yo tampoco lo he visto nunca, pero ese es el error que da. He probado de todo, de no poner nada, void, byte,....... Y sigue dando ese mismo error
Segundo: el constructor de SoftwareSerial por fuerza necesita dos enteros: pin para RX y pin para TX.
En cuanto al SoftwarfeSerial, se le declaran los parámetros en el fichero .cpp. Y no da ningún error. Por lo que entiendo que debe de funcionar. A lo mejor si se quita el primer error, empiezan a salir otros errores, que ahora desconozco.
Llevo dos dias dádole vueltas y vueltas, y nada de nada.
Gracias por la respuesta.
El compilador dice que no es válido colocar un tipo de retorno en un constructor; quítalo en el h y cpp. Si colocas void también habrá error.
PD: ¿dword equivale a long? Si utilizas un tipo de dato de menor tamaño, acabarás restringiendo el máximo de bps.
Hola de nuevo:
Nada, ¡¡¡¡tampoco!!!!
Sin ningún tipo de identificador de tipo, sigue dando el mismo error.
La verdad es que estoy desesperado, y lo peor es que estoy parado, sin poder avanzar.
Saludos
Tengo esto
#include <SoftwareSerial.h>// BLUETOOTH
class MiSerial {
public:
MiSerial(byte, byte, int );//Constructor
void ImprimirAlgo(String);//Método miembro
};
MiSerial::MiSerial(byte rx, byte tx, int baud ){
SoftwareSerial SOF_Serial(rx,tx);//Creando objeto de la clase SoftwareSerial
//Esta linea si funciona pero no en otro metodo SOF_Serial.print(Imprimir);
SOF_Serial.begin(9600);
Serial.begin(9600);
}
void MiSerial::ImprimirAlgo(String Imprimir){
SOF_Serial.print(Imprimir);//Linea de erroooooor por no estar declarada SOF_Serial segun el IDE
Serial.print(Imprimir);
}
MiSerial Serial_(2,4,9600);//Creando objeto de mi clase
void setup() {
Serial_.ImprimirAlgo("Imprime Setup");
}
void loop() {
Serial_.ImprimirAlgo("Imprime Loop");
}
Con este error
MiArchivo.ino: In member function 'void MiSerial::ImprimirAlgo(String)':
MiArchivo:16: error: 'SOF_Serial' was not declared in this scope
SOF_Serial.print(Imprimir);
^
exit status 1
'SOF_Serial' was not declared in this scope
Dándome a entender que lo que se haga en el constructor. En el constructor se queda.
y Lo digo porque la linea que me marca con el error que esta en la función
MiSerial::ImprimirAlgo(String Imprimir)
la comento y la pongo en el constructor y hay no marca el error
No se porque sucede esto de no poderse usar desde otras funciones o metodos.
Y pasa lo mismo con
Serial.begin(9600);
Ahora por curioso, tengo mas dudas.
Lo de StringCGE es porque SOF_Serial es solo una variable local del constructor; no ha sido declarada como miembro de la clase.
LOKOMOTORO_460 prueba esta definición de constructor:
LCD_40x4_Serial::LCD_40x4_Serial(byte rx, byte tx, dword baud_rate)
{
Serial_to_LCD = SoftwareSerial(rx, tx); // Asumiendo que un objeto se puede instanciar como ocurre con String
Serial_to_LCD.begin(baud_rate);
}
Gracias Lucario448 ya encontré la forma de hacer funcionar mi código
Aqui solo que no alcance a postear.
Ya probare el código como lo propone LOKOMOTORO_460 y tus correcciones.
Pasando a mi solución.
Uso un BLUETOOTH en los pines del SoftwareSerial para saber si funciona bien. En mi caso si funciono.
Desconozco el nombre de esto pero lo llamo
"Clases anidadas"
Archivo.ino
#include <SoftwareSerial.h>
class MiClase {
public:
MiClase(int rx,int tx, int baud);//Constructor
void ImprimirAlgo(String);//Metodo para hacer algo
private:
SoftwareSerial SOF_Serial;//Constructor de la clase que se usara internamente
};
//Constructor de Miclase //Constructor de la clase interna
MiClase::MiClase(int rx = 2, int tx = 4, int baud = 9600):SOF_Serial(rx,tx){
//Mas codigo que se desee ejecutar
Serial.begin(baud);
SOF_Serial.begin(baud);
}
//Metodo
void MiClase::ImprimirAlgo(String Imprimir){
//Mas codigo que se desee ejecutar
SOF_Serial.print(Imprimir);
Serial.print(Imprimir);
}
MiClase Serial_(2,4,9600);//Creando el objeto
//Sino se usa constructor seria asi
//MiClase Serial_;
//MiClase Serial_();error request for member 'ImprimirAlgo' in 'Serial_', which is of non-class type 'MiSerial()'
void setup() {
Serial_.ImprimirAlgo("Imprime Setup");
}
void loop() {
Serial_.ImprimirAlgo("Imprime Loop");
}
De no funcionar mi propuesta anterior; puedes probar esta otra definición:
LCD_40x4_Serial::LCD_40x4_Serial(byte rx, byte tx, dword baud_rate):Serial_to_LCD(rx, tx)
{
Serial_to_LCD.begin(baud_rate);
}
La tomé de la solución de noter en el hilo que StringCGE acaba de compartir.
StringCGE:
Desconozco el nombre de esto pero lo llamo
"Clases anidadas"
Llámalo como quieras, pero para mi no hay clases anidadas.
Técnicamente, una clase anidada es la declaración de una dentro de la declaración de otra. Lo que hiciste fue nada más unir código en un solo archivo, donde usualmente se hubiera separado en tres:
- Cabecera de C (.h): ahí usualmente solo se colocan las declaraciones de la clase.
- Código fuente de C++ (.cpp): ahí usualmente va la implementación de las funciones declaradas en la cabecera.
- Código fuente de Arduino (.ino): ahí usualmente van las rutinas de setup y loop.
Esta separación es la sugerida en la página de Arduino sobre la creación de librerías; mas no es obligatoria ya que el compilador lo único que le interesa es que todo esté estructurado como se debe, sin importar en cuantos archivos se haya separado el código (pero con todas las dependencias correctamente conectadas en los #include).
Bueno saber que no son anidadas, no se aun como se llamaría a eso.
Que este todo en un mismo archivo es por comodidad.
Si funciona se escribe la librería completa y si no funciona, a corregir hasta que el segmento de código salga bien.
StringCGE:
Que este todo en un mismo archivo es por comodidad.
Si funciona se escribe la librería completa y si no funciona, a corregir hasta que el segmento de código salga bien.
Buen punto, aunque el compilador igual dice de cuál archivo vino el error...
Si el compilador no dijera cual es el archivo y la linea de error, es porque el programador de ese compilador quiere ver arder al mundo.
Jajajaja básicamente. De ser así, sería una herramienta inútil...