Autor Tema: USART, ¿como capturar caracteres y trabajar con su valor numerico?  (Leído 7492 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado ALFREDOSKY

  • PIC16
  • ***
  • Mensajes: 118
Hola a todos, estoy atascado en un problema de manejo de datos, uso el dspic30f2010, el modulo USART tanto en RX como en TX y un motor dc; desde pc envio tres caracteres que los trato como hexadecimales, y cada caracter me indica una tarea a realizar, por ejemplo al enviar desde pc al pic la secuencia XXX, los caracteres los trato como:

- el 1er 'X' es un comando de control y no necesito su valor numérico
- el 2do caracter 'X' me indica el angulo de giro del motor , este caracter tiene el rango desde 0 a F (hexadecimal)
- el 3er caracter 'X' me indica la velocidad PWM del motor, también va de 0-F

los últimos 2 caracteres me representan cantidades variables, es decir, por ejemplo si escribo(o envío) 'A8F', voy a mandar girar a la izquierda(caracter A) 200°(caracter 8) y a un pwm del 100%(el caracter F)

Si escribo 'BF7' B:derecha, F:360° y 7:50% pwm y así de la misma manera para otros caracteres hexadecimales.

El problema que tengo es que necesito el valor númerico de esos caracteres, por ejemplo si el PIC recibe 'BF7', el valor de F es 15 en decimal y trabajo con ese valor para los cálculos con números flotantes y enteros y asi con todos los caracteres, lo que he estado haciendo es capturar cada caracter en varios arreglos de tipo char, agregarle un terminador o fin de cadena y convertirlo a entero usando la función atoi(), pero no me funciona; también he probado con -'0' sin usar la función atoi(), pero igual, nada pasa.

Alguien que sepa de estas cosas y me pueda dar un alcance sobre mis posibles errores y propuestas de mejoras seria de gran ayuda.  :mrgreen:

Desconectado AngelGris

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2480
Re: USART, ¿como capturar caracteres y trabajar con su valor numerico?
« Respuesta #1 en: 05 de Marzo de 2014, 12:48:15 »
  Yo he utilizado las funciones itoa y atoi con el viejo compilador HiTech y funcionaban bien. En XC8 sólo he probado itoa y también funciona bien.
De vez en cuando la vida
nos besa en la boca
y a colores se despliega
como un atlas

Desconectado rivale

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1707
Re: USART, ¿como capturar caracteres y trabajar con su valor numerico?
« Respuesta #2 en: 05 de Marzo de 2014, 12:57:20 »
el itoa y el atoi no funcionarían porque estas funciones requieren una cadena como argumento y tu solo quieres usar un byte.

una opcion seria usar un switch asi tienes que para:

case '0':
      pwm->0:

break;

case '1'
      pwm-->xxx

break;

y asi sigues.



otra opcion seria que verifiques si tu caracter esta dentro del '0' y el '9', entonces le restas 0x30, y si esta entre la 'A' y la 'F' le restas 0x41

por ejemplo algo asi:

int valor

if(caracter>= '0' && caracter <='9')
{
  valor=caracter-0x30;

}

else if(caracter>='A' && caracter<= 'F')
{
  valor =caracter-0x41;
}


con estas condiciones al final tu variable valor tendría valores numéricos de entre 0 y 16



"Nada es imposible, no si puedes imaginarlo"

Desconectado ALFREDOSKY

  • PIC16
  • ***
  • Mensajes: 118
Re: USART, ¿como capturar caracteres y trabajar con su valor numerico?
« Respuesta #3 en: 05 de Marzo de 2014, 15:21:50 »
AngelGris y rivale, gracias por sus prontas respuestas; yo uso el compilador C30 pero no me funciona la funcion atoi(), los  caracteres los convierto a string almacenandolo en 2 arreglos con tamaño de 3 bytes  y le coloco un '/0' como indicador de fin de cadena, pero igual,  la función atoi() no convierte nada  :?; En el caso del 'case' me parece buena alternativa pero algo larga ,tendría que testear cada caracter  :shock:... creo que la resta es la más conveniente  :mrgreen:, lo voy a implementar, gracias nuevamente por las sugerencias   ((:-))

Desconectado rivale

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1707
Re: USART, ¿como capturar caracteres y trabajar con su valor numerico?
« Respuesta #4 en: 05 de Marzo de 2014, 15:36:56 »
otro detalle es que el atoi solo convierte cuando están en base 10, es decir, no funcionará si recibe como argumentos letras.
"Nada es imposible, no si puedes imaginarlo"

Desconectado ALFREDOSKY

  • PIC16
  • ***
  • Mensajes: 118
Re: USART, ¿como capturar caracteres y trabajar con su valor numerico?
« Respuesta #5 en: 05 de Marzo de 2014, 16:03:46 »
rivale, tambien uso numeros, el rango es de 0 a F, pero igual, atoi() no me convierte ni los numeros  :x, cosa rara  :(

Desconectado rivale

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1707
Re: USART, ¿como capturar caracteres y trabajar con su valor numerico?
« Respuesta #6 en: 05 de Marzo de 2014, 17:14:24 »
el atoi no va a convertir nada si recibe una "F" por ejemplo, pero si recibe un "1", "2", ..."9" debería funcionar, tal vez el problema esta en como generas tu cadena para introducirla al atoi, debería ser algo así


char cad[3];
int num;

cad[0]='2';
cad[1]=0;

num=atoi(cad)


"Nada es imposible, no si puedes imaginarlo"

Desconectado ALFREDOSKY

  • PIC16
  • ***
  • Mensajes: 118
Re: USART, ¿como capturar caracteres y trabajar con su valor numerico?
« Respuesta #7 en: 05 de Marzo de 2014, 19:27:19 »
Asi es rivale, es exactamente lo que hago, pero no lo convierte  :shock:

Desconectado rivale

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1707
Re: USART, ¿como capturar caracteres y trabajar con su valor numerico?
« Respuesta #8 en: 05 de Marzo de 2014, 19:33:07 »
Asi es rivale, es exactamente lo que hago, pero no lo convierte  :shock:

que raro, podrías poner tu código de la conversión para ver si hay algo extraño. aunque como solo tienes un rango de 16 valores en hexa, creo que seria mas conveniente usar la resta que te comenté en el primer post
"Nada es imposible, no si puedes imaginarlo"

Desconectado ALFREDOSKY

  • PIC16
  • ***
  • Mensajes: 118
Re: USART, ¿como capturar caracteres y trabajar con su valor numerico?
« Respuesta #9 en: 05 de Marzo de 2014, 20:36:33 »
Código: [Seleccionar]
char BufferRX[4];          //arreglo de 16 bytes
char DataTX[4];            //arreglo de 16 bytes
int i;
int pos = 0;
char comando;
unsigned int RX_data;
int ang;
int pwm;
char PWM[3];
char ANG[3];

//recepcion de comandos
unsigned int check_command_serial()
{
    if (DataRdyUART1())
    {
        RX_data = ReadUART1();
       
        switch (RX_data)
        {
            case 10 : break;                     
            case 13 : if (pos>0)                   
                      {
                        comando = BufferRX[0];
                        pos = 0;                       
                        ANG[0] = BufferRX[1];
                        ANG[1] = 0;
                        PWM[0] = BufferRX[2];
                        PWM[1] = 0;
                        ang = atoi(ANG);
                        pwm = atoi(PWM);
                        pos = 0;
                        BufferRX[pos] = 0;
                        PWM[pos] = 0;
                        ANG[pos] = 0;
                        return 1;
                       }
                      break;
            default :
                      BufferRX[pos] = RX_data;     
                      pos++;                       
                      BufferRX[pos] = 0;                             
                      break;
        }
    }
    return 0;
}

Desconectado rivale

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1707
Re: USART, ¿como capturar caracteres y trabajar con su valor numerico?
« Respuesta #10 en: 05 de Marzo de 2014, 21:36:45 »
no se si el c30 es "case sensitive", tienes 2 variables con el mismo nombre
"Nada es imposible, no si puedes imaginarlo"

Desconectado ALFREDOSKY

  • PIC16
  • ***
  • Mensajes: 118
Re: USART, ¿como capturar caracteres y trabajar con su valor numerico?
« Respuesta #11 en: 06 de Marzo de 2014, 11:55:57 »
Cambiaré los nombres y probare, gracias por la sugerencia  :mrgreen:

Desconectado ALFREDOSKY

  • PIC16
  • ***
  • Mensajes: 118
Re: USART, ¿como capturar caracteres y trabajar con su valor numerico?
« Respuesta #12 en: 06 de Marzo de 2014, 18:01:34 »
Lamentablemente no convierte :8}

Desconectado rivale

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1707
Re: USART, ¿como capturar caracteres y trabajar con su valor numerico?
« Respuesta #13 en: 06 de Marzo de 2014, 18:07:40 »
intenta probar la función de atoi directamente, porque puede que no entre al case donde se utiliza
"Nada es imposible, no si puedes imaginarlo"

Desconectado KALLITOS

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1256
Re: USART, ¿como capturar caracteres y trabajar con su valor numerico?
« Respuesta #14 en: 06 de Marzo de 2014, 18:25:35 »
Hola paisano.

Creo que estan haciendo las cosas mal, las funciones atoi, atol y demas se ejecutan con "caracteres numericos" es decir ASCII, aqui veo que estan usando hexadecimal y por alli no va bien la cosa.

Para que te haces problemas si el valor esperado va de 0x00 a 0x0F entonces calcula directamente:

ang = ((unsigned short)BufferRX[1]*(unsigned short)100)/360;

pwm = ((unsigned short)BufferRX[2]*(unsigned short)100)/0x0f;

Sencillo no?

Ahora si quieres pasar de hexa a decimal o viceversa, en una libreria de ds1307 "creo de RedPic" existen estas funciones:

Código: C++
  1. unsigned char bin2bcd(unsigned char temp)
  2. {
  3. unsigned char retval=0;
  4. while(1)
  5.         {
  6.     if(temp >= 10)
  7.                 {
  8.         temp -= 10;
  9.         retval += 0x10;
  10.         }//
  11.         else   
  12.                 {
  13.         retval += temp;
  14.         break;
  15.         }//
  16.         }//
  17. return(retval);
  18. }//
  19.  
  20. unsigned char bcd2bin(unsigned char bcd_value)
  21. {
  22. unsigned char temp;
  23. temp = bcd_value;
  24. temp >>= 1;
  25. temp &= 0x78;
  26. return(temp + (temp >> 2) + (bcd_value & 0x0f));
  27. }//
A un microcontrolador hay que sacarle hasta el ultimo byte....(YO)

Cómo puede ser que un pic24EP512 me quede corto de memoria, señores de MICROCHIP saquen pics con más memoria flash

Más de 45 mil lineas de codigo y aun no termino el equipo, asu mare!!

S34ML08G1TFI200 no necesito mas memoria externa.


 

anything