Autor Tema: CCS y los números con signo (crash!)  (Leído 6332 veces)

0 Usuarios y 3 Visitantes están viendo este tema.

Desconectado droky

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 628
    • Diseños radikales libres
CCS y los números con signo (crash!)
« en: 01 de Diciembre de 2008, 08:50:13 »
Hola,
Os voy a explicar el problema que me he encontrado con CCS y su forma de operar con los números con signo.
El problema me ha venido al implementar un movimiento de "rebote" de una bolita en una matriz de leds usando un acelerómetro de 3 ejes.
Para dar realismo a la bolita, tenía que hacerla rebotar contra los bordes de la matriz ( como si estuviera en una cajita )con lo cual esto implica:
  • invertir el sentido de marcha de la bolita en los rebotes
  • invertir el sentido de la marcha de la bolita cuando la gravedad contrarreste la velocidad de ascension
  • aplicar una absorción a la velocidad de la bolita en el rebote (perdida de enercia potencial en el impacto)
Utilizando un vector de 2 dimensiones para la velocidad v(x,y), ésta va a aumentar con el tiempo en una proporción directa a su aceleración, es decir, el valor que nos devuelva el acelerómetro sobre ese eje, va a ir aumentando o reduciendo la velocidad del mismo en el vector v(x,y)

Supongamos que la variable (pax) nos da el valor del punto de reposo del eje del acelerómetro ( cero grados )
Y que la variable (ax) es el valor analógico que nos devuelve el acelerómetro en ese eje.
entonces tenemos que la inclinación ( factor de aceleracion ) será ax-pax lo que implica que la aceleración será positiva hacia un lado y negativa hacia el contrario.
Bien , ahora la fórmula que nos va a dar la velocidad en el eje va a ser del tipo:
Código: [Seleccionar]
vel_x = vel_x + (ax - pax);

La velocidad será tambien negativa hacia un lado y positiva hacia el otro ¿porque el signo? pues porque es la manera más simple de cambiar la posición aplicando aceleración y velocidad:
Código: [Seleccionar]
pos_x = pos_x + vel_x;
y juntando todo, tenemos un bucle (que es la recta del tiempo en la ecuacion v=a*t ):
Código: [Seleccionar]
While(1);
   {
       set_adc_channel(1);   //Leemos valor en ADC
       delay_us(10);
       ax = read_adc();

       vel_x = vel_x + (ax - pax)  //velocidad va aumentando o disminuyendo
                                   //según la inclinación
       pos_x = pos_x + vel_x;  //La posición varía según la velocidad
   }

Ahora resulta que como la velocidad crece muy rápido la pelota pasa del principo al final de la matriz en un instante, entonces es necesario aplicar una corrección al incremento de la velocidad, así que voy a dividir por (por ejemplo por 10)  la velocidad, ya que si divido la aceleracion (ax-pax) me quedo sin rango en ella porque es una escala muy pequeña (aproximadamente 1 bit por cada 2 grados de inclinación).
Como lo importante es preservar memoria y capacidad de cómputo en un PIC, en lugar de la división por 10, lo divido por 8 desplazando 3 bits a la derecha:

Código: [Seleccionar]
While(1);
   {
       set_adc_channel(1);   //Leemos valor en ADC
       delay_us(10);
       ax = read_adc();

       vel_x = vel_x + (ax - pax)>>3  //velocidad va aumentando o disminuyendo
                                   //según la inclinación. Aceleracion dividida por 8
       pos_x = pos_x + vel_x;  //La posición varía según la velocidad
   }

