[Resuelto] Modificar variables en librerias generadas por mi

Hola!

Estoy creando una librería para poner en limpio parte de un código muy largo que he hecho para un proyecto y facilitar que sea reutilizable en el futuro.

La primera cosa que me asalta es que, a diferencia de las funciones “normales”, parece que cuando le paso una variable, no la modifica, por ejemplo este método:

void aeroroblib::toggleChange(boolean toggle, int pinToggle){
 
  /*
   * Toggle function changes the value of "toggle" once per cycle to make
   * possible to measure the speed of the code with an osciloscope 
   * connected to pinToggle
   */
   
  if (toggle == 1) {
    toggle = 0;
  }
  else {
    toggle = 1;
  }
  digitalWrite(pinToggle, toggle);
}

En el código la llamo normal:

#include <aeroroblib.h>
aeroroblib aerorob;

loop(){
  aerorob.toggleChange(toogle, 31);
}
// faltan trozos, obvio, pero es que el codigo ahora es un caos y toda la librería... mas (mas de 1000 lineas)

Funciona, si le pongo unos prints para ayudarme al debugging los hace, etc, pero no modifica la variable. Si imprimo en el loop la variable no se ha modificado

La verdad es que en ese caso (el toggle) me da un poco más igual y lo he modificado para que el toggle sea una variable “private”, que incluso tiene más lógica. Sin embargo, en otras cosas, como funciones que no tienen por qué usarse siempre cuando se emplee la librería, no veo tener que generar una variable _private siempre.

O peor aún, por ejemplo si generase una matriz que necesito para un filtro y fuese una variable _private, no me dejaría tener varios filtros corriendo en paralelo… no se si me explico.

La verdad es que la referencia no dice mucho.

¿Alguien que haya generado librerías y me pueda dar algún consejo?

Porque no subes los archivos .h .cpp y el ino todos en un .zip

Porque no me dejan distribuirlo todavía T-T, y eso que no es nada del otro mundo.

De todos modos, haré un apaño ahora y subiré las funciones más básicas. Creo que de todos modos, no me he explicado muy bien antes...

La cuestión está en que si yo le paso una variable al método aunque se modifique internamente en el método, esa variable no cambia en el global. Imagino que esa es la forma de funcionar de las librerías, pero quien sabe.

Preparo un ino simplificado y lo subo.

Pero solo el ejemplo. NO me interesa lo que estas haciendo. Sino tenemos que ponernos nosotros a hacer funcionar tu ejemplo.

Pues eso, estoy aligerando :slight_smile:

Ahí va

Como vereis, como "timeprevious" no se actualiza en el global, timeStep en la practica es el tiempo que lleva transcurrida la función, cuando devería ser el tiempo del último ciclo.

En este ejemplo concreto, voy a hacer que timprevious sea una variable "private" de la librería, creo, porque rara vez va a haber una aplicación que no necesite un computo de tiempos, pero que sea mucho mas compacto, en la practica no sirve de nada tener la variable timeprevious en el loop.

La cuestión es que creo que no es una cuestión de mi ejemplo o mi código, sino de la forma de funcionar de las librerías. Las funciones si que alteran las variables que les pasas en el encabezado, pero parece que las librerías no.

Vaya que has hecho la tarea por la mitad jajaja

D:/Dropbox/Arduino/Borrar_0/aeroroblib/Examples/sketch_aug28a/sketch_aug28a.ino: In function 'void setup()':
D:/Dropbox/Arduino/Borrar_0/aeroroblib/Examples/sketch_aug28a/sketch_aug28a.ino:33:22: error: 'pinToogle' was not declared in this scope
   aerorob.toggleInit(pinToogle, 31);
                      ^
D:/Dropbox/Arduino/Borrar_0/aeroroblib/Examples/sketch_aug28a/sketch_aug28a.ino: In function 'void loop()':
D:/Dropbox/Arduino/Borrar_0/aeroroblib/Examples/sketch_aug28a/sketch_aug28a.ino:43:22: error: 'class aeroroblib' has no member named 'timeStepUpdate'
   timeStep = aerorob.timeStepUpdate(timeprevious);

Verificando errores...

Vaya! Si a mi me ha compilado! Revisando

Lo siento, este era el script que quería haber adjuntado, he adjuntado otro…

#include <aeroroblib.h>


aeroroblib aerorob;

int pinAccX = A3;
int pinAccZ = A5;
int pinGyro = A2;




byte   toggle = 1;


// Times

unsigned long timenow, timeprevious;
float timeStep;




void setup()
{
  Serial.begin(9600);
  Serial1.begin(9600);
  Serial2.begin(9600);
  
  // -- Toggle ---
//  pinMode(31, OUTPUT);
  
  aerorob.toggleInit(31, toggle);


}
void loop()
{
  //-------------------------------------
  // ---------- time measure ------------
  //-------------------------------------
  
  timeStep = aerorob.timeStepCalc(timeprevious);

  
  Serial.print(timeprevious);
  Serial.print(",");
  Serial.println(timeStep);
}

He modificado el enlace anterior con el documento erroneo, ahora redirige a lo mismo que este, que espero que funcione

La cuestión es que, por ejemplo en fortran (que es quizá lo que más he usado) cuando pasas una variable en una función, defines si es in, out, o inout, a mi me gustaría que algunas variables fuesen inout o out.

Claro, podría definir las funciones como

float function(float X,.....);

Sin embargo, eso solo da una variable de salida. No es un error en el script, lo que me cuestiono es cómo funcionan las librerías. Parece que no encuentro nada, voy a intentar buscar un manual de C++ a ver qué me cuenta y os comento.

Creo que he encontrado la solución, si al definir la función, en vez de decirle que le pasas la variable le pasas la referencia, modifica el valor de la variable.

Es decir, un método definido como:

void aeroroblib::gyroInit(int pinGyro, float offsetGyro){ // fichero aeroroblib.cpp
void gyroInit(int pinGyro, float offsetGyro);  // fichero aeroroblib.h

No modifica el valor de las variables pinGyro ni offsetGyro, en cambio si haces:

void aeroroblib::gyroInit(int pinGyro, float &offsetGyro){ // fichero aeroroblib.cpp
void gyroInit(int pinGyro, float &offsetGyro);  // fichero aeroroblib.h

Sí que se modifica el valor de la variable offsetGyro

Gracias por el apoyo!

Edito: Y añado que con los arrays no ocurre esto, se modifican sin necesidad de intermediar, porque a nivel interno de C++ ya son un puntero.