Tabla de contenido:

Wallace - Robot autónomo de bricolaje - Parte 5 - Agregar IMU: 9 pasos
Wallace - Robot autónomo de bricolaje - Parte 5 - Agregar IMU: 9 pasos

Video: Wallace - Robot autónomo de bricolaje - Parte 5 - Agregar IMU: 9 pasos

Video: Wallace - Robot autónomo de bricolaje - Parte 5 - Agregar IMU: 9 pasos
Video: Learn French While You Sleep - A2 - French Conversation 2024, Noviembre
Anonim
Image
Image

Seguimos adelante con Wallace. El nombre Wallace vino de una mezcla de "Wall-E", y de un proyecto anterior (reconocimiento de voz), y al usar la utilidad "espeak", sonaba un poco británico. Y como un ayuda de cámara o un mayordomo. Y ese es el objetivo final: que este proyecto se convierta en algo útil. Así "Wallace".

Wallace puede moverse, puede evitar obstáculos usando sensores de distancia IR (recientemente, de alguna manera se frieron (?) (Tengo que mirar eso cuando tengo la oportunidad), también tiene algunos sensores de distancia acústicos (tres de ellos se estropearon al mismo tiempo) tiempo, junto con un expansor MCP23017) y, finalmente, puede detectar cambios en la corriente del motor para saber cuándo choca con algo.

Además de los sensores, Wallace "recuerda" los 100 movimientos y tiene un análisis rudimentario utilizando el historial de movimientos.

Hasta ahora, el objetivo de Wallace es simplemente tratar de seguir avanzando y saber cuándo está atascado en algún patrón repetitivo (como en una esquina) y no avanza realmente.

He pasado por varias iteraciones para el movimiento y la navegación, y el dolor de cabeza constante ha sido durante la rotación.

Dado que Wallace es un robot rastreado, y yo quería simplificar las cosas en el software (para más adelante), para poder girar, simplemente lo hago pivotar / rotar en su lugar. Por lo tanto, aplique un ciclo de trabajo / potencia igual pero opuesto a los motores.

El problema encontrado se debe al diseño de la plataforma de robot Agent 390. Las correas de la oruga tienden a rozar los lados. Y lo que es peor, un lado lo hace más que el otro.

En pavimento y en línea recta, no ha sido un problema. Aparece en la alfombra. Elegí mantener a Wallace alejado de la alfombra después de que las pistas se ensuciaron (recogen la suciedad con mucha facilidad).

El verdadero problema es cuando se gira sobre el suelo.

Si hago que el software aplique un ciclo de trabajo de alto nivel, entonces gira de manera más o menos consistente. Sin embargo, durante un ciclo de trabajo bajo, puede que gire o no. O puede girar un poco y luego disminuir la velocidad. La acción de pivote parece ser incontrolable a través del software o, en el mejor de los casos, muy difícil.

El problema aparece durante la navegación y al moverse o alejarse de los obstáculos. Puede alejarse demasiado violentamente o atascarse al intentar hacer turnos muy pequeños, sin siquiera moverse.

Y entonces la explicación anterior motivó este Instructable.

Inicialmente, quería prescindir o retrasar la introducción de una unidad de detección de movimiento (IMU), porque son A) complicadas, B) ruidosas, C) se pueden introducir errores con el tiempo, etc., etc. Ha sido que podríamos hacerlo muy bien adelantándonos a los sensores láser IR de tiempo de vuelo. Y podríamos, usando láseres, podríamos saber si el robot giraba o no, rastreando los cambios en la distancia.

De hecho, también podríamos (más o menos) hacer eso ahora, con los sensores acústicos.

Sin embargo, todo eso es una forma muy indirecta y complicada de responder a una simple pregunta: "¿hemos rotado o no?"

Me pareció que saltar para usar los sensores láser ToF me llevaría al siguiente nivel de software; a saber, SLAM (localización y mapeo simultáneos). Todavía no estaba listo para ir allí.

