Go Down

Topic: LECTURA DE LOS ELEMENTOS DE UN STRING EMPEZANDO POR LA DERECHA (Read 1 time) previous topic - next topic

mrespejo

Estoy empezando en el mundo Arduino, y solicito ayuda.

Trato de separar los diferentes dígitos de la lectura de un sensor de temperatura TMP35, para visualizarlo en display 7 segmentos.

El valor, que puede ir desde 125.0º C hasta -40.0º C, lo pongo en un string llamado temperatura, para separar cada uno de los dígitos usando  (temperatura.charAt(x)). Esto realiza la separación  contando los elementos del string de izquierda a derecha.

Como el número de dígitos puede variar, según el valor el signo de la medida, se complica el poder asegurar si el dígito corresponde a centenas, decenas, unidades, punto decimal o décimas.

Esto se solucionaría si se  pudiera leer los elementos del string de derecha a izquierda.
¿Es esto posible?

Gracias por vuestra ayuda.

Manuel R. Espejo

surbyte

Me imagino que tu problema es para poder presentarlos justificado a derecha, es así?
Tengo una solución pero sin usar String.

Postea el código usando etiquetas (si no sabes lee las normas del foro, no pegues texto plano).

mrespejo

#2
Sep 25, 2017, 12:13 am Last Edit: Sep 25, 2017, 03:29 am by surbyte Reason: Código debe llevar etiqueta </>
Gracias por tu respuesta.

Trato de explicarme mejor. La variable temperatura, va cambiando con el tiempo.

125.7
80.4
 9.5
-5.8
-16.3

Si quiero visualizar estos valores en un display 7 segmentos, debo de empezar por separar y dirigir cada uno de los dígitos al display correcto.   Centenas al de centenas, decenas al de decenas etc.

Los valores los paso a un string, donde puedo separar los dígitos uno a uno, para enviarlo al display correspondiente.

Sería fácil, si el string lo pudiera leer de derecha a izquierda. Posición 0 corresponde a décimas. Posición 1 a las unidades y así consecutivamente hasta llegar a un espacio en blanco, que me indicaría que he terminado la lectura.

Esto lo haría usando (variable.charAt(x)) donde x sería la posición del dígito que quiero extraer, solo que esto empieza a contar los caracteres de izquierda a derecha, por lo que al ser variable el número de dígitos, según la temperatura medida, no puedo saber si empiezo leyendo centenas, decenas o unidades.

Lo probé usando



Code: [Select]
{
float lectura = analogRead(A0); //Se declara la variable lectura, que se inicializa con
                                //el valor presente en el pin de entrada analogico A0
float voltaje = 2.41 /1024 * lectura ;//Se declara la variable voltaje y se inicializa
                                      //asignándole el valor de lectura convertido en voltios
float temp = voltaje * 100 -50 ; //Se declara la variable temp, que se inicializa con el valor de
                                  //voltaje trasladado a grados centígrados. (TMP35)
String (despiece) = String (temp); //Se declara la variable despiece que se inicializa con el valor
                                   //de temp convirtiéndolo en un string de caracteres

Serial.print(despiece.charAt(0)); //separo cada uno de los caracteres. (Desgraciadamente
                                                // empieza de izquierda a derecha, por lo que no me sirve)
Serial.print("    ") ;
Serial.print(despiece.charAt(1));
Serial.print("    ") ;
Serial.print(despiece.charAt(2));
Serial.print("    ") ;
Serial.print(despiece.charAt(3));
Serial.print("    ") ;
Serial.println(despiece.charAt(4));
delay(2000);



Se me ocurre  alguna solución, como invertir el orden de los caracteres en el string, o utilizar length, lo que me permitiría contar los caracteres del string y saber si empiezo por las centenas, decenas o unidades.

De todas formas, si me sugieres otra forma de hacerlo, lo agradezco. (Se que hay bloques de displays  que utilizan pocos pines de entrada, y librerías que los manejan sin problemas, pero esto es un proyecto dirigido al aprendizaje.

Gracias,

Manuel R. Espejo

Lucario448

¿Por qué mejor no lo haces sin String? Más eficiente y además hace un tanto más fácil implementar el algoritmo de invertir el orden de una cadena de caracteres:

Code: [Select]
char despiece[10]; // Global

void loop() {
 float temp = (2.41 / 1024 * analogRead(A0)) * 100 - 50 ;
 // Se declara la variable temp, que se inicializa con el valor de voltaje trasladado a grados centígrados. (TMP35)
 dtostrf(temp, 0, 1, despiece); // Inicializa la variable despiece con el valor de temp convirtiéndolo en un string de caracteres
 // Tercer parámetro indica cuántos decimales imprimir.

 reverseString(despiece); // Invierte el string
 
 for (unsigned int i = 0, j = strlen(despiece); j; i++, j--) {
 // Siempre imprime la cantidad de caracteres escritos por dtostrf; no una cantidad fija como lo hacías antes.
 
 Serial.write(despiece[i]); //separo cada uno de los caracteres
 Serial.print(F("    ")) ;
 }
 
 delay(2000);
 }
 
void reverseString(char* s) {
 unsigned int j = strlen(s) - 1;
 const unsigned int mid = j / 2;
 
 for (unsigned int i = 0; i <= mid; i++, j--) { // Intercambia caracteres entre extremos, hasta llegar al punto medio
 char c = s[i];
 s[i] = s[j];
 s[j] = c;
 }
}

mrespejo

Muchas gracias, Lucario488.

reverseString soluciona mi problema. Estoy empezando, y desconocía esa posibilidad.

Sigo desarrollando mi sketch, y seguiré consultando si aparece alguna duda.

Gracias también al foro.

Manuel R. E.

SOLUCIONADO

rodripelto

reverseString soluciona mi problema. Estoy empezando, y desconocía esa posibilidad.
reverseString no es una posibilidad, es un metodo que se ha inventado Lucario448, no es algo propio del lenguaje.
Si alguna respuesta ha solucionado tu problema, da las gracias marcándola como solucionada.

mrespejo

Cuando he intentado ejecutar el sketch que me facilita Lucario448,  he visto que reverseString no es una instrucción Arduino que se ejecute directamente, si no que es lo que se llama una instrucción de creación propia, definida dentro un void.

Al final no es exactamente lo que esperaba, pero si que me interesa mucho porque me permite seguir aprendiendo en el mundo Arduino.

Muchas gracias,

Manuel R. E.

Lucario448

he visto que reverseString no es una instrucción Arduino que se ejecute directamente, si no que es lo que se llama una instrucción de creación propia, definida dentro un void.
Bueno pues la clase String no implementa una función así, por eso una opción era crearla "a mano".

Con un objeto String hubiera tenido un mayor sobrecargo (¿con usar c_str() hubiera sido lo mismo?), además de que no lo recomiendo para ejecuciones a largo plazo o proyectos definitivos; por eso recalco la importancia de utilizar espacios de memoria preasignados para las cadenas de caracteres o búferes. El ajetreo de estar constantemente liberando y reasignando espacio en memoria (algo que los objetos String suelen hacer) es lo que lo hace menos eficiente, y que a la larga fragmenta la memoria al punto de colgar el programa (con el espacio muy comprometido por variables globales y librerías, el cuelgue puede ocurrir en cuestión de horas o incluso minutos).


No es que String sea siempre una mala opción, tiene su razón de existir: hace muy fácil al principiante la manipulación de cadenas de caracteres, y perfectamente se puede utilizar en la etapa de pruebas. En la etapa definitiva podría restar fiabilidad al sistema y ser un problema cuando el espacio en memoria comience a escasear.
Cuando tengas suficiente experiencia con el tema de las cadenas de caracteres, bien serías ya capaz de prescindir del objeto String incluso al escribir código desde cero.

Go Up