Como quiero que el movimiento sea suave y solo tengo (por ejemplo) una matriz de 20 leds de eje x, y pos_x crece y disminuye muy rápido, entonces voy a trabajar en una proporcionalidad de 1/1000, es decir, el rango del eje x va a ser (0-19999) con lo que la posición real de x en la matrix será:
Código: [Seleccionar]
px = pos_x/1000
Bien, ahora ¿que pasa cuando la bola rebota en los bordes de la matriz pos_x=0 y pos_x=20000? pues sencillamente si invertimos el signo de la velocidad, pos_x tambien cambiará de sentido de desplazamiento, y si mantenemos la inclinación que hizo desplazarse la bola hacia el borde en el que ha rebotado, la velocidad va a ir reduciendose proporcionalmente según avance el tiempo ( otra vez v=a*t y e=v/t ).
Ejemplo:
Valor ADC ax=500, punto de 0 grados pax=425.
Factor de aceleracion (ax-pax)=75
Supongamos que llega al borde con una velocidad vel_x=17500, entonces cuando pos_x=19999, vel_x=0 - vel_x y ahora vel_x =-17500
Conforme avanza el tiempo y si se mantiene la inclinacion ( aceleracion ax-pax=75), vel_x va a ir -17500,-17425,-17350..... hasta llegar a cero y luego empezará a aumentar 0,75,150,225,..... que será cuando la pelota llegue al final de su rebote y vuelva a descender.
Así que añadimos el control del rebote en x=0 y x=19999:
Código: [Seleccionar]
While(1);
   {
       set_adc_channel(1);   //Leemos valor en ADC
       delay_us(10);
       ax = read_adc();

       vel_x = vel_x + (ax - pax)>>3  //velocidad va aumentando o disminuyendo
                                   //según la inclinación. Aceleracion dividida por 8
       pos_x = pos_x + vel_x;  //La posición varía según la velocidad

        if (pos_x < 0) {
          pos_x = 0;
          vel_x = 0 - (vel_x);
        }

        if (pos_x > 19999) {
          pos_x = 19999;
          vel_x = 0 - (vel_x);
        }

   }

Bien hasta aquí, la cosa parece sencilla. Ahora resulta que el rebote así no es real, ya que cuando una pelota golpea el suelo, pierde energía y rebota a menor altura que desde donde se lanzó ( bueno, menos las pelotitas saltarinas endiabladas  que por efecto de la contracción y expansión del caucho generan un rebote mayor, pero siempre acaban cayendo... :) ), así que tenemos que aplicar un efecto de absorción al rebote.
Muy fácil, además de cambiar de signo el valor de la velocidad, lo reducimos en una proporcion de 0.75 por ejemplo, que es lo mismo que multiplicarlo por 3 y dividirlo entre 4 (vel_x=vel_x * (3/4) ).
Y no nos olvidemos de definir correctamente las variables tipo int, long y signed según el caso en como se usen:

Código: [Seleccionar]
void   bolita()
{
  long   ax,ay,pax,pay;         //Definición de variables
  signed long  pos_x,pos_y;
  signed long  vel_x,vel_y;
  int   px,py;

  While(1);
   {
       set_adc_channel(1);   //Leemos valor en ADC
       delay_us(10);
       ax = read_adc();

       vel_x = vel_x + (ax - pax)>>3  //velocidad va aumentando o disminuyendo
                                   //según la inclinación. Aceleracion dividida por 8
       pos_x = pos_x + vel_x;  //La posición varía según la velocidad

        if (pos_x < 0) {        //rebote en x=0 con absorción de 0.75
          pos_x = 0;
          vel_x = 0 - (3*(vel_x>>2));
        }

        if (pos_x > 19999) {        //rebote en x=19999 con absorción de 0.75
          pos_x = 19999;
          vel_x = 0 - (3*(vel_x>>2));
        }

px = pos_x/1000     //posición real en la matriz

   }

Bueno, todo esto en un uC Freescale y compilado en Codewarrior funciona ok, pero no así en CCS ¿Porque? pues después de unos cuantos rompederos de cabeza, resulta que por culpa del uso de los signos por parte del compilador.
El CCS usa complemento a 2 para los números negativos, pero con la particularidad que aún siendo un número de 16bits (tipo long) si el valor está entre -128 y 127 usa un complemento a 2 de 8bits ( el bit signo está en el 8º bit del byte de menor peso ) cuando lo normal es que el bit de signo estuviera en el 16º bit de la variable siendo un complemento a 2 de 16 bits.
Es decir, para una variable definida como: signed long vel_x
para vel_x = -85, el valor en Hex leído es de 00AB cuando en 16 bits debería ser FFAB que en binario sería:
-85 en 8bits= 10101011  (en rojo el bit de signo)
-85 en 16bits =11111111 10101011  (en rojo el bit de signo)

Con las sumas y las restas, no hay problema porque se opera perfectamente, pero los productos y divisiones (internamente CCS usa muchos desplazamientos para operar productos y divisiones) es un desastre, porque se desplaza el bit de signo y ocurren cosas como esta:
Imaginemos que en la ejecución se produce un rebote de la bolita y la velocidad en ese momento era de -12500 = 0xCF2C
Entonces llegamos al punto del programa del cambio de signo de la velocidad y de aplicación del rebote:
Código: [Seleccionar]
vel_x = 0 - (3*(vel_x>>2));
Lo primero es que al hacer vel_x>>2 el resultado es:
-12500 = 0b_11001111_00101100 >> 2 = 0b_00110011_11001011 que es 13256 en lugar de -3125
Pensé en sustituir el desplazamiento >>2 por la división /4, pero el resultado es el mismo, ya que internamente no tiene en cuenta los signos en los productos ni las divisiones.
Con el producto -12500*3  me ocurrió algo similar.
Busqué alguna libreria de aritmética con signo pero no la encontré y además posiblemente ocuparía mucha RAM, así que opté por modificar las operaciones jugando con los signos.
La opción más rápida que se me ocurrió fue hacer las operaciones con el valor absoluto en caso de números negativos y luego devolverles el signo.
En el caso de -12500>>2 sería:
0 - (-12500 ) = 12500   le quito el signo.
12500 >> 2   Desplazo
0 - 3125 = -3125  Le devuelvo el signo

Pasandolo al programa, entonces tengo:
Código: [Seleccionar]
if (vel_x<0)      //Si la velocidad es negativa
      {
        velx_tmp = 0 - (3*(0 - vel_x)>>2);  //opero sin signo y se los devuelvo  poniendolo en un temporal
      }
   else
        velx_tmp = (3*vel_x>>2);    // Si es positiva opero normalmente y pongo en temporal
       
        if (pos_x < 0) {    //si hay colision
          pos_x = 0;
          vel_x = 0 - velx_tmp;     //invierto la velocidad
        }

        if (pos_x > 4999) {    //si hay colision
          pos_x = 4999;
          vel_x = 0 - velx_tmp;     //invierto la velocidad
        }

Y el resto, bueno, pues lo mismo con el resto de operaciones y lo demás ya es historia...
Es una pena que CCS no sea capaz de operar completamente con los números con signo, ya que si se han definido como signed, deberían serlo desde el principio hasta el final ( como el toro que es toro hasta el final del rabo )

Si alguien ve una solución mejor o yo lo haya hecho mal y sí se pueda operar sin andar con cambios de signo, que me lo haga saber...
hasta aqui la experiencia y este es el resultado:

Salu2
« Última modificación: 01 de Diciembre de 2008, 12:22:52 por droky »
Yo... he visto cosas que vosotros no creeríais... atacar naves en llamas más allá de Orión, he visto rayos C brillar en la oscuridad cerca de la puerta Tannhäuser.
Todos esos momentos se perderán en el tiempo como lágrimas en la lluvia.
Es hora de morir.

Si me buscas en twitter, me tienes por @radikaldesig

Desconectado LABmouse

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 3575
    • Juntos es mejor
Re: CCS y los números con signo (crash!)
« Respuesta #1 en: 01 de Diciembre de 2008, 09:52:08 »
Lo de CCS, no tendría nada que decir. Hay tantos problemas con ese compilador que no se sabe con que te vas a encontrar y el problema es que después de 2 días de matarte la cabeza, encuentras que la culpa no era del programa y si de CCS. Ya me ha pasado varias veces.

Del vídeo.. Muy muy precioso y el detalle del rebote es muy bueno. FELICIDAES!  :P

Desconectado Mario

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 873
Re: CCS y los números con signo (crash!)
« Respuesta #2 en: 01 de Diciembre de 2008, 13:37:04 »
Apenas me estoy iniciando en C y se ha escogido CCS y, como todos, se está empezando a ver las bondades y desventajas.

Lo del signo no lo sabía pero, tengo un programa donde realizo varias operaciones y si me marca bien el signo con las variables signed (lo voy a buscar, no vaya a ser que esté diciendo barbaridades).


Tres preguntas:
¿Cuánta memoria RAM y ROM utiliza el programa?
¿Qué µicro usas?
Si usas Freescale......¿por qué utilizar µicrochip?
La buena administración es utilizar el sentido común y la regla de oro; aunque el sentido común no es tan común como quisiéramos que fuera y, quien tiene el oro, hace las reglas.
George Terry

"A loser will defeat a genius with hard work"
Rock Lee

Desconectado Nocturno

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 18286
    • MicroPIC
Re: CCS y los números con signo (crash!)
« Respuesta #3 en: 01 de Diciembre de 2008, 16:48:40 »
O no he entendido nada, que sería lo más normal, o mi CCS se comporta de forma distinta.
Mira cómo representa una variable de tipo signed int16 con diversos valores:

Código: [Seleccionar]
d:  -2200 f768  1111011101101000
d:  -2000 f830  1111100000110000
d:  -1800 f8f8  1111100011111000
d:  -1600 f9c0  1111100111000000
d:  -1400 fa88  1111101010001000
d:  -1200 fb50  1111101101010000
d:  -1000 fc18  1111110000011000
d:   -800 fce0  1111110011100000
d:   -600 fda8  1111110110101000
d:   -400 fe70  1111111001110000
d:   -200 ff38  1111111100111000
d:      0 0000  0000000000000000
d:    200 00c8  0000000011001000
d:    400 0190  0000000110010000
d:    600 0258  0000001001011000
d:    800 0320  0000001100100000
d:   1000 03e8  0000001111101000
d:   1200 04b0  0000010010110000
d:   1400 0578  0000010101111000
d:   1600 0640  0000011001000000
d:   1800 0708  0000011100001000
d:   2000 07d0  0000011111010000
d:   2200 0898  0000100010011000

Yo pienso que lo hace bien, ¿no?

Desconectado MGLSOFT

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 7912
Re: CCS y los números con signo (crash!)
« Respuesta #4 en: 01 de Diciembre de 2008, 16:55:30 »
Hay que ver que version tiene cada uno. :mrgreen:
Ademas por lo que lei, Droki hace una rotacion para dividir por 8 el valor, es posible que alli se le produzca el error??? :shock: :shock:
Todos los dias aprendo algo nuevo, el ultimo día de mi vida aprenderé a morir....
Mi Abuelo.

Desconectado Mario

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 873
Re: CCS y los números con signo (crash!)
« Respuesta #5 en: 01 de Diciembre de 2008, 19:22:32 »
Ademas por lo que lei, Droki hace una rotacion para dividir por 8 el valor, es posible que alli se le produzca el error??? :shock: :shock:

Había pensado eso.... pero como mencionó que funciona con los de Freescale me quedé atónito: ¿cómo sabrá el compilador que debe conservar el bit de signo?


No estoy en la casa para revisar ese archivo donde se "probaron" las diferentes operaciones aritméticas con variables distintas, cuando llegue salgo de dudas.
La buena administración es utilizar el sentido común y la regla de oro; aunque el sentido común no es tan común como quisiéramos que fuera y, quien tiene el oro, hace las reglas.
George Terry

"A loser will defeat a genius with hard work"
Rock Lee

Desconectado gera

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2188
Re: CCS y los números con signo (crash!)
« Respuesta #6 en: 01 de Diciembre de 2008, 21:45:37 »
2 cositas para probar:
1-Actualiza tu version de CCS, mientras mas nueva la version, menos errores (al menos en teoria jeje)
2-Castea todo! Algunos compiladores son muy caprichosos con eso.

Saludos!!!

"conozco dos cosas infinitas: el universo y la estupidez humana. Y no estoy muy seguro del primero." A.Einstein

Desconectado droky

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 628
    • Diseños radikales libres
Re: CCS y los números con signo (crash!)
« Respuesta #7 en: 02 de Diciembre de 2008, 00:39:56 »
Hola,
Bueno, me he roto la cabeza un poco más y a ver si puedo responder a todos.

A mario:
-RAM usa un 21% y ROM un 23% con las rutinas de desplazamiento de la matrix incluidas y solo la rutina de manejo de la bolita
-Uso en este caso un 16F688 funcionando todo a 2.8-3.3v
-No uso Freescale porque hay mas recursos en la red para PICs, en España son muy fáciles de conseguir sin pagar portes excesivos desde USA y Microchip los regala-ba  :mrgreen: (por lo menos para los protos)

Nocturno:
Bien, he actualizado la versión de CCS y veo que ya no me hace lo de ponerme a 8bits con signo los signed long de -128 -- 127, justo lo que has comprobado.
Si hago operaciones sueltas, me responde bien con los signos, pero en el programa algo pasa que se vuelve "loco"

El caso es que si uso esto funciona perfectamente, como explique anteriormente, quitando el signo, operando y volviendolo a poner:
Código: [Seleccionar]
    p_axtmp = (ax - pax);
    if (p_axtmp<0)
      {
         vel_x = vel_x - ((3*((0-p_axtmp)>>2))>>1);
      }
    else
         vel_x = vel_x + (( 3 * (p_axtmp>>2))>>1);

Si lo cambio por la expresión que lo define, no funciona ni en broma:
Código: [Seleccionar]
vel_x += ((((ax - pax)/4)*3)/8);
Si cambio los operadores de sitio, funciona mal pero de diferente manera.
Y si opero independientemente sobre un temporal, funciona pero el movimiento no tiene la fluidez que corresponde, algo varía:
Código: [Seleccionar]
    p_axtmp = (ax - pax);
   
    p_axtmp = p_axtmp/4;
    p_axtmp = p_axtmp*3;
    p_axtmp = p_axtmp/8;
    vel_x += p_axtmp;

He intentado comprobar si entre las operaciones concatenadas se pudiera producir un overflow que me cambiara de signo y creo que es lo que pasa usando la expresion natural de una línea ( a saber como actua el compilador al concatenarlas), pero lo que no acabo de comprender es que varie el movimento al usar la última forma, operando una a una...quizás tambien llegue a overflow en algún momento al operar con el signo directamente o sea culpa de la estructura interna de la operación de division del CCS.
El caso es que operando sin signo, puedo concatenar varias operaciones y prescindo de la división usando desplazamientos que me ahorran una poquita de RAM aunque el código resulte más "guarro".
Creo que al final la práctica se impone al sentdo común.

Salu2
« Última modificación: 02 de Diciembre de 2008, 00:42:43 por droky »
Yo... he visto cosas que vosotros no creeríais... atacar naves en llamas más allá de Orión, he visto rayos C brillar en la oscuridad cerca de la puerta Tannhäuser.
Todos esos momentos se perderán en el tiempo como lágrimas en la lluvia.
Es hora de morir.

Si me buscas en twitter, me tienes por @radikaldesig

Desconectado Nocturno

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 18286
    • MicroPIC
Re: CCS y los números con signo (crash!)
« Respuesta #8 en: 02 de Diciembre de 2008, 03:51:35 »
El caso es que si uso esto funciona perfectamente, como explique anteriormente, quitando el signo, operando y volviendolo a poner:
Código: [Seleccionar]
    p_axtmp = (ax - pax);
    if (p_axtmp<0)
      {
         vel_x = vel_x - ((3*((0-p_axtmp)>>2))>>1);
      }
    else
         vel_x = vel_x + (( 3 * (p_axtmp>>2))>>1);

Lógico que así te funcione. Y si no me equivoco, también es lógico que no te funcione si el signo permanece, puesto que las rotaciones que estás haciendo también moverán el bit de signo.

Si lo cambio por la expresión que lo define, no funciona ni en broma:
Código: [Seleccionar]
vel_x += ((((ax - pax)/4)*3)/8);
Aunque el consumo de recursos se dispare, yo probaría lo siguiente, porque estoy convencido que el problema viene de redondeos y pérdidas de precisión:
Código: [Seleccionar]
vel_x += (signed long)((float)(ax - pax)*0.09375);
He intentado comprobar si entre las operaciones concatenadas se pudiera producir un overflow que me cambiara de signo y creo que es lo que pasa usando la expresion natural de una línea ( a saber como actua el compilador al concatenarlas), pero lo que no acabo de comprender es que varie el movimento al usar la última forma, operando una a una...quizás tambien llegue a overflow en algún momento al operar con el signo directamente o sea culpa de la estructura interna de la operación de division del CCS.
El caso es que operando sin signo, puedo concatenar varias operaciones y prescindo de la división usando desplazamientos que me ahorran una poquita de RAM aunque el código resulte más "guarro".
Creo que al final la práctica se impone al sentdo común.

Salu2

Yo creo que la opción de hacer dos fórmulas, en función del signo con el que vayas a operar, y utilizar desplazamientos para agilizar la operación, tiene todo el sentido común del mundo  :D

Desconectado droky

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 628
    • Diseños radikales libres
Re: CCS y los números con signo (crash!)
« Respuesta #9 en: 02 de Diciembre de 2008, 08:29:58 »
Hola Nocturno,

Aunque el consumo de recursos se dispare, yo probaría lo siguiente, porque estoy convencido que el problema viene de redondeos y pérdidas de precisión:
Código: [Seleccionar]
vel_x += (signed long)((float)(ax - pax)*0.09375);

Pues aunque parezca muy razonable, tampoco funciona como debería. La bola se vuelve loca y ni siquiera responde bien a la inclinación del acelerómetro, con lo que deduzco que al cambiar de posición de forma repentina y de sentido de desplazamiento, está cambiando el signo cuando no debería.
Desconozco ya el motivo del comportamiento y no puedo debuggear variables para hacerme una idea de porqué se comporta así.
Y ciertamente, el consumo de RAM se dispara en un 5-6% que puede no ser mucho pero para un 16F688 me limita otras cosas que quiero implementar.

Salu2
Yo... he visto cosas que vosotros no creeríais... atacar naves en llamas más allá de Orión, he visto rayos C brillar en la oscuridad cerca de la puerta Tannhäuser.
Todos esos momentos se perderán en el tiempo como lágrimas en la lluvia.
Es hora de morir.

Si me buscas en twitter, me tienes por @radikaldesig

Desconectado gONzAO

  • PIC10
  • *
  • Mensajes: 38
Re: CCS y los números con signo (crash!)
« Respuesta #10 en: 20 de Junio de 2010, 15:09:49 »
Hola,
...así que voy a dividir por (por ejemplo por 10)  la velocidad, ya que si divido la aceleracion (ax-pax) me quedo sin rango en ella porque es una escala muy pequeña (aproximadamente 1 bit por cada 2 grados de inclinación).
¿Qué es en realidad lo que divides? Según el código parece que es la aceleración y según el texto la velocidad.

( otra vez v=a*t y e=v/t ).
La segunda está mal ;)