Es bueno hacer un proyecto de robot en capas, con las primeras capas (inferiores) más simples y las últimas capas (superiores) más abstractas y que abordan problemas más difíciles.

Las capas se pueden pensar en algo como esto:

  1. estructura física del robot / base estructural mecánica
  2. sistema de accionamiento rudimentario (Raspberry, Roboclaw, motores, cableado, etc., software básico, controlado por teclado)
  3. circuitos esenciales para admitir sensores (variador de voltaje bidireccional, expansor de puerto, parada de emergencia, distribución de energía, etc.)
  4. sensores para evitar obstáculos (acústicos, infrarrojos)
  5. Posicionamiento y detección de movimiento básicos y esenciales (acelerómetro, giroscopio, magnetómetro, codificadores de motor, codificadores de rueda)

Puedes crear tu propia lista. Los puntos de esta lista son que probablemente deberías hacerlos más o menos en ese orden, y también que si dedicas algún tiempo a cada capa para que cada una de ellas funcione bien, eso debería ayudarte más adelante a medida que las cosas se complican.

La lista anterior podría mapearse más o menos a estas capas conceptuales en el software.

  • SLAM (localización y mapeo simultáneos)
  • Control y conciencia de movimiento, rotación
  • Evitación básica de obstáculos
  • Control y detección de datos de sensores
  • Movimiento esencial hacia adelante, hacia atrás, izquierda y derecha, acelerar, desacelerar, detener

Como puede ver, para esta lista, los primeros elementos serían las capas superiores más complicadas que abordan cuestiones y preguntas más abstractas, como "dónde estoy" y "dónde voy", mientras que los últimos elementos serían los capas de software inferiores que manejan "cómo hablar / escuchar el sensor A" o "cómo mover esta rueda".

Ahora, no estoy diciendo que cuando comienzas en una capa, la hayas completado y luego esté en la siguiente capa, para nunca volver a la anterior. Un proyecto de robot puede parecerse mucho a los métodos de desarrollo de software modernos e iterativos (ágil, SCRUM, etc.).

Solo digo que dedique tiempo a cada uno. Tendrá que equilibrar cuánto hacer en cada uno y decidir si lo que está intentando en una determinada capa vale la pena el tiempo y la molestia.

Existe un cierto "conflicto" o "tensión" entre dos ideas o direcciones en competencia.

Uno es lo que yo llamaría "plug-n-play" para resolver el problema A.

El otro es bricolaje (hágalo usted mismo). Y puede que ni siquiera sea la mejor etiqueta para esta otra idea.

Aquí hay un ejemplo de cada uno, con suerte verá la tensión o el conflicto entre las dos opciones.

Para este ejemplo, agrupemos SLAM, evitación de obstáculos y movimiento básico esencial, todo como un problema para resolver al mismo tiempo.

  1. Si decidimos seguir la ruta plug-n-play, saltamos inmediatamente (según el presupuesto) a cosas como los láseres giratorios montados en la parte superior, la cámara de profundidad de campo o los láseres ToF y la IMU (tema de este Instructable).
  2. Si, por otro lado, queremos ir por la segunda ruta, podemos intentar extraer toda la información posible de algunos sensores acústicos o sensores IR, o ningún sensor en absoluto, solo usamos el monitoreo de la corriente del motor (golpe)

¿Qué se puede decir sobre el n. ° 1 contra el n. ° 2? Una cosa sería que habremos aprendido mucho más haciendo el n. ° 2. Las limitaciones de tener solo sensores acústicos con los que trabajar, nos obliga a pensar en muchas más cuestiones.

Por otro lado, si estamos demasiado concentrados en hacer las cosas a través del n. ° 2, es posible que estemos perdiendo el tiempo, porque pedimos más de lo que deberíamos a los sensores acústicos.

