Thursday, October 6, 2016

Arduino juegos , millis






+

Volcado de temporización Uno de los artículos solicitados que encontré fue la manipulación 'vuelco' de 'millis () "y también," micros ()'. Esto no es realmente un asunto muy difícil de tratar, y es algo que he necesitado para hacer frente a una gran cantidad de veces en diferentes contextos, a partir de los controladores del núcleo de las aplicaciones, y por supuesto, micro-controladores. En primer lugar, voy a explicar de dos matemática del complemento, y firmado vs enteros sin signo. complemento de dos es una manera de representar números negativos en binario. Requiere que se sacrifica un poco de precisión (el bit más significativo), para manejar los valores negativos. Para un entero de 16 bits, el valor de complemento a dos puede representar cualquier número entre -32768 y 32767, ambos inclusive. Por ahora, esto es lo que voy a enfocar. Por definición, si se resta un 1 binario a partir de un cero binario, debe terminar con un -1 binario. Por el contrario, si se agrega un 1 binario a un binario -1, usted debe conseguir cero. Haciendo un poco de extrapolación atmosférica, que es bastante obvio que el siguiente es cierto. 1111111111111111 + 0000000000000001 = 0000000000000000 Si hubiera otro poco se muestra (es decir, el 'carry' bits) que se vería un número de 17 bits con el bit alto. Pero esto es la consecuencia de la utilización de un valor binario de longitud fija. Se obtiene el 'vuelco'. En consecuencia de la adición de 1 binario a "todos de 1" para llegar a cero, el siguiente también será cierto: 0000000000000000 - 0000000000000001 = 1111111111111111 Por lo que la representación de un -1 debe ser '' todos los bits 1 para cualquier número entero de complemento a dos, dado un tamaño de número entero de longitud fija en bits. Ahora bien, es importante distinguir 'sin signo' de 'firmado' operaciones con números enteros. Si desea restar dos valores sin signo, y tienen un resultado negativo si el segundo es más grande, que tiene que emitir el resultado a un entero con signo. Esto tratar el resultado sin firmar como si se tratara de complemento a dos, así: unsigned int i, j; . Y, este es el corazón de la solución a 'vuelco'. En el caso en que el valor de "i" aún no ha 'cruzado' el valor de 'j', el resultado de 'i - j' (emitido en un entero) será negativo. Si 'i' cruces 'j', el resultado será positivo. Ejemplo: Suponiendo que 'millis ()' devuelven un entero de 16 bits (para simplificar), si los 'millis ()' actuales tiempo es 65500 y quiere esperar a 1000 milisegundos, puede usar las matemáticas sin firmar para agregar 1000 a 65500 y obtener un resultado de 964 (desplazamiento sobre a cero en lo que sería 65536). Cuando 'millis ()' la resolución de 16 bits se da la vuelta 'a cero, que seguirán aumentando hasta que, también, alcanza el valor 964. En ese momento, su código de temporizador puede reconocer el "cruce" restando el tiempo de espera de millis (), convirtiéndolo a un entero con signo, y la comprobación de que es mayor que o igual a cero. El siguiente código comprueba para ver si ha "cruzado" a "punto de retardo '1000 milisegundos, e inician otra temporizador de retardo de 1000 milisegundos después de algún tipo de procesamiento periódico. El mismo tipo de código puede ser aplicado a 'micros ()' también. lWaitMillis largos sin signo estáticas; void setup () {\\ lWaitMillis = millis () + 1000; // configuración inicial } void loop () \\ {if ((largo) (Millis () - lWaitMillis) & gt; = 0) {// millis es ahora más tardar mi tiempo "siguiente" { hacer algo } lWaitMillis + = 1,000; // Hacerlo de nuevo 1 segundo más tarde} else {// millis sigue siendo "antes" mi tiempo "siguiente" // así que seguir esperando de retardo (1); // Una cosa que puede hacer posible}} Resolver el vuelco con la aritmética de registros El diagrama siguiente muestra cómo utilizar las variables sin signo, utilizando la aritmética registro para superar el problema de vuelco. El resultado se envía al monitor de serie. Si el cálculo de Millis () y (micros) se realiza con largo sin signo, la diferencia entre el nuevo tiempo y el tiempo antiguo es siempre válida, incluso en caso de un vuelco. Recuerda usar siempre las variables de largo sin signo para hacer este trabajo. // ------------------------------------------------ ------- // // // rollover boceto demostración Resolver el vuelco con la aritmética de registros // // Otro boceto de prueba para: // // // http://playground. arduino. cc/Code/TimingRollover El uso de piezas de: // // // http://arduino. cc/en/Tutorial/BlinkWithoutDelay dominio público // // Variables para la manifestación en la función de configuración (). // Las variables son & quot; & quot volátil; para forzar el cálculo // en el microcontrolador Arduino por sólo esta prueba. // No es necesario & quot; & quot volátil; en su dibujo. // Byte p volátil. q. r; volátil largo sin signo ulNew. ulOld. ul; // Variables para el parpadeo del LED. // Creado por: // // Pero http://arduino. cc/en/Tutorial/BlinkWithoutDelay actualizado para resolver el problema de vuelco. // Const int ledPin = 13; int ledState = BAJO; unsigned long ul_PreviousMillis = 0UL; unsigned long ul_Interval = 500 ul; void setup () {serie. comenzar (9600); // Si se utiliza el Leonardo o Micro, // esperar a que el monitor serie para abrir. mientras que (Serial.); De serie. println (F (& quot;. Rollover esbozo de demostración & quot;)); De serie. impresión (F (& quot; La solución del problema de vuelco & quot;)); De serie. println (F (& quot; con la aritmética de registros & quot;.)); De serie. println (& quot; & quot;); De serie. println (F (& quot; prueba con 8 bits sin signo & quot;.)); p = 150; q = 140; r = p - q; De serie. impresión (F (& quot 150; - 140 = & quot;)); De serie. println (r desc.); p = 4; // Vuelco del valor q = 260 250; r = p - q; // Válido para variables sin signo de serie. impresión (F (& quot; 260 (= 4) - 250 = & quot;)); De serie. println (r desc.); De serie. println (& quot; & quot;); De serie. println (F (& quot; prueba con largo sin signo & quot;.)); // http://arduino. cc/en/Reference/UnsignedLong ulNew = 3000000000UL; ulOld = 2000000000UL; ul = ulNew - ulOld; De serie. impresión (F (& quot; 3000000000 - 2000000000 = & quot;)); De serie. println (. ul DEC); ulNew = 705032704UL; // Vuelco del valor de 5.000.000.000 de ulOld = 4000000000UL; ul = ulNew - ulOld; // Válida para Serial largo sin signo. impresión (F (& quot; 5000000000 (= 705032704) - 4000000000 = & quot;)); De serie. println (. ul DEC); De serie. println (& quot; & quot;); // El bucle () función contiene un ejemplo con millis () en serie. impresión (F (& quot; un LED en el pin 13 parpadeará & quot;)); De serie. println (F (& quot; sin error vuelco & quot;)); pinMode (. ledPin SALIDA); ul_PreviousMillis = millis (); } void loop () {// Aquí es donde se coloca el código // que deberá estar funcionando todo el tiempo. // Parpadear los LED. sin firmar largos ul_CurrentMillis = millis (); // Las siguientes líneas son muy importantes // desde los millis () es unsigned long, también la prueba // y la actualización del tiempo debe hacerse con unsigned long. si (ul_CurrentMillis - ul_PreviousMillis & gt; ul_Interval) {// actualizar la última vez que el LED parpadeara // Esta actualización con el intervalo // También se debe hacer con mucho sin firmar. // Opción 1: // Establecer el tiempo anterior a la hora actual. // Un retraso por código cambiará everyting más en el tiempo. ul_PreviousMillis = ul_CurrentMillis; // Opción 2: // Incremento de la vez anterior con el intervalo. // El momento permanece en ritmo. // Un retraso por código, se acortará el siguiente intervalo. // Si dos intervalos se pierden, el siguiente intervalo // será muy corta, ya que está tratando de ponerse al día // con el tiempo. // Ul_PreviousMillis + = ul_Interval; // Si el LED está apagado, encenderlo y viceversa: si (ledState == LOW) ledState = ALTO; otra cosa ledState = BAJO; // Establecer el LED con el ledState de la variable: digitalWrite; (ledPin ledState.) }} El resultado del boceto es:




No comments:

Post a Comment