Por otro lado, me gustaría saber si no tienes problemas con los valores que da el ADC.
Yo estoy utilizando el MMA7260 de Freescale y con el ADC del 18F4550 los valores me varían aproximadamente +/-15 con el sensor quieto.

Gracias
gONzAO

Desconectado jfh900

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 3595
Re: CCS y los números con signo (crash!)
« Respuesta #11 en: 21 de Junio de 2010, 04:51:50 »
Parece que el problema está en la forma de guardar los valores de 16 bits internamente. Muchos compiladores guardan ese valor de forma inversa. Primero el bit de menor peso y después el bit de mayor peso. Esto tiene que ver con la forma de procesar el microprocesador, ya que los registros de trabajo trabajan de forma óptima de esta forma. Si intercambias el valor alto con el bajo antes de rotar y después de la rotación deshaces la operación, posiblemente te funcione correctamente.

Un saludo
* Cuando hables, procura que tus palabras sean mejores que el silencio.
* 'Todos somos ignorantes, lo que ocurre es que no todos ignoramos las mismas cosas.' Albert Einstein.
* No hay nada peor que un experto para evitar el progreso en un campo
* "La vida es como una novela. No importa que sea larga, sino que esté bien narrada" Seneca
* La vida no se vive por las veces que respiras, sino por los momentos que dejan sin aliento.
* Dios dijo: ∇·E=ρ/ε0 ; ∇·B=0 ; ∇xE=-dB/dt ; ∇xB= μ0ε0dE/dt..y la luz se hizo..!!..

Desde España Jesús

Desconectado droky

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 628
    • Diseños radikales libres
Re: CCS y los números con signo (crash!)
« Respuesta #12 en: 21 de Junio de 2010, 05:53:21 »
Hola,
...así que voy a dividir por (por ejemplo por 10)  la velocidad, ya que si divido la aceleracion (ax-pax) me quedo sin rango en ella porque es una escala muy pequeña (aproximadamente 1 bit por cada 2 grados de inclinación).
¿Qué es en realidad lo que divides? Según el código parece que es la aceleración y según el texto la velocidad.
El código puede dar lugar a confusión, pero si tienes en cuenta el orden de preferencia de operadores de CCS, el desplazamiento (division) se hace a la velocidad, ya que la suma le precede

( otra vez v=a*t y e=v/t ).
La segunda está mal ;)

Por otro lado, me gustaría saber si no tienes problemas con los valores que da el ADC.
Yo estoy utilizando el MMA7260 de Freescale y con el ADC del 18F4550 los valores me varían aproximadamente +/-15 con el sensor quieto.

Pues sí, ha sido un error de transcripción, e=v*t.
Para eliminar esa variación, deberías implementar un filtrado digital por software, por ejemplo un filtro kalman del que se ha hablado mucho por aquí.
Si te fijas, en mi código, existe un desplazamiento de 3 bits en las aceleraciones, con lo que esos +/-15 casi desaparecen ya que no es necesaria esa precisión para este caso en particular.
Salu2
Yo... he visto cosas que vosotros no creeríais... atacar naves en llamas más allá de Orión, he visto rayos C brillar en la oscuridad cerca de la puerta Tannhäuser.
Todos esos momentos se perderán en el tiempo como lágrimas en la lluvia.
Es hora de morir.

Si me buscas en twitter, me tienes por @radikaldesig