Un concepto o idea más para pensar: qué combinación de hardware y software responde mejor a las preguntas de "cómo" y qué combinación de software (y hardware) responde a la pregunta de "qué", "cuándo", "dónde".. Porque "cómo" es típicamente una pregunta de nivel inferior de la que dependen "qué", "cuándo" y "dónde" para obtener una respuesta.

De todos modos, todo lo anterior era solo algo en lo que pensar.

En mi caso, después de mucho esfuerzo y tener el molesto problema constante de la fricción en la pista y no poder obtener un control y movimiento consistentes, es hora de hacer otra cosa.

Por lo tanto, este Instructable: una IMU.

El objetivo es que si la IMU dice que el robot NO está girando, aumentemos el ciclo de trabajo. Si estamos girando demasiado rápido, disminuimos el ciclo de trabajo.

Paso 1: el sensor IMU

El sensor IMU
El sensor IMU
El sensor IMU
El sensor IMU

Entonces, nuestro próximo sensor para agregar a Wallace es el IMU. Después de investigar un poco, me decidí por un MPU6050. Pero entonces, en este momento, el MPU9050 (e incluso más recientemente, el MPU9250) parecía una idea aún mejor.

Mi fuente de referencia ha sido Amazon (en los EE. UU.). Así que ordené dos de ellos.

Lo que obtuve de hecho (parece que no hay control sobre esto; eso es lo que no me gusta de Amazon) fueron dos MPU92 / 65. Me pregunto un poco sobre la designación. Eche un vistazo a las imágenes; que parece ser una designación de "familia". En cualquier caso, eso es con lo que estoy atrapado.

Agregarlo es muy simple: obtenga una placa proto con pistas de conexión, suelde el sensor a la placa, agregue un bloque de terminales de tornillo de 10 pines (obtuve el mío de Pololu).

Para minimizar cualquier interferencia, traté de colocar estos sensores lejos de todo lo demás.

Eso también significó usar algunos tornillos / tuercas de nailon.

Voy a utilizar el protocolo I2C. Es de esperar que la longitud total del cable no sea tan mala.

Hay mucha información en otros lugares sobre las conexiones básicas y los niveles de voltaje, etc., por lo que no repetiré eso aquí.

Paso 2: las cosas no siempre son fáciles y limpias

Al momento de escribir este artículo, no parece haber mucho en línea para este MPU-92/65 en particular. Lo que está disponible, al igual que con la mayoría de los sensores, parecen ser ejemplos que usan Arduino.

Intento hacer que estos Instructables sean un poco diferentes al presentar un proceso no tan limpio, porque las cosas no siempre funcionan de inmediato.

Supongo que estos Instructables son más similares a un blog que directamente A-B-C, 1-2-3 "así es como se hace".

Paso 3: prueba inicial

Prueba inicial
Prueba inicial
Prueba inicial
Prueba inicial

De las imágenes del paso anterior, los cables rojo y negro que van a los sensores son, por supuesto, VCC (5V) y GND. Los cables verde y amarillo son las conexiones I2C.

Si ha realizado otros proyectos I2C, o ha estado siguiendo estas series, entonces ya conoce "i2cdetect", y ese es el primer paso para saber si la Raspberry puede ver el nuevo sensor.

Como puede ver en las imágenes de este paso, nuestro primer intento no tuvo éxito. La IMU no aparece (debe ser el id. De dispositivo 0x68).

Sin embargo, la buena noticia es que el bus I2C está funcionando. Vemos un dispositivo 0x20 y es el expansor de puerto MCP23017 (actualmente responsable de los sensores acústicos HCSR04).

No es fácil de ver en la imagen, pero conecté los mismos cables de color verde y amarillo desde la IMU al MCP23017 (vea la parte inferior izquierda de la imagen)

Tendremos que solucionar algunos problemas.

Paso 4: solución de problemas

Image
Image
Solución de problemas
Solución de problemas
Solución de problemas
Solución de problemas

