Go Down

Topic: concatenar lowByte (Read 139 times) previous topic - next topic

Jorge_LA

Jul 21, 2019, 04:20 pm Last Edit: Jul 23, 2019, 03:29 am by surbyte Reason: Agregado de etiqueta para Errores y/o códigos
Necesito concatenar varios datos en en array

Code: [Select]
int test = 1200;
char arreglo[2];

arreglo[0] = highByte(test);
arreglo[1] = lowByte(test);

Serial.print("Hight:"); Serial.println(highByte(test),HEX);  // Retorna Hight:4
Serial.print("Low:"); Serial.println(lowByte(test),HEX);     // REtorna Low:B0

Serial.print(arreglo[0],HEX); Serial.print("|"); Serial.print(arreglo[1],HEX); // Retorna 4|FFFFFFB0


por que en la concatenación me retorna FFFFFFB0 en lugar de B0?
Desde ya gracias por la ayuda

Sereno

#1
Jul 21, 2019, 06:27 pm Last Edit: Jul 22, 2019, 12:10 am by Sereno
Edito y borro.
Tienes toda la razón IgnoranteAbsoluto.

IgnoranteAbsoluto

Prueba a declarar el array como unsigned char
Code: [Select]
unsigned char arreglo[2];

O declararlo de tipo byte
Code: [Select]
byte arreglo[2];


El problema es que el parámetro HEX hace que Serial.println() trabaje con el valor del primer parámetro como si fuera un entero con signo de 32 bits y se ha de tener cuidado si se parte de un tipo con signo. El problema está en que los tipos "con signo" hacen que el bit de signo "se extienda" al "promocionar" a un tipo "superior".

El valor hexadecimal B0 de un char no es 176 en decimal, es -80 en decimal. Sí, es un número negativo.

Serial.print(arreglo[1], HEX) no trata arreglo[1] como un char (entero con signo de 8 bits) sino que espera un long int (entero con signo de 32 bits) así que "promociona" el char a long int. El -80 sigue siendo un -80, pero ya no es de 8 bits, sino de 32 bits y -80 en un entero de 32 bits con signo se representa en hexadecimal con el el valor FFFFFFB0 (cada letra representa cuatro bits). La solución es no trabajar con enteros con signo, sino trabajar con enteros de 8 bits sin signo. Tanto el tipo byte como el tipo unsigned char son ambos enteros de 8 bits sin signo.

Para "visualizar" un poco el problema prueba a ejecutar este programa en un Arduino UNO y observa qué sale en el monitor serie.

Code: [Select]
void setup() {
    Serial.begin(9600);
    Serial.print("      lowByte(-80): "); Serial.println(      lowByte(-80), HEX); //       lowByte(-80): B0
    Serial.print("         (byte)-80: "); Serial.println(         (byte)-80, HEX); //          (byte)-80: B0
    Serial.print("(unsigned char)-80: "); Serial.println((unsigned char)-80, HEX); // (unsigned char)-80: B0
    Serial.print("         (char)-80: "); Serial.println(         (char)-80, HEX); //          (char)-80: FFFFFFB0
    Serial.print("               -80: "); Serial.println(               -80, HEX); //                -80: FFFFFFB0
    Serial.println();
    Serial.print("      lowByte(176): "); Serial.println(      lowByte(176), HEX); //       lowByte(176): B0
    Serial.print("         (byte)176: "); Serial.println(         (byte)176, HEX); //          (byte)176: B0
    Serial.print("(unsigned char)176: "); Serial.println((unsigned char)176, HEX); // (unsigned char)176: B0
    Serial.print("         (char)176: "); Serial.println(         (char)176, HEX); //          (char)176: FFFFFFB0
    Serial.print("               176: "); Serial.println(               176, HEX); //                176: B0
    Serial.println();
    Serial.print("      lowByte(1200): "); Serial.println(      lowByte(1200), HEX); //       lowByte(1200): B0
    Serial.print("         (byte)1200: "); Serial.println(         (byte)1200, HEX); //          (byte)1200: B0
    Serial.print("(unsigned char)1200: "); Serial.println((unsigned char)1200, HEX); // (unsigned char)1200: B0
    Serial.print("         (char)1200: "); Serial.println(         (char)1200, HEX); //          (char)1200: FFFFFFB0
    Serial.print("               1200: "); Serial.println(               1200, HEX); //                1200: 4B0
}

void loop() {
    // Está vacío porque no queremos que se ejecute nada en bucle
}


El resultado ha de ser:

Code: [Select]
      lowByte(-80): B0
         (byte)-80: B0
(unsigned char)-80: B0
         (char)-80: FFFFFFB0
               -80: FFFFFFB0

      lowByte(176): B0
         (byte)176: B0
(unsigned char)176: B0
         (char)176: FFFFFFB0
               176: B0

      lowByte(1200): B0
         (byte)1200: B0
(unsigned char)1200: B0
         (char)1200: FFFFFFB0
               1200: 4B0


Observa que "el resultado" del las primeras tres líneas de los tres bloques coinciden. Y también son iguales los resultados de la penúltima línea de cada bloque. A pesar de estar trabajando con tres cantidades distintas (-80, 176 y 1200). Verás que la última linea da tres resultados diferentes en los tres bloques. Esto es porque en cada bloque las cuatro primeras líneas el Serial.println(..., HEX) obtienen el valor del primer parámetro a partir de un entero sin signo de 8 bits. En la tercera línea lo obtiene a partir de un entero con signo de 8 bits. Mientras que en la cuarta línea de cada bloque el valor lo obtiene a partir de un entero con signo de 16 bits.

Llama la atención que a un byte, a un char o a un unsigned char le da lo mismo si se le asigna el valor 176 o -80, porque "internamente" se guarda el mismo valor. Llama la atención, pero es así.

Jorge_LA

Perfecto. muchas gracias

Go Up