Cambio variables desde Bluetooth

Buenas, les comento:
Estoy haciendo un control de una maquina que tiene un montón de variables,controladas desde una APP. La idea es que cuando quiera cambiar una variable la APP mande un codigo tal que así: "VARIABLE#VALOR\n".

Uso serial.readStringUntil('#') y serial.parseInt(), para leer ambos valores; el nombre de la variable que quiero cambiar y el valor. Hasta aquí todo correcto, pero si uso directamente serial.readStringUntil('#') = serial.parseInt(), el valor no se asigna a la variable(string) que lee por bluetooth.
La otra opción es guardar ambas lecturas en dos variables y luego asignarle a esa variable el valor, pero nosé como hacerlo, ya que si hago lo siguiente:

dato = BTserial.readStringUntil('#');
valor = BTserial.parseInt();
dato = valor;

el valor no es asignado a la variable que esta dentro de "dato", sino que el string guardado en "dato" es sustituido por "valor".

Nose si me he explicado bien, quizás es algo lioso.

Haber si alguno tiene alguna idea de como conseguir hacerlo.

Saludos!
 
Última edición:
Lo único que entiendo es que usas un lenguaje orientado a objetos, ¿pero cúal es?

Obviamente si usas dato = valor; se borra dato y cambia a valor. no puedes decirle al programa que la variable llamada 'dato' se llene con el valor y menos usando cadenas por que al compilar 'dato' no se mantiene como 'dato' sino como una direccion 0x?????? y no podrias hacer una transferencia directa sin saber la direccion asignada,

usa switch case para algo asi

Código:
switch( dato ){
   case 'dato1': 
      dato1=valor; 
      break;
   case 'dato2':
      dato2 = valor;
...
}
 
Perdona, el lenguaje es el de Arduino que es donde estoy programando.

Esa posibilidad ya la había pensado, pero no quería tener que llenar el código con un montón de casos, pues serían muchísimas variables que podrían ser cambiabas. Aún así no es mala solución, aunque engorrosa. Haber si alguien sabe como podría hacerlo.
 
...
"VARIABLE#VALOR\n".
...

Uso serial.readStringUntil('#') y serial.parseInt(), para leer ambos valores; el nombre de la variable que quiero cambiar y el valor. Hasta aquí todo correcto,
(y)

pero si uso directamente serial.readStringUntil('#') = serial.parseInt(), el valor no se asigna a la variable(string) que lee por bluetooth.
(n)(n)
Me parece que estamos confundiendo las cosas. A ver si entiendo bien, estás pensando que si en algún lugar tenes una variable:
int miVariable;
y luego haces
ref = "miVariable";
al hacer
ref = 8;
te va a quedar miVariable = 8
me equivoco?.

Bueno no, un procesador + compilador no trabaja así.
Imagina que cuando escribís en el código int miVariable lo que estás haciendo es simplemente un alias hacia una dirección de memoria (ponele 0x1234), y luego cada vez que escribas miVariable el compilador va a decir "ajá!!! se está refiriendo a 0x1234, sustituyo por eso!!!, listo".
Luego cuando se compila y genera la imagen de programa que se carga al micro, ya no existe nada que vincule a la dirección 0x1234 con algo llamada miVariable.

La otra opción es guardar ambas lecturas en dos variables y luego asignarle a esa variable el valor, pero nosé como hacerlo, ya que si hago lo siguiente:

dato = BTserial.readStringUntil('#');
valor = BTserial.parseInt();
dato = valor;

el valor no es asignado a la variable que esta dentro de "dato", sino que el string guardado en "dato" es sustituido por "valor".

Nose si me he explicado bien, quizás es algo lioso.
Sí, confirmado, estás confundiendo el nombre de una variable con un string cuyo contenido tiene los mismos caracteres del nombre de la variable.

Para tu caso particular lo primero que se me ocurre (para nada optimo) es:

  1. Tener un vector/tabla con el nombre de las variables (strings) que vienen por el puerto serie:
    char *nombres[] = {"VARIABLE1", "VARIABLE2", "VARIABLE3"};
    No quise usar la clase Strings para ocupar un poco menos de memoria.
  2. Almacenar referencias (punteros) a las variables, que vamos a suponer todas del mismo tipo (si no es tu caso aclararlo):
    int *punteros[] = {&variable1, &variable2, &variable3};
  3. Llega un comando, buscar la variable en la tabla nombres, si se encuentra devolver un índice, y usarlo para escribir la variable a partir de punteros:
    dato = BTserial.readStringUntil('#');
    valor = BTserial.parseInt();
    indice = buscarVariable(dato);
    punteros[indice] = valor;
Algo así... se puede mejorar y mucho, pero por lo menos para empezar. En vez de un switch-case que se alarga vas a tener más elementos en punteros y nombres.
Se puede hacer más orientado a objetos, pero me parece más trabajo (una clase que tenga un campo string con el nombre de la variable, un campo ref con el puntero a la variable, blablabla).
 
No hay forma de pasar en un comando la dirección a escribir, te expliqué que cuando compilas el programa, la variable llamada DATO deja de ser identificada como DATO y se le asigna un espacio de memoria supongamos 0x10A2, si tu le intentas decir al programa que en la variable 'DATO' cargue un nuevo valor, el programa solo sabe que 'DATO' es una string, no puede asociarla a una dirección.

¿Si hay forma de hacer lo que quieres? Quizá la hay usando punteros, y eso significa asignar explícitamente la dirección de memoria que vas a modificar, no se llamara 'DATO' sino un valor 0x??????? y debes tener en consideración no realizar conflictos con los espacios de memoria, esto puede que sea mas engorroso por que debes asignar todo tú, no el compilador, o no sabrás la dirección de memoria asignada.
 
Última edición:
(y)

(n)(n)
Me parece que estamos confundiendo las cosas. A ver si entiendo bien, estás pensando que si en algún lugar tenes una variable:
int miVariable;
y luego haces
ref = "miVariable";
al hacer
ref = 8;
te va a quedar miVariable = 8
me equivoco?.

No eso exactamente, creo que no me expliqué bien. Lo que quiero hacer es mandar por bluetooth el nombre de la variable a cambiar y el valor. Algo como lo siguiente:

int velocidad = 0;
//Mando por bluetooh : "vel#15 \n"

BTserial.readStringUntil('#') = BTserial.parseInt(); // velocidad = 15;

Esta es la idea, pero así directamente no funciona, y estaba viendo si había otra forma.

No sabía que las variables se guardan en solamente como direcciones al compilar, soy nuevo en esto de la programación (por lo menos en aspectos "teóricos"), pero aún así podría al leer la variable asociarla a esa dirección de la misma manera que hace si lo hiciera con "cases" que yo mando la palabra y el la compara con esas variables que supuestamente ya solo son direcciones.

Muchas gracias por las respuestas, lo que decís de vectores, punteros etc apenas entiendo de eso, asique vosotros direis, si es la mejor opción me pongo a ello, sinó con usando switch case igual me es suficiente.

Un saludo!
 
No eso exactamente, creo que no me expliqué bien. Lo que quiero hacer es mandar por bluetooth el nombre de la variable a cambiar y el valor. Algo como lo siguiente:

int velocidad = 0;
//Mando por bluetooh : "vel#15 \n"

BTserial.readStringUntil('#') = BTserial.parseInt(); // velocidad = 15;

Esta es la idea, pero así directamente no funciona, y estaba viendo si había otra forma.

Sí, eso entendí al principio

No sabía que las variables se guardan en solamente como direcciones al compilar, soy nuevo en esto de la programación (por lo menos en aspectos "teóricos"), pero aún así podría al leer la variable asociarla a esa dirección de la misma manera que hace si lo hiciera con "cases" que yo mando la palabra y el la compara con esas variables que supuestamente ya solo son direcciones.

Claro... una variable es básicamente un "alias" para una zona de memoria. El compilador de C se encarga de hacer el trabajo por nosotros para leer, escribir, y operar con ellas; pero el procesador solo entiende de direcciones (con excepción de los registros que pueden tener direcciones abreviadas por decirlo de alguna forma).

Si no querés hacerte lío con punteros entonces sí, es más claro hacer un switch-case, pero no sé si es aplicable a cadenas, es decir, no sé si se puede hacer:
Código:
switch(cadenaEntrada)
{
  case "Variable1":
  break;
  case "Variable2":
  break;
  //etc
}

Creería que no... porque hasta donde sé el switch(algo) precisa que algo sea un tipo entero. Si en vez de "variable1" o "variable2" usas nombres de 1 letra ('c', 'a', 'm') entonces sí podes hacer un switch-case como:

Código:
switch(caracterEntrada)
{
  case 'c':
  break;
  case 'a':
  break;
  //etc
}

Si querés usar cadenas, podes hacer un if - else if - usando strcmp (o la función de comparación preferida de Arduino)


Código:
if(0 ==  strcmp(cadenaEntrada, "Variable1"))
{
  Variable1 = valorParseado;
}
else if(0 ==  strcmp(cadenaEntrada, "Variable2"))
{
  Variable2 = valorParseado;
}
else if(0 ==  strcmp(cadenaEntrada, "VariableN"))
{
  VariableN = valorParseado;
}

Suerte!!!
 
Atrás
Arriba