Usando la configuración de continuidad en un voltímetro (el que tiene el tono agudo), probé conexiones VCC (5V), GND, SDA y SCL. Aquellos eran buenos.

El siguiente intento fue desconectar el MCP23017 del bus I2C, dejando solo el MPU-92/65 en el bus. Eso resultó infructuoso: "i2cdetect" no mostró ningún dispositivo.

Entonces, a continuación, desmonté el sensor del tótem y lo volví a conectar directamente al bus bidireccional de 5 V a 3 V; es decir, directamente a la frambuesa. (¿cables más cortos?).

Y voilá. Esta vez hay éxito. Vemos que 0x68 aparece usando "i2cdetect".

Pero aún no sabemos por qué funcionó esta vez. ¿Podría ser la longitud de los cables? ¿La ubicación anterior?

Nota: No importaba si ADO estaba conectado a tierra o no. Podría ser que haya resistencias pullup y pull-down a bordo. Lo mismo podría ser cierto para FSYNC.

A continuación, volví a conectar el MCP23017. Entonces ahora tenemos dos dispositivos en el bus I2C. (ver imagen). Éxito, ahora vemos tanto 0x20 como 0x68 con i2cdetect.

Los videos explican un poco más lo que sucedió durante la resolución de problemas.

Paso 5: lectura de los datos del sensor

Image
Image
Leer los datos del sensor
Leer los datos del sensor
Leer los datos del sensor
Leer los datos del sensor

Varios enfoques

Decidí adoptar varios enfoques para obtener información útil del sensor. Aquí están, no en ningún orden:

  1. prueba algo de programación básica
  2. revise alguna documentación en línea sobre registros
  3. eche un vistazo a los ejemplos y / o el código de otros

¿Por qué estos enfoques? ¿Por qué no buscar simplemente alguna biblioteca o código existente?

Experimentando y probando algunas ideas, podemos absorber mejor algunos conocimientos no solo sobre este sensor en particular, sino también adquirir alguna técnica, habilidad y formas de pensar para abordar algo nuevo, y algo que puede no tener mucha documentación; algo que puede tener muchas incógnitas.

Además, una vez que hayamos jugado y probado algunas de nuestras propias ideas y adquirido algo de información, estaremos en una mejor posición para evaluar el código o la biblioteca de otra persona.

Por ejemplo, después de mirar algo de código C ++ para el MPU9250 en github, me di cuenta de que me estaba obligando a usar interrupciones, lo que todavía no deseo hacer.

Además, viene con cosas adicionales como calibración; de nuevo, algo en lo que todavía no estoy interesado.

Puede ser que lo que necesito hacer para responder a la simple pregunta "si el robot gira sí o no" podría responderse de manera muy simple con solo leer algunos registros.

Registros

Al momento de escribir este artículo, no parece haber mucho disponible en este sensor. De hecho, si miras las imágenes que vienen con este Instructable y miras de cerca las inscripciones en los chips reales, me pregunto si esto no es una imitación. No relaciono lo que veo con nada de Invense. Independientemente, elegí mirar la información de registro de los modelos que encontré: el MPU-6050 y el MPU-9250.

En ambos casos, lo siguiente es igual para ambos. Y para empezar, asumimos que también será lo mismo para este MPU-92/65.

59 a 64 - mediciones de acelerómetro

65, 66 - mediciones de temperatura 67 a 72 - mediciones de giroscopio 73 a 96 - datos de sensor externo

Una nota importante: el MPU-6050 parece NO tener un magnetómetro, mientras que el MPU-9250 (y asumimos que este también) sí tiene uno.

Alguna información más interesante, con suerte útil, obtenida del documento de registro:

Información del magnetómetro:

id del magnetómetro: 0x48 registros 00 a 09: 00H WIA 0 1 0 0 1 0 0 0 01H INFO INFO7 INFO6 INFO5 INFO4 INFO3 INFO2 INFO1 INFO0 02H ST1 0 0 0 0 0 0 DOR DRDY 03H HXL HX7 HX6 HX5 HX4 HX3 HX2 HX1 HX0 HXH HX15 HX14 HX13 HX12 HX11 HX10 HX9 HX8 05H HYL HY7 HY6 HY5 HY4 HY3 HY2 HY1 HY0 06H HYH HY15 HY14 HY13 HY12 HY11 HY10 HY9 HY8 07H HZL HZ7 HZ6 HZ5 HZ4 HZ3 HZ2 HZ12 HZ HZ11 ST2 0 0 0 BITM HOFL 0 0 0 un desglose de lo que significa cada registro: HXL [7: 0]: datos de medición del eje X inferiores a 8 bits HXH [15: 8]: datos de medición del eje X superiores a 8 bits HYL [7: 0]: Datos de medición del eje Y más bajo de 8 bits HYH [15: 8]: datos de medición del eje Y más alto de 8 bits HZL [7: 0]: datos de medición del eje Z más bajo de 8 bits HZH [15: 8]: datos de medición del eje Z más alto 8 bits

Programación

Otra información de los documentos de registro es que parecía haber solo unos 100 registros. Entonces, una táctica podría ser escribir un programa simple que acceda al dispositivo (0x68) e intente leer una serie de registros secuencialmente, sin tener en cuenta su significado, solo para ver qué datos se pueden ver.

Y luego, realice pasadas sucesivas, utilizando el mismo código, y compare los datos de una pasada con la siguiente.

La idea es que probablemente podríamos eliminar cualquier registro que parezca no tener datos (¿ceros o FF?) O que absolutamente nunca cambie, y también podríamos centrarnos en los que sí cambian.

Luego, si estamos viendo solo los que cambian, agregue una función de promedio que promedia las últimas N lecturas de ese registro, para ver si de hecho hay un cierto valor estable para ese registro. Esto supondría que mantenemos el sensor muy quieto y en la misma ubicación.

Finalmente, podríamos probar cosas con cuidado con el sensor, como empujarlo (acelerómetro, giroscopio) o soplarlo (temperatura), o rotarlo (los dos anteriores más el magnetómetro) y ver qué efecto tiene esto en los valores.

Me gusta usar la biblioteca wirePi tanto como sea posible. Tiene soporte para I2C.

Primer intento:

/********************************************************************************

* para construir: gcc first.test.mpu9265.c -o first.test.mpu9265 -lwiringPi * * para ejecutar: sudo./first.test.mpu9265 * * este programa acaba de generar un rango de (posibles) registros del MCP23017, * y luego desde el MPU9265 (o cualquier otro MPU en esa dirección 0x68) * * Lo usé para validar si podía leer desde el sensor, ya que ya * tenía confianza en el MCP23017. * *********************************************** **************************** / #include #include #include #include #include int main (int argc, char ** argv) {put ("Veamos qué tiene que decir MCP23017 @ 0x20:"); errno = 0; int deviceId1 = 0x20; int fd1 = cableadoPiI2CSetup (deviceId1); if (-1 == fd1) {fprintf (stderr, "No se puede abrir el dispositivo wirePi I2C:% s / n", strerror (errno)); return 1; } for (int reg = 0; reg <300; reg ++) {fprintf (stderr, "% d", cableadoPiI2CReadReg8 (fd1, reg)); fflush (stderr); retraso (10); } pone(""); put ("Veamos qué tiene que decir MPU9265 @ 0x20:"); errno = 0; int deviceId2 = 0x68; int fd2 = cableadoPiI2CSetup (deviceId2); if (-1 == fd2) {fprintf (stderr, "No se puede abrir el dispositivo wirePi I2C:% s / n", strerror (errno)); return 1; } for (int reg = 0; reg <300; reg ++) {fprintf (stderr, "% d", wirePiI2CReadReg8 (fd2, reg)); fflush (stderr); retraso (10); } pone(""); return 0; }

La segunda carrera:

/********************************************************************************

* para construir: gcc second.test.mpu9265.c -o second.test.mpu9265 -lwiringPi * * para ejecutar: sudo./second.test.mpu9265 * * Este programa genera el número de registro junto con el valor leído. * * Esto hace que sea útil canalizar (redirigir) la salida a un archivo, y luego * se pueden realizar varias ejecuciones para comparar. Podría dar una idea de * qué registros son importantes y cómo podrían comportarse los datos. * ********************************************** *************************** / #include #include #include #include #include #include int main (int argc, char ** argv) {int deviceId = -1; if (0) {} else if (! strncmp (argv [1], "0x20", strlen ("0x20"))) {deviceId = 0x20; } más si (! strncmp (argv [1], "0x68", strlen ("0x68"))) {deviceId = 0x68; } más si (! strncmp (argv [1], "0x69", strlen ("0x69"))) {deviceId = 0x69; } put ("Veamos qué tiene que decir MPU9265 @ 0x20:"); errno = 0; int fd = cableadoPiI2CSetup (deviceId); if (-1 == fd) {fprintf (stderr, "No se puede abrir el dispositivo wirePi I2C:% s / n", strerror (errno)); return 1; } for (int reg = 0; reg <300; reg ++) {fprintf (stderr, "% d:% d / n", reg, wirePiI2CReadReg8 (fd, reg)); fflush (stderr); retraso (10); } return 0; }

La tercera carrera:

/********************************************************************************

* para construir: gcc third.test.mpu9265.c -o third.test.mpu9265 -lwiringPi * * para ejecutar: sudo./third.test.mpu9265 * * Este programa es el resultado del segundo. Solo lee de los registros * que indicaron una diferencia entre una ejecución y la siguiente.* ********************************************** *************************** / #include #include #include #include #include #include int main (int argc, char ** argv) {int deviceId = -1; if (0) {} else if (! strncmp (argv [1], "0x68", strlen ("0x68"))) {deviceId = 0x68; } más si (! strncmp (argv [1], "0x69", strlen ("0x69"))) {deviceId = 0x69; } put ("Veamos qué tiene que decir MPU9265 @ 0x20:"); errno = 0; int fd = cableadoPiI2CSetup (deviceId); if (-1 == fd) {fprintf (stderr, "No se puede abrir el dispositivo wirePi I2C:% s / n", strerror (errno)); return 1; } for (int reg = 61; reg <= 73; reg ++) {fprintf (stderr, "% d:% d / n", reg, wirePiI2CReadReg8 (fd, reg)); fflush (stderr); retraso (10); } for (int reg = 111; reg <= 112; reg ++) {fprintf (stderr, "% d:% d / n", reg, wirePiI2CReadReg8 (fd, reg)); fflush (stderr); retraso (10); } for (int reg = 189; reg <= 201; reg ++) {fprintf (stderr, "% d:% d / n", reg, wirePiI2CReadReg8 (fd, reg)); fflush (stderr); retraso (10); } for (int reg = 239; reg <= 240; reg ++) {fprintf (stderr, "% d:% d / n", reg, wirePiI2CReadReg8 (fd, reg)); fflush (stderr); retraso (10); } return 0; }

Entonces, ¿qué aprendimos hasta ahora? La imagen de la tabla con áreas resaltadas de color indica que la salida parece coincidir con los primeros conjuntos de registros.

Los resultados hasta ahora pueden generar nuevas preguntas.

Pregunta: ¿por qué hay un solo resultado de registro para el grupo "externo"?

Pregunta: ¿qué son todos esos registros desconocidos "??????"

Pregunta: dado que el programa no está controlado por interrupciones, ¿solicitó datos demasiado lento? ¿demasiado rapido?

Pregunta: ¿podemos afectar los resultados probando cosas con el sensor mismo mientras se ejecuta?

Paso 6: profundicemos en las lecturas / datos

Creo que el siguiente paso antes que nada es mejorar el programa para:

  • Sea flexible en cuanto a la demora de bucle (ms)
  • Sea flexible en cuanto a la cantidad de lecturas para dar un promedio móvil por registro.

(Tuve que adjuntar el programa como un archivo. Parecía ser un problema insertarlo aquí. "Cuarto.prueba.mpu9265.c")

Aquí hay una ejecución usando las últimas 10 lecturas para un promedio, en un bucle de 10 ms:

sudo./fourth.test.mpu9265 0x68 10 10

61:255 0 255 0 255 0 255 0 0 0: 102 62:204 112 140 164 148 156 188 248 88 228: 167 63:189 188 189 187 189 188 188 188 188 189: 188 64: 60 40 16 96 208 132 116 252 172 36: 112 65: 7 7 7 7 7 7 7 7 7 7: 7 66:224 224 224 240 160 208 224 208 144 96: 195 67: 0 0 0 0 0 0 0 0 0 0: 0 68:215 228 226 228 203 221 239 208 214 187: 216 69: 0 255 0 255 255 0 255 0 0 0: 102 70:242 43 253 239 239 45 206 28 247 207: 174 71: 0 255 255 0 255 255 255 255 255 255: 204 72: 51 199 19 214 11 223 21 236 193 8: 117 73: 0 0 0 0 0 0 0 0 0 0: 0 111: 46 149 91 199 215 46 142 2 233 199: 132 112: 0 0 0 0 0 0 0 0 0 0: 0 189:255 0 255 0 255 0 0 255 0 255: 127 190: 76 36 240 36 100 0 164 164 152 244: 121 191:188 188 188 188 187 188 187 189 187 189: 187 192: 8 48 48 196 96 220 144 0 76 40: 87 193: 7 7 7 7 7 8 7 7 7 7: 7 194:208 224 144 240 176 240 224 208 240 224: 212 195: 0 0 0 0 0 0 0 0 0 0: 0 196:243 184 233 200 225 192 189 242 188 203: 209 197:255 0 0 0 255 0 255 0 0 255: 102 198:223 39 247 43 245 22 255 221 0 6: 130 199: 0 255 255 255 0 255 255 255 255 0: 178 200:231 225 251 1 252 20 211 216 218 16: 164 201: 0 0 0 0 0 0 0 0 0 0: 0 239: 21 138 196 87 26 89 16 245 187 144: 114 240: 0 0 0 0 0 0 0 0 0 0: 0

La primera columna situada más a la izquierda es el número de registro. Luego vienen las últimas 10 lecturas para ese registro. Finalmente, la última columna es el promedio de cada fila.

Parece que los registros 61, 69, 71, 189, 197 y 199 son solo binarios, o están listos / no listos, o son el byte alto de un valor de 16 bits (¿negativo?).

Otras observaciones interesantes:

  • registros 65, 193 - muy estable y el mismo valor
  • registro 63, 191 - muy estable y el mismo valor
  • registros 73, 112, 195, 201, 240 - todos en cero

Relacionemos estas observaciones con la imagen de la tabla resaltada de varios colores de antes.

Registro 65 - temperatura

Registro 193 - ??????

Registro 63 - acelerómetro

Registro 191 - ??????

Registro 73 - externo

Regístrese 112 y en adelante - ??????

Bueno, todavía tenemos incógnitas, sin embargo, hemos aprendido algo útil.

El registro 65 (temperatura) y el registro 63 (acelerómetro) fueron muy estables. Esto es algo que esperaríamos. No he tocado el sensor; no se mueve, aparte de las vibraciones accidentales, ya que el robot está descansando sobre la misma mesa que mi computadora.

Hay una prueba interesante que podemos hacer para cada uno de estos registros de temperatura / acelerómetro. Para esa prueba, necesitamos otra versión del programa.

Paso 7: podemos afectar la temperatura y la aceleración

En los pasos anteriores, redujimos al menos un registro de temperatura y otro de aceleración.

Con esta próxima versión del programa ("quinta.prueba.mpu9265.c"), podemos ver un cambio en ambos registros. Por favor mire los videos.

Más excavación

Si retrocedemos y echamos un vistazo a la información del registro, vemos que hay:

  • tres salidas de 16 bits para giroscopio
  • tres salidas de 16 bits para acelerómetro
  • tres salidas de 16 bits para magnetómetro
  • una salida de 16 bits para temperatura

Sin embargo, los resultados obtenidos por nuestros programas de prueba simples fueron todos salidas individuales de 8 bits. (registros únicos).

Intentemos más del mismo enfoque, pero esta vez leyendo 16 bits en lugar de 8.

Probablemente tengamos que hacer algo como a continuación. Usemos la temperatura como ejemplo, ya que es solo una salida de 16 bits.

// obtener el descriptor de archivo fd…

int tempRegHi = 65; int tempRegLo = 66; int hiByte = cableadoPiI2CReadReg8 (fd, tempRegHi); int loByte = cableadoPiI2CReadReg8 (fd, tempRegLo); int resultado = hiByte << 8; // coloca los 8 bits de orden superior en la parte superior de un resultado de valor de 16 bits | = loByte; // ahora agregue en el orden inferior 8 bits, obteniendo un número completo de 16 bits // imprima ese número o use la función de visualización de gráficos horizontales de antes

En nuestros pasos anteriores, hemos visto que el registro 65 es bastante estable, mientras que el registro 66 es muy ruidoso. Dado que 65 es el byte de orden superior y 66 el byte de orden inferior, eso tiene sentido.

Para la lectura, podemos tomar los datos del registro 65 como están, pero podemos promediar los valores del registro 66.

O simplemente podemos promediar todo el resultado.

Eche un vistazo al último video de esta parte; demuestra la lectura de todo el valor de temperatura de 16 bits. El código es "6th.test.mpu9265.c"

Paso 8: Acelerómetro y giroscopio

Image
Image

Los videos de esta sección muestran la salida del acelerómetro y el giroscopio, utilizando un programa de prueba "séptimo.prueba.mpu9265.c". Ese código puede leer 1, 2 o 3 pares de bytes consecutivos (bytes altos y bajos) y convierte los valores en un solo valor de 16 bits. Por lo tanto, podemos leer cualquier eje individual, o podemos leer dos de ellos juntos (y suma los cambios), o podemos leer los tres (y suma los cambios).

Para reiterar, para esta fase, para este Instructable, solo estoy buscando responder una pregunta simple: "¿el robot giró / pivotó?". No estoy buscando ningún valor preciso, como si giró 90 grados. Eso vendrá más tarde cuando lleguemos a hacer SLAM, pero no es necesario para evitar obstáculos simples y movimientos aleatorios.

Paso 9: (trabajo en curso) el magnetómetro

cuando se usa la herramienta i2cdetect, el MPU9265 aparece como 0x68 en la tabla:

0 1 2 3 4 5 6 7 8 9 a b c d e f

00: -- -- -- -- -- -- -- -- -- -- -- -- -- 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 60: -- -- -- -- -- -- -- -- 68 -- -- -- -- -- -- -- 70: -- -- -- -- -- -- -- --

Se requieren pasos adicionales para leer desde la parte del magnetómetro de la IMU.

Desde el documento PDF de registros de Invesense:

REGISTROS 37 A 39 - CONTROL I2C SLAVE 0

  • REGISTRO 37 - I2C_SLV0_ADDR
  • REGISTRO 38 - I2C_SLV0_REG
  • REGISTRO 39 - I2C_SLV0_CTRL

Recomendado: